[Security Solution] show case names in isolation success message (#102664)

This commit is contained in:
Kevin Logan 2021-06-22 14:01:24 -04:00 committed by GitHub
parent c5e8df02c1
commit bfbe6ab0b2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
41 changed files with 318 additions and 235 deletions

View file

@ -14,6 +14,28 @@ import { CasesStatusResponseRt, CaseStatusRt } from './status';
import { CaseConnectorRt, ESCaseConnector } from '../connectors';
import { SubCaseResponseRt } from './sub_case';
const BucketsAggs = rt.array(
rt.type({
key: rt.string,
})
);
export const GetCaseIdsByAlertIdAggsRt = rt.type({
references: rt.type({
doc_count: rt.number,
caseIds: rt.type({
buckets: BucketsAggs,
}),
}),
});
export const CasesByAlertIdRt = rt.array(
rt.type({
id: rt.string,
title: rt.string,
})
);
export enum CaseType {
collection = 'collection',
individual = 'individual',
@ -311,3 +333,6 @@ export type ESCasePatchRequest = Omit<CasePatchRequest, 'connector'> & {
export type AllTagsFindRequest = rt.TypeOf<typeof AllTagsFindRequestRt>;
export type AllReportersFindRequest = AllTagsFindRequest;
export type GetCaseIdsByAlertIdAggs = rt.TypeOf<typeof GetCaseIdsByAlertIdAggsRt>;
export type CasesByAlertId = rt.TypeOf<typeof CasesByAlertIdRt>;

View file

@ -10,21 +10,6 @@ import { SavedObjectFindOptionsRt } from '../saved_object';
import { UserRT } from '../user';
const BucketsAggs = rt.array(
rt.type({
key: rt.string,
})
);
export const GetCaseIdsByAlertIdAggsRt = rt.type({
references: rt.type({
doc_count: rt.number,
caseIds: rt.type({
buckets: BucketsAggs,
}),
}),
});
/**
* this is used to differentiate between an alert attached to a top-level case and a group of alerts that should only
* be attached to a sub case. The reason we need this is because an alert group comment will have references to both a case and
@ -152,4 +137,3 @@ export type CommentPatchRequest = rt.TypeOf<typeof CommentPatchRequestRt>;
export type CommentPatchAttributes = rt.TypeOf<typeof CommentPatchAttributesRt>;
export type CommentRequestUserType = rt.TypeOf<typeof ContextTypeUserRt>;
export type CommentRequestAlertType = rt.TypeOf<typeof AlertCommentRequestRt>;
export type GetCaseIdsByAlertIdAggs = rt.TypeOf<typeof GetCaseIdsByAlertIdAggsRt>;

View file

@ -45,7 +45,7 @@ Client wrapper that contains accessor methods for individual entities within the
**Returns:** [*CasesClient*](client.casesclient.md)
Defined in: [client.ts:28](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/client.ts#L28)
Defined in: [client.ts:28](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/client.ts#L28)
## Properties
@ -53,7 +53,7 @@ Defined in: [client.ts:28](https://github.com/jonathan-buttner/kibana/blob/0e98e
`Private` `Readonly` **\_attachments**: [*AttachmentsSubClient*](../interfaces/attachments_client.attachmentssubclient.md)
Defined in: [client.ts:24](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/client.ts#L24)
Defined in: [client.ts:24](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/client.ts#L24)
___
@ -61,7 +61,7 @@ ___
`Private` `Readonly` **\_cases**: [*CasesSubClient*](../interfaces/cases_client.casessubclient.md)
Defined in: [client.ts:23](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/client.ts#L23)
Defined in: [client.ts:23](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/client.ts#L23)
___
@ -69,7 +69,7 @@ ___
`Private` `Readonly` **\_casesClientInternal**: *CasesClientInternal*
Defined in: [client.ts:22](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/client.ts#L22)
Defined in: [client.ts:22](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/client.ts#L22)
___
@ -77,7 +77,7 @@ ___
`Private` `Readonly` **\_configure**: [*ConfigureSubClient*](../interfaces/configure_client.configuresubclient.md)
Defined in: [client.ts:27](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/client.ts#L27)
Defined in: [client.ts:27](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/client.ts#L27)
___
@ -85,7 +85,7 @@ ___
`Private` `Readonly` **\_stats**: [*StatsSubClient*](../interfaces/stats_client.statssubclient.md)
Defined in: [client.ts:28](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/client.ts#L28)
Defined in: [client.ts:28](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/client.ts#L28)
___
@ -93,7 +93,7 @@ ___
`Private` `Readonly` **\_subCases**: [*SubCasesClient*](../interfaces/sub_cases_client.subcasesclient.md)
Defined in: [client.ts:26](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/client.ts#L26)
Defined in: [client.ts:26](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/client.ts#L26)
___
@ -101,7 +101,7 @@ ___
`Private` `Readonly` **\_userActions**: [*UserActionsSubClient*](../interfaces/user_actions_client.useractionssubclient.md)
Defined in: [client.ts:25](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/client.ts#L25)
Defined in: [client.ts:25](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/client.ts#L25)
## Accessors
@ -113,7 +113,7 @@ Retrieves an interface for interacting with attachments (comments) entities.
**Returns:** [*AttachmentsSubClient*](../interfaces/attachments_client.attachmentssubclient.md)
Defined in: [client.ts:50](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/client.ts#L50)
Defined in: [client.ts:50](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/client.ts#L50)
___
@ -125,7 +125,7 @@ Retrieves an interface for interacting with cases entities.
**Returns:** [*CasesSubClient*](../interfaces/cases_client.casessubclient.md)
Defined in: [client.ts:43](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/client.ts#L43)
Defined in: [client.ts:43](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/client.ts#L43)
___
@ -137,7 +137,7 @@ Retrieves an interface for interacting with the configuration of external connec
**Returns:** [*ConfigureSubClient*](../interfaces/configure_client.configuresubclient.md)
Defined in: [client.ts:76](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/client.ts#L76)
Defined in: [client.ts:76](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/client.ts#L76)
___
@ -149,7 +149,7 @@ Retrieves an interface for retrieving statistics related to the cases entities.
**Returns:** [*StatsSubClient*](../interfaces/stats_client.statssubclient.md)
Defined in: [client.ts:83](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/client.ts#L83)
Defined in: [client.ts:83](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/client.ts#L83)
___
@ -163,7 +163,7 @@ Currently this functionality is disabled and will throw an error if this functio
**Returns:** [*SubCasesClient*](../interfaces/sub_cases_client.subcasesclient.md)
Defined in: [client.ts:66](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/client.ts#L66)
Defined in: [client.ts:66](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/client.ts#L66)
___
@ -175,4 +175,4 @@ Retrieves an interface for interacting with the user actions associated with the
**Returns:** [*UserActionsSubClient*](../interfaces/user_actions_client.useractionssubclient.md)
Defined in: [client.ts:57](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/client.ts#L57)
Defined in: [client.ts:57](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/client.ts#L57)

View file

@ -21,7 +21,7 @@ The arguments needed for creating a new attachment to a case.
The case ID that this attachment will be associated with
Defined in: [attachments/add.ts:305](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/attachments/add.ts#L305)
Defined in: [attachments/add.ts:305](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/attachments/add.ts#L305)
___
@ -31,4 +31,4 @@ ___
The attachment values.
Defined in: [attachments/add.ts:309](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/attachments/add.ts#L309)
Defined in: [attachments/add.ts:309](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/attachments/add.ts#L309)

View file

@ -35,7 +35,7 @@ Adds an attachment to a case.
**Returns:** *Promise*<[*ICaseResponse*](typedoc_interfaces.icaseresponse.md)\>
Defined in: [attachments/client.ts:35](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/attachments/client.ts#L35)
Defined in: [attachments/client.ts:35](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/attachments/client.ts#L35)
___
@ -53,7 +53,7 @@ Deletes a single attachment for a specific case.
**Returns:** *Promise*<void\>
Defined in: [attachments/client.ts:43](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/attachments/client.ts#L43)
Defined in: [attachments/client.ts:43](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/attachments/client.ts#L43)
___
@ -71,7 +71,7 @@ Deletes all attachments associated with a single case.
**Returns:** *Promise*<void\>
Defined in: [attachments/client.ts:39](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/attachments/client.ts#L39)
Defined in: [attachments/client.ts:39](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/attachments/client.ts#L39)
___
@ -89,7 +89,7 @@ Retrieves all comments matching the search criteria.
**Returns:** *Promise*<[*ICommentsResponse*](typedoc_interfaces.icommentsresponse.md)\>
Defined in: [attachments/client.ts:47](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/attachments/client.ts#L47)
Defined in: [attachments/client.ts:47](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/attachments/client.ts#L47)
___
@ -107,7 +107,7 @@ Retrieves a single attachment for a case.
**Returns:** *Promise*<{ `comment`: *string* ; `owner`: *string* ; `type`: user } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* } & { `alertId`: *string* \| *string*[] ; `index`: *string* \| *string*[] ; `owner`: *string* ; `rule`: { id: string \| null; name: string \| null; } ; `type`: alert \| generatedAlert } & { `associationType`: AssociationType ; `created_at`: *string* ; `created_by`: { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `owner`: *string* ; `pushed_at`: ``null`` \| *string* ; `pushed_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } ; `updated_at`: ``null`` \| *string* ; `updated_by`: ``null`` \| { email: string \| null \| undefined; full\_name: string \| null \| undefined; username: string \| null \| undefined; } } & { `id`: *string* ; `version`: *string* }\>
Defined in: [attachments/client.ts:59](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/attachments/client.ts#L59)
Defined in: [attachments/client.ts:59](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/attachments/client.ts#L59)
___
@ -125,7 +125,7 @@ Gets all attachments for a single case.
**Returns:** *Promise*<[*IAllCommentsResponse*](typedoc_interfaces.iallcommentsresponse.md)\>
Defined in: [attachments/client.ts:55](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/attachments/client.ts#L55)
Defined in: [attachments/client.ts:55](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/attachments/client.ts#L55)
___
@ -143,7 +143,7 @@ Retrieves all alerts attach to a case given a single case ID
**Returns:** *Promise*<{ `attached_at`: *string* ; `id`: *string* ; `index`: *string* }[]\>
Defined in: [attachments/client.ts:51](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/attachments/client.ts#L51)
Defined in: [attachments/client.ts:51](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/attachments/client.ts#L51)
___
@ -163,4 +163,4 @@ The request must include all fields for the attachment. Even the fields that are
**Returns:** *Promise*<[*ICaseResponse*](typedoc_interfaces.icaseresponse.md)\>
Defined in: [attachments/client.ts:65](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/attachments/client.ts#L65)
Defined in: [attachments/client.ts:65](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/attachments/client.ts#L65)

View file

@ -21,7 +21,7 @@ Parameters for deleting all comments of a case or sub case.
The case ID to delete all attachments for
Defined in: [attachments/delete.ts:31](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/attachments/delete.ts#L31)
Defined in: [attachments/delete.ts:31](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/attachments/delete.ts#L31)
___
@ -31,4 +31,4 @@ ___
If specified the caseID will be ignored and this value will be used to find a sub case for deleting all the attachments
Defined in: [attachments/delete.ts:35](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/attachments/delete.ts#L35)
Defined in: [attachments/delete.ts:35](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/attachments/delete.ts#L35)

View file

@ -22,7 +22,7 @@ Parameters for deleting a single attachment of a case or sub case.
The attachment ID to delete
Defined in: [attachments/delete.ts:49](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/attachments/delete.ts#L49)
Defined in: [attachments/delete.ts:49](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/attachments/delete.ts#L49)
___
@ -32,7 +32,7 @@ ___
The case ID to delete an attachment from
Defined in: [attachments/delete.ts:45](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/attachments/delete.ts#L45)
Defined in: [attachments/delete.ts:45](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/attachments/delete.ts#L45)
___
@ -42,4 +42,4 @@ ___
If specified the caseID will be ignored and this value will be used to find a sub case for deleting the attachment
Defined in: [attachments/delete.ts:53](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/attachments/delete.ts#L53)
Defined in: [attachments/delete.ts:53](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/attachments/delete.ts#L53)

View file

@ -21,7 +21,7 @@ Parameters for finding attachments of a case
The case ID for finding associated attachments
Defined in: [attachments/get.ts:47](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/attachments/get.ts#L47)
Defined in: [attachments/get.ts:47](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/attachments/get.ts#L47)
___
@ -48,4 +48,4 @@ Optional parameters for filtering the returned attachments
| `sortOrder` | *undefined* \| ``"desc"`` \| ``"asc"`` |
| `subCaseId` | *undefined* \| *string* |
Defined in: [attachments/get.ts:51](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/attachments/get.ts#L51)
Defined in: [attachments/get.ts:51](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/attachments/get.ts#L51)

View file

@ -18,4 +18,4 @@
The ID of the case to retrieve the alerts from
Defined in: [attachments/get.ts:87](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/attachments/get.ts#L87)
Defined in: [attachments/get.ts:87](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/attachments/get.ts#L87)

View file

@ -22,7 +22,7 @@ Parameters for retrieving all attachments of a case
The case ID to retrieve all attachments for
Defined in: [attachments/get.ts:61](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/attachments/get.ts#L61)
Defined in: [attachments/get.ts:61](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/attachments/get.ts#L61)
___
@ -32,7 +32,7 @@ ___
Optionally include the attachments associated with a sub case
Defined in: [attachments/get.ts:65](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/attachments/get.ts#L65)
Defined in: [attachments/get.ts:65](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/attachments/get.ts#L65)
___
@ -42,4 +42,4 @@ ___
If included the case ID will be ignored and the attachments will be retrieved from the specified ID of the sub case
Defined in: [attachments/get.ts:69](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/attachments/get.ts#L69)
Defined in: [attachments/get.ts:69](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/attachments/get.ts#L69)

View file

@ -19,7 +19,7 @@
The ID of the attachment to retrieve
Defined in: [attachments/get.ts:80](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/attachments/get.ts#L80)
Defined in: [attachments/get.ts:80](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/attachments/get.ts#L80)
___
@ -29,4 +29,4 @@ ___
The ID of the case to retrieve an attachment from
Defined in: [attachments/get.ts:76](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/attachments/get.ts#L76)
Defined in: [attachments/get.ts:76](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/attachments/get.ts#L76)

View file

@ -22,7 +22,7 @@ Parameters for updating a single attachment
The ID of the case that is associated with this attachment
Defined in: [attachments/update.ts:32](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/attachments/update.ts#L32)
Defined in: [attachments/update.ts:32](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/attachments/update.ts#L32)
___
@ -32,7 +32,7 @@ ___
The ID of a sub case, if specified a sub case will be searched for to perform the attachment update instead of on a case
Defined in: [attachments/update.ts:40](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/attachments/update.ts#L40)
Defined in: [attachments/update.ts:40](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/attachments/update.ts#L40)
___
@ -42,4 +42,4 @@ ___
The full attachment request with the fields updated with appropriate values
Defined in: [attachments/update.ts:36](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/attachments/update.ts#L36)
Defined in: [attachments/update.ts:36](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/attachments/update.ts#L36)

View file

@ -14,7 +14,7 @@ API for interacting with the cases entities.
- [delete](cases_client.casessubclient.md#delete)
- [find](cases_client.casessubclient.md#find)
- [get](cases_client.casessubclient.md#get)
- [getCaseIDsByAlertID](cases_client.casessubclient.md#getcaseidsbyalertid)
- [getCasesByAlertID](cases_client.casessubclient.md#getcasesbyalertid)
- [getReporters](cases_client.casessubclient.md#getreporters)
- [getTags](cases_client.casessubclient.md#gettags)
- [push](cases_client.casessubclient.md#push)
@ -36,7 +36,7 @@ Creates a case.
**Returns:** *Promise*<[*ICaseResponse*](typedoc_interfaces.icaseresponse.md)\>
Defined in: [cases/client.ts:48](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/cases/client.ts#L48)
Defined in: [cases/client.ts:49](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/cases/client.ts#L49)
___
@ -56,7 +56,7 @@ Delete a case and all its comments.
**Returns:** *Promise*<void\>
Defined in: [cases/client.ts:72](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/cases/client.ts#L72)
Defined in: [cases/client.ts:73](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/cases/client.ts#L73)
___
@ -76,7 +76,7 @@ If the `owner` field is left empty then all the cases that the user has access t
**Returns:** *Promise*<[*ICasesFindResponse*](typedoc_interfaces.icasesfindresponse.md)\>
Defined in: [cases/client.ts:54](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/cases/client.ts#L54)
Defined in: [cases/client.ts:55](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/cases/client.ts#L55)
___
@ -94,25 +94,25 @@ Retrieves a single case with the specified ID.
**Returns:** *Promise*<[*ICaseResponse*](typedoc_interfaces.icaseresponse.md)\>
Defined in: [cases/client.ts:58](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/cases/client.ts#L58)
Defined in: [cases/client.ts:59](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/cases/client.ts#L59)
___
### getCaseIDsByAlertID
### getCasesByAlertID
**getCaseIDsByAlertID**(`params`: [*CaseIDsByAlertIDParams*](cases_get.caseidsbyalertidparams.md)): *Promise*<string[]\>
**getCasesByAlertID**(`params`: [*CasesByAlertIDParams*](cases_get.casesbyalertidparams.md)): *Promise*<{ `id`: *string* ; `title`: *string* }[]\>
Retrieves the case IDs given a single alert ID
Retrieves the cases ID and title that have the requested alert attached to them
#### Parameters
| Name | Type |
| :------ | :------ |
| `params` | [*CaseIDsByAlertIDParams*](cases_get.caseidsbyalertidparams.md) |
| `params` | [*CasesByAlertIDParams*](cases_get.casesbyalertidparams.md) |
**Returns:** *Promise*<string[]\>
**Returns:** *Promise*<{ `id`: *string* ; `title`: *string* }[]\>
Defined in: [cases/client.ts:84](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/cases/client.ts#L84)
Defined in: [cases/client.ts:85](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/cases/client.ts#L85)
___
@ -131,7 +131,7 @@ Retrieves all the reporters across all accessible cases.
**Returns:** *Promise*<{ `email`: *undefined* \| ``null`` \| *string* ; `full_name`: *undefined* \| ``null`` \| *string* ; `username`: *undefined* \| ``null`` \| *string* }[]\>
Defined in: [cases/client.ts:80](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/cases/client.ts#L80)
Defined in: [cases/client.ts:81](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/cases/client.ts#L81)
___
@ -150,7 +150,7 @@ Retrieves all the tags across all cases the user making the request has access t
**Returns:** *Promise*<string[]\>
Defined in: [cases/client.ts:76](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/cases/client.ts#L76)
Defined in: [cases/client.ts:77](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/cases/client.ts#L77)
___
@ -168,7 +168,7 @@ Pushes a specific case to an external system.
**Returns:** *Promise*<[*ICaseResponse*](typedoc_interfaces.icaseresponse.md)\>
Defined in: [cases/client.ts:62](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/cases/client.ts#L62)
Defined in: [cases/client.ts:63](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/cases/client.ts#L63)
___
@ -186,4 +186,4 @@ Update the specified cases with the passed in values.
**Returns:** *Promise*<[*ICasesResponse*](typedoc_interfaces.icasesresponse.md)\>
Defined in: [cases/client.ts:66](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/cases/client.ts#L66)
Defined in: [cases/client.ts:67](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/cases/client.ts#L67)

View file

@ -1,40 +0,0 @@
[Cases Client API Interface](../cases_client_api.md) / [cases/get](../modules/cases_get.md) / CaseIDsByAlertIDParams
# Interface: CaseIDsByAlertIDParams
[cases/get](../modules/cases_get.md).CaseIDsByAlertIDParams
Parameters for finding cases IDs using an alert ID
## Table of contents
### Properties
- [alertID](cases_get.caseidsbyalertidparams.md#alertid)
- [options](cases_get.caseidsbyalertidparams.md#options)
## Properties
### alertID
**alertID**: *string*
The alert ID to search for
Defined in: [cases/get.ts:42](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/cases/get.ts#L42)
___
### options
**options**: *object*
The filtering options when searching for associated cases.
#### Type declaration
| Name | Type |
| :------ | :------ |
| `owner` | *undefined* \| *string* \| *string*[] |
Defined in: [cases/get.ts:46](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/cases/get.ts#L46)

View file

@ -0,0 +1,40 @@
[Cases Client API Interface](../cases_client_api.md) / [cases/get](../modules/cases_get.md) / CasesByAlertIDParams
# Interface: CasesByAlertIDParams
[cases/get](../modules/cases_get.md).CasesByAlertIDParams
Parameters for finding cases IDs using an alert ID
## Table of contents
### Properties
- [alertID](cases_get.casesbyalertidparams.md#alertid)
- [options](cases_get.casesbyalertidparams.md#options)
## Properties
### alertID
**alertID**: *string*
The alert ID to search for
Defined in: [cases/get.ts:44](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/cases/get.ts#L44)
___
### options
**options**: *object*
The filtering options when searching for associated cases.
#### Type declaration
| Name | Type |
| :------ | :------ |
| `owner` | *undefined* \| *string* \| *string*[] |
Defined in: [cases/get.ts:48](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/cases/get.ts#L48)

View file

@ -22,7 +22,7 @@ The parameters for retrieving a case
Case ID
Defined in: [cases/get.ts:110](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/cases/get.ts#L110)
Defined in: [cases/get.ts:145](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/cases/get.ts#L145)
___
@ -32,7 +32,7 @@ ___
Whether to include the attachments for a case in the response
Defined in: [cases/get.ts:114](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/cases/get.ts#L114)
Defined in: [cases/get.ts:149](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/cases/get.ts#L149)
___
@ -42,4 +42,4 @@ ___
Whether to include the attachments for all children of a case in the response
Defined in: [cases/get.ts:118](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/cases/get.ts#L118)
Defined in: [cases/get.ts:153](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/cases/get.ts#L153)

View file

@ -21,7 +21,7 @@ Parameters for pushing a case to an external system
The ID of a case
Defined in: [cases/push.ts:53](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/cases/push.ts#L53)
Defined in: [cases/push.ts:53](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/cases/push.ts#L53)
___
@ -31,4 +31,4 @@ ___
The ID of an external system to push to
Defined in: [cases/push.ts:57](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/cases/push.ts#L57)
Defined in: [cases/push.ts:57](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/cases/push.ts#L57)

View file

@ -31,7 +31,7 @@ Creates a configuration if one does not already exist. If one exists it is delet
**Returns:** *Promise*<[*ICasesConfigureResponse*](typedoc_interfaces.icasesconfigureresponse.md)\>
Defined in: [configure/client.ts:98](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/configure/client.ts#L98)
Defined in: [configure/client.ts:98](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/configure/client.ts#L98)
___
@ -50,7 +50,7 @@ Retrieves the external connector configuration for a particular case owner.
**Returns:** *Promise*<{} \| [*ICasesConfigureResponse*](typedoc_interfaces.icasesconfigureresponse.md)\>
Defined in: [configure/client.ts:80](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/configure/client.ts#L80)
Defined in: [configure/client.ts:80](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/configure/client.ts#L80)
___
@ -62,7 +62,7 @@ Retrieves the valid external connectors supported by the cases plugin.
**Returns:** *Promise*<FindActionResult[]\>
Defined in: [configure/client.ts:84](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/configure/client.ts#L84)
Defined in: [configure/client.ts:84](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/configure/client.ts#L84)
___
@ -81,4 +81,4 @@ Updates a particular configuration with new values.
**Returns:** *Promise*<[*ICasesConfigureResponse*](typedoc_interfaces.icasesconfigureresponse.md)\>
Defined in: [configure/client.ts:91](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/configure/client.ts#L91)
Defined in: [configure/client.ts:91](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/configure/client.ts#L91)

View file

@ -29,4 +29,4 @@ Retrieves the total number of open, closed, and in-progress cases.
**Returns:** *Promise*<{ `count_closed_cases`: *number* ; `count_in_progress_cases`: *number* ; `count_open_cases`: *number* }\>
Defined in: [stats/client.ts:34](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/stats/client.ts#L34)
Defined in: [stats/client.ts:34](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/stats/client.ts#L34)

View file

@ -31,7 +31,7 @@ Deletes the specified entities and their attachments.
**Returns:** *Promise*<void\>
Defined in: [sub_cases/client.ts:68](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/sub_cases/client.ts#L68)
Defined in: [sub_cases/client.ts:68](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/sub_cases/client.ts#L68)
___
@ -49,7 +49,7 @@ Retrieves the sub cases matching the search criteria.
**Returns:** *Promise*<[*ISubCasesFindResponse*](typedoc_interfaces.isubcasesfindresponse.md)\>
Defined in: [sub_cases/client.ts:72](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/sub_cases/client.ts#L72)
Defined in: [sub_cases/client.ts:72](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/sub_cases/client.ts#L72)
___
@ -67,7 +67,7 @@ Retrieves a single sub case.
**Returns:** *Promise*<[*ISubCaseResponse*](typedoc_interfaces.isubcaseresponse.md)\>
Defined in: [sub_cases/client.ts:76](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/sub_cases/client.ts#L76)
Defined in: [sub_cases/client.ts:76](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/sub_cases/client.ts#L76)
___
@ -86,4 +86,4 @@ Updates the specified sub cases to the new values included in the request.
**Returns:** *Promise*<[*ISubCasesResponse*](typedoc_interfaces.isubcasesresponse.md)\>
Defined in: [sub_cases/client.ts:80](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/sub_cases/client.ts#L80)
Defined in: [sub_cases/client.ts:80](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/sub_cases/client.ts#L80)

View file

@ -21,7 +21,7 @@ Parameters for retrieving user actions for a particular case
The ID of the case
Defined in: [user_actions/client.ts:19](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/user_actions/client.ts#L19)
Defined in: [user_actions/client.ts:19](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/user_actions/client.ts#L19)
___
@ -31,4 +31,4 @@ ___
If specified then a sub case will be used for finding all the user actions
Defined in: [user_actions/client.ts:23](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/user_actions/client.ts#L23)
Defined in: [user_actions/client.ts:23](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/user_actions/client.ts#L23)

View file

@ -28,4 +28,4 @@ Retrieves all user actions for a particular case.
**Returns:** *Promise*<[*ICaseUserActionsResponse*](typedoc_interfaces.icaseuseractionsresponse.md)\>
Defined in: [user_actions/client.ts:33](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/user_actions/client.ts#L33)
Defined in: [user_actions/client.ts:33](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/user_actions/client.ts#L33)

View file

@ -6,7 +6,7 @@
### Interfaces
- [CaseIDsByAlertIDParams](../interfaces/cases_get.caseidsbyalertidparams.md)
- [CasesByAlertIDParams](../interfaces/cases_get.casesbyalertidparams.md)
- [GetParams](../interfaces/cases_get.getparams.md)
### Functions
@ -31,7 +31,7 @@ Retrieves the reporters from all the cases.
**Returns:** *Promise*<User[]\>
Defined in: [cases/get.ts:255](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/cases/get.ts#L255)
Defined in: [cases/get.ts:290](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/cases/get.ts#L290)
___
@ -50,4 +50,4 @@ Retrieves the tags from all the cases.
**Returns:** *Promise*<string[]\>
Defined in: [cases/get.ts:205](https://github.com/jonathan-buttner/kibana/blob/0e98e105663/x-pack/plugins/cases/server/client/cases/get.ts#L205)
Defined in: [cases/get.ts:240](https://github.com/jonathan-buttner/kibana/blob/b65ed845242/x-pack/plugins/cases/server/client/cases/get.ts#L240)

View file

@ -12,6 +12,7 @@ import {
User,
AllTagsFindRequest,
AllReportersFindRequest,
CasesByAlertId,
} from '../../../common';
import { CasesClient } from '../client';
import { CasesClientInternal } from '../client_internal';
@ -28,9 +29,9 @@ import { create } from './create';
import { deleteCases } from './delete';
import { find } from './find';
import {
CaseIDsByAlertIDParams,
CasesByAlertIDParams,
get,
getCaseIDsByAlertID,
getCasesByAlertID,
GetParams,
getReporters,
getTags,
@ -79,9 +80,9 @@ export interface CasesSubClient {
*/
getReporters(params: AllReportersFindRequest): Promise<User[]>;
/**
* Retrieves the case IDs given a single alert ID
* Retrieves the cases ID and title that have the requested alert attached to them
*/
getCaseIDsByAlertID(params: CaseIDsByAlertIDParams): Promise<string[]>;
getCasesByAlertID(params: CasesByAlertIDParams): Promise<CasesByAlertId>;
}
/**
@ -103,8 +104,7 @@ export const createCasesSubClient = (
delete: (ids: string[]) => deleteCases(ids, clientArgs),
getTags: (params: AllTagsFindRequest) => getTags(params, clientArgs),
getReporters: (params: AllReportersFindRequest) => getReporters(params, clientArgs),
getCaseIDsByAlertID: (params: CaseIDsByAlertIDParams) =>
getCaseIDsByAlertID(params, clientArgs),
getCasesByAlertID: (params: CasesByAlertIDParams) => getCasesByAlertID(params, clientArgs),
};
return Object.freeze(casesSubClient);

View file

@ -25,6 +25,8 @@ import {
CasesByAlertIDRequest,
CasesByAlertIDRequestRt,
ENABLE_CASE_CONNECTOR,
CasesByAlertId,
CasesByAlertIdRt,
} from '../../../common';
import { countAlertsForID, createCaseError, flattenCaseSavedObject } from '../../common';
import { CasesClientArgs } from '..';
@ -35,7 +37,7 @@ import { CasesService } from '../../services';
/**
* Parameters for finding cases IDs using an alert ID
*/
export interface CaseIDsByAlertIDParams {
export interface CasesByAlertIDParams {
/**
* The alert ID to search for
*/
@ -47,15 +49,15 @@ export interface CaseIDsByAlertIDParams {
}
/**
* Case Client wrapper function for retrieving the case IDs that have a particular alert ID
* Case Client wrapper function for retrieving the case IDs and titles that have a particular alert ID
* attached to them. This handles RBAC before calling the saved object API.
*
* @ignore
*/
export const getCaseIDsByAlertID = async (
{ alertID, options }: CaseIDsByAlertIDParams,
export const getCasesByAlertID = async (
{ alertID, options }: CasesByAlertIDParams,
clientArgs: CasesClientArgs
): Promise<string[]> => {
): Promise<CasesByAlertId> => {
const { unsecuredSavedObjectsClient, caseService, logger, authorization } = clientArgs;
try {
@ -75,12 +77,15 @@ export const getCaseIDsByAlertID = async (
Operations.getCaseIDsByAlertID.savedObjectType
);
// This will likely only return one comment saved object, the response aggregation will contain
// the keys we need to retrieve the cases
const commentsWithAlert = await caseService.getCaseIdsByAlertId({
unsecuredSavedObjectsClient,
alertId: alertID,
filter,
});
// make sure the comments returned have the right owner
ensureSavedObjectsAreAuthorized(
commentsWithAlert.saved_objects.map((comment) => ({
owner: comment.attributes.owner,
@ -88,7 +93,37 @@ export const getCaseIDsByAlertID = async (
}))
);
return CasesService.getCaseIDsFromAlertAggs(commentsWithAlert);
const caseIds = CasesService.getCaseIDsFromAlertAggs(commentsWithAlert);
// if we didn't find any case IDs then let's return early because there's nothing to request
if (caseIds.length <= 0) {
return [];
}
const casesInfo = await caseService.getCases({
unsecuredSavedObjectsClient,
caseIds,
});
// if there was an error retrieving one of the cases (maybe it was deleted, but the alert comment still existed)
// just ignore it
const validCasesInfo = casesInfo.saved_objects.filter(
(caseInfo) => caseInfo.error === undefined
);
ensureSavedObjectsAreAuthorized(
validCasesInfo.map((caseInfo) => ({
owner: caseInfo.attributes.owner,
id: caseInfo.id,
}))
);
return CasesByAlertIdRt.encode(
validCasesInfo.map((caseInfo) => ({
id: caseInfo.id,
title: caseInfo.attributes.title,
}))
);
} catch (error) {
throw createCaseError({
message: `Failed to get case IDs using alert ID: ${alertID} options: ${JSON.stringify(

View file

@ -28,7 +28,7 @@ const createCasesSubClientMock = (): CasesSubClientMock => {
delete: jest.fn(),
getTags: jest.fn(),
getReporters: jest.fn(),
getCaseIDsByAlertID: jest.fn(),
getCasesByAlertID: jest.fn(),
};
};

View file

@ -12,7 +12,7 @@ import { RouteDeps } from '../../types';
import { escapeHatch, wrapError } from '../../utils';
import { CASE_ALERTS_URL, CasesByAlertIDRequest } from '../../../../../common';
export function initGetCaseIdsByAlertIdApi({ router, logger }: RouteDeps) {
export function initGetCasesByAlertIdApi({ router, logger }: RouteDeps) {
router.get(
{
path: CASE_ALERTS_URL,
@ -33,7 +33,7 @@ export function initGetCaseIdsByAlertIdApi({ router, logger }: RouteDeps) {
const options = request.query as CasesByAlertIDRequest;
return response.ok({
body: await casesClient.cases.getCaseIDsByAlertID({ alertID, options }),
body: await casesClient.cases.getCasesByAlertID({ alertID, options }),
});
} catch (error) {
logger.error(

View file

@ -38,7 +38,7 @@ import { initPatchSubCasesApi } from './sub_case/patch_sub_cases';
import { initFindSubCasesApi } from './sub_case/find_sub_cases';
import { initDeleteSubCasesApi } from './sub_case/delete_sub_cases';
import { ENABLE_CASE_CONNECTOR } from '../../../common';
import { initGetCaseIdsByAlertIdApi } from './cases/alerts/get_cases';
import { initGetCasesByAlertIdApi } from './cases/alerts/get_cases';
import { initGetAllAlertsAttachToCaseApi } from './comments/get_alerts';
/**
@ -89,6 +89,6 @@ export function initCaseApi(deps: RouteDeps) {
// Tags
initGetTagsApi(deps);
// Alerts
initGetCaseIdsByAlertIdApi(deps);
initGetCasesByAlertIdApi(deps);
initGetAllAlertsAttachToCaseApi(deps);
}

View file

@ -41,27 +41,27 @@ export const HostIsolationPanel = React.memo(
return findAlertId ? findAlertId[0] : '';
}, [details]);
const { caseIds } = useCasesFromAlerts({ alertId });
const { casesInfo } = useCasesFromAlerts({ alertId });
// Cases related components to be used in both isolate and unisolate actions from the alert details flyout entry point
const caseCount: number = useMemo(() => caseIds.length, [caseIds]);
const caseCount: number = useMemo(() => casesInfo.length, [casesInfo]);
const casesList = useMemo(
() =>
caseIds.map((id, index) => {
casesInfo.map((caseInfo, index) => {
return (
<li key={id}>
<CaseDetailsLink detailName={id}>
<li key={caseInfo.id}>
<CaseDetailsLink detailName={caseInfo.id}>
<FormattedMessage
id="xpack.securitySolution.endpoint.hostIsolation.placeholderCase"
defaultMessage="Case {caseIndex}"
values={{ caseIndex: index + 1 }}
defaultMessage="{caseName}"
values={{ caseName: caseInfo.title }}
/>
</CaseDetailsLink>
</li>
);
}),
[caseIds]
[casesInfo]
);
const associatedCases = useMemo(() => {
@ -90,7 +90,7 @@ export const HostIsolationPanel = React.memo(
endpointId={endpointId}
hostName={hostName}
cases={associatedCases}
caseIds={caseIds}
casesInfo={casesInfo}
cancelCallback={cancelCallback}
/>
) : (
@ -98,7 +98,7 @@ export const HostIsolationPanel = React.memo(
endpointId={endpointId}
hostName={hostName}
cases={associatedCases}
caseIds={caseIds}
casesInfo={casesInfo}
cancelCallback={cancelCallback}
/>
);

View file

@ -15,24 +15,29 @@ import {
EndpointIsolateForm,
EndpointIsolateSuccess,
} from '../../../common/components/endpoint/host_isolation';
import { CasesFromAlertsResponse } from '../../containers/detection_engine/alerts/types';
export const IsolateHost = React.memo(
({
endpointId,
hostName,
cases,
caseIds,
casesInfo,
cancelCallback,
}: {
endpointId: string;
hostName: string;
cases: ReactNode;
caseIds: string[];
casesInfo: CasesFromAlertsResponse;
cancelCallback: () => void;
}) => {
const [comment, setComment] = useState('');
const [isIsolated, setIsIsolated] = useState(false);
const caseIds: string[] = casesInfo.map((caseInfo): string => {
return caseInfo.id;
});
const { loading, isolateHost } = useHostIsolation({ endpointId, comment, caseIds });
const confirmHostIsolation = useCallback(async () => {
@ -47,7 +52,7 @@ export const IsolateHost = React.memo(
[]
);
const caseCount: number = useMemo(() => caseIds.length, [caseIds]);
const caseCount: number = useMemo(() => casesInfo.length, [casesInfo]);
const hostIsolatedSuccess = useMemo(() => {
return (

View file

@ -15,24 +15,29 @@ import {
EndpointUnisolateForm,
} from '../../../common/components/endpoint/host_isolation';
import { useHostUnisolation } from '../../containers/detection_engine/alerts/use_host_unisolation';
import { CasesFromAlertsResponse } from '../../containers/detection_engine/alerts/types';
export const UnisolateHost = React.memo(
({
endpointId,
hostName,
cases,
caseIds,
casesInfo,
cancelCallback,
}: {
endpointId: string;
hostName: string;
cases: ReactNode;
caseIds: string[];
casesInfo: CasesFromAlertsResponse;
cancelCallback: () => void;
}) => {
const [comment, setComment] = useState('');
const [isUnIsolated, setIsUnIsolated] = useState(false);
const caseIds: string[] = casesInfo.map((caseInfo): string => {
return caseInfo.id;
});
const { loading, unIsolateHost } = useHostUnisolation({ endpointId, comment, caseIds });
const confirmHostUnIsolation = useCallback(async () => {
@ -47,7 +52,7 @@ export const UnisolateHost = React.memo(
[]
);
const caseCount: number = useMemo(() => caseIds.length, [caseIds]);
const caseCount: number = useMemo(() => casesInfo.length, [casesInfo]);
const hostUnisolatedSuccess = useMemo(() => {
return (

View file

@ -1046,6 +1046,6 @@ export const mockHostIsolation: HostIsolationResponse = {
};
export const mockCaseIdsFromAlertId: CasesFromAlertsResponse = [
'818601a0-b26b-11eb-8759-6b318e8cf4bc',
'8a774850-b26b-11eb-8759-6b318e8cf4bc',
{ id: '818601a0-b26b-11eb-8759-6b318e8cf4bc', title: 'Case 1' },
{ id: '8a774850-b26b-11eb-8759-6b318e8cf4bc', title: 'Case 2' },
];

View file

@ -48,7 +48,7 @@ export interface AlertsIndex {
index_mapping_outdated: boolean;
}
export type CasesFromAlertsResponse = string[];
export type CasesFromAlertsResponse = Array<{ id: string; title: string }>;
export interface Privilege {
username: string;

View file

@ -35,7 +35,7 @@ describe('useCasesFromAlerts hook', () => {
expect(spyOnCases).toHaveBeenCalledTimes(1);
expect(result.current).toEqual({
loading: false,
caseIds: mockCaseIdsFromAlertId,
casesInfo: mockCaseIdsFromAlertId,
});
});
});

View file

@ -15,7 +15,7 @@ import { CasesFromAlertsResponse } from './types';
interface CasesFromAlertsStatus {
loading: boolean;
caseIds: CasesFromAlertsResponse;
casesInfo: CasesFromAlertsResponse;
}
export const useCasesFromAlerts = ({ alertId }: { alertId: string }): CasesFromAlertsStatus => {
@ -48,5 +48,5 @@ export const useCasesFromAlerts = ({ alertId }: { alertId: string }): CasesFromA
isMounted = false;
};
}, [alertId, addError]);
return { loading, caseIds: cases };
return { loading, casesInfo: cases };
};

View file

@ -10,6 +10,7 @@ import { RequestHandler } from 'src/core/server';
import uuid from 'uuid';
import { TypeOf } from '@kbn/config-schema';
import { CommentType } from '../../../../../cases/common';
import { CasesByAlertId } from '../../../../../cases/common/api/cases/case';
import { HostIsolationRequestSchema } from '../../../../common/endpoint/schema/actions';
import { ISOLATE_HOST_ROUTE, UNISOLATE_HOST_ROUTE } from '../../../../common/endpoint/constants';
import { AGENT_ACTIONS_INDEX } from '../../../../../fleet/common';
@ -103,12 +104,17 @@ export const isolationRequestHandler = function (
let caseIDs: string[] = req.body.case_ids?.slice() || [];
if (req.body.alert_ids && req.body.alert_ids.length > 0) {
const newIDs: string[][] = await Promise.all(
req.body.alert_ids.map(async (a: string) =>
(await endpointContext.service.getCasesClient(req)).cases.getCaseIDsByAlertID({
req.body.alert_ids.map(async (a: string) => {
const cases: CasesByAlertId = await (
await endpointContext.service.getCasesClient(req)
).cases.getCasesByAlertID({
alertID: a,
options: { owner: APP_ID },
})
)
});
return cases.map((caseInfo): string => {
return caseInfo.id;
});
})
);
caseIDs = caseIDs.concat(...newIDs);
}

View file

@ -46,6 +46,7 @@ import {
CasesConfigurationsResponse,
CaseUserActionsResponse,
AlertResponse,
CasesByAlertId,
} from '../../../../plugins/cases/common/api';
import { getPostCaseRequest, postCollectionReq, postCommentGenAlertReq } from './mock';
import { getCaseUserActionUrl, getSubCasesUrl } from '../../../../plugins/cases/common/api/helpers';
@ -1017,7 +1018,7 @@ export const findCases = async ({
return res;
};
export const getCaseIDsByAlert = async ({
export const getCasesByAlert = async ({
supertest,
alertID,
query = {},
@ -1029,7 +1030,7 @@ export const getCaseIDsByAlert = async ({
query?: Record<string, unknown>;
expectedHttpCode?: number;
auth?: { user: User; space: string | null };
}): Promise<string[]> => {
}): Promise<CasesByAlertId> => {
const { body: res } = await supertest
.get(`${getSpaceUrlPrefix(auth.space)}${CASES_URL}/alerts/${alertID}`)
.auth(auth.user.username, auth.user.password)

View file

@ -0,0 +1,27 @@
/*
* 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 expect from '@kbn/expect';
import { CaseResponse, CasesByAlertId } from '../../../../plugins/cases/common';
/**
* Ensure that the result of the alerts API request matches with the cases created for the test.
*/
export function validateCasesFromAlertIDResponse(
casesFromAPIResponse: CasesByAlertId,
createdCasesForTest: CaseResponse[]
) {
const idToTitle = new Map<string, string>(
createdCasesForTest.map((caseInfo) => [caseInfo.id, caseInfo.title])
);
for (const apiResCase of casesFromAPIResponse) {
// check that the title in the api response matches the title in the map from the created cases
expect(apiResCase.title).to.be(idToTitle.get(apiResCase.id));
}
}

View file

@ -13,9 +13,10 @@ import { getPostCaseRequest, postCommentAlertReq } from '../../../../common/lib/
import {
createCase,
createComment,
getCaseIDsByAlert,
getCasesByAlert,
deleteAllCaseItems,
} from '../../../../common/lib/utils';
import { validateCasesFromAlertIDResponse } from '../../../../common/lib/validation';
import { CaseResponse } from '../../../../../../plugins/cases/common';
import {
globalRead,
@ -41,9 +42,9 @@ export default ({ getService }: FtrProviderContext): void => {
it('should return all cases with the same alert ID attached to them', async () => {
const [case1, case2, case3] = await Promise.all([
createCase(supertest, getPostCaseRequest()),
createCase(supertest, getPostCaseRequest()),
createCase(supertest, getPostCaseRequest()),
createCase(supertest, getPostCaseRequest({ title: 'a' })),
createCase(supertest, getPostCaseRequest({ title: 'b' })),
createCase(supertest, getPostCaseRequest({ title: 'c' })),
]);
await Promise.all([
@ -52,12 +53,10 @@ export default ({ getService }: FtrProviderContext): void => {
createComment({ supertest, caseId: case3.id, params: postCommentAlertReq }),
]);
const caseIDsWithAlert = await getCaseIDsByAlert({ supertest, alertID: 'test-id' });
const caseIDsWithAlert = await getCasesByAlert({ supertest, alertID: 'test-id' });
expect(caseIDsWithAlert.length).to.eql(3);
expect(caseIDsWithAlert).to.contain(case1.id);
expect(caseIDsWithAlert).to.contain(case2.id);
expect(caseIDsWithAlert).to.contain(case3.id);
validateCasesFromAlertIDResponse(caseIDsWithAlert, [case1, case2, case3]);
});
it('should return all cases with the same alert ID when more than 100 cases', async () => {
@ -80,13 +79,11 @@ export default ({ getService }: FtrProviderContext): void => {
await Promise.all(commentPromises);
const caseIDsWithAlert = await getCaseIDsByAlert({ supertest, alertID: 'test-id' });
const caseIDsWithAlert = await getCasesByAlert({ supertest, alertID: 'test-id' });
expect(caseIDsWithAlert.length).to.eql(numCases);
for (const caseInfo of cases) {
expect(caseIDsWithAlert).to.contain(caseInfo.id);
}
validateCasesFromAlertIDResponse(caseIDsWithAlert, cases);
});
it('should return no cases when the alert ID is not found', async () => {
@ -102,7 +99,7 @@ export default ({ getService }: FtrProviderContext): void => {
createComment({ supertest, caseId: case3.id, params: postCommentAlertReq }),
]);
const caseIDsWithAlert = await getCaseIDsByAlert({ supertest, alertID: 'test-id100' });
const caseIDsWithAlert = await getCasesByAlert({ supertest, alertID: 'test-id100' });
expect(caseIDsWithAlert.length).to.eql(0);
});
@ -120,7 +117,7 @@ export default ({ getService }: FtrProviderContext): void => {
createComment({ supertest, caseId: case3.id, params: postCommentAlertReq }),
]);
const caseIDsWithAlert = await getCaseIDsByAlert({
const caseIDsWithAlert = await getCasesByAlert({
supertest,
alertID: 'test-id',
query: { owner: 'not-real' },
@ -137,7 +134,7 @@ export default ({ getService }: FtrProviderContext): void => {
describe('rbac', () => {
const supertestWithoutAuth = getService('supertestWithoutAuth');
it('should return the correct case IDs', async () => {
it('should return the correct cases info', async () => {
const secOnlyAuth = { user: secOnly, space: 'space1' };
const obsOnlyAuth = { user: obsOnly, space: 'space1' };
@ -176,20 +173,20 @@ export default ({ getService }: FtrProviderContext): void => {
for (const scenario of [
{
user: globalRead,
caseIDs: [case1.id, case2.id, case3.id],
cases: [case1, case2, case3],
},
{
user: superUser,
caseIDs: [case1.id, case2.id, case3.id],
cases: [case1, case2, case3],
},
{ user: secOnlyRead, caseIDs: [case1.id, case2.id] },
{ user: obsOnlyRead, caseIDs: [case3.id] },
{ user: secOnlyRead, cases: [case1, case2] },
{ user: obsOnlyRead, cases: [case3] },
{
user: obsSecRead,
caseIDs: [case1.id, case2.id, case3.id],
cases: [case1, case2, case3],
},
]) {
const res = await getCaseIDsByAlert({
const res = await getCasesByAlert({
supertest: supertestWithoutAuth,
// cast because the official type is string | string[] but the ids will always be a single value in the tests
alertID: postCommentAlertReq.alertId as string,
@ -198,10 +195,9 @@ export default ({ getService }: FtrProviderContext): void => {
space: 'space1',
},
});
expect(res.length).to.eql(scenario.caseIDs.length);
for (const caseID of scenario.caseIDs) {
expect(res).to.contain(caseID);
}
expect(res.length).to.eql(scenario.cases.length);
validateCasesFromAlertIDResponse(res, scenario.cases);
}
});
@ -224,7 +220,7 @@ export default ({ getService }: FtrProviderContext): void => {
auth: { user: superUser, space: scenario.space },
});
await getCaseIDsByAlert({
await getCasesByAlert({
supertest: supertestWithoutAuth,
alertID: postCommentAlertReq.alertId as string,
auth: { user: scenario.user, space: scenario.space },
@ -260,17 +256,17 @@ export default ({ getService }: FtrProviderContext): void => {
}),
]);
const res = await getCaseIDsByAlert({
const res = await getCasesByAlert({
supertest: supertestWithoutAuth,
alertID: postCommentAlertReq.alertId as string,
auth,
query: { owner: 'securitySolutionFixture' },
});
expect(res).to.eql([case1.id]);
expect(res).to.eql([{ id: case1.id, title: case1.title }]);
});
it('should return the correct case IDs when the owner query parameter contains unprivileged values', async () => {
it('should return the correct cases info when the owner query parameter contains unprivileged values', async () => {
const auth = { user: obsSec, space: 'space1' };
const [case1, case2] = await Promise.all([
createCase(supertestWithoutAuth, getPostCaseRequest(), 200, auth),
@ -297,7 +293,7 @@ export default ({ getService }: FtrProviderContext): void => {
}),
]);
const res = await getCaseIDsByAlert({
const res = await getCasesByAlert({
supertest: supertestWithoutAuth,
alertID: postCommentAlertReq.alertId as string,
auth: { user: secOnly, space: 'space1' },
@ -305,7 +301,7 @@ export default ({ getService }: FtrProviderContext): void => {
query: { owner: ['securitySolutionFixture', 'observabilityFixture'] },
});
expect(res).to.eql([case1.id]);
expect(res).to.eql([{ id: case1.id, title: case1.title }]);
});
});
});

View file

@ -12,7 +12,7 @@ import { getPostCaseRequest, postCommentAlertReq } from '../../../../common/lib/
import {
createCase,
createComment,
getCaseIDsByAlert,
getCasesByAlert,
deleteAllCaseItems,
} from '../../../../common/lib/utils';
import {
@ -30,6 +30,7 @@ import {
superUserDefaultSpaceAuth,
obsSecDefaultSpaceAuth,
} from '../../../utils';
import { validateCasesFromAlertIDResponse } from '../../../../common/lib/validation';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext): void => {
@ -43,7 +44,7 @@ export default ({ getService }: FtrProviderContext): void => {
const supertestWithoutAuth = getService('supertestWithoutAuth');
it('should return the correct case IDs', async () => {
it('should return the correct cases info', async () => {
const [case1, case2, case3] = await Promise.all([
createCase(supertestWithoutAuth, getPostCaseRequest(), 200, secOnlyDefaultSpaceAuth),
createCase(supertestWithoutAuth, getPostCaseRequest(), 200, secOnlyDefaultSpaceAuth),
@ -79,20 +80,20 @@ export default ({ getService }: FtrProviderContext): void => {
for (const scenario of [
{
user: globalRead,
caseIDs: [case1.id, case2.id, case3.id],
cases: [case1, case2, case3],
},
{
user: superUser,
caseIDs: [case1.id, case2.id, case3.id],
cases: [case1, case2, case3],
},
{ user: secOnlyReadSpacesAll, caseIDs: [case1.id, case2.id] },
{ user: obsOnlyReadSpacesAll, caseIDs: [case3.id] },
{ user: secOnlyReadSpacesAll, cases: [case1, case2] },
{ user: obsOnlyReadSpacesAll, cases: [case3] },
{
user: obsSecReadSpacesAll,
caseIDs: [case1.id, case2.id, case3.id],
cases: [case1, case2, case3],
},
]) {
const res = await getCaseIDsByAlert({
const cases = await getCasesByAlert({
supertest: supertestWithoutAuth,
// cast because the official type is string | string[] but the ids will always be a single value in the tests
alertID: postCommentAlertReq.alertId as string,
@ -101,10 +102,9 @@ export default ({ getService }: FtrProviderContext): void => {
space: null,
},
});
expect(res.length).to.eql(scenario.caseIDs.length);
for (const caseID of scenario.caseIDs) {
expect(res).to.contain(caseID);
}
expect(cases.length).to.eql(scenario.cases.length);
validateCasesFromAlertIDResponse(cases, scenario.cases);
}
});
@ -123,7 +123,7 @@ export default ({ getService }: FtrProviderContext): void => {
auth: superUserDefaultSpaceAuth,
});
await getCaseIDsByAlert({
await getCasesByAlert({
supertest: supertestWithoutAuth,
alertID: postCommentAlertReq.alertId as string,
auth: { user: noKibanaPrivileges, space: null },
@ -157,7 +157,7 @@ export default ({ getService }: FtrProviderContext): void => {
}),
]);
await getCaseIDsByAlert({
await getCasesByAlert({
supertest: supertestWithoutAuth,
alertID: postCommentAlertReq.alertId as string,
auth: { user: obsSecSpacesAll, space: 'space1' },
@ -192,17 +192,17 @@ export default ({ getService }: FtrProviderContext): void => {
}),
]);
const res = await getCaseIDsByAlert({
const cases = await getCasesByAlert({
supertest: supertestWithoutAuth,
alertID: postCommentAlertReq.alertId as string,
auth: obsSecDefaultSpaceAuth,
query: { owner: 'securitySolutionFixture' },
});
expect(res).to.eql([case1.id]);
expect(cases).to.eql([{ id: case1.id, title: case1.title }]);
});
it('should return the correct case IDs when the owner query parameter contains unprivileged values', async () => {
it('should return the correct cases info when the owner query parameter contains unprivileged values', async () => {
const [case1, case2] = await Promise.all([
createCase(supertestWithoutAuth, getPostCaseRequest(), 200, obsSecDefaultSpaceAuth),
createCase(
@ -228,7 +228,7 @@ export default ({ getService }: FtrProviderContext): void => {
}),
]);
const res = await getCaseIDsByAlert({
const cases = await getCasesByAlert({
supertest: supertestWithoutAuth,
alertID: postCommentAlertReq.alertId as string,
auth: secOnlyDefaultSpaceAuth,
@ -236,7 +236,7 @@ export default ({ getService }: FtrProviderContext): void => {
query: { owner: ['securitySolutionFixture', 'observabilityFixture'] },
});
expect(res).to.eql([case1.id]);
expect(cases).to.eql([{ id: case1.id, title: case1.title }]);
});
});
};

View file

@ -12,10 +12,11 @@ import { getPostCaseRequest, postCommentAlertReq } from '../../../../common/lib/
import {
createCase,
createComment,
getCaseIDsByAlert,
getCasesByAlert,
deleteAllCaseItems,
getAuthWithSuperUser,
} from '../../../../common/lib/utils';
import { validateCasesFromAlertIDResponse } from '../../../../common/lib/validation';
// eslint-disable-next-line import/no-default-export
export default ({ getService }: FtrProviderContext): void => {
@ -57,16 +58,14 @@ export default ({ getService }: FtrProviderContext): void => {
}),
]);
const caseIDsWithAlert = await getCaseIDsByAlert({
const cases = await getCasesByAlert({
supertest,
alertID: 'test-id',
auth: authSpace1,
});
expect(caseIDsWithAlert.length).to.eql(3);
expect(caseIDsWithAlert).to.contain(case1.id);
expect(caseIDsWithAlert).to.contain(case2.id);
expect(caseIDsWithAlert).to.contain(case3.id);
expect(cases.length).to.eql(3);
validateCasesFromAlertIDResponse(cases, [case1, case2, case3]);
});
it('should return 1 case in space2 when 2 cases were created in space1 and 1 in space2', async () => {
@ -97,14 +96,14 @@ export default ({ getService }: FtrProviderContext): void => {
}),
]);
const caseIDsWithAlert = await getCaseIDsByAlert({
const casesByAlert = await getCasesByAlert({
supertest,
alertID: 'test-id',
auth: authSpace2,
});
expect(caseIDsWithAlert.length).to.eql(1);
expect(caseIDsWithAlert).to.eql([case3.id]);
expect(casesByAlert.length).to.eql(1);
expect(casesByAlert).to.eql([{ id: case3.id, title: case3.title }]);
});
});
};