Skip to content

Commit

Permalink
Pull defaults into reusable function
Browse files Browse the repository at this point in the history
  • Loading branch information
marshallmain committed Nov 12, 2020
1 parent beccc22 commit 9aac141
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 118 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,12 @@
* you may not use this file except in compliance with the Elastic License.
*/

/* eslint-disable complexity */

import uuid from 'uuid';
import { transformRuleToAlertAction } from '../../../../../common/detection_engine/transform_actions';
import { validate } from '../../../../../common/validate';
import { createRuleValidateTypeDependents } from '../../../../../common/detection_engine/schemas/request/create_rules_type_dependents';
import { createRulesBulkSchema } from '../../../../../common/detection_engine/schemas/request/create_rules_bulk_schema';
import { rulesBulkSchema } from '../../../../../common/detection_engine/schemas/response/rules_bulk_schema';
import { IRouter } from '../../../../../../../../src/core/server';
import {
DEFAULT_MAX_SIGNALS,
DETECTION_ENGINE_RULES_URL,
SERVER_APP_ID,
SIGNALS_ID,
} from '../../../../../common/constants';
import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants';
import { SetupPlugins } from '../../../../plugin';
import { buildMlAuthz } from '../../../machine_learning/authz';
import { throwHttpError } from '../../../machine_learning/validation';
Expand All @@ -30,9 +21,7 @@ import { buildRouteValidation } from '../../../../utils/build_validation/route_v

import { transformBulkError, createBulkErrorObject, buildSiemResponse } from '../utils';
import { updateRulesNotifications } from '../../rules/update_rules_notifications';
import { typeSpecificSnakeToCamel } from '../../schemas/rule_converters';
import { InternalRuleCreate } from '../../schemas/rule_schemas';
import { addTags } from '../../rules/add_tags';
import { convertCreateAPIToInternalSchema } from '../../schemas/rule_converters';

export const createRulesBulkRoute = (router: IRouter, ml: SetupPlugins['ml']) => {
router.post(
Expand Down Expand Up @@ -84,50 +73,7 @@ export const createRulesBulkRoute = (router: IRouter, ml: SetupPlugins['ml']) =>
});
}
}
const typeSpecificParams = typeSpecificSnakeToCamel(payloadRule);
const newRuleId = payloadRule.rule_id ?? uuid.v4();
const throttle = payloadRule.throttle ?? null;
const internalRule: InternalRuleCreate = {
name: payloadRule.name,
tags: addTags(payloadRule.tags ?? [], newRuleId, false),
alertTypeId: SIGNALS_ID,
consumer: SERVER_APP_ID,
params: {
author: payloadRule.author ?? [],
buildingBlockType: payloadRule.building_block_type,
description: payloadRule.description,
ruleId: newRuleId,
falsePositives: payloadRule.false_positives ?? [],
from: payloadRule.from ?? 'now-6m',
immutable: false,
license: payloadRule.license,
outputIndex: payloadRule.output_index ?? siemClient.getSignalsIndex(),
timelineId: payloadRule.timeline_id,
timelineTitle: payloadRule.timeline_title,
meta: payloadRule.meta,
maxSignals: payloadRule.max_signals ?? DEFAULT_MAX_SIGNALS,
riskScore: payloadRule.risk_score,
riskScoreMapping: payloadRule.risk_score_mapping ?? [],
ruleNameOverride: payloadRule.rule_name_override,
severity: payloadRule.severity,
severityMapping: payloadRule.severity_mapping ?? [],
threat: payloadRule.threat ?? [],
timestampOverride: payloadRule.timestamp_override,
to: payloadRule.to ?? 'now',
references: payloadRule.references ?? [],
note: payloadRule.note,
version: payloadRule.version ?? 1,
exceptionsList: payloadRule.exceptions_list ?? [],
...typeSpecificParams,
},
schedule: { interval: payloadRule.interval ?? '5m' },
enabled: payloadRule.enabled ?? true,
actions:
throttle === 'rule'
? (payloadRule.actions ?? []).map(transformRuleToAlertAction)
: [],
throttle: null,
};
const internalRule = convertCreateAPIToInternalSchema(payloadRule, siemClient);
try {
const validationErrors = createRuleValidateTypeDependents(payloadRule);
if (validationErrors.length) {
Expand Down Expand Up @@ -159,13 +105,17 @@ export const createRulesBulkRoute = (router: IRouter, ml: SetupPlugins['ml']) =>
savedObjectsClient,
enabled: createdRule.enabled,
actions: payloadRule.actions,
throttle,
throttle: payloadRule.throttle ?? null,
name: createdRule.name,
});

