Skip to content

Commit 3abe3a9

Browse files
[Security Solution][Case] Fix alerts push (#91638) (#92705)
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
1 parent 14b9432 commit 3abe3a9

File tree

6 files changed

+99
-34
lines changed

6 files changed

+99
-34
lines changed

x-pack/plugins/case/server/client/cases/mock.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {
1111
ConnectorMappingsAttributes,
1212
CaseUserActionsResponse,
1313
AssociationType,
14+
CommentResponseAlertsType,
1415
} from '../../../common/api';
1516

1617
import { BasicParams } from './types';
@@ -76,6 +77,20 @@ export const commentAlert: CommentResponse = {
7677
version: 'WzEsMV0=',
7778
};
7879

80+
export const commentAlertMultipleIds: CommentResponseAlertsType = {
81+
...commentAlert,
82+
id: 'mock-comment-2',
83+
alertId: ['alert-id-1', 'alert-id-2'],
84+
index: 'alert-index-1',
85+
type: CommentType.alert as const,
86+
};
87+
88+
export const commentGeneratedAlert: CommentResponseAlertsType = {
89+
...commentAlertMultipleIds,
90+
id: 'mock-comment-3',
91+
type: CommentType.generatedAlert as const,
92+
};
93+
7994
export const defaultPipes = ['informationCreated'];
8095
export const basicParams: BasicParams = {
8196
description: 'a description',

x-pack/plugins/case/server/client/cases/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export interface TransformFieldsArgs<P, S> {
7272

7373
export interface ExternalServiceComment {
7474
comment: string;
75-
commentId: string;
75+
commentId?: string;
7676
}
7777

7878
export interface MapIncident {

x-pack/plugins/case/server/client/cases/utils.test.ts

Lines changed: 42 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import {
1717
basicParams,
1818
userActions,
1919
commentAlert,
20+
commentAlertMultipleIds,
21+
commentGeneratedAlert,
2022
} from './mock';
2123

2224
import {
@@ -48,7 +50,7 @@ describe('utils', () => {
4850
{
4951
actionType: 'overwrite',
5052
key: 'short_description',
51-
pipes: ['informationCreated'],
53+
pipes: [],
5254
value: 'a title',
5355
},
5456
{
@@ -71,7 +73,7 @@ describe('utils', () => {
7173
{
7274
actionType: 'overwrite',
7375
key: 'short_description',
74-
pipes: ['myTestPipe'],
76+
pipes: [],
7577
value: 'a title',
7678
},
7779
{
@@ -98,7 +100,7 @@ describe('utils', () => {
98100
});
99101

100102
expect(res).toEqual({
101-
short_description: 'a title (created at 2020-03-13T08:34:53.450Z by Elastic User)',
103+
short_description: 'a title',
102104
description: 'a description (created at 2020-03-13T08:34:53.450Z by Elastic User)',
103105
});
104106
});
@@ -122,13 +124,13 @@ describe('utils', () => {
122124
},
123125
fields,
124126
currentIncident: {
125-
short_description: 'first title (created at 2020-03-13T08:34:53.450Z by Elastic User)',
127+
short_description: 'first title',
126128
description: 'first description (created at 2020-03-13T08:34:53.450Z by Elastic User)',
127129
},
128130
});
129131

130132
expect(res).toEqual({
131-
short_description: 'a title (updated at 2020-03-15T08:34:53.450Z by Another User)',
133+
short_description: 'a title',
132134
description:
133135
'first description (created at 2020-03-13T08:34:53.450Z by Elastic User) \r\na description (updated at 2020-03-15T08:34:53.450Z by Another User)',
134136
});
@@ -168,7 +170,7 @@ describe('utils', () => {
168170
});
169171

170172
expect(res).toEqual({
171-
short_description: 'a title (created at 2020-03-13T08:34:53.450Z by elastic)',
173+
short_description: 'a title',
172174
description: 'a description (created at 2020-03-13T08:34:53.450Z by elastic)',
173175
});
174176
});
@@ -190,7 +192,7 @@ describe('utils', () => {
190192
});
191193

192194
expect(res).toEqual({
193-
short_description: 'a title (updated at 2020-03-15T08:34:53.450Z by anotherUser)',
195+
short_description: 'a title',
194196
description: 'a description (updated at 2020-03-15T08:34:53.450Z by anotherUser)',
195197
});
196198
});
@@ -448,8 +450,7 @@ describe('utils', () => {
448450
labels: ['defacement'],
449451
issueType: null,
450452
parent: null,
451-
short_description:
452-
'Super Bad Security Issue (created at 2019-11-25T21:54:48.952Z by elastic)',
453+
short_description: 'Super Bad Security Issue',
453454
description:
454455
'This is a brand new case of a bad meanie defacing data (created at 2019-11-25T21:54:48.952Z by elastic)',
455456
externalId: null,
@@ -504,15 +505,17 @@ describe('utils', () => {
504505
expect(res.comments).toEqual([]);
505506
});
506507

507-
it('it creates comments of type alert correctly', async () => {
508+
it('it adds the total alert comments correctly', async () => {
508509
const res = await createIncident({
509510
actionsClient: actionsMock,
510511
theCase: {
511512
...theCase,
512513
comments: [
513514
{ ...commentObj, id: 'comment-user-1' },
514515
{ ...commentAlert, id: 'comment-alert-1' },
515-
{ ...commentAlert, id: 'comment-alert-2' },
516+
{
517+
...commentAlertMultipleIds,
518+
},
516519
],
517520
},
518521
// Remove second push
@@ -536,14 +539,36 @@ describe('utils', () => {
536539
commentId: 'comment-user-1',
537540
},
538541
{
539-
comment:
540-
'Alert with ids alert-id-1 added to case (added at 2019-11-25T21:55:00.177Z by elastic)',
541-
commentId: 'comment-alert-1',
542+
comment: 'Elastic Security Alerts attached to the case: 3',
542543
},
544+
]);
545+
});
546+
547+
it('it removes alerts correctly', async () => {
548+
const res = await createIncident({
549+
actionsClient: actionsMock,
550+
theCase: {
551+
...theCase,
552+
comments: [
553+
{ ...commentObj, id: 'comment-user-1' },
554+
commentAlertMultipleIds,
555+
commentGeneratedAlert,
556+
],
557+
},
558+
userActions,
559+
connector,
560+
mappings,
561+
alerts: [],
562+
});
563+
564+
expect(res.comments).toEqual([
543565
{
544566
comment:
545-
'Alert with ids alert-id-1 added to case (added at 2019-11-25T21:55:00.177Z by elastic)',
546-
commentId: 'comment-alert-2',
567+
'Wow, good luck catching that bad meanie! (added at 2019-11-25T21:55:00.177Z by elastic)',
568+
commentId: 'comment-user-1',
569+
},
570+
{
571+
comment: 'Elastic Security Alerts attached to the case: 4',
547572
},
548573
]);
549574
});
@@ -578,8 +603,7 @@ describe('utils', () => {
578603
description:
579604
'fun description \r\nThis is a brand new case of a bad meanie defacing data (updated at 2019-11-25T21:54:48.952Z by elastic)',
580605
externalId: 'external-id',
581-
short_description:
582-
'Super Bad Security Issue (updated at 2019-11-25T21:54:48.952Z by elastic)',
606+
short_description: 'Super Bad Security Issue',
583607
},
584608
comments: [],
585609
});

x-pack/plugins/case/server/client/cases/utils.ts

Lines changed: 39 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,15 @@ import {
4040
} from './types';
4141
import { getAlertIds } from '../../routes/api/utils';
4242

43+
interface CreateIncidentArgs {
44+
actionsClient: ActionsClient;
45+
theCase: CaseResponse;
46+
userActions: CaseUserActionsResponse;
47+
connector: ActionConnector;
48+
mappings: ConnectorMappingsAttributes[];
49+
alerts: CaseClientGetAlertsResponse;
50+
}
51+
4352
export const getLatestPushInfo = (
4453
connectorId: string,
4554
userActions: CaseUserActionsResponse
@@ -75,14 +84,13 @@ const getCommentContent = (comment: CommentResponse): string => {
7584
return '';
7685
};
7786

78-
interface CreateIncidentArgs {
79-
actionsClient: ActionsClient;
80-
theCase: CaseResponse;
81-
userActions: CaseUserActionsResponse;
82-
connector: ActionConnector;
83-
mappings: ConnectorMappingsAttributes[];
84-
alerts: CaseClientGetAlertsResponse;
85-
}
87+
const countAlerts = (comments: CaseResponse['comments']): number =>
88+
comments?.reduce<number>((total, comment) => {
89+
if (comment.type === CommentType.alert || comment.type === CommentType.generatedAlert) {
90+
return total + (Array.isArray(comment.alertId) ? comment.alertId.length : 1);
91+
}
92+
return total;
93+
}, 0) ?? 0;
8694

8795
export const createIncident = async ({
8896
actionsClient,
@@ -152,22 +160,34 @@ export const createIncident = async ({
152160
userActions
153161
.slice(latestPushInfo?.index ?? 0)
154162
.filter(
155-
(action, index) =>
156-
Array.isArray(action.action_field) && action.action_field[0] === 'comment'
163+
(action) => Array.isArray(action.action_field) && action.action_field[0] === 'comment'
157164
)
158165
.map((action) => action.comment_id)
159166
);
160-
const commentsToBeUpdated = caseComments?.filter((comment) =>
161-
commentsIdsToBeUpdated.has(comment.id)
167+
168+
const commentsToBeUpdated = caseComments?.filter(
169+
(comment) =>
170+
// We push only user's comments
171+
comment.type === CommentType.user && commentsIdsToBeUpdated.has(comment.id)
162172
);
163173

174+
const totalAlerts = countAlerts(caseComments);
175+
164176
let comments: ExternalServiceComment[] = [];
177+
165178
if (commentsToBeUpdated && Array.isArray(commentsToBeUpdated) && commentsToBeUpdated.length > 0) {
166179
const commentsMapping = mappings.find((m) => m.source === 'comments');
167180
if (commentsMapping?.action_type !== 'nothing') {
168181
comments = transformComments(commentsToBeUpdated, ['informationAdded']);
169182
}
170183
}
184+
185+
if (totalAlerts > 0) {
186+
comments.push({
187+
comment: `Elastic Security Alerts attached to the case: ${totalAlerts}`,
188+
});
189+
}
190+
171191
return { incident, comments };
172192
};
173193

@@ -247,7 +267,13 @@ export const prepareFieldsForTransformation = ({
247267
key: mapping.target,
248268
value: params[mapping.source] ?? '',
249269
actionType: mapping.action_type,
250-
pipes: mapping.action_type === 'append' ? [...defaultPipes, 'append'] : defaultPipes,
270+
pipes:
271+
// Do not transform titles
272+
mapping.source !== 'title'
273+
? mapping.action_type === 'append'
274+
? [...defaultPipes, 'append']
275+
: defaultPipes
276+
: [],
251277
},
252278
]
253279
: acc,

x-pack/plugins/case/server/routes/api/cases/push_case.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ describe('Push case', () => {
170170
parent: null,
171171
priority: 'High',
172172
labels: ['LOLBins'],
173-
summary: 'Another bad one (created at 2019-11-25T22:32:17.947Z by elastic)',
173+
summary: 'Another bad one',
174174
description:
175175
'Oh no, a bad meanie going LOLBins all over the place! (created at 2019-11-25T22:32:17.947Z by elastic)',
176176
externalId: null,

x-pack/plugins/security_solution/public/cases/components/connectors/servicenow/translations.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export const PRIORITY = i18n.translate(
8787
export const ALERT_FIELDS_LABEL = i18n.translate(
8888
'xpack.securitySolution.components.connectors.serviceNow.alertFieldsTitle',
8989
{
90-
defaultMessage: 'Fields associated with alerts',
90+
defaultMessage: 'Select Observables to push',
9191
}
9292
);
9393

0 commit comments

Comments
 (0)