;
+ effectiveFeaturePrivileges: EffectivePrivilegesTuple[];
}
export const PrivilegeSummaryExpandedRow = (props: Props) => {
+ const allSpacesEffectivePrivileges = useMemo(
+ () => props.effectiveFeaturePrivileges.find(([spaces]) => spaces.includes(ALL_SPACES_ID)),
+ [props.effectiveFeaturePrivileges]
+ );
+
+ const renderIndependentPrivilegeGroup = useCallback(
+ (
+ effectiveSubFeaturePrivileges: string[],
+ privilegeGroup: SubFeaturePrivilegeGroup,
+ index: number
+ ) => {
+ return (
+
+ {privilegeGroup.privileges.map((privilege: SubFeaturePrivilege) => {
+ const isGranted = effectiveSubFeaturePrivileges.includes(privilege.id);
+ return (
+
+
+
+
+
+
+ {privilege.name}
+
+
+
+ );
+ })}
+
+ );
+ },
+ []
+ );
+
+ const renderMutuallyExclusivePrivilegeGroup = useCallback(
+ (
+ effectiveSubFeaturePrivileges: string[],
+ privilegeGroup: SubFeaturePrivilegeGroup,
+ index: number,
+ isDisabledDueToSpaceSelection: boolean
+ ) => {
+ const firstSelectedPrivilege = !isDisabledDueToSpaceSelection
+ ? privilegeGroup.privileges.find((p) => effectiveSubFeaturePrivileges.includes(p.id))?.name
+ : null;
+
+ return (
+
+
+
+
+
+
+ {firstSelectedPrivilege ?? 'None'}
+
+
+
+ );
+ },
+ []
+ );
+
+ const renderPrivilegeGroup = useCallback(
+ (
+ effectiveSubFeaturePrivileges: string[],
+ { requireAllSpaces, spaces }: { requireAllSpaces: boolean; spaces: string[] }
+ ) => {
+ return (privilegeGroup: SubFeaturePrivilegeGroup, index: number) => {
+ const isDisabledDueToSpaceSelection = requireAllSpaces && !spaces.includes(ALL_SPACES_ID);
+
+ switch (privilegeGroup.groupType) {
+ case 'independent':
+ return renderIndependentPrivilegeGroup(
+ effectiveSubFeaturePrivileges,
+ privilegeGroup,
+ index
+ );
+ case 'mutually_exclusive':
+ return renderMutuallyExclusivePrivilegeGroup(
+ effectiveSubFeaturePrivileges,
+ privilegeGroup,
+ index,
+ isDisabledDueToSpaceSelection
+ );
+ default:
+ throw new Error(`Unsupported privilege group type: ${privilegeGroup.groupType}`);
+ }
+ };
+ },
+ [renderIndependentPrivilegeGroup, renderMutuallyExclusivePrivilegeGroup]
+ );
+
+ const getEffectiveFeaturePrivileges = useCallback(
+ (subFeature: SecuredSubFeature) => {
+ return props.effectiveFeaturePrivileges.map((entry, index) => {
+ const [spaces, privs] =
+ subFeature.requireAllSpaces && allSpacesEffectivePrivileges
+ ? allSpacesEffectivePrivileges
+ : entry;
+
+ return (
+
+ {subFeature.getPrivilegeGroups().map(
+ renderPrivilegeGroup(privs.subFeature, {
+ requireAllSpaces: subFeature.requireAllSpaces,
+ spaces,
+ })
+ )}
+
+ );
+ });
+ },
+ [props.effectiveFeaturePrivileges, allSpacesEffectivePrivileges, renderPrivilegeGroup]
+ );
+
return (
{props.feature.getSubFeatures().map((subFeature) => {
@@ -34,105 +170,11 @@ export const PrivilegeSummaryExpandedRow = (props: Props) => {
{subFeature.name}
- {props.effectiveFeaturePrivileges.map((privs, index) => {
- return (
-
- {subFeature.getPrivilegeGroups().map(renderPrivilegeGroup(privs.subFeature))}
-
- );
- })}
+ {getEffectiveFeaturePrivileges(subFeature)}
);
})}
);
-
- function renderPrivilegeGroup(effectiveSubFeaturePrivileges: string[]) {
- return (privilegeGroup: SubFeaturePrivilegeGroup, index: number) => {
- switch (privilegeGroup.groupType) {
- case 'independent':
- return renderIndependentPrivilegeGroup(
- effectiveSubFeaturePrivileges,
- privilegeGroup,
- index
- );
- case 'mutually_exclusive':
- return renderMutuallyExclusivePrivilegeGroup(
- effectiveSubFeaturePrivileges,
- privilegeGroup,
- index
- );
- default:
- throw new Error(`Unsupported privilege group type: ${privilegeGroup.groupType}`);
- }
- };
- }
-
- function renderIndependentPrivilegeGroup(
- effectiveSubFeaturePrivileges: string[],
- privilegeGroup: SubFeaturePrivilegeGroup,
- index: number
- ) {
- return (
-
- {privilegeGroup.privileges.map((privilege: SubFeaturePrivilege) => {
- const isGranted = effectiveSubFeaturePrivileges.includes(privilege.id);
- return (
-
-
-
-
-
-
- {privilege.name}
-
-
-
- );
- })}
-
- );
- }
-
- function renderMutuallyExclusivePrivilegeGroup(
- effectiveSubFeaturePrivileges: string[],
- privilegeGroup: SubFeaturePrivilegeGroup,
- index: number
- ) {
- const firstSelectedPrivilege = privilegeGroup.privileges.find((p) =>
- effectiveSubFeaturePrivileges.includes(p.id)
- )?.name;
-
- return (
-
-
-
-
-
-
- {firstSelectedPrivilege ?? 'None'}
-
-
-
- );
- }
};
diff --git a/x-pack/platform/plugins/shared/security/public/management/roles/edit_role/privileges/kibana/privilege_summary/privilege_summary_table.test.tsx b/x-pack/platform/plugins/shared/security/public/management/roles/edit_role/privileges/kibana/privilege_summary/privilege_summary_table.test.tsx
index e1ca5300ee9f7..f344cf29a479b 100644
--- a/x-pack/platform/plugins/shared/security/public/management/roles/edit_role/privileges/kibana/privilege_summary/privilege_summary_table.test.tsx
+++ b/x-pack/platform/plugins/shared/security/public/management/roles/edit_role/privileges/kibana/privilege_summary/privilege_summary_table.test.tsx
@@ -21,6 +21,7 @@ import { mountWithIntl } from '@kbn/test-jest-helpers';
import { getDisplayedFeaturePrivileges } from './__fixtures__';
import type { PrivilegeSummaryTableProps } from './privilege_summary_table';
import { PrivilegeSummaryTable } from './privilege_summary_table';
+import { ALL_SPACES_ID } from '../../../../../../../common/constants';
const createRole = (roleKibanaPrivileges: RoleKibanaPrivilege[]) => ({
name: 'some-role',
@@ -431,7 +432,7 @@ describe('PrivilegeSummaryTable', () => {
hasCustomizedSubFeaturePrivileges: false,
primaryFeaturePrivilege: 'All',
...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
- 'Require all spaces Sub Feature': ['Cool toggle 1'],
+ 'Require all spaces Sub Feature': [],
}),
},
},
@@ -440,7 +441,7 @@ describe('PrivilegeSummaryTable', () => {
hasCustomizedSubFeaturePrivileges: false,
primaryFeaturePrivilege: 'None',
...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
- 'Require all spaces Sub Feature': ['Cool toggle 1'],
+ 'Require all spaces Sub Feature': [],
}),
},
},
@@ -642,7 +643,7 @@ describe('PrivilegeSummaryTable', () => {
hasCustomizedSubFeaturePrivileges: false,
primaryFeaturePrivilege: 'None',
...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
- 'Require all spaces Sub Feature': ['Cool toggle 1'],
+ 'Require all spaces Sub Feature': [],
}),
},
},
@@ -874,7 +875,7 @@ describe('PrivilegeSummaryTable', () => {
hasCustomizedSubFeaturePrivileges: false,
primaryFeaturePrivilege: 'Read',
...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
- 'Require all spaces Sub Feature': ['Cool toggle 1'],
+ 'Require all spaces Sub Feature': [],
}),
},
},
@@ -1023,6 +1024,138 @@ describe('PrivilegeSummaryTable', () => {
});
});
+ it('renders effective privileges when all spaces option is selected', async () => {
+ const kibanaPrivileges = createKibanaPrivileges(kibanaFeatures, {
+ allowSubFeaturePrivileges,
+ });
+
+ const role = createRole([
+ {
+ base: ['all'],
+ feature: {
+ with_sub_features: ['minimal_read', 'cool_all'],
+ },
+ spaces: ['*'],
+ },
+ {
+ base: [],
+ feature: {
+ with_sub_features: ['all'],
+ },
+ spaces: ['default', 'space-1'],
+ },
+ ]);
+
+ const wrapper = await setup({
+ spaces: [
+ {
+ id: ALL_SPACES_ID,
+ name: '*All Spaces',
+ disabledFeatures: [],
+ },
+ ],
+ kibanaPrivileges,
+ role,
+ canCustomizeSubFeaturePrivileges: allowSubFeaturePrivileges,
+ spacesApiUi,
+ });
+
+ const displayedPrivileges = getDisplayedFeaturePrivileges(wrapper, role);
+
+ expect(displayedPrivileges).toEqual({
+ excluded_from_base: {
+ '*': {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'None',
+ ...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
+ 'Cool Sub Feature': [],
+ }),
+ },
+ 'default, space-1': {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'None',
+ ...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
+ 'Cool Sub Feature': [],
+ }),
+ },
+ },
+ no_sub_features: {
+ '*': {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'All',
+ },
+ 'default, space-1': {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'All',
+ },
+ },
+ with_excluded_sub_features: {
+ '*': {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'All',
+ ...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
+ 'Excluded Sub Feature': [],
+ }),
+ },
+ 'default, space-1': {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'All',
+ ...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
+ 'Excluded Sub Feature': [],
+ }),
+ },
+ },
+ with_sub_features: {
+ '*': {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'All',
+ ...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
+ 'Cool Sub Feature': ['Cool toggle 1', 'Cool toggle 2', 'All'],
+ }),
+ },
+ 'default, space-1': {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'All',
+ ...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
+ 'Cool Sub Feature': ['Cool toggle 1', 'Cool toggle 2', 'All'],
+ }),
+ },
+ },
+ with_require_all_spaces_sub_features: {
+ '*': {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'All',
+ ...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
+ 'Require all spaces Sub Feature': ['Cool toggle 1'],
+ }),
+ },
+ 'default, space-1': {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'All',
+ ...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
+ 'Require all spaces Sub Feature': ['Cool toggle 1'],
+ }),
+ },
+ },
+ with_require_all_spaces_for_feature_and_sub_features: {
+ '*': {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'All',
+ ...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
+ 'Require all spaces Sub Feature': ['Cool toggle 1'],
+ }),
+ },
+ 'default, space-1': {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'All',
+ ...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
+ 'Require all spaces Sub Feature': ['Cool toggle 1'],
+ }),
+ },
+ },
+ });
+ });
+
it('renders effective privileges for a complex setup', async () => {
const kibanaPrivileges = createKibanaPrivileges(kibanaFeatures, {
allowSubFeaturePrivileges,
@@ -1180,7 +1313,7 @@ describe('PrivilegeSummaryTable', () => {
hasCustomizedSubFeaturePrivileges: false,
primaryFeaturePrivilege: 'None',
...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
- 'Require all spaces Sub Feature': ['Cool toggle 1'],
+ 'Require all spaces Sub Feature': [],
}),
},
'space-1, space-2': {
@@ -1193,6 +1326,360 @@ describe('PrivilegeSummaryTable', () => {
},
});
});
+
+ it('renders effective privileges for requireAllSpaces feature when all spaces is not selected', async () => {
+ const kibanaPrivileges = createKibanaPrivileges(kibanaFeatures, {
+ allowSubFeaturePrivileges,
+ });
+
+ const role = createRole([
+ {
+ base: [],
+ feature: {
+ with_sub_features: ['all'],
+ },
+ spaces: ['default', 'space-1'],
+ },
+ ]);
+
+ const wrapper = await setup({
+ spaces,
+ kibanaPrivileges,
+ role,
+ canCustomizeSubFeaturePrivileges: allowSubFeaturePrivileges,
+ spacesApiUi,
+ });
+
+ const displayedPrivileges = getDisplayedFeaturePrivileges(wrapper, role);
+
+ expect(displayedPrivileges.with_require_all_spaces_sub_features).toEqual({
+ 'default, space-1': {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'None',
+ ...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
+ 'Require all spaces Sub Feature': [],
+ }),
+ },
+ });
+
+ expect(displayedPrivileges.with_require_all_spaces_for_feature_and_sub_features).toEqual({
+ 'default, space-1': {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'None',
+ ...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
+ 'Require all spaces Sub Feature': [],
+ }),
+ },
+ });
+ });
+
+ it('renders effective privileges for requireAllSpaces feature when all spaces is selected without granting access', async () => {
+ const kibanaPrivileges = createKibanaPrivileges(kibanaFeatures, {
+ allowSubFeaturePrivileges,
+ });
+
+ const role = createRole([
+ {
+ base: [],
+ feature: {
+ with_sub_features: ['all'],
+ },
+ spaces: ['*'],
+ },
+ {
+ base: [],
+ feature: {
+ with_sub_features: ['all'],
+ },
+ spaces: ['default', 'space-1'],
+ },
+ ]);
+
+ const wrapper = await setup({
+ spaces: [
+ {
+ id: ALL_SPACES_ID,
+ name: '*All Spaces',
+ disabledFeatures: [],
+ },
+ ...spaces,
+ ],
+ kibanaPrivileges,
+ role,
+ canCustomizeSubFeaturePrivileges: allowSubFeaturePrivileges,
+ spacesApiUi,
+ });
+
+ const displayedPrivileges = getDisplayedFeaturePrivileges(wrapper, role);
+
+ expect(displayedPrivileges.with_require_all_spaces_sub_features).toEqual({
+ '*': {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'None',
+ ...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
+ 'Require all spaces Sub Feature': [],
+ }),
+ },
+ 'default, space-1': {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'None',
+ ...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
+ 'Require all spaces Sub Feature': [],
+ }),
+ },
+ });
+
+ expect(displayedPrivileges.with_require_all_spaces_for_feature_and_sub_features).toEqual({
+ '*': {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'None',
+ ...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
+ 'Require all spaces Sub Feature': [],
+ }),
+ },
+ 'default, space-1': {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'None',
+ ...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
+ 'Require all spaces Sub Feature': [],
+ }),
+ },
+ });
+ });
+
+ it('renders effective privileges for requireAllSpaces feature when all spaces grants read access', async () => {
+ const kibanaPrivileges = createKibanaPrivileges(kibanaFeatures, {
+ allowSubFeaturePrivileges,
+ });
+
+ const role = createRole([
+ {
+ base: [],
+ feature: {
+ with_require_all_spaces_for_feature_and_sub_features: ['read'],
+ },
+ spaces: ['*'],
+ },
+ {
+ base: ['all'],
+ feature: {},
+ spaces: ['default'],
+ },
+ ]);
+
+ const wrapper = await setup({
+ spaces: [
+ {
+ id: ALL_SPACES_ID,
+ name: '*All Spaces',
+ disabledFeatures: [],
+ },
+ ...spaces,
+ ],
+ kibanaPrivileges,
+ role,
+ canCustomizeSubFeaturePrivileges: allowSubFeaturePrivileges,
+ spacesApiUi,
+ });
+
+ const displayedPrivileges = getDisplayedFeaturePrivileges(wrapper, role);
+
+ expect(displayedPrivileges.with_require_all_spaces_for_feature_and_sub_features).toEqual({
+ '*': {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'Read',
+ ...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
+ 'Require all spaces Sub Feature': [],
+ }),
+ },
+ default: {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'Read',
+ ...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
+ 'Require all spaces Sub Feature': [],
+ }),
+ },
+ });
+ });
+
+ it('renders effective privileges for requireAllSpaces feature when all spaces grants all access', async () => {
+ const kibanaPrivileges = createKibanaPrivileges(kibanaFeatures, {
+ allowSubFeaturePrivileges,
+ });
+
+ const role = createRole([
+ {
+ base: [],
+ feature: {
+ with_require_all_spaces_for_feature_and_sub_features: ['all'],
+ with_require_all_spaces_sub_features: ['all'],
+ },
+ spaces: ['*'],
+ },
+ {
+ base: ['read'],
+ feature: {},
+ spaces: ['default'],
+ },
+ ]);
+
+ const wrapper = await setup({
+ spaces: [
+ {
+ id: ALL_SPACES_ID,
+ name: '*All Spaces',
+ disabledFeatures: [],
+ },
+ ...spaces,
+ ],
+ kibanaPrivileges,
+ role,
+ canCustomizeSubFeaturePrivileges: allowSubFeaturePrivileges,
+ spacesApiUi,
+ });
+
+ const displayedPrivileges = getDisplayedFeaturePrivileges(wrapper, role);
+
+ expect(displayedPrivileges.with_require_all_spaces_sub_features).toEqual({
+ '*': {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'All',
+ ...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
+ 'Require all spaces Sub Feature': ['Cool toggle 1'],
+ }),
+ },
+ default: {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'All',
+ ...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
+ 'Require all spaces Sub Feature': ['Cool toggle 1'],
+ }),
+ },
+ });
+
+ expect(displayedPrivileges.with_require_all_spaces_for_feature_and_sub_features).toEqual({
+ '*': {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'All',
+ ...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
+ 'Require all spaces Sub Feature': ['Cool toggle 1'],
+ }),
+ },
+ default: {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'All',
+ ...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
+ 'Require all spaces Sub Feature': ['Cool toggle 1'],
+ }),
+ },
+ });
+ });
+
+ it('renders effective privileges for requireAllSpaces feature when all spaces grants base read access', async () => {
+ const kibanaPrivileges = createKibanaPrivileges(kibanaFeatures, {
+ allowSubFeaturePrivileges,
+ });
+
+ const role = createRole([
+ {
+ base: ['read'],
+ feature: {},
+ spaces: ['*'],
+ },
+ {
+ base: ['all'],
+ feature: {},
+ spaces: ['default'],
+ },
+ ]);
+
+ const wrapper = await setup({
+ spaces: [
+ {
+ id: ALL_SPACES_ID,
+ name: '*All Spaces',
+ disabledFeatures: [],
+ },
+ ...spaces,
+ ],
+ kibanaPrivileges,
+ role,
+ canCustomizeSubFeaturePrivileges: allowSubFeaturePrivileges,
+ spacesApiUi,
+ });
+
+ const displayedPrivileges = getDisplayedFeaturePrivileges(wrapper, role);
+
+ expect(displayedPrivileges.with_require_all_spaces_for_feature_and_sub_features).toEqual({
+ '*': {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'Read',
+ ...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
+ 'Require all spaces Sub Feature': [],
+ }),
+ },
+ default: {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'Read',
+ ...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
+ 'Require all spaces Sub Feature': [],
+ }),
+ },
+ });
+ });
+
+ it('renders effective privileges for requireAllSpaces feature when all spaces grants base all access', async () => {
+ const kibanaPrivileges = createKibanaPrivileges(kibanaFeatures, {
+ allowSubFeaturePrivileges,
+ });
+
+ const role = createRole([
+ {
+ base: ['all'],
+ feature: {},
+ spaces: ['*'],
+ },
+ {
+ base: ['read'],
+ feature: {},
+ spaces: ['default'],
+ },
+ ]);
+
+ const wrapper = await setup({
+ spaces: [
+ {
+ id: ALL_SPACES_ID,
+ name: '*All Spaces',
+ disabledFeatures: [],
+ },
+ ...spaces,
+ ],
+ kibanaPrivileges,
+ role,
+ canCustomizeSubFeaturePrivileges: allowSubFeaturePrivileges,
+ spacesApiUi,
+ });
+
+ const displayedPrivileges = getDisplayedFeaturePrivileges(wrapper, role);
+
+ expect(displayedPrivileges.with_require_all_spaces_for_feature_and_sub_features).toEqual({
+ '*': {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'All',
+ ...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
+ 'Require all spaces Sub Feature': ['Cool toggle 1'],
+ }),
+ },
+ default: {
+ hasCustomizedSubFeaturePrivileges: false,
+ primaryFeaturePrivilege: 'All',
+ ...maybeExpectSubFeaturePrivileges(allowSubFeaturePrivileges, {
+ 'Require all spaces Sub Feature': ['Cool toggle 1'],
+ }),
+ },
+ });
+ });
});
});
});
diff --git a/x-pack/platform/plugins/shared/security/public/management/roles/edit_role/privileges/kibana/privilege_summary/privilege_summary_table.tsx b/x-pack/platform/plugins/shared/security/public/management/roles/edit_role/privileges/kibana/privilege_summary/privilege_summary_table.tsx
index 5dc856e5af5d9..43dc296cb4987 100644
--- a/x-pack/platform/plugins/shared/security/public/management/roles/edit_role/privileges/kibana/privilege_summary/privilege_summary_table.tsx
+++ b/x-pack/platform/plugins/shared/security/public/management/roles/edit_role/privileges/kibana/privilege_summary/privilege_summary_table.tsx
@@ -48,14 +48,31 @@ function getColumnKey(entry: RoleKibanaPrivilege) {
return `privilege_entry_${entry.spaces.join('|')}`;
}
-function showPrivilege(allSpacesSelected: boolean, primaryFeature?: PrimaryFeaturePrivilege) {
+function showPrivilege({
+ allSpacesSelected,
+ primaryFeature,
+ globalPrimaryFeature,
+}: {
+ allSpacesSelected: boolean;
+ primaryFeature?: PrimaryFeaturePrivilege;
+ globalPrimaryFeature?: PrimaryFeaturePrivilege;
+}) {
if (
primaryFeature?.name == null ||
primaryFeature?.disabled ||
- (primaryFeature.requireAllSpaces && !allSpacesSelected)
+ (primaryFeature?.requireAllSpaces && !allSpacesSelected)
) {
return 'None';
}
+
+ // If primary feature requires all spaces we cannot rely on primaryFeature.name.
+ // Example:
+ // primaryFeature: feature with requireAllSpaces in space-a has all privileges set to All
+ // globalPrimaryFeature: feature in *AllSpaces has privileges set to Read (this is the correct one to display)
+ if (primaryFeature?.requireAllSpaces && allSpacesSelected) {
+ return globalPrimaryFeature?.name ?? 'None';
+ }
+
return primaryFeature?.name;
}
@@ -127,6 +144,15 @@ export const PrivilegeSummaryTable = (props: PrivilegeSummaryTableProps) => {
}
return 0;
});
+
+ const globalRawPrivilege = rawKibanaPrivileges.find((entry) =>
+ isGlobalPrivilegeDefinition(entry)
+ );
+
+ const globalPrivilege = globalRawPrivilege
+ ? calculator.getEffectiveFeaturePrivileges(globalRawPrivilege)
+ : null;
+
const privilegeColumns = rawKibanaPrivileges.map((entry) => {
const key = getColumnKey(entry);
return {
@@ -161,10 +187,11 @@ export const PrivilegeSummaryTable = (props: PrivilegeSummaryTableProps) => {
hasCustomizedSubFeaturePrivileges ? 'additionalPrivilegesGranted' : ''
}`}
>
- {showPrivilege(
- props.spaces.some((space) => space.id === ALL_SPACES_ID),
- primary
- )}{' '}
+ {showPrivilege({
+ allSpacesSelected: props.spaces.some((space) => space.id === ALL_SPACES_ID),
+ primaryFeature: primary,
+ globalPrimaryFeature: globalPrivilege?.[record.featureId]?.primary,
+ })}{' '}
{iconTip}
);
@@ -178,12 +205,14 @@ export const PrivilegeSummaryTable = (props: PrivilegeSummaryTableProps) => {
}
columns.push(featureColumn, ...privilegeColumns);
- const privileges = rawKibanaPrivileges.reduce((acc, entry) => {
+ const privileges = rawKibanaPrivileges.reduce<
+ Record
+ >((acc, entry) => {
return {
...acc,
- [getColumnKey(entry)]: calculator.getEffectiveFeaturePrivileges(entry),
+ [getColumnKey(entry)]: [entry.spaces, calculator.getEffectiveFeaturePrivileges(entry)],
};
- }, {} as Record);
+ }, {});
const accordions: any[] = [];
@@ -210,11 +239,15 @@ export const PrivilegeSummaryTable = (props: PrivilegeSummaryTableProps) => {
);
+ const categoryPrivileges = Object.fromEntries(
+ Object.entries(privileges).map(([key, [, featurePrivileges]]) => [key, featurePrivileges])
+ );
+
const categoryItems = featuresInCategory.map((feature) => {
return {
feature,
featureId: feature.id,
- ...privileges,
+ ...categoryPrivileges,
};
});
@@ -241,7 +274,10 @@ export const PrivilegeSummaryTable = (props: PrivilegeSummaryTableProps) => {
[featureId]: (
p[featureId])}
+ effectiveFeaturePrivileges={Object.values(privileges).map(([spaces, privs]) => [
+ spaces,
+ privs[featureId],
+ ])}
/>
),
};
diff --git a/x-pack/platform/plugins/shared/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/privilege_space_form.test.tsx b/x-pack/platform/plugins/shared/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/privilege_space_form.test.tsx
index 751db03939dda..d172c46e3a660 100644
--- a/x-pack/platform/plugins/shared/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/privilege_space_form.test.tsx
+++ b/x-pack/platform/plugins/shared/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/privilege_space_form.test.tsx
@@ -115,15 +115,11 @@ describe('PrivilegeSpaceForm', () => {
},
"with_require_all_spaces_for_feature_and_sub_features": Object {
"primaryFeaturePrivilege": "none",
- "subFeaturePrivileges": Array [
- "cool_toggle_1",
- ],
+ "subFeaturePrivileges": Array [],
},
"with_require_all_spaces_sub_features": Object {
"primaryFeaturePrivilege": "all",
- "subFeaturePrivileges": Array [
- "cool_toggle_1",
- ],
+ "subFeaturePrivileges": Array [],
},
"with_sub_features": Object {
"primaryFeaturePrivilege": "all",
diff --git a/x-pack/platform/plugins/shared/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/space_aware_privilege_section.tsx b/x-pack/platform/plugins/shared/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/space_aware_privilege_section.tsx
index 2bb3292932870..2773dd92753ce 100644
--- a/x-pack/platform/plugins/shared/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/space_aware_privilege_section.tsx
+++ b/x-pack/platform/plugins/shared/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(