diff --git a/x-pack/packages/security/ui_components/src/kibana_privilege_table/feature_table_expanded_row.tsx b/x-pack/packages/security/ui_components/src/kibana_privilege_table/feature_table_expanded_row.tsx index 436119884f51d..ad14f76187236 100644 --- a/x-pack/packages/security/ui_components/src/kibana_privilege_table/feature_table_expanded_row.tsx +++ b/x-pack/packages/security/ui_components/src/kibana_privilege_table/feature_table_expanded_row.tsx @@ -132,6 +132,7 @@ export const FeatureTableExpandedRow = ({ onChange={(updatedPrivileges) => onChange(feature.id, updatedPrivileges)} selectedFeaturePrivileges={selectedFeaturePrivileges} disabled={disabled || !isCustomizing || isDisabledDueToSpaceSelection} + allSpacesSelected={allSpacesSelected} /> ); diff --git a/x-pack/packages/security/ui_components/src/kibana_privilege_table/sub_feature_form.tsx b/x-pack/packages/security/ui_components/src/kibana_privilege_table/sub_feature_form.tsx index 21bf95955328b..f2def06147a7a 100644 --- a/x-pack/packages/security/ui_components/src/kibana_privilege_table/sub_feature_form.tsx +++ b/x-pack/packages/security/ui_components/src/kibana_privilege_table/sub_feature_form.tsx @@ -34,6 +34,7 @@ interface Props { onChange: (selectedPrivileges: string[]) => void; disabled?: boolean; categoryId?: string; + allSpacesSelected?: boolean; } export const SubFeatureForm = (props: Props) => { @@ -157,12 +158,18 @@ export const SubFeatureForm = (props: Props) => { privilegeGroup: SubFeaturePrivilegeGroup, index: number ) { + const nonePrivilege = { + id: NO_PRIVILEGE_VALUE, + label: 'None', + isDisabled: props.disabled, + }; + const firstSelectedPrivilege = props.privilegeCalculator.getSelectedMutuallyExclusiveSubFeaturePrivilege( props.featureId, privilegeGroup, props.privilegeIndex - ); + ) ?? nonePrivilege; const options = [ ...privilegeGroup.privileges.map((privilege, privilegeIndex) => { @@ -174,11 +181,12 @@ export const SubFeatureForm = (props: Props) => { }), ]; - options.push({ - id: NO_PRIVILEGE_VALUE, - label: 'None', - isDisabled: props.disabled, - }); + options.push(nonePrivilege); + + const idSelected = + props.subFeature.requireAllSpaces && !props.allSpacesSelected + ? nonePrivilege.id + : firstSelectedPrivilege.id; return ( { data-test-subj="mutexSubFeaturePrivilegeControl" isFullWidth options={options} - idSelected={firstSelectedPrivilege?.id ?? NO_PRIVILEGE_VALUE} + idSelected={idSelected} isDisabled={props.disabled} onChange={(selectedPrivilegeId: string) => { // Deselect all privileges which belong to this mutually-exclusive group diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/privilege_summary/privilege_summary_expanded_row.tsx b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/privilege_summary/privilege_summary_expanded_row.tsx index 83f1e26ad1284..46d6fc34fe497 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/privilege_summary/privilege_summary_expanded_row.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/privilege_summary/privilege_summary_expanded_row.tsx @@ -20,6 +20,7 @@ import type { EffectiveFeaturePrivileges } from './privilege_summary_calculator' interface Props { feature: SecuredFeature; effectiveFeaturePrivileges: Array; + isAllSpacesSelected: boolean; } export const PrivilegeSummaryExpandedRow = (props: Props) => { @@ -37,7 +38,9 @@ export const PrivilegeSummaryExpandedRow = (props: Props) => { {props.effectiveFeaturePrivileges.map((privs, index) => { return ( - {subFeature.getPrivilegeGroups().map(renderPrivilegeGroup(privs.subFeature))} + {subFeature + .getPrivilegeGroups() + .map(renderPrivilegeGroup(privs.subFeature, subFeature.requireAllSpaces))} ); })} @@ -48,7 +51,10 @@ export const PrivilegeSummaryExpandedRow = (props: Props) => { ); - function renderPrivilegeGroup(effectiveSubFeaturePrivileges: string[]) { + function renderPrivilegeGroup( + effectiveSubFeaturePrivileges: string[], + requireAllSpaces: boolean + ) { return (privilegeGroup: SubFeaturePrivilegeGroup, index: number) => { switch (privilegeGroup.groupType) { case 'independent': @@ -61,7 +67,8 @@ export const PrivilegeSummaryExpandedRow = (props: Props) => { return renderMutuallyExclusivePrivilegeGroup( effectiveSubFeaturePrivileges, privilegeGroup, - index + index, + requireAllSpaces ); default: throw new Error(`Unsupported privilege group type: ${privilegeGroup.groupType}`); @@ -112,11 +119,14 @@ export const PrivilegeSummaryExpandedRow = (props: Props) => { function renderMutuallyExclusivePrivilegeGroup( effectiveSubFeaturePrivileges: string[], privilegeGroup: SubFeaturePrivilegeGroup, - index: number + index: number, + requireAllSpaces: boolean ) { - const firstSelectedPrivilege = privilegeGroup.privileges.find((p) => - effectiveSubFeaturePrivileges.includes(p.id) - )?.name; + const isDisabledDueToSpaceSelection = requireAllSpaces && !props.isAllSpacesSelected; + + const firstSelectedPrivilege = !isDisabledDueToSpaceSelection + ? privilegeGroup.privileges.find((p) => effectiveSubFeaturePrivileges.includes(p.id))?.name + : null; return ( diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/privilege_summary/privilege_summary_table.tsx b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/privilege_summary/privilege_summary_table.tsx index 5dc856e5af5d9..82167ed9f1a2d 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/privilege_summary/privilege_summary_table.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/privilege_summary/privilege_summary_table.tsx @@ -52,7 +52,7 @@ function showPrivilege(allSpacesSelected: boolean, primaryFeature?: PrimaryFeatu if ( primaryFeature?.name == null || primaryFeature?.disabled || - (primaryFeature.requireAllSpaces && !allSpacesSelected) + (primaryFeature?.requireAllSpaces && !allSpacesSelected) ) { return 'None'; } @@ -218,6 +218,8 @@ export const PrivilegeSummaryTable = (props: PrivilegeSummaryTableProps) => { }; }); + const isAllSpacesSelected = props.spaces.some((space) => space.id === ALL_SPACES_ID); + accordions.push( { p[featureId])} + isAllSpacesSelected={isAllSpacesSelected} /> ), }; diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/space_aware_privilege_section.tsx b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/space_aware_privilege_section.tsx index 2bb3292932870..2773dd92753ce 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/space_aware_privilege_section.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/space_aware_privilege_section.tsx @@ -218,7 +218,7 @@ export class SpaceAwarePrivilegeSection extends Component { const viewMatrixButton = ( { return [this.globalSpaceEntry, ...this.props.spaces]; }; + private getSelectedSpaces = () => + this.getDisplaySpaces().filter((space) => + this.props.role.kibana.some((entry) => entry.spaces.includes(space.id)) + ); + private getAvailableSpaces = (includeSpacesFromPrivilegeIndex: number = -1) => { const spacesToExclude = _.uniq( _.flatten(