diff --git a/x-pack/plugins/cases/common/api/cases/case.ts b/x-pack/plugins/cases/common/api/cases/case.ts index f529baca53b922..3477791a555614 100644 --- a/x-pack/plugins/cases/common/api/cases/case.ts +++ b/x-pack/plugins/cases/common/api/cases/case.ts @@ -38,8 +38,8 @@ const CaseBasicRt = rt.type({ [caseTypeField]: CaseTypeRt, connector: CaseConnectorRt, settings: SettingsRt, - // TODO: should a user be able to update the class? - class: rt.string, + // TODO: should a user be able to update the scope? + scope: rt.string, }); const CaseExternalServiceBasicRt = rt.type({ @@ -80,7 +80,7 @@ const CasePostRequestNoTypeRt = rt.type({ title: rt.string, connector: CaseConnectorRt, settings: SettingsRt, - class: rt.string, + scope: rt.string, }); /** diff --git a/x-pack/plugins/cases/common/api/cases/sub_case.ts b/x-pack/plugins/cases/common/api/cases/sub_case.ts index 7c8cdf023d8d72..0940f2951d4012 100644 --- a/x-pack/plugins/cases/common/api/cases/sub_case.ts +++ b/x-pack/plugins/cases/common/api/cases/sub_case.ts @@ -39,7 +39,7 @@ export const SubCasesFindRequestRt = rt.partial({ searchFields: rt.array(rt.string), sortField: rt.string, sortOrder: rt.union([rt.literal('desc'), rt.literal('asc')]), - class: rt.string, + scope: rt.string, }); export const SubCaseResponseRt = rt.intersection([ diff --git a/x-pack/plugins/cases/common/constants.ts b/x-pack/plugins/cases/common/constants.ts index 4cac3a7b73a220..6198dc0ab1f4fc 100644 --- a/x-pack/plugins/cases/common/constants.ts +++ b/x-pack/plugins/cases/common/constants.ts @@ -76,4 +76,4 @@ export const MAX_GENERATED_ALERTS_PER_SUB_CASE = MAX_ALERTS_PER_SUB_CASE / DEFAU * This must be the same value that the security solution plugin uses to define the case kind when it registers the * feature for the 7.13 migration only. */ -export const SECURITY_SOLUTION_CONSUMER = 'securitySolution'; +export const SECURITY_SOLUTION_SCOPE = 'securitySolution'; diff --git a/x-pack/plugins/cases/server/authorization/authorization.ts b/x-pack/plugins/cases/server/authorization/authorization.ts index daa46957e14a44..832ee6acccbe5b 100644 --- a/x-pack/plugins/cases/server/authorization/authorization.ts +++ b/x-pack/plugins/cases/server/authorization/authorization.ts @@ -11,7 +11,7 @@ import { KueryNode } from '../../../../../src/plugins/data/server'; import { SecurityPluginStart } from '../../../security/server'; import { PluginStartContract as FeaturesPluginStart } from '../../../features/server'; import { GetSpaceFn, ReadOperations, WriteOperations } from './types'; -import { getClassFilter } from './utils'; +import { getScopesFilter } from './utils'; /** * This class handles ensuring that the user making a request has the correct permissions @@ -20,7 +20,7 @@ import { getClassFilter } from './utils'; export class Authorization { private readonly request: KibanaRequest; private readonly securityAuth: SecurityPluginStart['authz'] | undefined; - private readonly featureCaseClasses: Set; + private readonly featureCaseScopes: Set; private readonly isAuthEnabled: boolean; // TODO: create this // private readonly auditLogger: AuthorizationAuditLogger; @@ -28,17 +28,17 @@ export class Authorization { private constructor({ request, securityAuth, - caseClasses, + caseScopes, isAuthEnabled, }: { request: KibanaRequest; securityAuth?: SecurityPluginStart['authz']; - caseClasses: Set; + caseScopes: Set; isAuthEnabled: boolean; }) { this.request = request; this.securityAuth = securityAuth; - this.featureCaseClasses = caseClasses; + this.featureCaseScopes = caseScopes; this.isAuthEnabled = isAuthEnabled; } @@ -59,58 +59,58 @@ export class Authorization { isAuthEnabled: boolean; }): Promise { // Since we need to do async operations, this static method handles that before creating the Auth class - let caseClasses: Set; + let caseScopes: Set; try { const disabledFeatures = new Set((await getSpace(request))?.disabledFeatures ?? []); - caseClasses = new Set( + caseScopes = new Set( features .getKibanaFeatures() - // get all the features' cases classes that aren't disabled + // get all the features' cases scopes that aren't disabled .filter(({ id }) => !disabledFeatures.has(id)) .flatMap((feature) => feature.cases ?? []) ); } catch (error) { - caseClasses = new Set(); + caseScopes = new Set(); } - return new Authorization({ request, securityAuth, caseClasses, isAuthEnabled }); + return new Authorization({ request, securityAuth, caseScopes, isAuthEnabled }); } private shouldCheckAuthorization(): boolean { return this.securityAuth?.mode?.useRbacForRequest(this.request) ?? false; } - public async ensureAuthorized(className: string, operation: ReadOperations | WriteOperations) { + public async ensureAuthorized(scope: string, operation: ReadOperations | WriteOperations) { // TODO: remove if (!this.isAuthEnabled) { return; } const { securityAuth } = this; - const isAvailableClass = this.featureCaseClasses.has(className); + const isScopeAvailable = this.featureCaseScopes.has(scope); // TODO: throw if the request is not authorized if (securityAuth && this.shouldCheckAuthorization()) { // TODO: implement ensure logic - const requiredPrivileges: string[] = [securityAuth.actions.cases.get(className, operation)]; + const requiredPrivileges: string[] = [securityAuth.actions.cases.get(scope, operation)]; const checkPrivileges = securityAuth.checkPrivilegesDynamicallyWithRequest(this.request); const { hasAllRequested, username, privileges } = await checkPrivileges({ kibana: requiredPrivileges, }); - if (!isAvailableClass) { - // TODO: throw if any of the class are not available + if (!isScopeAvailable) { + // TODO: throw if any of the scope are not available /** * Under most circumstances this would have been caught by `checkPrivileges` as - * a user can't have Privileges to an unknown class, but super users - * don't actually get "privilege checked" so the made up class *will* return + * a user can't have Privileges to an unknown scope, but super users + * don't actually get "privilege checked" so the made up scope *will* return * as Privileged. * This check will ensure we don't accidentally let these through */ // TODO: audit log using `username` - throw Boom.forbidden('User does not have permissions for this class'); + throw Boom.forbidden('User does not have permissions for this scope'); } if (hasAllRequested) { @@ -129,11 +129,11 @@ export class Authorization { // TODO: audit log // TODO: User unauthorized. throw an error. authorizedPrivileges & unauthorizedPrivilages are needed for logging. - throw Boom.forbidden('Not authorized for this class'); + throw Boom.forbidden('Not authorized for this scope'); } - } else if (!isAvailableClass) { + } else if (!isScopeAvailable) { // TODO: throw an error - throw Boom.forbidden('Security is disabled but no class was found'); + throw Boom.forbidden('Security is disabled but no scope was found'); } // else security is disabled so let the operation proceed @@ -143,46 +143,46 @@ export class Authorization { savedObjectType: string ): Promise<{ filter?: KueryNode; - ensureSavedObjectIsAuthorized: (className: string) => void; + ensureSavedObjectIsAuthorized: (scope: string) => void; }> { const { securityAuth } = this; if (securityAuth && this.shouldCheckAuthorization()) { - const { authorizedClassNames } = await this.getAuthorizedClassNames([ReadOperations.Find]); + const { authorizedScopes } = await this.getAuthorizedScopes([ReadOperations.Find]); - if (!authorizedClassNames.length) { + if (!authorizedScopes.length) { // TODO: Better error message, log error - throw Boom.forbidden('Not authorized for this class'); + throw Boom.forbidden('Not authorized for this scope'); } return { - filter: getClassFilter(savedObjectType, authorizedClassNames), - ensureSavedObjectIsAuthorized: (className: string) => { - if (!authorizedClassNames.includes(className)) { + filter: getScopesFilter(savedObjectType, authorizedScopes), + ensureSavedObjectIsAuthorized: (scope: string) => { + if (!authorizedScopes.includes(scope)) { // TODO: log error - throw Boom.forbidden('Not authorized for this class'); + throw Boom.forbidden('Not authorized for this scope'); } }, }; } - return { ensureSavedObjectIsAuthorized: (className: string) => {} }; + return { ensureSavedObjectIsAuthorized: (scope: string) => {} }; } - private async getAuthorizedClassNames( + private async getAuthorizedScopes( operations: Array ): Promise<{ username?: string; hasAllRequested: boolean; - authorizedClassNames: string[]; + authorizedScopes: string[]; }> { - const { securityAuth, featureCaseClasses } = this; + const { securityAuth, featureCaseScopes } = this; if (securityAuth && this.shouldCheckAuthorization()) { const checkPrivileges = securityAuth.checkPrivilegesDynamicallyWithRequest(this.request); const requiredPrivileges = new Map(); - for (const className of featureCaseClasses) { + for (const scope of featureCaseScopes) { for (const operation of operations) { - requiredPrivileges.set(securityAuth.actions.cases.get(className, operation), [className]); + requiredPrivileges.set(securityAuth.actions.cases.get(scope, operation), [scope]); } } @@ -193,24 +193,21 @@ export class Authorization { return { hasAllRequested, username, - authorizedClassNames: hasAllRequested - ? Array.from(featureCaseClasses) - : privileges.kibana.reduce( - (authorizedClassNames, { authorized, privilege }) => { - if (authorized && requiredPrivileges.has(privilege)) { - const [className] = requiredPrivileges.get(privilege)!; - authorizedClassNames.push(className); - } - - return authorizedClassNames; - }, - [] - ), + authorizedScopes: hasAllRequested + ? Array.from(featureCaseScopes) + : privileges.kibana.reduce((authorizedScopes, { authorized, privilege }) => { + if (authorized && requiredPrivileges.has(privilege)) { + const [scope] = requiredPrivileges.get(privilege)!; + authorizedScopes.push(scope); + } + + return authorizedScopes; + }, []), }; } else { return { hasAllRequested: true, - authorizedClassNames: Array.from(featureCaseClasses), + authorizedScopes: Array.from(featureCaseScopes), }; } } diff --git a/x-pack/plugins/cases/server/authorization/utils.ts b/x-pack/plugins/cases/server/authorization/utils.ts index 435ef18c4feec5..e06556326e98b2 100644 --- a/x-pack/plugins/cases/server/authorization/utils.ts +++ b/x-pack/plugins/cases/server/authorization/utils.ts @@ -9,11 +9,11 @@ import { remove, uniq } from 'lodash'; import { nodeBuilder } from '../../../../../src/plugins/data/common'; import { KueryNode } from '../../../../../src/plugins/data/server'; -export const getClassFilter = (savedObjectType: string, classNames: string[]): KueryNode => { +export const getScopesFilter = (savedObjectType: string, scopes: string[]): KueryNode => { return nodeBuilder.or( - classNames.reduce((query, className) => { - ensureFieldIsSafeForQuery('class', className); - query.push(nodeBuilder.is(`${savedObjectType}.attributes.class`, className)); + scopes.reduce((query, scope) => { + ensureFieldIsSafeForQuery('scope', scope); + query.push(nodeBuilder.is(`${savedObjectType}.attributes.scope`, scope)); return query; }, []) ); @@ -43,4 +43,4 @@ export const ensureFieldIsSafeForQuery = (field: string, value: string): boolean }; export const includeFieldsRequiredForAuthentication = (fields: string[]): string[] => - uniq([...fields, 'class']); + uniq([...fields, 'scope']); diff --git a/x-pack/plugins/cases/server/client/cases/create.test.ts b/x-pack/plugins/cases/server/client/cases/create.test.ts index cb37b3f810734e..9ad755725bdb79 100644 --- a/x-pack/plugins/cases/server/client/cases/create.test.ts +++ b/x-pack/plugins/cases/server/client/cases/create.test.ts @@ -45,7 +45,7 @@ describe('create', () => { settings: { syncAlerts: true, }, - class: 'awesome', + scope: 'awesome', }; const savedObjectsClient = createMockSavedObjectsRepository({ @@ -57,7 +57,7 @@ describe('create', () => { expect(res).toMatchInlineSnapshot(` Object { - "class": "awesome", + "scope": "awesome", "closed_at": null, "closed_by": null, "comments": Array [], @@ -121,7 +121,7 @@ describe('create', () => { "connector", "settings", ], - "new_value": "{\\"type\\":\\"individual\\",\\"description\\":\\"This is a brand new case of a bad meanie defacing data\\",\\"title\\":\\"Super Bad Security Issue\\",\\"tags\\":[\\"defacement\\"],\\"connector\\":{\\"id\\":\\"123\\",\\"name\\":\\"Jira\\",\\"type\\":\\".jira\\",\\"fields\\":{\\"issueType\\":\\"Task\\",\\"priority\\":\\"High\\",\\"parent\\":null}},\\"settings\\":{\\"syncAlerts\\":true},\\"class\\":\\"awesome\\"}", + "new_value": "{\\"type\\":\\"individual\\",\\"description\\":\\"This is a brand new case of a bad meanie defacing data\\",\\"title\\":\\"Super Bad Security Issue\\",\\"tags\\":[\\"defacement\\"],\\"connector\\":{\\"id\\":\\"123\\",\\"name\\":\\"Jira\\",\\"type\\":\\".jira\\",\\"fields\\":{\\"issueType\\":\\"Task\\",\\"priority\\":\\"High\\",\\"parent\\":null}},\\"settings\\":{\\"syncAlerts\\":true},\\"scope\\":\\"awesome\\"}", "old_value": null, }, "references": Array [ @@ -151,7 +151,7 @@ describe('create', () => { settings: { syncAlerts: true, }, - class: 'awesome', + scope: 'awesome', }; const savedObjectsClient = createMockSavedObjectsRepository({ @@ -162,7 +162,7 @@ describe('create', () => { expect(res).toMatchInlineSnapshot(` Object { - "class": "awesome", + "scope": "awesome", "closed_at": null, "closed_by": null, "comments": Array [], @@ -216,7 +216,7 @@ describe('create', () => { settings: { syncAlerts: true, }, - class: 'awesome', + scope: 'awesome', }; const savedObjectsClient = createMockSavedObjectsRepository({ @@ -230,7 +230,7 @@ describe('create', () => { expect(res).toMatchInlineSnapshot(` Object { - "class": "awesome", + "scope": "awesome", "closed_at": null, "closed_by": null, "comments": Array [], @@ -429,7 +429,7 @@ describe('create', () => { settings: { syncAlerts: true, }, - class: 'awesome', + scope: 'awesome', }; const savedObjectsClient = createMockSavedObjectsRepository({ @@ -458,7 +458,7 @@ describe('create', () => { settings: { syncAlerts: true, }, - class: 'awesome', + scope: 'awesome', }; const savedObjectsClient = createMockSavedObjectsRepository({ caseSavedObject: mockCases, diff --git a/x-pack/plugins/cases/server/client/cases/create.ts b/x-pack/plugins/cases/server/client/cases/create.ts index 736ee0b13baa74..2ceabad6545779 100644 --- a/x-pack/plugins/cases/server/client/cases/create.ts +++ b/x-pack/plugins/cases/server/client/cases/create.ts @@ -72,7 +72,7 @@ export const create = async ({ try { try { - await auth.ensureAuthorized(query.class, WriteOperations.Create); + await auth.ensureAuthorized(query.scope, WriteOperations.Create); } catch (error) { // TODO: log error using audit logger throw error; diff --git a/x-pack/plugins/cases/server/client/cases/find.ts b/x-pack/plugins/cases/server/client/cases/find.ts index 39c5435c8ff5db..58d7d08b2dcfd3 100644 --- a/x-pack/plugins/cases/server/client/cases/find.ts +++ b/x-pack/plugins/cases/server/client/cases/find.ts @@ -80,7 +80,7 @@ export const find = async ({ }); for (const theCase of cases.casesMap.values()) { - ensureSavedObjectIsAuthorized(theCase.class); + ensureSavedObjectIsAuthorized(theCase.scope); } // TODO: Make sure we do not leak information when authorization is on diff --git a/x-pack/plugins/cases/server/routes/api/cases/post_case.test.ts b/x-pack/plugins/cases/server/routes/api/cases/post_case.test.ts index c211ee1320694e..7c11a15b6a836f 100644 --- a/x-pack/plugins/cases/server/routes/api/cases/post_case.test.ts +++ b/x-pack/plugins/cases/server/routes/api/cases/post_case.test.ts @@ -46,7 +46,7 @@ describe('POST cases', () => { settings: { syncAlerts: true, }, - class: 'awesome', + scope: 'awesome', }, }); @@ -86,7 +86,7 @@ describe('POST cases', () => { settings: { syncAlerts: true, }, - class: 'awesome', + scope: 'awesome', }, }); @@ -120,7 +120,7 @@ describe('POST cases', () => { settings: { syncAlerts: true, }, - class: 'awesome', + scope: 'awesome', }, }); @@ -146,7 +146,7 @@ describe('POST cases', () => { settings: { syncAlerts: true, }, - class: 'awesome', + scope: 'awesome', }, }); @@ -180,7 +180,7 @@ describe('POST cases', () => { settings: { syncAlerts: true, }, - class: 'awesome', + scope: 'awesome', }, }); @@ -196,7 +196,7 @@ describe('POST cases', () => { expect(response.status).toEqual(200); expect(response.payload).toMatchInlineSnapshot(` Object { - "class": "awesome", + "scope": "awesome", "closed_at": null, "closed_by": null, "comments": Array [], diff --git a/x-pack/plugins/cases/server/saved_object_types/cases.ts b/x-pack/plugins/cases/server/saved_object_types/cases.ts index 4464adf8562ab4..02708b80587687 100644 --- a/x-pack/plugins/cases/server/saved_object_types/cases.ts +++ b/x-pack/plugins/cases/server/saved_object_types/cases.ts @@ -31,9 +31,6 @@ export const caseSavedObjectType: SavedObjectsType = { }, }, }, - class: { - type: 'keyword', - }, created_at: { type: 'date', }, @@ -114,6 +111,9 @@ export const caseSavedObjectType: SavedObjectsType = { title: { type: 'keyword', }, + scope: { + type: 'keyword', + }, status: { type: 'keyword', }, diff --git a/x-pack/plugins/cases/server/saved_object_types/comments.ts b/x-pack/plugins/cases/server/saved_object_types/comments.ts index 66c44f1588d02b..bba7e6fc524d99 100644 --- a/x-pack/plugins/cases/server/saved_object_types/comments.ts +++ b/x-pack/plugins/cases/server/saved_object_types/comments.ts @@ -21,7 +21,7 @@ export const caseCommentSavedObjectType: SavedObjectsType = { comment: { type: 'text', }, - class: { + scope: { type: 'keyword', }, type: { diff --git a/x-pack/plugins/cases/server/saved_object_types/configure.ts b/x-pack/plugins/cases/server/saved_object_types/configure.ts index 2b7588cca7b6e6..1d525b2a4a7349 100644 --- a/x-pack/plugins/cases/server/saved_object_types/configure.ts +++ b/x-pack/plugins/cases/server/saved_object_types/configure.ts @@ -15,9 +15,6 @@ export const caseConfigureSavedObjectType: SavedObjectsType = { namespaceType: 'single', mappings: { properties: { - class: { - type: 'keyword', - }, created_at: { type: 'date', }, @@ -60,6 +57,9 @@ export const caseConfigureSavedObjectType: SavedObjectsType = { closure_type: { type: 'keyword', }, + scope: { + type: 'keyword', + }, updated_at: { type: 'date', }, diff --git a/x-pack/plugins/cases/server/saved_object_types/connector_mappings.ts b/x-pack/plugins/cases/server/saved_object_types/connector_mappings.ts index 5bcf2dc319c717..5ac333c7e9fb7d 100644 --- a/x-pack/plugins/cases/server/saved_object_types/connector_mappings.ts +++ b/x-pack/plugins/cases/server/saved_object_types/connector_mappings.ts @@ -28,7 +28,7 @@ export const caseConnectorMappingsSavedObjectType: SavedObjectsType = { }, }, }, - class: { + scope: { type: 'keyword', }, }, diff --git a/x-pack/plugins/cases/server/saved_object_types/migrations.ts b/x-pack/plugins/cases/server/saved_object_types/migrations.ts index 905ea2c2be3ba1..b7ba955e295ac8 100644 --- a/x-pack/plugins/cases/server/saved_object_types/migrations.ts +++ b/x-pack/plugins/cases/server/saved_object_types/migrations.ts @@ -15,7 +15,7 @@ import { AssociationType, ESConnectorFields, } from '../../common/api'; -import { SECURITY_SOLUTION_CONSUMER } from '../../common/constants'; +import { SECURITY_SOLUTION_SCOPE } from '../../common/constants'; interface UnsanitizedCaseConnector { connector_id: string; @@ -61,16 +61,16 @@ interface SanitizedCaseType { } interface SanitizedCaseClass { - class: string; + scope: string; } -const addClassToSO = >( +const addScopeToSO = >( doc: SavedObjectUnsanitizedDoc ): SavedObjectSanitizedDoc => ({ ...doc, attributes: { ...doc.attributes, - class: SECURITY_SOLUTION_CONSUMER, + scope: SECURITY_SOLUTION_SCOPE, }, references: doc.references || [], }); @@ -132,7 +132,7 @@ export const caseMigrations = { '7.13.0': ( doc: SavedObjectUnsanitizedDoc> ): SavedObjectSanitizedDoc => { - return addClassToSO(doc); + return addScopeToSO(doc); }, }; @@ -159,7 +159,7 @@ export const configureMigrations = { '7.13.0': ( doc: SavedObjectUnsanitizedDoc> ): SavedObjectSanitizedDoc => { - return addClassToSO(doc); + return addScopeToSO(doc); }, }; @@ -205,7 +205,7 @@ export const userActionsMigrations = { '7.13.0': ( doc: SavedObjectUnsanitizedDoc> ): SavedObjectSanitizedDoc => { - return addClassToSO(doc); + return addScopeToSO(doc); }, }; @@ -260,7 +260,7 @@ export const commentsMigrations = { '7.13.0': ( doc: SavedObjectUnsanitizedDoc> ): SavedObjectSanitizedDoc => { - return addClassToSO(doc); + return addScopeToSO(doc); }, }; @@ -268,7 +268,7 @@ export const connectorMappingsMigrations = { '7.13.0': ( doc: SavedObjectUnsanitizedDoc> ): SavedObjectSanitizedDoc => { - return addClassToSO(doc); + return addScopeToSO(doc); }, }; @@ -276,6 +276,6 @@ export const subCasesMigrations = { '7.13.0': ( doc: SavedObjectUnsanitizedDoc> ): SavedObjectSanitizedDoc => { - return addClassToSO(doc); + return addScopeToSO(doc); }, }; diff --git a/x-pack/plugins/cases/server/saved_object_types/sub_case.ts b/x-pack/plugins/cases/server/saved_object_types/sub_case.ts index d2e49e3574e972..f7d3264ddd8974 100644 --- a/x-pack/plugins/cases/server/saved_object_types/sub_case.ts +++ b/x-pack/plugins/cases/server/saved_object_types/sub_case.ts @@ -31,9 +31,6 @@ export const subCaseSavedObjectType: SavedObjectsType = { }, }, }, - class: { - type: 'keyword', - }, created_at: { type: 'date', }, @@ -50,6 +47,9 @@ export const subCaseSavedObjectType: SavedObjectsType = { }, }, }, + scope: { + type: 'keyword', + }, status: { type: 'keyword', }, diff --git a/x-pack/plugins/cases/server/saved_object_types/user_actions.ts b/x-pack/plugins/cases/server/saved_object_types/user_actions.ts index a94b23f63c1a87..44c3029bbff1cf 100644 --- a/x-pack/plugins/cases/server/saved_object_types/user_actions.ts +++ b/x-pack/plugins/cases/server/saved_object_types/user_actions.ts @@ -37,15 +37,15 @@ export const caseUserActionSavedObjectType: SavedObjectsType = { }, }, }, - class: { - type: 'keyword', - }, new_value: { type: 'text', }, old_value: { type: 'text', }, + scope: { + type: 'keyword', + }, }, }, migrations: userActionsMigrations, diff --git a/x-pack/plugins/security/server/authorization/actions/cases.test.ts b/x-pack/plugins/security/server/authorization/actions/cases.test.ts index e1c91543570356..877f59112fd348 100644 --- a/x-pack/plugins/security/server/authorization/actions/cases.test.ts +++ b/x-pack/plugins/security/server/authorization/actions/cases.test.ts @@ -20,23 +20,23 @@ describe('#get', () => { ${{}} `(`operation of ${JSON.stringify('$operation')}`, ({ operation }) => { const actions = new CasesActions(version); - expect(() => actions.get('class', operation)).toThrowErrorMatchingSnapshot(); + expect(() => actions.get('scope', operation)).toThrowErrorMatchingSnapshot(); }); it.each` - className + scope ${null} ${undefined} ${''} ${1} ${true} ${{}} - `(`class of ${JSON.stringify('$className')}`, ({ className }) => { + `(`scope of ${JSON.stringify('$scope')}`, ({ scope }) => { const actions = new CasesActions(version); - expect(() => actions.get(className, 'operation')).toThrowErrorMatchingSnapshot(); + expect(() => actions.get(scope, 'operation')).toThrowErrorMatchingSnapshot(); }); - it('returns `cases:${class}/${operation}`', () => { + it('returns `cases:${scope}/${operation}`', () => { const alertingActions = new CasesActions(version); expect(alertingActions.get('security', 'bar-operation')).toBe( 'cases:1.0.0-zeta1:security/bar-operation' diff --git a/x-pack/plugins/security/server/authorization/actions/cases.ts b/x-pack/plugins/security/server/authorization/actions/cases.ts index c428f8c0f0ecb6..622c732513e031 100644 --- a/x-pack/plugins/security/server/authorization/actions/cases.ts +++ b/x-pack/plugins/security/server/authorization/actions/cases.ts @@ -14,15 +14,15 @@ export class CasesActions { this.prefix = `cases:${versionNumber}:`; } - public get(className: string, operation: string): string { + public get(scope: string, operation: string): string { if (!operation || !isString(operation)) { throw new Error('operation is required and must be a string'); } - if (!className || !isString(className)) { - throw new Error('class is required and must be a string'); + if (!scope || !isString(scope)) { + throw new Error('scope is required and must be a string'); } - return `${this.prefix}${className}/${operation}`; + return `${this.prefix}${scope}/${operation}`; } } diff --git a/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/cases.ts b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/cases.ts index 4b5c42361543db..3cdbc8278ac719 100644 --- a/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/cases.ts +++ b/x-pack/plugins/security/server/authorization/privileges/feature_privilege_builder/cases.ts @@ -19,9 +19,9 @@ export class FeaturePrivilegeCasesBuilder extends BaseFeaturePrivilegeBuilder { privilegeDefinition: FeatureKibanaPrivileges, feature: KibanaFeature ): string[] { - const getCasesPrivilege = (operations: string[], classes: readonly string[]) => { - return classes.flatMap((className) => - operations.map((operation) => this.actions.cases.get(className, operation)) + const getCasesPrivilege = (operations: string[], scopes: readonly string[]) => { + return scopes.flatMap((scope) => + operations.map((operation) => this.actions.cases.get(scope, operation)) ); }; diff --git a/x-pack/plugins/security_solution/public/cases/components/create/form_context.tsx b/x-pack/plugins/security_solution/public/cases/components/create/form_context.tsx index 722c08552702d8..e098321829d8aa 100644 --- a/x-pack/plugins/security_solution/public/cases/components/create/form_context.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/create/form_context.tsx @@ -84,7 +84,7 @@ export const FormContext: React.FC = ({ connector: connectorToUpdate, settings: { syncAlerts }, // TODO: need to replace this with the value that the plugin registers in the feature registration - class: 'securitySolution', + scope: 'securitySolution', }); if (afterCaseCreated && updatedCase) { diff --git a/x-pack/plugins/security_solution/public/cases/components/create/schema.tsx b/x-pack/plugins/security_solution/public/cases/components/create/schema.tsx index bc0fc0e770a834..da475e7046bf25 100644 --- a/x-pack/plugins/security_solution/public/cases/components/create/schema.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/create/schema.tsx @@ -19,8 +19,8 @@ export const schemaTags = { labelAppend: OptionalFieldLabel, }; -// TODO: remove class from here? -export type FormProps = Omit & { +// TODO: remove scope from here? +export type FormProps = Omit & { connectorId: string; fields: ConnectorTypeFields['fields']; syncAlerts: boolean;