diff --git a/public/apps/configuration/panels/role-edit/role-edit.tsx b/public/apps/configuration/panels/role-edit/role-edit.tsx index 53ec39d30..142cba1b3 100644 --- a/public/apps/configuration/panels/role-edit/role-edit.tsx +++ b/public/apps/configuration/panels/role-edit/role-edit.tsx @@ -46,7 +46,7 @@ import { } from './tenant-panel'; import { RoleIndexPermissionStateClass, RoleTenantPermissionStateClass } from './types'; import { buildHashUrl, buildUrl } from '../../utils/url-builder'; -import { ComboBoxOptions, ResourceType, Action } from '../../types'; +import { ComboBoxOptions, ResourceType, Action, ActionGroupItem } from '../../types'; import { useToastState, createUnknownErrorToast, @@ -106,12 +106,12 @@ export function RoleEdit(props: RoleEditDeps) { } }, [addToast, props.action, props.coreStart.http, props.sourceRoleName]); - const [actionGroups, setActionGroups] = useState([]); + const [actionGroups, setActionGroups] = useState>([]); React.useEffect(() => { const fetchActionGroupNames = async () => { try { const actionGroupsObject = await fetchActionGroups(props.coreStart.http); - setActionGroups(Object.keys(actionGroupsObject)); + setActionGroups(Object.entries(actionGroupsObject)); } catch (e) { addToast(createUnknownErrorToast('actionGroup', 'load data')); console.error(e); @@ -167,12 +167,25 @@ export function RoleEdit(props: RoleEditDeps) { const clusterWisePermissionOptions = [ { label: 'Permission groups', - options: actionGroups.map(stringToComboBoxOption), + options: actionGroups + .filter((actionGroup) => actionGroup[1].type === 'cluster') + .map((actionGroup) => actionGroup[0]) + .map(stringToComboBoxOption), }, { label: 'Cluster permissions', options: CLUSTER_PERMISSIONS.map(stringToComboBoxOption), }, + ]; + + const indexWisePermissionOptions = [ + { + label: 'Permission groups', + options: actionGroups + .filter((actionGroup) => actionGroup[1].type === 'index') + .map((actionGroup) => actionGroup[0]) + .map(stringToComboBoxOption), + }, { label: 'Index permissions', options: INDEX_PERMISSIONS.map(stringToComboBoxOption), @@ -219,7 +232,7 @@ export function RoleEdit(props: RoleEditDeps) { ({ + getRoleDetail: jest.fn().mockReturnValue({ + cluster_permissions: [], + index_permissions: [], + tenant_permissions: [], + reserved: false, + }), + updateRole: jest.fn(), +})); +jest.mock('../../../utils/action-groups-utils'); + +jest.mock('../cluster-permission-panel', () => ({ + ClusterPermissionPanel: jest.fn(() => null) as jest.Mock, +})); + +jest.mock('../index-permission-panel', () => ({ + IndexPermissionPanel: jest.fn(() => null) as jest.Mock, +})); + +describe('Role edit filtering', () => { + const sampleSourceRole = 'role'; + const mockCoreStart = { + http: 1, + }; + + (fetchActionGroups as jest.Mock).mockResolvedValue({ + data_access: { + reserved: true, + hidden: false, + allowed_actions: ['indices:data/*', 'crud'], + type: 'index', + description: 'Allow all read/write operations on data', + static: true, + }, + cluster_manage_pipelines: { + reserved: true, + hidden: false, + allowed_actions: ['cluster:admin/ingest/pipeline/*'], + type: 'cluster', + description: 'Manage pipelines', + static: true, + }, + }); + + it('basic cluster permission panel rendering', async () => { + const action = 'create'; + const buildBreadcrumbs = jest.fn(); + + render( + + ); + + await act(async () => { + await waitFor(() => { + expect(ClusterPermissionPanel).toHaveBeenCalled(); + }); + }); + + const lastCallArgs = + ClusterPermissionPanel.mock.calls[ClusterPermissionPanel.mock.calls.length - 1]; + const [props] = lastCallArgs; + + // Cluster Permission Panel props is filtered to action groups with type cluster, and only the cluster permission constants + expect(props.optionUniverse).toEqual([ + { + label: 'Permission groups', + options: [ + { + label: 'cluster_manage_pipelines', + }, + ], + }, + { + label: 'Cluster permissions', + options: CLUSTER_PERMISSIONS.map((x) => { + return { label: x }; + }), + }, + ]); + }); + + it('basic index permission panel rendering', async () => { + const action = 'create'; + const buildBreadcrumbs = jest.fn(); + + render( + + ); + + await act(async () => { + await waitFor(() => { + expect(IndexPermissionPanel).toHaveBeenCalled(); + }); + }); + + const lastCallArgs = + IndexPermissionPanel.mock.calls[IndexPermissionPanel.mock.calls.length - 1]; + const [props] = lastCallArgs; + + // Index Permission Panel props is filtered to action groups with type index, and only the index permission constants + expect(props.optionUniverse).toEqual([ + { + label: 'Permission groups', + options: [ + { + label: 'data_access', + }, + ], + }, + { + label: 'Index permissions', + options: INDEX_PERMISSIONS.map((x) => { + return { label: x }; + }), + }, + ]); + }); +});