Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SECURITY] Add Privilege deprecations services in security plugin #113151

Merged
merged 18 commits into from
Oct 5, 2021
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
558089b
non-working POC for privilege deprecations
legrego Sep 1, 2021
d36f13c
wip to be bale to deprecated sub feature case in security solutions
XavierM Sep 21, 2021
9c2f036
Merge branch 'master' of github.com:elastic/kibana into deprecated-su…
XavierM Sep 21, 2021
398b5a9
finalyze deprecations of cases sub feature in security solutions
XavierM Sep 24, 2021
58ac232
Merge branch 'master' of github.com:elastic/kibana into deprecated-su…
XavierM Sep 24, 2021
f8f8343
only adding the deprecation servces in security
XavierM Sep 27, 2021
0225c38
Merge branch 'master' of github.com:elastic/kibana into privilege-dep…
XavierM Sep 27, 2021
4e426fc
Merge branch 'master' of github.com:elastic/kibana into privilege-dep…
XavierM Sep 28, 2021
2110d6c
add test + translation
XavierM Sep 28, 2021
de67951
Merge branch 'master' of github.com:elastic/kibana into privilege-dep…
XavierM Sep 28, 2021
bda97f8
Update x-pack/plugins/security/server/deprecations/privilege_deprecat…
XavierM Oct 1, 2021
f6c9b39
Merge branch 'master' of github.com:elastic/kibana into privilege-dep…
XavierM Oct 1, 2021
db90c30
joe reviews
XavierM Oct 1, 2021
8051eba
Merge branch 'master' of github.com:elastic/kibana into privilege-dep…
XavierM Oct 1, 2021
627594e
Merge branch 'master' of github.com:elastic/kibana into privilege-dep…
XavierM Oct 1, 2021
8daea19
Merge branch 'master' of github.com:elastic/kibana into privilege-dep…
XavierM Oct 4, 2021
f56f749
renaming + double check
XavierM Oct 4, 2021
6775a93
Merge branch 'master' into privilege-deprecations-services
kibanamachine Oct 5, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions x-pack/plugins/security/common/model/deprecations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import type { DeprecationsDetails, GetDeprecationsContext } from '../../../../../src/core/server';
import type { Role } from './role';

export interface PrivilegeDeprecationsRolesByFeatureIdResponse {
roles?: Role[];
errors?: DeprecationsDetails[];
}

export interface PrivilegeDeprecationsRolesByFeatureIdRequest {
context: GetDeprecationsContext;
featureId: string;
}
export interface PrivilegeDeprecationsServices {
getKibanaRolesByFeatureId: (
args: PrivilegeDeprecationsRolesByFeatureIdRequest
) => Promise<PrivilegeDeprecationsRolesByFeatureIdResponse>;
}
5 changes: 5 additions & 0 deletions x-pack/plugins/security/common/model/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,8 @@ export {
RoleTemplate,
RoleMapping,
} from './role_mapping';
export {
PrivilegeDeprecationsRolesByFeatureIdRequest,
PrivilegeDeprecationsRolesByFeatureIdResponse,
PrivilegeDeprecationsServices,
} from './deprecations';
1 change: 1 addition & 0 deletions x-pack/plugins/security/server/authorization/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ export {
} from './authorization_service';
export { CheckSavedObjectsPrivileges } from './check_saved_objects_privileges';
export { CheckPrivilegesPayload } from './types';
export { transformElasticsearchRoleToRole, ElasticsearchRole } from './roles';
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
import {
GLOBAL_RESOURCE,
RESERVED_PRIVILEGES_APPLICATION_WILDCARD,
} from '../../../../../common/constants';
import type { Role, RoleKibanaPrivilege } from '../../../../../common/model';
import { PrivilegeSerializer } from '../../../../authorization/privilege_serializer';
import { ResourceSerializer } from '../../../../authorization/resource_serializer';
} from '../../../common/constants';
import type { Role, RoleKibanaPrivilege } from '../../../common/model';
import { PrivilegeSerializer } from '../privilege_serializer';
import { ResourceSerializer } from '../resource_serializer';

export type ElasticsearchRole = Pick<Role, 'name' | 'metadata' | 'transient_metadata'> & {
applications: Array<{
Expand Down
8 changes: 8 additions & 0 deletions x-pack/plugins/security/server/authorization/roles/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

export { transformElasticsearchRoleToRole, ElasticsearchRole } from './elasticsearch_role';
12 changes: 12 additions & 0 deletions x-pack/plugins/security/server/deprecations/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

/**
* getKibanaRolesByFeature
*/

export { getPrivilegeDeprecationsServices } from './privilege_deprecations';
Original file line number Diff line number Diff line change
@@ -0,0 +1,284 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import type { GetDeprecationsContext } from 'src/core/server';
import { elasticsearchServiceMock, loggingSystemMock } from 'src/core/server/mocks';

import { getPrivilegeDeprecationsServices } from '.';
import { licenseMock } from '../../common/licensing/index.mock';

const kibanaIndexName = '.a-kibana-index';
const application = `kibana-${kibanaIndexName}`;

describe('#getPrivilegeDeprecationsServices', () => {
describe('#getKibanaRolesByFeatureId', () => {
const mockAsCurrentUser = elasticsearchServiceMock.createScopedClusterClient();
const mockLicense = licenseMock.create();
const mockLogger = loggingSystemMock.createLogger();
const authz = { applicationName: application };

const { getKibanaRolesByFeatureId } = getPrivilegeDeprecationsServices(
authz,
mockLicense,
mockLogger
);

it('happy path to find siem roles with feature_siem privileges', async () => {
mockAsCurrentUser.asCurrentUser.security.getRole.mockResolvedValue(
elasticsearchServiceMock.createSuccessTransportRequestPromise({
first_role: {
cluster: [],
indices: [],
applications: [
{
application,
privileges: ['feature_siem.all', 'feature_siem.cases_read'],
resources: ['space:securitySolutions'],
},
],
run_as: [],
metadata: {
_reserved: true,
},
transient_metadata: {
enabled: true,
},
},
})
);

const mockContext = {
esClient: mockAsCurrentUser,
savedObjectsClient: jest.fn(),
} as unknown as GetDeprecationsContext;

const resp = await getKibanaRolesByFeatureId({ context: mockContext, featureId: 'siem' });
expect(resp).toMatchInlineSnapshot(`
Object {
"roles": Array [
Object {
"_transform_error": Array [],
"_unrecognized_applications": Array [],
"elasticsearch": Object {
"cluster": Array [],
"indices": Array [],
"run_as": Array [],
},
"kibana": Array [
Object {
"base": Array [],
"feature": Object {
"siem": Array [
"all",
"cases_read",
],
},
"spaces": Array [
"securitySolutions",
],
},
],
"metadata": Object {
"_reserved": true,
},
"name": "first_role",
"transient_metadata": Object {
"enabled": true,
},
},
],
}
`);
});

it('happy path to find siem roles with feature_siem and feature_foo and feature_bar privileges', async () => {
mockAsCurrentUser.asCurrentUser.security.getRole.mockResolvedValue(
elasticsearchServiceMock.createSuccessTransportRequestPromise({
first_role: {
cluster: [],
indices: [],
applications: [
{
application,
privileges: [
'feature_foo.foo-privilege-1',
'feature_foo.foo-privilege-2',
'feature_bar.bar-privilege-1',
'feature_siem.all',
'feature_siem.cases_read',
],
resources: ['space:securitySolutions'],
},
],
run_as: [],
metadata: {
_reserved: true,
},
transient_metadata: {
enabled: true,
},
},
})
);

const mockContext = {
esClient: mockAsCurrentUser,
savedObjectsClient: jest.fn(),
} as unknown as GetDeprecationsContext;

const resp = await getKibanaRolesByFeatureId({ context: mockContext, featureId: 'siem' });
expect(resp).toMatchInlineSnapshot(`
Object {
"roles": Array [
Object {
"_transform_error": Array [],
"_unrecognized_applications": Array [],
"elasticsearch": Object {
"cluster": Array [],
"indices": Array [],
"run_as": Array [],
},
"kibana": Array [
Object {
"base": Array [],
"feature": Object {
"bar": Array [
"bar-privilege-1",
],
"foo": Array [
"foo-privilege-1",
"foo-privilege-2",
],
"siem": Array [
"all",
"cases_read",
],
},
"spaces": Array [
"securitySolutions",
],
},
],
"metadata": Object {
"_reserved": true,
},
"name": "first_role",
"transient_metadata": Object {
"enabled": true,
},
},
],
}
`);
});

it('happy path to NOT find siem roles with and feature_foo and feature_bar privileges', async () => {
mockAsCurrentUser.asCurrentUser.security.getRole.mockResolvedValue(
elasticsearchServiceMock.createSuccessTransportRequestPromise({
first_role: {
cluster: [],
indices: [],
applications: [
{
application,
privileges: [
'feature_foo.foo-privilege-1',
'feature_foo.foo-privilege-2',
'feature_bar.bar-privilege-1',
],
resources: ['space:securitySolutions'],
},
],
run_as: [],
metadata: {
_reserved: true,
},
transient_metadata: {
enabled: true,
},
},
})
);

const mockContext = {
esClient: mockAsCurrentUser,
savedObjectsClient: jest.fn(),
} as unknown as GetDeprecationsContext;

const resp = await getKibanaRolesByFeatureId({ context: mockContext, featureId: 'siem' });
expect(resp).toMatchInlineSnapshot(`
Object {
"roles": Array [],
}
`);
});

it('unhappy path with status code 400, we should have the attribute errors', async () => {
mockAsCurrentUser.asCurrentUser.security.getRole.mockResolvedValue(
elasticsearchServiceMock.createErrorTransportRequestPromise({
message: 'Test error',
statusCode: 400,
})
);

const mockContext = {
esClient: mockAsCurrentUser,
savedObjectsClient: jest.fn(),
} as unknown as GetDeprecationsContext;

const resp = await getKibanaRolesByFeatureId({ context: mockContext, featureId: 'siem' });
expect(resp).toMatchInlineSnapshot(`
Object {
"errors": Array [
Object {
"correctiveActions": Object {
"manualSteps": Array [
"A user with the \\"manage_security\\" cluster privilege is required to perform this check.",
],
},
"level": "fetch_error",
"message": "Error retrieving roles for privilege deprecations: Test error",
"title": "Error in privilege deprecations services",
},
],
}
`);
});

it('unhappy path with status code 403, we should have unauthorized message in the attribute errors', async () => {
mockAsCurrentUser.asCurrentUser.security.getRole.mockResolvedValue(
elasticsearchServiceMock.createErrorTransportRequestPromise({
message: 'Test error',
statusCode: 403,
})
);

const mockContext = {
esClient: mockAsCurrentUser,
savedObjectsClient: jest.fn(),
} as unknown as GetDeprecationsContext;

const resp = await getKibanaRolesByFeatureId({ context: mockContext, featureId: 'siem' });
expect(resp).toMatchInlineSnapshot(`
Object {
"errors": Array [
Object {
"correctiveActions": Object {
"manualSteps": Array [
"A user with the \\"manage_security\\" cluster privilege is required to perform this check.",
],
},
"level": "fetch_error",
"message": "You must have the 'manage_security' cluster privilege to fix role deprecations.",
"title": "Error in privilege deprecations services",
},
],
}
`);
});
});
});
Loading