mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Security Solution] Push user action comments for Host Isolation to connectors (#105265)
This commit is contained in:
parent
41a93079b2
commit
c9b1a3cdef
3 changed files with 210 additions and 2 deletions
|
@ -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',
|
||||
|
|
|
@ -18,6 +18,9 @@ import {
|
|||
commentAlert,
|
||||
commentAlertMultipleIds,
|
||||
commentGeneratedAlert,
|
||||
isolateCommentActions,
|
||||
releaseCommentActions,
|
||||
isolateCommentActionsMultipleTargets,
|
||||
} from './mock';
|
||||
|
||||
import {
|
||||
|
@ -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', () => {
|
||||
|
@ -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', () => {
|
||||
|
|
|
@ -19,6 +19,7 @@ import {
|
|||
CommentAttributes,
|
||||
CommentRequestUserType,
|
||||
CommentRequestAlertType,
|
||||
CommentRequestActionsType,
|
||||
} from '../../../common';
|
||||
import { ActionsClient } from '../../../../actions/server';
|
||||
import { CasesClientGetAlertsResponse } from '../../client/alerts/types';
|
||||
|
@ -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 '';
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue