Skip to content

Commit

Permalink
[Security Solution] Push user action comments for Host Isolation to c…
Browse files Browse the repository at this point in the history
…onnectors (#105265) (#105348)

Co-authored-by: Kevin Logan <56395104+kevinlog@users.noreply.github.com>
  • Loading branch information
kibanamachine and kevinlog committed Jul 12, 2021
1 parent 6dee8d8 commit 9e84d7a
Show file tree
Hide file tree
Showing 3 changed files with 210 additions and 2 deletions.
100 changes: 100 additions & 0 deletions x-pack/plugins/cases/server/client/cases/mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,106 @@ export const comment: CommentResponse = {
version: 'WzEsMV0=',
};

export const isolateCommentActions: CommentResponse = {
associationType: AssociationType.case,
id: 'mock-action-comment-1',
comment: 'Isolating this for investigation',
type: CommentType.actions as const,
created_at: '2019-11-25T21:55:00.177Z',
actions: {
targets: [
{
endpointId: '123',
hostname: 'windows-host-1',
},
],
type: 'isolate',
},
created_by: {
full_name: 'elastic',
email: 'testemail@elastic.co',
username: 'elastic',
},
owner: SECURITY_SOLUTION_OWNER,
pushed_at: null,
pushed_by: null,
updated_at: '2019-11-25T21:55:00.177Z',
updated_by: {
full_name: 'elastic',
email: 'testemail@elastic.co',
username: 'elastic',
},
version: 'WzEsMV0=',
};

export const releaseCommentActions: CommentResponse = {
associationType: AssociationType.case,
id: 'mock-action-comment-1',
comment: 'Releasing this for investigation',
type: CommentType.actions as const,
created_at: '2019-11-25T21:55:00.177Z',
actions: {
targets: [
{
endpointId: '123',
hostname: 'windows-host-1',
},
],
type: 'unisolate',
},
created_by: {
full_name: 'elastic',
email: 'testemail@elastic.co',
username: 'elastic',
},
owner: SECURITY_SOLUTION_OWNER,
pushed_at: null,
pushed_by: null,
updated_at: '2019-11-25T21:55:00.177Z',
updated_by: {
full_name: 'elastic',
email: 'testemail@elastic.co',
username: 'elastic',
},
version: 'WzEsMV0=',
};

export const isolateCommentActionsMultipleTargets: CommentResponse = {
associationType: AssociationType.case,
id: 'mock-action-comment-1',
comment: 'Isolating this for investigation',
type: CommentType.actions as const,
created_at: '2019-11-25T21:55:00.177Z',
actions: {
targets: [
{
endpointId: '123',
hostname: 'windows-host-1',
},
{
endpointId: '456',
hostname: 'windows-host-2',
},
],
type: 'isolate',
},
created_by: {
full_name: 'elastic',
email: 'testemail@elastic.co',
username: 'elastic',
},
owner: SECURITY_SOLUTION_OWNER,
pushed_at: null,
pushed_by: null,
updated_at: '2019-11-25T21:55:00.177Z',
updated_by: {
full_name: 'elastic',
email: 'testemail@elastic.co',
username: 'elastic',
},
version: 'WzEsMV0=',
};

export const commentAlert: CommentResponse = {
associationType: AssociationType.case,
id: 'mock-comment-1',
Expand Down
85 changes: 85 additions & 0 deletions x-pack/plugins/cases/server/client/cases/utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ import {
commentAlert,
commentAlertMultipleIds,
commentGeneratedAlert,
isolateCommentActions,
releaseCommentActions,
isolateCommentActionsMultipleTargets,
} from './mock';

import {
Expand All @@ -37,6 +40,52 @@ const formatComment = {
comment: 'Wow, good luck catching that bad meanie!',
};

const formatIsolateActionComment = {
commentId: isolateCommentActions.id,
comment: 'Isolating this for investigation',
actions: {
targets: [
{
hostname: 'windows-host-1',
endpointId: '123',
},
],
type: 'isolate',
},
};

const formatReleaseActionComment = {
commentId: releaseCommentActions.id,
comment: 'Releasing this for investigation',
actions: {
targets: [
{
hostname: 'windows-host-1',
endpointId: '123',
},
],
type: 'unisolate',
},
};

const formatIsolateCommentActionsMultipleTargets = {
commentId: isolateCommentActionsMultipleTargets.id,
comment: 'Isolating this for investigation',
actions: {
targets: [
{
hostname: 'windows-host-1',
endpointId: '123',
},
{
hostname: 'windows-host-2',
endpointId: '456',
},
],
type: 'isolate',
},
};

const params = { ...basicParams };

describe('utils', () => {
Expand Down Expand Up @@ -289,6 +338,42 @@ describe('utils', () => {
},
]);
});

test('transform isolate action comment', () => {
const comments = [isolateCommentActions];
const res = transformComments(comments, ['informationCreated']);
const actionText = `Isolated host ${formatIsolateActionComment.actions.targets[0].hostname} with comment: ${formatIsolateActionComment.comment}`;
expect(res).toEqual([
{
commentId: formatIsolateActionComment.commentId,
comment: `${actionText} (created at ${comments[0].created_at} by ${comments[0].created_by.full_name})`,
},
]);
});

test('transform release action comment', () => {
const comments = [releaseCommentActions];
const res = transformComments(comments, ['informationCreated']);
const actionText = `Released host ${formatReleaseActionComment.actions.targets[0].hostname} with comment: ${formatReleaseActionComment.comment}`;
expect(res).toEqual([
{
commentId: formatReleaseActionComment.commentId,
comment: `${actionText} (created at ${comments[0].created_at} by ${comments[0].created_by.full_name})`,
},
]);
});

test('transform isolate action comment with multiple hosts', () => {
const comments = [isolateCommentActionsMultipleTargets];
const res = transformComments(comments, ['informationCreated']);
const actionText = `Isolated host ${formatIsolateCommentActionsMultipleTargets.actions.targets[0].hostname} and 1 more with comment: ${formatIsolateCommentActionsMultipleTargets.comment}`;
expect(res).toEqual([
{
commentId: formatIsolateCommentActionsMultipleTargets.commentId,
comment: `${actionText} (created at ${comments[0].created_at} by ${comments[0].created_by.full_name})`,
},
]);
});
});