return transformValidateBulkError(newRuleId, createdRule, ruleActions);
return transformValidateBulkError(
internalRule.params.ruleId,
createdRule,
ruleActions
);
} catch (err) {
return transformBulkError(newRuleId, err);
return transformBulkError(internalRule.params.ruleId, err);
}
})
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,9 @@
* you may not use this file except in compliance with the Elastic License.
*/

/* eslint-disable complexity */

import uuid from 'uuid';

import { buildRouteValidation } from '../../../../utils/build_validation/route_validation';
import { IRouter } from '../../../../../../../../src/core/server';
import {
DETECTION_ENGINE_RULES_URL,
SIGNALS_ID,
SERVER_APP_ID,
DEFAULT_MAX_SIGNALS,
} from '../../../../../common/constants';
import { DETECTION_ENGINE_RULES_URL } from '../../../../../common/constants';
import { SetupPlugins } from '../../../../plugin';
import { buildMlAuthz } from '../../../machine_learning/authz';
import { throwHttpError } from '../../../machine_learning/validation';
Expand All @@ -24,13 +15,10 @@ import { getIndexExists } from '../../index/get_index_exists';
import { transformError, buildSiemResponse } from '../utils';
import { updateRulesNotifications } from '../../rules/update_rules_notifications';
import { ruleStatusSavedObjectsClientFactory } from '../../signals/rule_status_saved_objects_client';
import { addTags } from '../../rules/add_tags';
import { transformRuleToAlertAction } from '../../../../../common/detection_engine/transform_actions';
import { createRulesSchema } from '../../../../../common/detection_engine/schemas/request';
import { newTransformValidate } from './validate';
import { InternalRuleCreate } from '../../schemas/rule_schemas';
import { typeSpecificSnakeToCamel } from '../../schemas/rule_converters';
import { createRuleValidateTypeDependents } from '../../../../../common/detection_engine/schemas/request/create_rules_type_dependents';
import { convertCreateAPIToInternalSchema } from '../../schemas/rule_converters';

export const createRulesRoute = (router: IRouter, ml: SetupPlugins['ml']): void => {
router.post(
Expand Down Expand Up @@ -73,48 +61,7 @@ export const createRulesRoute = (router: IRouter, ml: SetupPlugins['ml']): void
}
}

const typeSpecificParams = typeSpecificSnakeToCamel(request.body);
const newRuleId = request.body.rule_id ?? uuid.v4();
const throttle = request.body.throttle ?? null;
const internalRule: InternalRuleCreate = {
name: request.body.name,
tags: addTags(request.body.tags ?? [], newRuleId, false),
alertTypeId: SIGNALS_ID,
consumer: SERVER_APP_ID,
params: {
author: request.body.author ?? [],
buildingBlockType: request.body.building_block_type,
description: request.body.description,
ruleId: newRuleId,
falsePositives: request.body.false_positives ?? [],
from: request.body.from ?? 'now-6m',
immutable: false,
license: request.body.license,
outputIndex: request.body.output_index ?? siemClient.getSignalsIndex(),
timelineId: request.body.timeline_id,
timelineTitle: request.body.timeline_title,
meta: request.body.meta,
maxSignals: request.body.max_signals ?? DEFAULT_MAX_SIGNALS,
riskScore: request.body.risk_score,
riskScoreMapping: request.body.risk_score_mapping ?? [],
ruleNameOverride: request.body.rule_name_override,
severity: request.body.severity,
severityMapping: request.body.severity_mapping ?? [],
threat: request.body.threat ?? [],
timestampOverride: request.body.timestamp_override,
to: request.body.to ?? 'now',
references: request.body.references ?? [],
note: request.body.note,
version: request.body.version ?? 1,
exceptionsList: request.body.exceptions_list ?? [],
...typeSpecificParams,
},
schedule: { interval: request.body.interval ?? '5m' },
enabled: request.body.enabled ?? true,
actions:
throttle === 'rule' ? (request.body.actions ?? []).map(transformRuleToAlertAction) : [],
throttle: null,
};
const internalRule = convertCreateAPIToInternalSchema(request.body, siemClient);

