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

[Cases] Cases assignees sub feature #201654

Merged
merged 58 commits into from
Jan 30, 2025
Merged
Show file tree
Hide file tree
Changes from 56 commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
0c5ab06
WIP stack v3 cases working
kqualters-elastic Nov 25, 2024
994389d
Merge branch 'main' into cases-assignees
kqualters-elastic Nov 25, 2024
2fc8550
Merge remote-tracking branch 'upstream/main' into cases-assignees
kqualters-elastic Nov 25, 2024
81791a8
Merge remote-tracking branch 'upstream/main' into cases-assignees
kqualters-elastic Dec 2, 2024
3318b46
Add sec/obs case assignee sub feature + tests
kqualters-elastic Dec 10, 2024
ceeb37c
Merge remote-tracking branch 'upstream/main' into cases-assignees
kqualters-elastic Dec 10, 2024
86f2829
Fix tests and i18n warning
kqualters-elastic Dec 10, 2024
12bd761
Merge remote-tracking branch 'upstream/main' into cases-assignees
kqualters-elastic Dec 10, 2024
fbb8427
Fix types
kqualters-elastic Dec 12, 2024
dc2a26d
Merge remote-tracking branch 'upstream/main' into cases-assignees
kqualters-elastic Dec 12, 2024
d3ac4f2
Move security cases priv definition to right location
kqualters-elastic Dec 12, 2024
2d0383f
Fix test types
kqualters-elastic Dec 12, 2024
d6fd7e2
Update snapshots
kqualters-elastic Dec 13, 2024
225bfb9
More test fixes
kqualters-elastic Dec 13, 2024
2ad42bf
Merge remote-tracking branch 'upstream/main' into cases-assignees
kqualters-elastic Dec 13, 2024
dd7006a
Test/type fixes
kqualters-elastic Dec 17, 2024
381d8ca
Merge remote-tracking branch 'upstream/main' into cases-assignees
kqualters-elastic Dec 17, 2024
2ddcf56
Fix failing tests
kqualters-elastic Dec 18, 2024
e6a16e4
Merge remote-tracking branch 'upstream/main' into cases-assignees
kqualters-elastic Dec 23, 2024
218cef6
PR feedback
kqualters-elastic Dec 23, 2024
a7c7c15
Unique i18n ids
kqualters-elastic Dec 23, 2024
d09ad61
Merge remote-tracking branch 'upstream/main' into cases-assignees
kqualters-elastic Jan 10, 2025
52a2f60
Merge branch 'main' into cases-assignees
kqualters-elastic Jan 14, 2025
d6b39f5
PR feedback
kqualters-elastic Jan 15, 2025
5c37cb4
Merge remote-tracking branch 'upstream/main' into cases-assignees
kqualters-elastic Jan 16, 2025
4245847
WIP pr fixup
kqualters-elastic Jan 17, 2025
eaf107e
Change magic string
kqualters-elastic Jan 21, 2025
70ebc3b
Merge remote-tracking branch 'upstream/main' into cases-assignees-wip
kqualters-elastic Jan 21, 2025
d38065d
Use correct form of permission/capability
kqualters-elastic Jan 22, 2025
5acb55b
Merge remote-tracking branch 'upstream/main' into cases-assignees
kqualters-elastic Jan 22, 2025
e7a4375
Fix types
kqualters-elastic Jan 22, 2025
e726eda
Fix tests, clean up solution feature definitions
kqualters-elastic Jan 22, 2025
84a69c4
Merge remote-tracking branch 'upstream/main' into cases-assignees
kqualters-elastic Jan 22, 2025
9964c69
Align solution feature definitions
kqualters-elastic Jan 22, 2025
c83a7bf
More integration test scenarios
kqualters-elastic Jan 23, 2025
52b59b8
Update test
kqualters-elastic Jan 23, 2025
6ffea47
Merge remote-tracking branch 'upstream/main' into cases-assignees
kqualters-elastic Jan 23, 2025
faee86a
Fix tests that were too permissive
kqualters-elastic Jan 24, 2025
d871528
Fix ui capability not being linked to cases api operation
kqualters-elastic Jan 24, 2025
4de0bcc
Add assignee checks to create apis + unit tests
kqualters-elastic Jan 24, 2025
095bd0f
Use correct type for update cases api
kqualters-elastic Jan 24, 2025
7e1d80d
Merge remote-tracking branch 'upstream/main' into cases-assignees
kqualters-elastic Jan 25, 2025
28f03c2
Update snapshot
kqualters-elastic Jan 25, 2025
0f6a236
Update new test
kqualters-elastic Jan 25, 2025
11eb611
Merge remote-tracking branch 'upstream/main' into cases-assignees
kqualters-elastic Jan 28, 2025
368aef6
Merge remote-tracking branch 'upstream/main' into cases-assignees
kqualters-elastic Jan 28, 2025
49b7667
PR feedback
kqualters-elastic Jan 28, 2025
7728f45
Merge remote-tracking branch 'origin/cases-assignees' into cases-assi…
kqualters-elastic Jan 28, 2025
1135a50
Merge remote-tracking branch 'upstream/main' into cases-assignees
kqualters-elastic Jan 28, 2025
7437b84
Merge remote-tracking branch 'upstream/main' into cases-assignees
kqualters-elastic Jan 29, 2025
4b16c26
Feature definition pr feedback
kqualters-elastic Jan 29, 2025
547e024
Merge remote-tracking branch 'upstream/main' into cases-assignees
kqualters-elastic Jan 29, 2025
d124d4a
More feature definition refinement
kqualters-elastic Jan 29, 2025
cbef6bf
Merge remote-tracking branch 'upstream/main' into cases-assignees
kqualters-elastic Jan 29, 2025
b9a8de8
Update new snapshots
kqualters-elastic Jan 30, 2025
0a09c89
Merge remote-tracking branch 'upstream/main' into cases-assignees
kqualters-elastic Jan 30, 2025
e9d4f33
Add new subfeatures to feature privileges tests
kqualters-elastic Jan 30, 2025
f9fd4d9
Merge branch 'main' into cases-assignees
elasticmachine Jan 30, 2025
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

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ describe(`cases`, () => {
"cases:security/updateConfiguration",
"cases:security/createComment",
"cases:security/reopenCase",
"cases:security/assignCase",
"cases:obs/getCase",
"cases:obs/getComment",
"cases:obs/getTags",
Expand Down Expand Up @@ -187,6 +188,7 @@ describe(`cases`, () => {
"cases:security/updateConfiguration",
"cases:security/createComment",
"cases:security/reopenCase",
"cases:security/assignCase",
"cases:other-security/pushCase",
"cases:other-security/createCase",
"cases:other-security/getCase",
Expand All @@ -203,6 +205,7 @@ describe(`cases`, () => {
"cases:other-security/updateConfiguration",
"cases:other-security/createComment",
"cases:other-security/reopenCase",
"cases:other-security/assignCase",
"cases:obs/getCase",
"cases:obs/getComment",
"cases:obs/getTags",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const deleteOperations = ['deleteCase', 'deleteComment'] as const;
const settingsOperations = ['createConfiguration', 'updateConfiguration'] as const;
const createCommentOperations = ['createComment'] as const;
const reopenOperations = ['reopenCase'] as const;
const assignOperations = ['assignCase'] as const;
const allOperations = [
...pushOperations,
...createOperations,
Expand All @@ -46,6 +47,7 @@ const allOperations = [
...settingsOperations,
...createCommentOperations,
...reopenOperations,
...assignOperations,
] as const;

export class FeaturePrivilegeCasesBuilder extends BaseFeaturePrivilegeBuilder {
Expand All @@ -71,6 +73,7 @@ export class FeaturePrivilegeCasesBuilder extends BaseFeaturePrivilegeBuilder {
...getCasesPrivilege(settingsOperations, privilegeDefinition.cases?.settings),
...getCasesPrivilege(createCommentOperations, privilegeDefinition.cases?.createComment),
...getCasesPrivilege(reopenOperations, privilegeDefinition.cases?.reopenCase),
...getCasesPrivilege(assignOperations, privilegeDefinition.cases?.assign),
]);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@ import { CASE_VIEW_PAGE_TABS } from '../types';
*/

export const APP_ID = 'cases' as const;
/** @deprecated Please use FEATURE_ID_V2 instead */
/** @deprecated Please use FEATURE_ID_V3 instead */
export const FEATURE_ID = 'generalCases' as const;
/** @deprecated Please use FEATURE_ID_V3 instead */
export const FEATURE_ID_V2 = 'generalCasesV2' as const;
export const FEATURE_ID_V3 = 'generalCasesV3' as const;
export const APP_OWNER = 'cases' as const;
export const APP_PATH = '/app/management/insightsAndAlerting/cases' as const;
export const CASES_CREATE_PATH = '/create' as const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ export const CASES_SETTINGS_CAPABILITY = 'cases_settings' as const;
export const CASES_CONNECTORS_CAPABILITY = 'cases_connectors' as const;
export const CASES_REOPEN_CAPABILITY = 'case_reopen' as const;
export const CREATE_COMMENT_CAPABILITY = 'create_comment' as const;
export const ASSIGN_CASE_CAPABILITY = 'cases_assign' as const;

/**
* Cases API Tags
Expand Down
1 change: 1 addition & 0 deletions x-pack/platform/plugins/shared/cases/common/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ export {
CASES_SETTINGS_CAPABILITY,
CREATE_COMMENT_CAPABILITY,
CASES_REOPEN_CAPABILITY,
ASSIGN_CASE_CAPABILITY,
} from './constants';

export type { AttachmentAttributes } from './types/domain';
Expand Down
3 changes: 3 additions & 0 deletions x-pack/platform/plugins/shared/cases/common/ui/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import type {
UPDATE_CASES_CAPABILITY,
CREATE_COMMENT_CAPABILITY,
CASES_REOPEN_CAPABILITY,
ASSIGN_CASE_CAPABILITY,
} from '..';
import type {
CASES_CONNECTORS_CAPABILITY,
Expand Down Expand Up @@ -325,6 +326,7 @@ export interface CasesPermissions {
settings: boolean;
reopenCase: boolean;
createComment: boolean;
assign: boolean;
}

export interface CasesCapabilities {
Expand All @@ -337,4 +339,5 @@ export interface CasesCapabilities {
[CASES_SETTINGS_CAPABILITY]: boolean;
[CREATE_COMMENT_CAPABILITY]: boolean;
[CASES_REOPEN_CAPABILITY]: boolean;
[ASSIGN_CASE_CAPABILITY]: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ describe('createUICapabilities', () => {
"push_cases",
"cases_connectors",
],
"assignCase": Array [
"cases_assign",
],
"createComment": Array [
"create_comment",
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
CASES_SETTINGS_CAPABILITY,
CASES_REOPEN_CAPABILITY,
CREATE_COMMENT_CAPABILITY,
ASSIGN_CASE_CAPABILITY,
} from '../constants';

export interface CasesUiCapabilities {
Expand All @@ -24,6 +25,7 @@ export interface CasesUiCapabilities {
settings: readonly string[];
reopenCase: readonly string[];
createComment: readonly string[];
assignCase: readonly string[];
}
/**
* Return the UI capabilities for each type of operation. These strings must match the values defined in the UI
Expand All @@ -42,4 +44,5 @@ export const createUICapabilities = (): CasesUiCapabilities => ({
settings: [CASES_SETTINGS_CAPABILITY] as const,
reopenCase: [CASES_REOPEN_CAPABILITY] as const,
createComment: [CREATE_COMMENT_CAPABILITY] as const,
assignCase: [ASSIGN_CASE_CAPABILITY] as const,
});
Original file line number Diff line number Diff line change
Expand Up @@ -20,67 +20,67 @@ import { canUseCases } from './can_use_cases';

type CasesCapabilities = Pick<
ApplicationStart['capabilities'],
'securitySolutionCasesV2' | 'observabilityCasesV2' | 'generalCasesV2'
'securitySolutionCasesV3' | 'observabilityCasesV3' | 'generalCasesV3'
>;

const hasAll: CasesCapabilities = {
securitySolutionCasesV2: allCasesCapabilities(),
observabilityCasesV2: allCasesCapabilities(),
generalCasesV2: allCasesCapabilities(),
securitySolutionCasesV3: allCasesCapabilities(),
observabilityCasesV3: allCasesCapabilities(),
generalCasesV3: allCasesCapabilities(),
};

const hasNone: CasesCapabilities = {
securitySolutionCasesV2: noCasesCapabilities(),
observabilityCasesV2: noCasesCapabilities(),
generalCasesV2: noCasesCapabilities(),
securitySolutionCasesV3: noCasesCapabilities(),
observabilityCasesV3: noCasesCapabilities(),
generalCasesV3: noCasesCapabilities(),
};

const hasSecurity: CasesCapabilities = {
securitySolutionCasesV2: allCasesCapabilities(),
observabilityCasesV2: noCasesCapabilities(),
generalCasesV2: noCasesCapabilities(),
securitySolutionCasesV3: allCasesCapabilities(),
observabilityCasesV3: noCasesCapabilities(),
generalCasesV3: noCasesCapabilities(),
};

const hasObservability: CasesCapabilities = {
securitySolutionCasesV2: noCasesCapabilities(),
observabilityCasesV2: allCasesCapabilities(),
generalCasesV2: noCasesCapabilities(),
securitySolutionCasesV3: noCasesCapabilities(),
observabilityCasesV3: allCasesCapabilities(),
generalCasesV3: noCasesCapabilities(),
};

const hasObservabilityWriteTrue: CasesCapabilities = {
securitySolutionCasesV2: noCasesCapabilities(),
observabilityCasesV2: writeCasesCapabilities(),
generalCasesV2: noCasesCapabilities(),
securitySolutionCasesV3: noCasesCapabilities(),
observabilityCasesV3: writeCasesCapabilities(),
generalCasesV3: noCasesCapabilities(),
};

const hasSecurityWriteTrue: CasesCapabilities = {
securitySolutionCasesV2: writeCasesCapabilities(),
observabilityCasesV2: noCasesCapabilities(),
generalCasesV2: noCasesCapabilities(),
securitySolutionCasesV3: writeCasesCapabilities(),
observabilityCasesV3: noCasesCapabilities(),
generalCasesV3: noCasesCapabilities(),
};

const hasObservabilityReadTrue: CasesCapabilities = {
securitySolutionCasesV2: noCasesCapabilities(),
observabilityCasesV2: readCasesCapabilities(),
generalCasesV2: noCasesCapabilities(),
securitySolutionCasesV3: noCasesCapabilities(),
observabilityCasesV3: readCasesCapabilities(),
generalCasesV3: noCasesCapabilities(),
};

const hasSecurityReadTrue: CasesCapabilities = {
securitySolutionCasesV2: readCasesCapabilities(),
observabilityCasesV2: noCasesCapabilities(),
generalCasesV2: noCasesCapabilities(),
securitySolutionCasesV3: readCasesCapabilities(),
observabilityCasesV3: noCasesCapabilities(),
generalCasesV3: noCasesCapabilities(),
};

const hasSecurityWriteAndObservabilityRead: CasesCapabilities = {
securitySolutionCasesV2: writeCasesCapabilities(),
observabilityCasesV2: readCasesCapabilities(),
generalCasesV2: noCasesCapabilities(),
securitySolutionCasesV3: writeCasesCapabilities(),
observabilityCasesV3: readCasesCapabilities(),
generalCasesV3: noCasesCapabilities(),
};

const hasSecurityConnectors: CasesCapabilities = {
securitySolutionCasesV2: readCasesCapabilities(),
observabilityCasesV2: noCasesCapabilities(),
generalCasesV2: noCasesCapabilities(),
securitySolutionCasesV3: readCasesCapabilities(),
observabilityCasesV3: noCasesCapabilities(),
generalCasesV3: noCasesCapabilities(),
};

describe('canUseCases', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import type { ApplicationStart } from '@kbn/core/public';
import {
FEATURE_ID_V2,
FEATURE_ID_V3,
GENERAL_CASES_OWNER,
OBSERVABILITY_OWNER,
SECURITY_SOLUTION_OWNER,
Expand All @@ -32,9 +32,9 @@ export const canUseCases =
owners: CasesOwners[] = [OBSERVABILITY_OWNER, SECURITY_SOLUTION_OWNER, GENERAL_CASES_OWNER]
): CasesPermissions => {
const aggregatedPermissions = owners.reduce<CasesPermissions>(
// eslint-disable-next-line complexity
(acc, owner) => {
const userCapabilitiesForOwner = getUICapabilities(capabilities[getFeatureID(owner)]);

acc.create = acc.create || userCapabilitiesForOwner.create;
acc.read = acc.read || userCapabilitiesForOwner.read;
acc.update = acc.update || userCapabilitiesForOwner.update;
Expand All @@ -44,6 +44,7 @@ export const canUseCases =
acc.settings = acc.settings || userCapabilitiesForOwner.settings;
acc.reopenCase = acc.reopenCase || userCapabilitiesForOwner.reopenCase;
acc.createComment = acc.createComment || userCapabilitiesForOwner.createComment;
acc.assign = acc.assign || userCapabilitiesForOwner.assign;

const allFromAcc =
acc.create &&
Expand All @@ -54,7 +55,8 @@ export const canUseCases =
acc.connectors &&
acc.settings &&
acc.reopenCase &&
acc.createComment;
acc.createComment &&
acc.assign;

acc.all = acc.all || userCapabilitiesForOwner.all || allFromAcc;

Expand All @@ -71,6 +73,7 @@ export const canUseCases =
settings: false,
reopenCase: false,
createComment: false,
assign: false,
}
);

Expand All @@ -81,8 +84,8 @@ export const canUseCases =

const getFeatureID = (owner: CasesOwners) => {
if (owner === GENERAL_CASES_OWNER) {
return FEATURE_ID_V2;
return FEATURE_ID_V3;
}

return `${owner}CasesV2`;
return `${owner}CasesV3`;
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ describe('getUICapabilities', () => {
expect(getUICapabilities(undefined)).toMatchInlineSnapshot(`
Object {
"all": false,
"assign": false,
"connectors": false,
"create": false,
"createComment": false,
Expand All @@ -29,6 +30,7 @@ describe('getUICapabilities', () => {
expect(getUICapabilities()).toMatchInlineSnapshot(`
Object {
"all": false,
"assign": false,
"connectors": false,
"create": false,
"createComment": false,
Expand All @@ -46,6 +48,7 @@ describe('getUICapabilities', () => {
expect(getUICapabilities({ create_cases: true })).toMatchInlineSnapshot(`
Object {
"all": false,
"assign": false,
"connectors": false,
"create": true,
"createComment": false,
Expand All @@ -72,6 +75,7 @@ describe('getUICapabilities', () => {
).toMatchInlineSnapshot(`
Object {
"all": false,
"assign": false,
"connectors": false,
"create": false,
"createComment": false,
Expand All @@ -89,6 +93,7 @@ describe('getUICapabilities', () => {
expect(getUICapabilities({})).toMatchInlineSnapshot(`
Object {
"all": false,
"assign": false,
"connectors": false,
"create": false,
"createComment": false,
Expand All @@ -115,6 +120,7 @@ describe('getUICapabilities', () => {
).toMatchInlineSnapshot(`
Object {
"all": false,
"assign": false,
"connectors": true,
"create": false,
"createComment": false,
Expand Down Expand Up @@ -142,6 +148,7 @@ describe('getUICapabilities', () => {
).toMatchInlineSnapshot(`
Object {
"all": false,
"assign": false,
"connectors": false,
"create": true,
"createComment": false,
Expand Down Expand Up @@ -169,6 +176,7 @@ describe('getUICapabilities', () => {
).toMatchInlineSnapshot(`
Object {
"all": false,
"assign": false,
"connectors": true,
"create": true,
"createComment": false,
Expand All @@ -186,6 +194,7 @@ describe('getUICapabilities', () => {
expect(getUICapabilities({ cases_settings: true })).toMatchInlineSnapshot(`
Object {
"all": false,
"assign": false,
"connectors": false,
"create": false,
"createComment": false,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
UPDATE_CASES_CAPABILITY,
CASES_REOPEN_CAPABILITY,
CREATE_COMMENT_CAPABILITY,
ASSIGN_CASE_CAPABILITY,
} from '../../../common/constants';

export const getUICapabilities = (
Expand All @@ -30,6 +31,7 @@ export const getUICapabilities = (
const settings = !!featureCapabilities?.[CASES_SETTINGS_CAPABILITY];
const reopenCase = !!featureCapabilities?.[CASES_REOPEN_CAPABILITY];
const createComment = !!featureCapabilities?.[CREATE_COMMENT_CAPABILITY];
const assignCases = !!featureCapabilities?.[ASSIGN_CASE_CAPABILITY];

const all =
create &&
Expand All @@ -40,7 +42,8 @@ export const getUICapabilities = (
connectors &&
settings &&
reopenCase &&
createComment;
createComment &&
assignCases;

return {
all,
Expand All @@ -53,5 +56,6 @@ export const getUICapabilities = (
settings,
reopenCase,
createComment,
assign: assignCases,
};
};
Loading