describe('transformers', () => {
Expand Down
27 changes: 25 additions & 2 deletions x-pack/plugins/cases/server/client/cases/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {
CommentAttributes,
CommentRequestUserType,
CommentRequestAlertType,
CommentRequestActionsType,
} from '../../../common';
import { ActionsClient } from '../../../../actions/server';
import { CasesClientGetAlertsResponse } from '../../client/alerts/types';
Expand Down Expand Up @@ -76,6 +77,17 @@ const getCommentContent = (comment: CommentResponse): string => {
} else if (comment.type === CommentType.alert || comment.type === CommentType.generatedAlert) {
const ids = getAlertIds(comment);
return `Alert with ids ${ids.join(', ')} added to case`;
} else if (
comment.type === CommentType.actions &&
(comment.actions.type === 'isolate' || comment.actions.type === 'unisolate')
) {
const firstHostname =
comment.actions.targets?.length > 0 ? comment.actions.targets[0].hostname : 'unknown';
const totalHosts = comment.actions.targets.length;
const actionText = comment.actions.type === 'isolate' ? 'Isolated' : 'Released';
const additionalHostsText = totalHosts - 1 > 0 ? `and ${totalHosts - 1} more ` : ``;

return `${actionText} host ${firstHostname} ${additionalHostsText}with comment: ${comment.comment}`;
}

return '';
Expand Down Expand Up @@ -161,7 +173,8 @@ export const createIncident = async ({
const commentsToBeUpdated = caseComments?.filter(
(comment) =>
// We push only user's comments
comment.type === CommentType.user && commentsIdsToBeUpdated.has(comment.id)
(comment.type === CommentType.user || comment.type === CommentType.actions) &&
commentsIdsToBeUpdated.has(comment.id)
);

const totalAlerts = countAlerts(caseComments);
Expand Down Expand Up @@ -322,7 +335,7 @@ export const isCommentAlertType = (

export const getCommentContextFromAttributes = (
attributes: CommentAttributes
): CommentRequestUserType | CommentRequestAlertType => {
): CommentRequestUserType | CommentRequestAlertType | CommentRequestActionsType => {
const owner = attributes.owner;
switch (attributes.type) {
case CommentType.user:
Expand All @@ -340,6 +353,16 @@ export const getCommentContextFromAttributes = (
rule: attributes.rule,
owner,
};
case CommentType.actions:
return {
type: attributes.type,
comment: attributes.comment,
actions: {
targets: attributes.actions.targets,
type: attributes.actions.type,
},
owner,
};
default:
return {
type: CommentType.user,
Expand Down

0 comments on commit 9e84d7a

Please sign in to comment.