const mlAuthz = buildMlAuthz({
license: context.licensing.license,
Expand Down Expand Up @@ -148,7 +95,7 @@ export const createRulesRoute = (router: IRouter, ml: SetupPlugins['ml']): void
savedObjectsClient,
enabled: createdRule.enabled,
actions: request.body.actions,
throttle,
throttle: request.body.throttle ?? null,
name: createdRule.name,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,20 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { InternalRuleResponse, TypeSpecificRuleParams } from './rule_schemas';
import uuid from 'uuid';
import { InternalRuleCreate, InternalRuleResponse, TypeSpecificRuleParams } from './rule_schemas';
import { assertUnreachable } from '../../../../common/utility_types';
import {
CreateRulesSchema,
CreateTypeSpecific,
FullResponseSchema,
ResponseTypeSpecific,
} from '../../../../common/detection_engine/schemas/request';
import { RuleActions } from '../rule_actions/types';
import { AppClient } from '../../../types';
import { addTags } from '../rules/add_tags';
import { DEFAULT_MAX_SIGNALS, SERVER_APP_ID, SIGNALS_ID } from '../../../../common/constants';
import { transformRuleToAlertAction } from '../../../../common/detection_engine/transform_actions';

// These functions provide conversions from the request API schema to the internal rule schema and from the internal rule schema
// to the response API schema. This provides static type-check assurances that the internal schema is in sync with the API schema for
Expand Down Expand Up @@ -94,6 +100,52 @@ export const typeSpecificSnakeToCamel = (params: CreateTypeSpecific): TypeSpecif
}
};

export const convertCreateAPIToInternalSchema = (
input: CreateRulesSchema,
siemClient: AppClient
): InternalRuleCreate => {
const typeSpecificParams = typeSpecificSnakeToCamel(input);
const newRuleId = input.rule_id ?? uuid.v4();
return {
name: input.name,
tags: addTags(input.tags ?? [], newRuleId, false),
alertTypeId: SIGNALS_ID,
consumer: SERVER_APP_ID,
params: {
author: input.author ?? [],
buildingBlockType: input.building_block_type,
description: input.description,
ruleId: newRuleId,
falsePositives: input.false_positives ?? [],
from: input.from ?? 'now-6m',
immutable: false,
license: input.license,
outputIndex: input.output_index ?? siemClient.getSignalsIndex(),
timelineId: input.timeline_id,
timelineTitle: input.timeline_title,
meta: input.meta,
maxSignals: input.max_signals ?? DEFAULT_MAX_SIGNALS,
riskScore: input.risk_score,
riskScoreMapping: input.risk_score_mapping ?? [],
ruleNameOverride: input.rule_name_override,
severity: input.severity,
severityMapping: input.severity_mapping ?? [],
threat: input.threat ?? [],
timestampOverride: input.timestamp_override,
to: input.to ?? 'now',
references: input.references ?? [],
note: input.note,
version: input.version ?? 1,
exceptionsList: input.exceptions_list ?? [],
...typeSpecificParams,
},
schedule: { interval: input.interval ?? '5m' },
enabled: input.enabled ?? true,
actions: input.throttle === 'rule' ? (input.actions ?? []).map(transformRuleToAlertAction) : [],
throttle: null,
};
};

// Converts the internal rule data structure to the response API schema
export const typeSpecificCamelToSnake = (params: TypeSpecificRuleParams): ResponseTypeSpecific => {
switch (params.type) {
Expand Down

0 comments on commit 9aac141

Please sign in to comment.