mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Spaces] Excluded roles with reserved only privileges (#192041)
## Summary Excluded roles with reserved only privileges `/internal/security/roles/{spaceId}` route. `_reserved` privileges are legacy, and they do not grant access to spaces directly, but rather rely on other roles to grant that access in order to function. ### 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 __Fixes: https://github.com/elastic/kibana/issues/191996__ --------- Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
c6dce5826f
commit
ab1646f4e4
2 changed files with 107 additions and 13 deletions
|
@ -320,5 +320,81 @@ describe('GET all roles by space id', () => {
|
|||
],
|
||||
},
|
||||
});
|
||||
|
||||
getRolesTest(`filters roles with reserved only privileges`, {
|
||||
apiResponse: () => ({
|
||||
first_role: {
|
||||
description: 'first role description',
|
||||
cluster: [],
|
||||
indices: [],
|
||||
applications: [],
|
||||
run_as: [],
|
||||
metadata: {
|
||||
_reserved: true,
|
||||
},
|
||||
transient_metadata: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
second_role: {
|
||||
cluster: [],
|
||||
indices: [],
|
||||
applications: [
|
||||
{
|
||||
application,
|
||||
privileges: ['space_all', 'space_read'],
|
||||
resources: ['space:marketing', 'space:sales'],
|
||||
},
|
||||
],
|
||||
run_as: [],
|
||||
metadata: {
|
||||
_reserved: true,
|
||||
},
|
||||
transient_metadata: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
third_role: {
|
||||
cluster: [],
|
||||
indices: [],
|
||||
applications: [],
|
||||
run_as: [],
|
||||
transient_metadata: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
}),
|
||||
spaceId: 'marketing',
|
||||
asserts: {
|
||||
statusCode: 200,
|
||||
result: [
|
||||
{
|
||||
_transform_error: [],
|
||||
_unrecognized_applications: [],
|
||||
elasticsearch: {
|
||||
cluster: [],
|
||||
indices: [],
|
||||
remote_cluster: undefined,
|
||||
remote_indices: undefined,
|
||||
run_as: [],
|
||||
},
|
||||
kibana: [
|
||||
{
|
||||
base: ['all', 'read'],
|
||||
feature: {},
|
||||
spaces: ['marketing', 'sales'],
|
||||
},
|
||||
],
|
||||
metadata: {
|
||||
_reserved: true,
|
||||
},
|
||||
name: 'second_role',
|
||||
transient_metadata: {
|
||||
enabled: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
import { schema } from '@kbn/config-schema';
|
||||
|
||||
import type { RouteDefinitionParams } from '../..';
|
||||
import type { Role } from '../../../../common';
|
||||
import { ALL_SPACES_ID } from '../../../../common/constants';
|
||||
import { compareRolesByName, transformElasticsearchRoleToRole } from '../../../authorization';
|
||||
import { wrapIntoCustomErrorResponse } from '../../../errors';
|
||||
|
@ -43,25 +44,42 @@ export function defineGetAllRolesBySpaceRoutes({
|
|||
// Transform elasticsearch roles into Kibana roles and return in a list sorted by the role name.
|
||||
return response.ok({
|
||||
body: Object.entries(elasticsearchRoles)
|
||||
.map(([roleName, elasticsearchRole]) =>
|
||||
transformElasticsearchRoleToRole(
|
||||
.reduce<Role[]>((acc, [roleName, elasticsearchRole]) => {
|
||||
if (hideReservedRoles && elasticsearchRole.metadata?._reserved) {
|
||||
return acc;
|
||||
}
|
||||
|
||||
const role = transformElasticsearchRoleToRole(
|
||||
features,
|
||||
// @ts-expect-error @elastic/elasticsearch SecurityIndicesPrivileges.names expected to be string[]
|
||||
elasticsearchRole,
|
||||
roleName,
|
||||
authz.applicationName,
|
||||
logger
|
||||
)
|
||||
)
|
||||
.filter(
|
||||
(role) =>
|
||||
!(hideReservedRoles && role.metadata?._reserved) &&
|
||||
role.kibana.some(
|
||||
(privilege) =>
|
||||
privilege.spaces.includes(request.params.spaceId) ||
|
||||
privilege.spaces.includes(ALL_SPACES_ID)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
const includeRoleForSpace = role.kibana.some((privilege) => {
|
||||
const privilegeInSpace =
|
||||
privilege.spaces.includes(request.params.spaceId) ||
|
||||
privilege.spaces.includes(ALL_SPACES_ID);
|
||||
|
||||
if (privilegeInSpace && privilege.base.length) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const hasFeaturePrivilege = Object.values(privilege.feature).some(
|
||||
(featureList) => featureList.length
|
||||
);
|
||||
|
||||
return privilegeInSpace && hasFeaturePrivilege;
|
||||
});
|
||||
|
||||
if (includeRoleForSpace) {
|
||||
acc.push(role);
|
||||
}
|
||||
|
||||
return acc;
|
||||
}, [])
|
||||
.sort(compareRolesByName),
|
||||
});
|
||||
} catch (error) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue