Added ui capabilities to role management (#181424)

## Summary

Part of the Spaces UX redesign requires us to show the list of roles
which grant access to the space. Since not all users who manage spaces
can also manage roles, we need to make this a conditional view based on
user privileges.

Added `view` UI Capability to role management, it will be available at
`capabilities.roles?.view`


### Checklist

- [x] [Unit or functional
tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)
were updated or added to match the most common scenarios
- [x] [Flaky Test
Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was
used on any tests changed

### For maintainers

- [x] This was checked for breaking API changes and was [labeled
appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)

__Fixes: https://github.com/elastic/kibana/issues/181315__

## Release note
Added UI Capability to role management.

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
elena-shostak 2024-04-26 14:10:54 +02:00 committed by GitHub
parent 96bf7b1f06
commit 63cbdb8be7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 117 additions and 4 deletions

View file

@ -34,11 +34,11 @@ const rolesManagementFeature: ElasticsearchFeatureConfig = {
privileges: [
{
requiredClusterPrivileges: ['manage_security'],
ui: ['save'],
ui: ['save', 'view'],
},
{
requiredClusterPrivileges: ['read_security'],
ui: [],
ui: ['view'],
},
],
};

View file

@ -24,7 +24,7 @@ const NoKibanaPrivileges: User = {
},
};
const Superuser: User = {
export const Superuser: User = {
username: 'superuser',
fullName: 'superuser',
password: 'superuser-password',
@ -96,7 +96,7 @@ const DualPrivilegesRead: User = {
},
};
const GlobalAll: User = {
export const GlobalAll: User = {
username: 'global_all',
fullName: 'global_all',
password: 'global_all-password',
@ -227,6 +227,43 @@ const NothingSpaceRead: User = {
},
};
export const ReadSecurity: User = {
username: 'read_security',
fullName: 'read_security',
password: 'read_security-password',
role: {
name: 'read_security_role',
kibana: [
{
base: ['all'],
spaces: ['*'],
},
],
elasticsearch: {
cluster: ['read_security'],
indices: [],
},
},
};
export const ManageSecurity: User = {
username: 'manage_security',
fullName: 'manage_security',
password: 'manage_security-password',
role: {
name: 'manage_security_role',
kibana: [
{
base: ['all'],
spaces: ['*'],
},
],
elasticsearch: {
cluster: ['manage_security'],
},
},
};
export const Users: User[] = [
NoKibanaPrivileges,
Superuser,
@ -241,6 +278,8 @@ export const Users: User[] = [
EverythingSpaceRead,
NothingSpaceAll,
NothingSpaceRead,
ReadSecurity,
ManageSecurity,
];
const EverythingSpace: Space = {

View file

@ -40,6 +40,7 @@ export default function uiCapabilitiesTests({ loadTestFile, getService }: FtrPro
if (isCustomRoleSpecification(role)) {
await securityService.role.create(role.name, {
kibana: role.kibana,
...(role.elasticsearch ? { elasticsearch: role.elasticsearch } : {}),
});
}
}
@ -66,5 +67,6 @@ export default function uiCapabilitiesTests({ loadTestFile, getService }: FtrPro
loadTestFile(require.resolve('./catalogue'));
loadTestFile(require.resolve('./foo'));
loadTestFile(require.resolve('./nav_links'));
loadTestFile(require.resolve('./roles'));
});
}

View file

@ -0,0 +1,72 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import expect from '@kbn/expect';
import { FtrProviderContext } from '../../common/ftr_provider_context';
import { UICapabilitiesService } from '../../common/services/ui_capabilities';
import {
GlobalAll as GlobalAllUser,
Superuser,
ReadSecurity as ReadSecurityRoleUser,
ManageSecurity as ManageSecurityRoleUser,
} from '../scenarios';
export default function fooTests({ getService }: FtrProviderContext) {
const uiCapabilitiesService: UICapabilitiesService = getService('uiCapabilities');
describe('role management', () => {
it('Superuser role capabilities should have all role capabilities set to true', async () => {
const uiCapabilities = await uiCapabilitiesService.get({
credentials: { username: Superuser.username, password: Superuser.password },
});
expect(uiCapabilities.value!.roles).to.eql({
view: true,
save: true,
});
});
it('User without cluster privilages should have all role capabilities set to false', async () => {
const uiCapabilities = await uiCapabilitiesService.get({
credentials: { username: GlobalAllUser.username, password: GlobalAllUser.password },
});
expect(uiCapabilities.value!.roles).to.eql({
view: false,
save: false,
});
});
it('user with read_security cluster privilege should have view role capabilities set to true', async () => {
const uiCapabilities = await uiCapabilitiesService.get({
credentials: {
username: ReadSecurityRoleUser.username,
password: ReadSecurityRoleUser.password,
},
});
expect(uiCapabilities.value!.roles).to.eql({
view: true,
save: false,
});
});
it('user with manage_security cluster privilege should have view/save role capabilities set to true', async () => {
const uiCapabilities = await uiCapabilitiesService.get({
credentials: {
username: ManageSecurityRoleUser.username,
password: ManageSecurityRoleUser.password,
},
});
expect(uiCapabilities.value!.roles).to.eql({
view: true,
save: true,
});
});
});
}