Skip to content

Commit

Permalink
Create ServiceNow SIR case connector fields
Browse files Browse the repository at this point in the history
  • Loading branch information
cnasikas committed Jan 21, 2021
1 parent 135a3cd commit 222688f
Show file tree
Hide file tree
Showing 30 changed files with 792 additions and 81 deletions.
25 changes: 18 additions & 7 deletions x-pack/plugins/case/common/api/connectors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,28 @@ import * as rt from 'io-ts';

import { JiraFieldsRT } from './jira';
import { ResilientFieldsRT } from './resilient';
import { ServiceNowFieldsRT } from './servicenow';
import { ServiceNowIMFieldsRT } from './servicenow';
import { ServiceNowSIRFieldsRT } from './servicenow_sir';

export * from './jira';
export * from './servicenow';
export * from './servicenow_sir';
export * from './resilient';
export * from './mappings';

export const ConnectorFieldsRt = rt.union([
JiraFieldsRT,
ResilientFieldsRT,
ServiceNowFieldsRT,
ServiceNowIMFieldsRT,
ServiceNowSIRFieldsRT,
rt.null,
]);

export enum ConnectorTypes {
jira = '.jira',
resilient = '.resilient',
servicenow = '.servicenow',
serviceNowIM = '.servicenow',
serviceNowSIR = '.servicenow-sir',
none = '.none',
}

Expand All @@ -37,9 +42,14 @@ const ConnectorResillientTypeFieldsRt = rt.type({
fields: rt.union([ResilientFieldsRT, rt.null]),
});

