Includes 'spaces' feature ID when disabling capabilities based on privilege (#189675)

Related to https://github.com/elastic/kibana/issues/188318 (see
https://github.com/elastic/kibana/issues/188318#issuecomment-2231636907)

## Summary

This PR includes the root 'spaces' feature ID in the security
capabilities checker when disabling capabilities based on privilege. Due
to changes in the capabilities checker in
https://github.com/elastic/kibana/pull/154098, the root-level 'spaces'
UI capabilities were not properly being disabled based on user
privileges. This bug affected only UI component visibility, and did not
affect the security of spaces in any way.


### Automated Tests
-
x-pack/plugins/security/server/authorization/disable_ui_capabilities.test.ts:
augmented to verify the two exceptional root-level feature IDs that
should be affected by the security capabilities (globalSettings and
spaces).

### Manual Testing
- Start ES & Kibana
- Log in as the elastic operator
- Verify that in the top navigation space selector, the manage spaces
button is visible
- Create a role with access to all spaces, assign all 'all' privileges
individually, DO NOT USE THE 'Privileges for all features' section
- Create new user with only this role, and log in as that user
- Verify that in the top navigation space selector, the manage spaces
button is not visible
This commit is contained in:
Jeramy Soucy 2024-08-05 17:52:31 +02:00 committed by GitHub
parent f2d7a28134
commit f5047b79f4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 30 additions and 4 deletions

View file

@ -362,6 +362,8 @@ describe('usingPrivileges', () => {
{ privilege: actions.ui.get('kibanaFeature2', 'bar'), authorized: false },
{ privilege: actions.ui.get('optOutFeature', 'foo'), authorized: false },
{ privilege: actions.ui.get('optOutFeature', 'bar'), authorized: false },
{ privilege: actions.ui.get('spaces', 'manage'), authorized: false },
{ privilege: actions.ui.get('globalSettings', 'show'), authorized: false },
],
elasticsearch: {
cluster: [
@ -419,6 +421,12 @@ describe('usingPrivileges', () => {
es_manage_sec: true,
},
esManagementFeature: {},
spaces: {
manage: true,
},
globalSettings: {
show: true,
},
})
);
@ -457,6 +465,12 @@ describe('usingPrivileges', () => {
es_manage_sec: true,
},
esManagementFeature: {},
spaces: {
manage: false,
},
globalSettings: {
show: false,
},
});
});
@ -475,6 +489,8 @@ describe('usingPrivileges', () => {
{ privilege: actions.ui.get('kibanaFeature2', 'bar'), authorized: true },
{ privilege: actions.ui.get('optOutFeature', 'foo'), authorized: true },
{ privilege: actions.ui.get('optOutFeature', 'bar'), authorized: true },
{ privilege: actions.ui.get('spaces', 'manage'), authorized: true },
{ privilege: actions.ui.get('globalSettings', 'show'), authorized: true },
],
elasticsearch: {
cluster: [
@ -528,6 +544,12 @@ describe('usingPrivileges', () => {
es_manage_sec: false,
},
esManagementFeature: {},
spaces: {
manage: false,
},
globalSettings: {
show: false,
},
});
const result = await usingPrivileges(allFalseCapabilities);

View file

@ -75,11 +75,15 @@ export function disableUICapabilitiesFactory(
const shouldAffectCapability = (featureId: keyof UICapabilities, uiCapability: string) => {
// This method answers: 'Should we affect a capability based on privileges?'
// 'spaces' and 'fileUpload' feature ID's are handled independently
// The spaces and file_upload plugins have their own capabilites switchers
// 'fileUpload' feature ID is handled independently
// The spaces and file_upload plugins have their own capabilities switchers.
// Always affect global settings
if (featureId === 'globalSettings') {
// The spaces capabilities switcher handles disabling capabilities within a specific
// space, but the root 'spaces' feature ID needs to be affected here, where we can check
// if the current user is privileged to for general spaces capabilities (e.g., manage).
// Always affect global settings, and the "spaces" feature (see above)
if (featureId === 'globalSettings' || featureId === 'spaces') {
return true;
}