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 client enchantment #95923

Merged
merged 13 commits into from
Apr 6, 2021
3 changes: 1 addition & 2 deletions x-pack/plugins/cases/server/authorization/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@
*/

import { remove, uniq } from 'lodash';
import { nodeBuilder } from '../../../../../src/plugins/data/common';
import { KueryNode } from '../../../../../src/plugins/data/server';
import { nodeBuilder, KueryNode } from '../../../../../src/plugins/data/common';

export const getOwnersFilter = (savedObjectType: string, owners: string[]): KueryNode => {
return nodeBuilder.or(
Expand Down
58 changes: 58 additions & 0 deletions x-pack/plugins/cases/server/client/alerts/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { CaseStatuses } from '../../../common/api';
import { AlertInfo } from '../../common';
import { CasesClientGetAlertsResponse } from './types';
import { get } from './get';
import { updateStatus } from './update_status';
import { CasesClientArgs } from '../types';

/**
* Defines the fields necessary to update an alert's status.
*/
export interface UpdateAlertRequest {
id: string;
index: string;
status: CaseStatuses;
}

export interface AlertUpdateStatus {
alerts: UpdateAlertRequest[];
}

export interface AlertGet {
alertsInfo: AlertInfo[];
}

export interface AlertSubClient {
get(args: AlertGet): Promise<CasesClientGetAlertsResponse>;
updateStatus(args: AlertUpdateStatus): Promise<void>;
}

export const createAlertsSubClient = (args: CasesClientArgs): AlertSubClient => {
const { alertsService, scopedClusterClient, logger } = args;

const alertsSubClient: AlertSubClient = {
get: (params: AlertGet) =>
get({
...params,
alertsService,
scopedClusterClient,
logger,
}),
updateStatus: (params: AlertUpdateStatus) =>
updateStatus({
...params,
alertsService,
scopedClusterClient,
logger,
}),
};

return Object.freeze(alertsSubClient);
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ describe('updateAlertsStatus', () => {
const savedObjectsClient = createMockSavedObjectsRepository();

const casesClient = await createCasesClientWithMockSavedObjectsClient({ savedObjectsClient });
await casesClient.client.updateAlertsStatus({
await casesClient.client.updateStatus({
cnasikas marked this conversation as resolved.
Show resolved Hide resolved
alerts: [{ id: 'alert-id-1', index: '.siem-signals', status: CaseStatuses.closed }],
});

Expand Down
4 changes: 2 additions & 2 deletions x-pack/plugins/cases/server/client/alerts/update_status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

import { ElasticsearchClient, Logger } from 'src/core/server';
import { AlertServiceContract } from '../../services';
import { UpdateAlertRequest } from '../types';
import { UpdateAlertRequest } from './client';

interface UpdateAlertsStatusArgs {
alertsService: AlertServiceContract;
Expand All @@ -16,7 +16,7 @@ interface UpdateAlertsStatusArgs {
logger: Logger;
}

export const updateAlertsStatus = async ({
export const updateStatus = async ({
alertsService,
alerts,
scopedClusterClient,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ import {
buildCommentUserActionItem,
} from '../../services/user_actions/helpers';

import { CaseServiceSetup, CaseUserActionServiceSetup } from '../../services';
import { AttachmentService, CaseService, CaseUserActionService } from '../../services';
import { CommentableCase, createAlertUpdateRequest } from '../../common';
import { CasesClientHandler } from '..';
import { CasesClientArgs, CasesClientInternal } from '..';
import { createCaseError } from '../../common/error';
import {
MAX_GENERATED_ALERTS_PER_SUB_CASE,
Expand All @@ -50,17 +50,17 @@ async function getSubCase({
userActionService,
user,
}: {
caseService: CaseServiceSetup;
caseService: CaseService;
savedObjectsClient: SavedObjectsClientContract;
caseId: string;
createdAt: string;
userActionService: CaseUserActionServiceSetup;
userActionService: CaseUserActionService;
user: User;
}): Promise<SavedObject<SubCaseAttributes>> {
const mostRecentSubCase = await caseService.getMostRecentSubCase(savedObjectsClient, caseId);
if (mostRecentSubCase && mostRecentSubCase.attributes.status !== CaseStatuses.closed) {
const subCaseAlertsAttachement = await caseService.getAllSubCaseComments({
client: savedObjectsClient,
soClient: savedObjectsClient,
id: mostRecentSubCase.id,
options: {
fields: [],
Expand All @@ -79,13 +79,13 @@ async function getSubCase({
}

const newSubCase = await caseService.createSubCase({
client: savedObjectsClient,
soClient: savedObjectsClient,
createdAt,
caseId,
createdBy: user,
});
await userActionService.postUserActions({
client: savedObjectsClient,
await userActionService.bulkCreate({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 thanks for the rename.

soClient: savedObjectsClient,
actions: [
buildCaseUserActionItem({
action: 'create',
Expand All @@ -102,20 +102,22 @@ async function getSubCase({
}

interface AddCommentFromRuleArgs {
casesClient: CasesClientHandler;
casesClientInternal: CasesClientInternal;
caseId: string;
comment: CommentRequestAlertType;
savedObjectsClient: SavedObjectsClientContract;
caseService: CaseServiceSetup;
userActionService: CaseUserActionServiceSetup;
attachmentService: AttachmentService;
caseService: CaseService;
userActionService: CaseUserActionService;
logger: Logger;
}

const addGeneratedAlerts = async ({
savedObjectsClient,
attachmentService,
caseService,
userActionService,
casesClient,
casesClientInternal,
caseId,
comment,
logger,
Expand All @@ -136,7 +138,7 @@ const addGeneratedAlerts = async ({
const createdDate = new Date().toISOString();

const caseInfo = await caseService.getCase({
client: savedObjectsClient,
soClient: savedObjectsClient,
id: caseId,
});

Expand Down Expand Up @@ -167,7 +169,8 @@ const addGeneratedAlerts = async ({
collection: caseInfo,
subCase,
soClient: savedObjectsClient,
service: caseService,
caseService,
attachmentService,
});

const {
Expand All @@ -184,13 +187,13 @@ const addGeneratedAlerts = async ({
comment: query,
status: subCase.attributes.status,
});
await casesClient.updateAlertsStatus({
await casesClientInternal.alerts.updateStatus({
cnasikas marked this conversation as resolved.
Show resolved Hide resolved
alerts: alertsToUpdate,
});
}

await userActionService.postUserActions({
client: savedObjectsClient,
await userActionService.bulkCreate({
soClient: savedObjectsClient,
actions: [
buildCommentUserActionItem({
action: 'create',
Expand All @@ -216,25 +219,27 @@ const addGeneratedAlerts = async ({
};

async function getCombinedCase({
service,
client,
caseService,
attachmentService,
soClient,
id,
logger,
}: {
service: CaseServiceSetup;
client: SavedObjectsClientContract;
caseService: CaseService;
attachmentService: AttachmentService;
soClient: SavedObjectsClientContract;
id: string;
logger: Logger;
}): Promise<CommentableCase> {
const [casePromise, subCasePromise] = await Promise.allSettled([
service.getCase({
client,
caseService.getCase({
soClient,
id,
}),
...(ENABLE_CASE_CONNECTOR
? [
service.getSubCase({
client,
caseService.getSubCase({
soClient,
id,
}),
]
Expand All @@ -243,16 +248,17 @@ async function getCombinedCase({

if (subCasePromise.status === 'fulfilled') {
if (subCasePromise.value.references.length > 0) {
const caseValue = await service.getCase({
client,
const caseValue = await caseService.getCase({
soClient,
id: subCasePromise.value.references[0].id,
});
return new CommentableCase({
logger,
collection: caseValue,
subCase: subCasePromise.value,
service,
soClient: client,
caseService,
attachmentService,
soClient,
});
} else {
throw Boom.badRequest('Sub case found without reference to collection');
Expand All @@ -265,38 +271,39 @@ async function getCombinedCase({
return new CommentableCase({
logger,
collection: casePromise.value,
service,
soClient: client,
caseService,
attachmentService,
soClient,
});
}
}

interface AddCommentArgs {
casesClient: CasesClientHandler;
caseId: string;
comment: CommentRequest;
savedObjectsClient: SavedObjectsClientContract;
caseService: CaseServiceSetup;
userActionService: CaseUserActionServiceSetup;
user: User;
logger: Logger;
casesClientInternal: CasesClientInternal;
}

export const addComment = async ({
savedObjectsClient,
caseService,
userActionService,
casesClient,
caseId,
comment,
user,
logger,
}: AddCommentArgs): Promise<CaseResponse> => {
casesClientInternal,
...rest
}: AddCommentArgs & CasesClientArgs): Promise<CaseResponse> => {
const query = pipe(
CommentRequestRt.decode(comment),
fold(throwErrors(Boom.badRequest), identity)
);

const {
savedObjectsClient,
caseService,
userActionService,
attachmentService,
user,
logger,
} = rest;

if (isCommentRequestTypeGenAlert(comment)) {
if (!ENABLE_CASE_CONNECTOR) {
throw Boom.badRequest(
Expand All @@ -307,10 +314,11 @@ export const addComment = async ({
return addGeneratedAlerts({
caseId,
comment,
casesClient,
casesClientInternal,
savedObjectsClient,
userActionService,
caseService,
attachmentService,
logger,
});
}
Expand All @@ -320,8 +328,9 @@ export const addComment = async ({
const createdDate = new Date().toISOString();

const combinedCase = await getCombinedCase({
service: caseService,
client: savedObjectsClient,
caseService,
attachmentService,
soClient: savedObjectsClient,
id: caseId,
logger,
});
Expand All @@ -346,13 +355,13 @@ export const addComment = async ({
status: updatedCase.status,
});

await casesClient.updateAlertsStatus({
await casesClientInternal.alerts.updateStatus({
alerts: alertsToUpdate,
});
}

await userActionService.postUserActions({
client: savedObjectsClient,
await userActionService.bulkCreate({
soClient: savedObjectsClient,
actions: [
buildCommentUserActionItem({
action: 'create',
Expand Down
Loading