const ConnectorServiceNowTypeFieldsRt = rt.type({
type: rt.literal(ConnectorTypes.servicenow),
fields: rt.union([ServiceNowFieldsRT, rt.null]),
const ConnectorServiceNowIMTypeFieldsRt = rt.type({
type: rt.literal(ConnectorTypes.serviceNowIM),
fields: rt.union([ServiceNowIMFieldsRT, rt.null]),
});

const ConnectorServiceNowSIRTypeFieldsRt = rt.type({
type: rt.literal(ConnectorTypes.serviceNowSIR),
fields: rt.union([ServiceNowSIRFieldsRT, rt.null]),
});

const ConnectorNoneTypeFieldsRt = rt.type({
Expand All @@ -50,7 +60,8 @@ const ConnectorNoneTypeFieldsRt = rt.type({
export const ConnectorTypeFieldsRt = rt.union([
ConnectorJiraTypeFieldsRt,
ConnectorResillientTypeFieldsRt,
ConnectorServiceNowTypeFieldsRt,
ConnectorServiceNowIMTypeFieldsRt,
ConnectorServiceNowSIRTypeFieldsRt,
ConnectorNoneTypeFieldsRt,
]);

Expand Down
6 changes: 4 additions & 2 deletions x-pack/plugins/case/common/api/connectors/mappings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ import {
ServiceNowIMIncident,
} from '../../../../actions/server/builtin_action_types/servicenow/types';
import { ResilientFieldsRT } from './resilient';
import { ServiceNowFieldsRT } from './servicenow';
import { ServiceNowIMFieldsRT } from './servicenow';
import { JiraFieldsRT } from './jira';
import { ServiceNowSIRFieldsRT } from './servicenow_sir';

export {
JiraPushToServiceApiParams,
Expand Down Expand Up @@ -143,7 +144,8 @@ export const ServiceConnectorBasicCaseParamsRt = rt.type({
export const ConnectorPartialFieldsRt = rt.partial({
...JiraFieldsRT.props,
...ResilientFieldsRT.props,
...ServiceNowFieldsRT.props,
...ServiceNowIMFieldsRT.props,
...ServiceNowSIRFieldsRT.props,
});

export const ServiceConnectorCaseParamsRt = rt.intersection([
Expand Down
4 changes: 2 additions & 2 deletions x-pack/plugins/case/common/api/connectors/servicenow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@

import * as rt from 'io-ts';

export const ServiceNowFieldsRT = rt.type({
export const ServiceNowIMFieldsRT = rt.type({
impact: rt.union([rt.string, rt.null]),
severity: rt.union([rt.string, rt.null]),
urgency: rt.union([rt.string, rt.null]),
});

export type ServiceNowFieldsType = rt.TypeOf<typeof ServiceNowFieldsRT>;
export type ServiceNowIMFieldsType = rt.TypeOf<typeof ServiceNowIMFieldsRT>;
19 changes: 19 additions & 0 deletions x-pack/plugins/case/common/api/connectors/servicenow_sir.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import * as rt from 'io-ts';

export const ServiceNowSIRFieldsRT = rt.type({
category: rt.union([rt.string, rt.null]),
destIP: rt.union([rt.string, rt.null]),
malwareHash: rt.union([rt.string, rt.null]),
malwareUrl: rt.union([rt.string, rt.null]),
priority: rt.union([rt.string, rt.null]),
sourceIP: rt.union([rt.string, rt.null]),
subcategory: rt.union([rt.string, rt.null]),
});

export type ServiceNowSIRFieldsType = rt.TypeOf<typeof ServiceNowSIRFieldsRT>;
6 changes: 4 additions & 2 deletions x-pack/plugins/case/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,14 @@ export const CASE_USER_ACTIONS_URL = `${CASE_DETAILS_URL}/user_actions`;

export const ACTION_URL = '/api/actions';
export const ACTION_TYPES_URL = '/api/actions/list_action_types';
export const SERVICENOW_ACTION_TYPE_ID = '.servicenow';
export const SERVICENOW_IM_ACTION_TYPE_ID = '.servicenow';
export const SERVICENOW_SIR_ACTION_TYPE_ID = '.servicenow-sir';
export const JIRA_ACTION_TYPE_ID = '.jira';
export const RESILIENT_ACTION_TYPE_ID = '.resilient';

export const SUPPORTED_CONNECTORS = [
SERVICENOW_ACTION_TYPE_ID,
SERVICENOW_IM_ACTION_TYPE_ID,
SERVICENOW_SIR_ACTION_TYPE_ID,
JIRA_ACTION_TYPE_ID,
RESILIENT_ACTION_TYPE_ID,
];
4 changes: 2 additions & 2 deletions x-pack/plugins/case/server/client/configure/mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export const mappings: TestMappings = {
action_type: 'append',
},
],
[ConnectorTypes.servicenow]: [
[ConnectorTypes.serviceNowIM]: [
{
source: 'title',
target: 'short_description',
Expand Down Expand Up @@ -610,7 +610,7 @@ export const formatFieldsTestData: FormatFieldsTestData[] = [
{ id: 'upon_reject', name: 'Upon reject', required: false, type: 'text' },
],
fields: serviceNowFields,
type: ConnectorTypes.servicenow,
type: ConnectorTypes.serviceNowIM,
},
];
export const mockGetFieldsResponse = {
Expand Down
4 changes: 2 additions & 2 deletions x-pack/plugins/case/server/client/configure/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export const formatFields = (theData: unknown, theType: string): ConnectorField[
return normalizeJiraFields(theData as JiraGetFieldsResponse);
case ConnectorTypes.resilient:
return normalizeResilientFields(theData as ResilientGetFieldsResponse);
case ConnectorTypes.servicenow:
case ConnectorTypes.serviceNowIM:
return normalizeServiceNowFields(theData as ServiceNowGetFieldsResponse);
default:
return [];
Expand All @@ -96,7 +96,7 @@ const getPreferredFields = (theType: string) => {
} else if (theType === ConnectorTypes.resilient) {
title = 'name';
description = 'description';
} else if (theType === ConnectorTypes.servicenow) {
} else if (theType === ConnectorTypes.serviceNowIM) {
title = 'short_description';
description = 'description';
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,11 @@ import { FindActionResult } from '../../../../../../actions/server/types';

import {
CASE_CONFIGURE_CONNECTORS_URL,
SERVICENOW_ACTION_TYPE_ID,
JIRA_ACTION_TYPE_ID,
RESILIENT_ACTION_TYPE_ID,
SUPPORTED_CONNECTORS,
} from '../../../../../common/constants';

const isConnectorSupported = (action: FindActionResult): boolean =>
[SERVICENOW_ACTION_TYPE_ID, JIRA_ACTION_TYPE_ID, RESILIENT_ACTION_TYPE_ID].includes(
action.actionTypeId
);
SUPPORTED_CONNECTORS.includes(action.actionTypeId);

/*
* Be aware that this api will only return 20 connectors
Expand Down
13 changes: 12 additions & 1 deletion x-pack/plugins/case/server/routes/api/cases/configure/mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,24 @@ export const params = {
severityCode: '1',
...entity,
} as ServiceConnectorCaseParams,
[ConnectorTypes.servicenow]: {
[ConnectorTypes.serviceNowIM]: {
...basicParams,
impact: '3',
severity: '1',
urgency: '2',
...entity,
} as ServiceConnectorCaseParams,
[ConnectorTypes.serviceNowSIR]: {
...basicParams,
category: 'Denial of Service',
destIP: '192.68.1.1',
sourceIP: '192.68.1.2',
malwareHash: '098f6bcd4621d373cade4e832627b4f6',
malwareUrl: 'https://attack.com',
priority: '1',
subcategory: '20',
...entity,
} as ServiceConnectorCaseParams,
[ConnectorTypes.none]: {},
};
export const mappings: ConnectorMappingsAttributes[] = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import {
import { actionsClientMock } from '../../../../../../actions/server/actions_client.mock';
import { mappings as mappingsMock } from '../../../../client/configure/mock';
const formatComment = { commentId: commentObj.commentId, comment: commentObj.comment };
const serviceNowParams = params[ConnectorTypes.servicenow] as ServiceConnectorCaseParams;
const serviceNowParams = params[ConnectorTypes.serviceNowIM] as ServiceConnectorCaseParams;
describe('api/cases/configure/utils', () => {
describe('prepareFieldsForTransformation', () => {
test('prepare fields with defaults', () => {
Expand Down Expand Up @@ -394,8 +394,8 @@ describe('api/cases/configure/utils', () => {
const res = await mapIncident(
actionsMock,
'123',
ConnectorTypes.servicenow,
mappingsMock[ConnectorTypes.servicenow],
ConnectorTypes.serviceNowIM,
mappingsMock[ConnectorTypes.serviceNowIM],
serviceNowParams
);
expect(res).toEqual({
Expand All @@ -420,7 +420,7 @@ describe('api/cases/configure/utils', () => {
actionsMock,
'123',
'invalid',
mappingsMock[ConnectorTypes.servicenow],
mappingsMock[ConnectorTypes.serviceNowIM],
serviceNowParams
).catch((e) => {
expect(e).not.toBeNull();
Expand All @@ -440,8 +440,8 @@ describe('api/cases/configure/utils', () => {
const res = await mapIncident(
actionsMock,
'123',
ConnectorTypes.servicenow,
mappingsMock[ConnectorTypes.servicenow],
ConnectorTypes.serviceNowIM,
mappingsMock[ConnectorTypes.serviceNowIM],
{ ...serviceNowParams, externalId: '123' }
);
expect(res).toEqual({
Expand Down Expand Up @@ -469,8 +469,8 @@ describe('api/cases/configure/utils', () => {
await mapIncident(
actionsMock,
'123',
ConnectorTypes.servicenow,
mappingsMock[ConnectorTypes.servicenow],
ConnectorTypes.serviceNowIM,
mappingsMock[ConnectorTypes.serviceNowIM],
{ ...serviceNowParams, externalId: '123' }
).catch((e) => {
expect(e).not.toBeNull();
Expand Down Expand Up @@ -506,7 +506,7 @@ describe('api/cases/configure/utils', () => {
},
},
{
name: ConnectorTypes.servicenow,
name: ConnectorTypes.serviceNowIM,
result: {
incident: {
impact: '3',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export const serviceFormatter = (
incident: { incidentTypes, severityCode },
thirdPartyName: 'Resilient',
};
case ConnectorTypes.servicenow:
case ConnectorTypes.serviceNowIM:
const {
severity,
urgency,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -507,7 +507,7 @@ describe('CaseView ', () => {
connector: {
id: 'servicenow-1',
name: 'SN 1',
type: ConnectorTypes.servicenow,
type: ConnectorTypes.serviceNowIM,
fields: null,
},
}}
Expand Down Expand Up @@ -555,7 +555,7 @@ describe('CaseView ', () => {
connector: {
id: 'servicenow-1',
name: 'SN 1',
type: ConnectorTypes.servicenow,
type: ConnectorTypes.serviceNowIM,
fields: null,
},
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ describe('Connectors', () => {
const newWrapper = mount(
<Connectors
{...props}
selectedConnector={{ id: 'servicenow-1', type: ConnectorTypes.servicenow }}
selectedConnector={{ id: 'servicenow-1', type: ConnectorTypes.serviceNowIM }}
/>,
{
wrappingComponent: TestProviders,
Expand All @@ -98,7 +98,7 @@ describe('Connectors', () => {
const newWrapper = mount(
<Connectors
{...props}
selectedConnector={{ id: 'servicenow-1', type: ConnectorTypes.servicenow }}
selectedConnector={{ id: 'servicenow-1', type: ConnectorTypes.serviceNowIM }}
/>,
{
wrappingComponent: TestProviders,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,14 +174,14 @@ describe('ConfigureCases', () => {
connector: {
id: 'servicenow-1',
name: 'unchanged',
type: ConnectorTypes.servicenow,
type: ConnectorTypes.serviceNowIM,
fields: null,
},
currentConfiguration: {
connector: {
id: 'servicenow-1',
name: 'unchanged',
type: ConnectorTypes.servicenow,
type: ConnectorTypes.serviceNowIM,
fields: null,
},
closureType: 'close-by-user',
Expand Down Expand Up @@ -259,7 +259,7 @@ describe('ConfigureCases', () => {
connector: {
id: 'servicenow-1',
name: 'unchanged',
type: ConnectorTypes.servicenow,
type: ConnectorTypes.serviceNowIM,
fields: null,
},
closureType: 'close-by-user',
Expand Down Expand Up @@ -305,7 +305,7 @@ describe('ConfigureCases', () => {
connector: {
id: 'servicenow-1',
name: 'SN',
type: ConnectorTypes.servicenow,
type: ConnectorTypes.serviceNowIM,
fields: null,
},
persistLoading: true,
Expand Down Expand Up @@ -424,7 +424,7 @@ describe('ConfigureCases', () => {
connector: {
id: 'servicenow-1',
name: 'My connector',
type: ConnectorTypes.servicenow,
type: ConnectorTypes.serviceNowIM,
fields: null,
},
}))
Expand Down Expand Up @@ -467,7 +467,7 @@ describe('closure options', () => {
connector: {
id: 'servicenow-1',
name: 'My connector',
type: ConnectorTypes.servicenow,
type: ConnectorTypes.serviceNowIM,
fields: null,
},
currentConfiguration: {
Expand Down Expand Up @@ -496,7 +496,7 @@ describe('closure options', () => {
connector: {
id: 'servicenow-1',
name: 'My connector',
type: ConnectorTypes.servicenow,
type: ConnectorTypes.serviceNowIM,
fields: null,
},
closureType: 'close-by-pushing',
Expand All @@ -520,7 +520,7 @@ describe('user interactions', () => {
connector: {
id: 'resilient-2',
name: 'unchanged',
type: ConnectorTypes.servicenow,
type: ConnectorTypes.serviceNowIM,
fields: null,
},
closureType: 'close-by-user',
Expand Down
Loading

0 comments on commit 222688f

Please sign in to comment.