Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/7.12' into backport/7.12/pr-93726
Browse files Browse the repository at this point in the history
  • Loading branch information
cnasikas committed Mar 9, 2021
2 parents 2025319 + 8990d33 commit 87aa3fe
Show file tree
Hide file tree
Showing 638 changed files with 1,867 additions and 4,272 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
},
"author": "Rashid Khan <[email protected]>",
"scripts": {
"bazel": "bazel",
"preinstall": "node ./preinstall_check",
"kbn": "node scripts/kbn",
"es": "node scripts/es",
Expand Down
39 changes: 34 additions & 5 deletions x-pack/plugins/case/server/client/cases/create.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ describe('create', () => {
return (
caseClient.client
// @ts-expect-error
.create({ theCase: postCase })
.create(postCase)
.catch((e) => {
expect(e).not.toBeNull();
expect(e.isBoom).toBe(true);
Expand Down Expand Up @@ -309,7 +309,7 @@ describe('create', () => {
return (
caseClient.client
// @ts-expect-error
.create({ theCase: postCase })
.create(postCase)
.catch((e) => {
expect(e).not.toBeNull();
expect(e.isBoom).toBe(true);
Expand Down Expand Up @@ -338,7 +338,7 @@ describe('create', () => {
return (
caseClient.client
// @ts-expect-error
.create({ theCase: postCase })
.create(postCase)
.catch((e) => {
expect(e).not.toBeNull();
expect(e.isBoom).toBe(true);
Expand All @@ -362,7 +362,7 @@ describe('create', () => {
return (
caseClient.client
// @ts-expect-error
.create({ theCase: postCase })
.create(postCase)
.catch((e) => {
expect(e).not.toBeNull();
expect(e.isBoom).toBe(true);
Expand Down Expand Up @@ -392,7 +392,7 @@ describe('create', () => {
return (
caseClient.client
// @ts-expect-error
.create({ theCase: postCase })
.create(postCase)
.catch((e) => {
expect(e).not.toBeNull();
expect(e.isBoom).toBe(true);
Expand Down Expand Up @@ -460,5 +460,34 @@ describe('create', () => {
expect(boomErr.output.statusCode).toBe(400);
});
});

test('it throws if type != individual', async () => {
expect.assertions(3);
const postCase = {
title: 'Super Bad Security Issue',
description: 'This is a brand new case of a bad meanie defacing data',
tags: ['defacement'],
connector: {
id: 'none',
name: 'none',
type: ConnectorTypes.none,
fields: null,
},
settings: {
syncAlerts: true,
},
type: CaseType.collection,
};

const savedObjectsClient = createMockSavedObjectsRepository({
caseSavedObject: mockCases,
});
const caseClient = await createCaseClientWithMockSavedObjectsClient({ savedObjectsClient });
return caseClient.client.create(postCase).catch((e) => {
expect(e).not.toBeNull();
expect(e.isBoom).toBe(true);
expect(e.output.statusCode).toBe(400);
});
});
});
});
6 changes: 6 additions & 0 deletions x-pack/plugins/case/server/client/cases/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ export const create = async ({
fold(throwErrors(Boom.badRequest), identity)
);

if (type !== CaseType.individual) {
throw Boom.badRequest(
`Failed to create case, a case must have type 'individual', but received: '${type}'`
);
}

try {
// eslint-disable-next-line @typescript-eslint/naming-convention
const { username, full_name, email } = user;
Expand Down
13 changes: 13 additions & 0 deletions x-pack/plugins/case/server/client/cases/update.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,18 @@ function throwIfUpdateStatusOfCollection(
}
}

/**
* Throws an error if any of the requests attempt to update the case type field.
*/
function throwIfUpdateCaseType(requests: ESCasePatchRequest[]) {
const requestsUpdatingCaseType = requests.filter((req) => req.type !== undefined);

if (requestsUpdatingCaseType.length > 0) {
const ids = requestsUpdatingCaseType.map((req) => req.id);
throw Boom.badRequest(`Updating the type of a case is not allowed ids: [${ids.join(', ')}]`);
}
}

/**
* Throws an error if any of the requests attempt to update a collection style case to an individual one.
*/
Expand Down Expand Up @@ -396,6 +408,7 @@ export const update = async ({
return acc;
}, new Map<string, SavedObject<ESCaseAttributes>>());

throwIfUpdateCaseType(updateFilterCases);
throwIfUpdateStatusOfCollection(updateFilterCases, casesMap);
throwIfUpdateTypeCollectionToIndividual(updateFilterCases, casesMap);
await throwIfInvalidUpdateOfTypeWithAlerts({
Expand Down
6 changes: 4 additions & 2 deletions x-pack/plugins/case/server/connectors/case/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ describe('case connector', () => {
expect(validateParams(caseActionType, params)).toEqual(params);
});

it('succeeds when type is an alert', () => {
it('fails when type is an alert', () => {
const params: Record<string, unknown> = {
subAction: 'addComment',
subActionParams: {
Expand All @@ -724,7 +724,9 @@ describe('case connector', () => {
},
};

expect(validateParams(caseActionType, params)).toEqual(params);
expect(() => {
validateParams(caseActionType, params);
}).toThrow();
});

it('fails when params is not valid', () => {
Expand Down
62 changes: 3 additions & 59 deletions x-pack/plugins/case/server/connectors/case/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,7 @@
import { curry } from 'lodash';
import { Logger } from 'src/core/server';
import { ActionTypeExecutorResult } from '../../../../actions/common';
import {
CasePatchRequest,
CasePostRequest,
CommentRequest,
CommentType,
} from '../../../common/api';
import { CasePatchRequest, CasePostRequest, CommentRequest } from '../../../common/api';
import { createExternalCaseClient } from '../../client';
import { CaseExecutorParamsSchema, CaseConfigurationSchema, CommentSchemaType } from './schema';
import {
Expand All @@ -24,7 +19,7 @@ import {
} from './types';
import * as i18n from './translations';

import { GetActionTypeParams, isCommentGeneratedAlert, separator } from '..';
import { GetActionTypeParams } from '..';
import { nullUser } from '../../common';
import { createCaseError } from '../../common/error';

Expand Down Expand Up @@ -145,15 +140,6 @@ async function executor(
return { status: 'ok', data: data ?? {}, actionId };
}

/**
* This converts a connector style generated alert ({_id: string} | {_id: string}[]) to the expected format of addComment.
*/
interface AttachmentAlerts {
ids: string[];
indices: string[];
rule: { id: string | null; name: string | null };
}

/**
* Convert a connector style comment passed through the action plugin to the expected format for the add comment functionality.
*
Expand All @@ -166,47 +152,5 @@ export const transformConnectorComment = (
comment: CommentSchemaType,
logger?: Logger
): CommentRequest => {
if (isCommentGeneratedAlert(comment)) {
try {
const genAlerts: Array<{
_id: string;
_index: string;
ruleId: string | undefined;
ruleName: string | undefined;
}> = JSON.parse(
`${comment.alerts.substring(0, comment.alerts.lastIndexOf(separator))}]`.replace(
new RegExp(separator, 'g'),
','
)
);

const { ids, indices, rule } = genAlerts.reduce<AttachmentAlerts>(
(acc, { _id, _index, ruleId, ruleName }) => {
// Mutation is faster than destructing.
// Mutation usually leads to side effects but for this scenario it's ok to do it.
acc.ids.push(_id);
acc.indices.push(_index);
// We assume one rule per batch of alerts, this will use the rule information from the last entry in the array
acc.rule = { id: ruleId ?? null, name: ruleName ?? null };
return acc;
},
{ ids: [], indices: [], rule: { id: null, name: null } }
);

return {
type: CommentType.generatedAlert,
alertId: ids,
index: indices,
rule,
};
} catch (e) {
throw createCaseError({
message: `Error parsing generated alert in case connector -> ${e}`,
error: e,
logger,
});
}
} else {
return comment;
}
return comment;
};
4 changes: 2 additions & 2 deletions x-pack/plugins/case/server/connectors/case/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ export type ContextTypeAlertSchemaType = typeof ContextTypeAlertSchema.type;

export const CommentSchema = schema.oneOf([
ContextTypeUserSchema,
ContextTypeAlertSchema,
ContextTypeAlertGroupSchema,
// ContextTypeAlertSchema,
// ContextTypeAlertGroupSchema,
]);

export type CommentSchemaType = typeof CommentSchema.type;
Expand Down
25 changes: 1 addition & 24 deletions x-pack/plugins/case/server/connectors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,12 @@
* 2.0.
*/

import {
RegisterConnectorsArgs,
ExternalServiceFormatterMapper,
CommentSchemaType,
ContextTypeGeneratedAlertType,
ContextTypeAlertSchemaType,
} from './types';
import { RegisterConnectorsArgs, ExternalServiceFormatterMapper } from './types';
import { getActionType as getCaseConnector } from './case';
import { serviceNowITSMExternalServiceFormatter } from './servicenow/itsm_formatter';
import { serviceNowSIRExternalServiceFormatter } from './servicenow/sir_formatter';
import { jiraExternalServiceFormatter } from './jira/external_service_formatter';
import { resilientExternalServiceFormatter } from './resilient/external_service_formatter';
import { CommentRequest, CommentType } from '../../common/api';

export * from './types';
export { transformConnectorComment } from './case';
Expand Down Expand Up @@ -56,22 +49,6 @@ export const externalServiceFormatters: ExternalServiceFormatterMapper = {
'.resilient': resilientExternalServiceFormatter,
};

export const isCommentGeneratedAlert = (
comment: CommentSchemaType | CommentRequest
): comment is ContextTypeGeneratedAlertType => {
return (
comment.type === CommentType.generatedAlert &&
'alerts' in comment &&
comment.alerts !== undefined
);
};

export const isCommentAlert = (
comment: CommentSchemaType
): comment is ContextTypeAlertSchemaType => {
return comment.type === CommentType.alert;
};

interface AlertIDIndex {
_id: string;
_index: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,6 @@ export function initDeleteAllCommentsApi({
params: schema.object({
case_id: schema.string(),
}),
query: schema.maybe(
schema.object({
subCaseId: schema.maybe(schema.string()),
})
),
},
},
async (context, request, response) => {
Expand All @@ -40,13 +35,11 @@ export function initDeleteAllCommentsApi({
const { username, full_name, email } = await caseService.getUser({ request });
const deleteDate = new Date().toISOString();

const id = request.query?.subCaseId ?? request.params.case_id;
const id = request.params.case_id;
const comments = await caseService.getCommentsByAssociation({
client,
id,
associationType: request.query?.subCaseId
? AssociationType.subCase
: AssociationType.case,
associationType: AssociationType.case,
});

await Promise.all(
Expand All @@ -66,7 +59,7 @@ export function initDeleteAllCommentsApi({
actionAt: deleteDate,
actionBy: { username, full_name, email },
caseId: request.params.case_id,
subCaseId: request.query?.subCaseId,
subCaseId: undefined,
commentId: comment.id,
fields: ['comment'],
})
Expand All @@ -76,7 +69,7 @@ export function initDeleteAllCommentsApi({
return response.noContent();
} catch (error) {
logger.error(
`Failed to delete all comments in route case id: ${request.params.case_id} sub case id: ${request.query?.subCaseId}: ${error}`
`Failed to delete all comments in route case id: ${request.params.case_id}: ${error}`
);
return response.customError(wrapError(error));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import Boom from '@hapi/boom';
import { schema } from '@kbn/config-schema';

import { CASE_SAVED_OBJECT, SUB_CASE_SAVED_OBJECT } from '../../../../saved_object_types';
import { CASE_SAVED_OBJECT } from '../../../../saved_object_types';
import { buildCommentUserActionItem } from '../../../../services/user_actions/helpers';
import { RouteDeps } from '../../types';
import { wrapError } from '../../utils';
Expand All @@ -28,11 +28,6 @@ export function initDeleteCommentApi({
case_id: schema.string(),
comment_id: schema.string(),
}),
query: schema.maybe(
schema.object({
subCaseId: schema.maybe(schema.string()),
})
),
},
},
async (context, request, response) => {
Expand All @@ -51,8 +46,8 @@ export function initDeleteCommentApi({
throw Boom.notFound(`This comment ${request.params.comment_id} does not exist anymore.`);
}

const type = request.query?.subCaseId ? SUB_CASE_SAVED_OBJECT : CASE_SAVED_OBJECT;
const id = request.query?.subCaseId ?? request.params.case_id;
const type = CASE_SAVED_OBJECT;
const id = request.params.case_id;

const caseRef = myComment.references.find((c) => c.type === type);
if (caseRef == null || (caseRef != null && caseRef.id !== id)) {
Expand All @@ -74,7 +69,7 @@ export function initDeleteCommentApi({
actionAt: deleteDate,
actionBy: { username, full_name, email },
caseId: id,
subCaseId: request.query?.subCaseId,
subCaseId: undefined,
commentId: request.params.comment_id,
fields: ['comment'],
}),
Expand All @@ -84,7 +79,7 @@ export function initDeleteCommentApi({
return response.noContent();
} catch (error) {
logger.error(
`Failed to delete comment in route case id: ${request.params.case_id} comment id: ${request.params.comment_id} sub case id: ${request.query?.subCaseId}: ${error}`
`Failed to delete comment in route case id: ${request.params.case_id} comment id: ${request.params.comment_id}: ${error}`
);
return response.customError(wrapError(error));
}
Expand Down
Loading

0 comments on commit 87aa3fe

Please sign in to comment.