[Security Solution] Implement API client code generation for integrational tests (#179074)

## Summary

- Extended the code generation package to allow for bundling of OpenAPI
specifications before passing them to a template. Here's an example of
how the new `bundle` option can be used:
  ```ts
  await generate({
    title: 'API client for tests',
    rootDir: SECURITY_SOLUTION_ROOT,
    sourceGlob: './**/*.schema.yaml',
    templateName: 'api_client_supertest',
    skipLinting: true,
    bundle: {
outFile: join(REPO_ROOT,
'x-pack/test/api_integration/services/security_solution_api.gen.ts'),
    },
  })
  ```
- Added a new template
(`packages/kbn-openapi-generator/src/template_service/templates/api_client_supertest.handlebars`)
that allows to generate an API client to be used in integrational tests.
The template outputs a collection of all Security Solution APIs that is
later added to `FtrProviderContext` for easy access in test files.
- The generated client is located in
`x-pack/test/api_integration/services/security_solution_api.gen.ts`
-  It is now used in some detection engine API integration tests.
  Before:
  ```ts
  const { body } = await supertest
    .post(DETECTION_ENGINE_RULES_URL)
    .set('kbn-xsrf', 'true')
    .set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
    .send(rule)
    .expect(200);
  ```
  After:
  ```ts
  const securitySolutionApi = getService('securitySolutionApi');
const { body } = await securitySolutionApi.createRule({ body: rule
}).expect(200);
  ```
- All API methods of the generated client now have correct types defined
for body, query, and param arguments
This commit is contained in:
Dmitrii Shevchenko 2024-03-28 13:32:47 +01:00 committed by GitHub
parent a7c8ef421e
commit 4d497c79b1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
30 changed files with 1291 additions and 1424 deletions

View file

@ -23,14 +23,21 @@ import type { OpenApiDocument } from './parser/openapi_types';
import { initTemplateService, TemplateName } from './template_service/template_service';
export interface GeneratorConfig {
title?: string;
rootDir: string;
sourceGlob: string;
templateName: TemplateName;
skipLinting?: boolean;
bundle?: {
/**
* If provided, the OpenAPI specifications will be bundled and written to this file
*/
outFile: string;
};
}
export const generate = async (config: GeneratorConfig) => {
const { rootDir, sourceGlob, templateName, skipLinting } = config;
const { title = 'API schemas', rootDir, sourceGlob, templateName, skipLinting, bundle } = config;
if (!skipLinting) {
await lint({
@ -39,7 +46,7 @@ export const generate = async (config: GeneratorConfig) => {
});
}
console.log(chalk.bold(`Generating API route schemas`));
console.log(chalk.bold(`Generating ${config.title} `));
console.log(chalk.bold(`Working directory: ${chalk.underline(rootDir)}`));
console.log(`👀 Searching for source files`);
@ -47,40 +54,76 @@ export const generate = async (config: GeneratorConfig) => {
const schemaPaths = await globby([sourceFilesGlob]);
console.log(`🕵️‍♀️ Found ${schemaPaths.length} schemas, parsing`);
const parsedSources = await Promise.all(
let parsedSources = await Promise.all(
schemaPaths.map(async (sourcePath) => {
const parsedSchema = (await SwaggerParser.parse(sourcePath)) as OpenApiDocument;
return { sourcePath, parsedSchema };
return {
sourcePath,
generationContext: getGenerationContext(parsedSchema),
};
})
);
// If there are no operations or components to generate, skip this file
parsedSources = parsedSources.filter(
({ generationContext }) =>
generationContext.operations.length > 0 || generationContext.components !== undefined
);
console.log(`🧹 Cleaning up any previously generated artifacts`);
await removeGenArtifacts(rootDir);
if (bundle) {
await fs.rm(bundle.outFile, { force: true });
} else {
await removeGenArtifacts(rootDir);
}
console.log(`🪄 Generating new artifacts`);
const TemplateService = await initTemplateService();
await Promise.all(
parsedSources.map(async ({ sourcePath, parsedSchema }) => {
const generationContext = getGenerationContext(parsedSchema);
if (bundle) {
console.log(`📦 Bundling ${title}`);
const operations = parsedSources
.flatMap(({ generationContext, sourcePath }) =>
// Add the sourcePath to each operation so we can generate the correct import paths for bundled operations
generationContext.operations.map((op) => ({
...op,
sourcePath,
version: generationContext.info.version,
}))
)
// Sort the operations by operationId so the output is deterministic
.sort((a, b) => a.operationId.localeCompare(b.operationId));
// If there are no operations or components to generate, skip this file
const shouldGenerate =
generationContext.operations.length > 0 || generationContext.components !== undefined;
if (!shouldGenerate) {
return;
}
const result = TemplateService.compileTemplate(templateName, {
operations,
components: {},
info: {
title,
version: 'Bundle (no version)',
},
imports: {},
});
const result = TemplateService.compileTemplate(templateName, generationContext);
await fs.writeFile(bundle.outFile, result);
console.log(`📖 Wrote bundled artifact to ${chalk.bold(bundle.outFile)}`);
} else {
await Promise.all(
parsedSources.map(async ({ sourcePath, generationContext }) => {
const result = TemplateService.compileTemplate(templateName, generationContext);
// Write the generation result to disk
await fs.writeFile(getGeneratedFilePath(sourcePath), result);
})
);
// Write the generation result to disk
await fs.writeFile(getGeneratedFilePath(sourcePath), result);
})
);
}
// Format the output folder using prettier as the generator produces
// unformatted code and fix any eslint errors
console.log(`💅 Formatting output`);
const generatedArtifactsGlob = resolve(rootDir, './**/*.gen.ts');
await formatOutput(generatedArtifactsGlob);
await fixEslint(generatedArtifactsGlob);
if (bundle) {
await formatOutput(bundle.outFile);
await fixEslint(bundle.outFile);
} else {
const generatedArtifactsGlob = resolve(rootDir, './**/*.gen.ts');
await formatOutput(generatedArtifactsGlob);
await fixEslint(generatedArtifactsGlob);
}
};

View file

@ -50,4 +50,10 @@ export function registerHelpers(handlebarsInstance: typeof Handlebars) {
handlebarsInstance.registerHelper('startsWithSpecialChar', (val: string) => {
return /^[^a-zA-Z0-9]/.test(val);
});
handlebarsInstance.registerHelper(
'replace',
(val: string, searchValue: string, replaceValue: string) => {
return val.replace(searchValue, replaceValue);
}
);
}

View file

@ -0,0 +1,67 @@
/*
* 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 { ELASTIC_HTTP_VERSION_HEADER, X_ELASTIC_INTERNAL_ORIGIN_REQUEST } from '@kbn/core-http-common';
import { FtrProviderContext } from 'x-pack/test/api_integration/ftr_provider_context';
{{> disclaimer}}
{{#each operations}}
import {
{{operationId}}RequestQueryInput,
{{operationId}}RequestParamsInput,
{{operationId}}RequestBodyInput
} from '{{replace sourcePath 'schema.yaml' 'gen'}}';
{{/each}}
export function SecuritySolutionApiProvider({ getService }: FtrProviderContext) {
const supertest = getService('supertest');
return {
{{#each operations}}
{{#if description}}
/**
* {{{description}}}
*/
{{/if}}
{{camelCase operationId}}({{#if (or requestQuery requestParams requestBody)}}props: {{operationId}}Props{{/if}}) {
return supertest
.{{method}}({{#if requestParams}}replaceParams('{{path}}', props.params){{else}}'{{path}}'{{/if}})
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '{{version}}')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
{{~#if requestBody}}.send(props.body as object){{/if}}
{{~#if requestQuery}}.query(props.query){{/if}}
},
{{/each}}
}
}
{{#each operations}}
{{#if (or requestQuery requestParams requestBody)}}
export interface {{operationId}}Props {
{{~#if requestQuery}}query: {{operationId}}RequestQueryInput;{{/if}}
{{~#if requestParams}}params: {{operationId}}RequestParamsInput;{{/if}}
{{~#if requestBody}}body: {{operationId}}RequestBodyInput;{{/if}}
}
{{/if}}
{{/each}}
/**
* Replaces placeholders in a path string with provided param value
*
* @param path Path string with placeholders for params
* @param params Object with params to replace
* @returns Path string with params replaced
*/
function replaceParams(path: string, params: Record<string, string | number>): string {
let output = path;
Object.entries(params).forEach(([param, value]) => {
output = path.replace(`{${param}}`, `${value}`);
});
return output;
}

View file

@ -22,9 +22,7 @@ export type GetEndpointSuggestionsRequestParams = z.infer<
typeof GetEndpointSuggestionsRequestParams
>;
export const GetEndpointSuggestionsRequestParams = z.object({
query: z.object({
suggestion_type: z.literal('eventFilters').optional(),
}),
suggestion_type: z.literal('eventFilters'),
});
export type GetEndpointSuggestionsRequestParamsInput = z.input<
typeof GetEndpointSuggestionsRequestParams

View file

@ -24,16 +24,14 @@ paths:
filters: {}
fieldMeta: {}
parameters:
- name: query
- name: suggestion_type
in: path
required: true
schema:
type: object
properties:
suggestion_type:
type: string
enum:
- eventFilters
type: string
enum:
- eventFilters
responses:
'200':
description: OK

View file

@ -7,12 +7,28 @@
require('../../../../../src/setup_node_env');
const { generate } = require('@kbn/openapi-generator');
const { resolve } = require('path');
const { REPO_ROOT } = require('@kbn/repo-info');
const { resolve, join } = require('path');
const SECURITY_SOLUTION_ROOT = resolve(__dirname, '../..');
generate({
rootDir: SECURITY_SOLUTION_ROOT,
sourceGlob: './**/*.schema.yaml',
templateName: 'zod_operation_schema',
});
(async () => {
await generate({
title: 'API route schemas',
rootDir: SECURITY_SOLUTION_ROOT,
sourceGlob: './**/*.schema.yaml',
templateName: 'zod_operation_schema',
skipLinting: true,
});
await generate({
title: 'API client for tests',
rootDir: SECURITY_SOLUTION_ROOT,
sourceGlob: './**/*.schema.yaml',
templateName: 'api_client_supertest',
skipLinting: true,
bundle: {
outFile: join(REPO_ROOT, 'x-pack/test/api_integration/services/security_solution_api.gen.ts'),
},
});
})();

View file

@ -24,6 +24,7 @@ import { IngestPipelinesProvider } from './ingest_pipelines';
import { IndexManagementProvider } from './index_management';
import { DataViewApiProvider } from './data_view_api';
import { SloApiProvider } from './slo';
import { SecuritySolutionApiProvider } from './security_solution_api.gen';
export const services = {
...commonServices,
@ -43,4 +44,5 @@ export const services = {
ingestPipelines: IngestPipelinesProvider,
indexManagement: IndexManagementProvider,
slo: SloApiProvider,
securitySolutionApi: SecuritySolutionApiProvider,
};

View file

@ -0,0 +1,377 @@
/*
* 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 {
ELASTIC_HTTP_VERSION_HEADER,
X_ELASTIC_INTERNAL_ORIGIN_REQUEST,
} from '@kbn/core-http-common';
/*
* NOTICE: Do not edit this file manually.
* This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator.
*
* info:
* title: API client for tests
* version: Bundle (no version)
*/
import { BulkCreateRulesRequestBodyInput } from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/bulk_crud/bulk_create_rules/bulk_create_rules_route.gen';
import { BulkDeleteRulesRequestBodyInput } from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/bulk_crud/bulk_delete_rules/bulk_delete_rules_route.gen';
import { BulkPatchRulesRequestBodyInput } from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/bulk_crud/bulk_patch_rules/bulk_patch_rules_route.gen';
import { BulkUpdateRulesRequestBodyInput } from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/bulk_crud/bulk_update_rules/bulk_update_rules_route.gen';
import { CreateRuleRequestBodyInput } from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/crud/create_rule/create_rule_route.gen';
import { DeleteRuleRequestQueryInput } from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/crud/delete_rule/delete_rule_route.gen';
import {
ExportRulesRequestQueryInput,
ExportRulesRequestBodyInput,
} from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/export_rules/export_rules_route.gen';
import { FindRulesRequestQueryInput } from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/find_rules/find_rules_route.gen';
import { GetAgentPolicySummaryRequestQueryInput } from '@kbn/security-solution-plugin/common/api/endpoint/policy/policy.gen';
import {
GetEndpointSuggestionsRequestParamsInput,
GetEndpointSuggestionsRequestBodyInput,
} from '@kbn/security-solution-plugin/common/api/endpoint/suggestions/get_suggestions.gen';
import { GetPolicyResponseRequestQueryInput } from '@kbn/security-solution-plugin/common/api/endpoint/policy/policy.gen';
import {
GetRuleExecutionEventsRequestQueryInput,
GetRuleExecutionEventsRequestParamsInput,
} from '@kbn/security-solution-plugin/common/api/detection_engine/rule_monitoring/rule_execution_logs/get_rule_execution_events/get_rule_execution_events_route.gen';
import {
GetRuleExecutionResultsRequestQueryInput,
GetRuleExecutionResultsRequestParamsInput,
} from '@kbn/security-solution-plugin/common/api/detection_engine/rule_monitoring/rule_execution_logs/get_rule_execution_results/get_rule_execution_results_route.gen';
import { ImportRulesRequestQueryInput } from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/import_rules/import_rules_route.gen';
import { PatchRuleRequestBodyInput } from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/crud/patch_rule/patch_rule_route.gen';
import {
PerformBulkActionRequestQueryInput,
PerformBulkActionRequestBodyInput,
} from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/bulk_actions/bulk_actions_route.gen';
import { ReadRuleRequestQueryInput } from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/crud/read_rule/read_rule_route.gen';
import { SetAlertAssigneesRequestBodyInput } from '@kbn/security-solution-plugin/common/api/detection_engine/alert_assignees/set_alert_assignees_route.gen';
import { SuggestUserProfilesRequestQueryInput } from '@kbn/security-solution-plugin/common/api/detection_engine/users/suggest_user_profiles_route.gen';
import { UpdateRuleRequestBodyInput } from '@kbn/security-solution-plugin/common/api/detection_engine/rule_management/crud/update_rule/update_rule_route.gen';
import { FtrProviderContext } from '../ftr_provider_context';
export function SecuritySolutionApiProvider({ getService }: FtrProviderContext) {
const supertest = getService('supertest');
return {
/**
* Creates new detection rules in bulk.
*/
bulkCreateRules(props: BulkCreateRulesProps) {
return supertest
.post('/api/detection_engine/rules/_bulk_create')
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.send(props.body as object);
},
/**
* Deletes multiple rules.
*/
bulkDeleteRules(props: BulkDeleteRulesProps) {
return supertest
.delete('/api/detection_engine/rules/_bulk_delete')
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.send(props.body as object);
},
/**
* Updates multiple rules using the `PATCH` method.
*/
bulkPatchRules(props: BulkPatchRulesProps) {
return supertest
.patch('/api/detection_engine/rules/_bulk_update')
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.send(props.body as object);
},
/**
* Updates multiple rules using the `PUT` method.
*/
bulkUpdateRules(props: BulkUpdateRulesProps) {
return supertest
.put('/api/detection_engine/rules/_bulk_update')
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.send(props.body as object);
},
/**
* Create a single detection rule
*/
createRule(props: CreateRuleProps) {
return supertest
.post('/api/detection_engine/rules')
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.send(props.body as object);
},
/**
* Deletes a single rule using the `rule_id` or `id` field.
*/
deleteRule(props: DeleteRuleProps) {
return supertest
.delete('/api/detection_engine/rules')
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.query(props.query);
},
/**
* Exports rules to an `.ndjson` file. The following configuration items are also included in the `.ndjson` file - Actions, Exception lists. Prebuilt rules cannot be exported.
*/
exportRules(props: ExportRulesProps) {
return supertest
.post('/api/detection_engine/rules/_export')
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.send(props.body as object)
.query(props.query);
},
/**
* Finds rules that match the given query.
*/
findRules(props: FindRulesProps) {
return supertest
.get('/api/detection_engine/rules/_find')
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.query(props.query);
},
getAgentPolicySummary(props: GetAgentPolicySummaryProps) {
return supertest
.get('/api/endpoint/policy/summaries')
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.query(props.query);
},
getEndpointSuggestions(props: GetEndpointSuggestionsProps) {
return supertest
.post(replaceParams('/api/endpoint/suggestions/{suggestion_type}', props.params))
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.send(props.body as object);
},
getPolicyResponse(props: GetPolicyResponseProps) {
return supertest
.get('/api/endpoint/policy_response')
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.query(props.query);
},
getPrebuiltRulesAndTimelinesStatus() {
return supertest
.get('/api/detection_engine/rules/prepackaged/_status')
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana');
},
getRuleExecutionEvents(props: GetRuleExecutionEventsProps) {
return supertest
.put(
replaceParams('/internal/detection_engine/rules/{ruleId}/execution/events', props.params)
)
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '1')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.query(props.query);
},
getRuleExecutionResults(props: GetRuleExecutionResultsProps) {
return supertest
.put(
replaceParams('/internal/detection_engine/rules/{ruleId}/execution/results', props.params)
)
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '1')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.query(props.query);
},
/**
* Imports rules from an `.ndjson` file, including actions and exception lists.
*/
importRules(props: ImportRulesProps) {
return supertest
.post('/api/detection_engine/rules/_import')
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.query(props.query);
},
installPrebuiltRulesAndTimelines() {
return supertest
.put('/api/detection_engine/rules/prepackaged')
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana');
},
/**
* Patch a single rule
*/
patchRule(props: PatchRuleProps) {
return supertest
.patch('/api/detection_engine/rules')
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.send(props.body as object);
},
/**
* The bulk action is applied to all rules that match the filter or to the list of rules by their IDs.
*/
performBulkAction(props: PerformBulkActionProps) {
return supertest
.post('/api/detection_engine/rules/_bulk_action')
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.send(props.body as object)
.query(props.query);
},
/**
* Read a single rule
*/
readRule(props: ReadRuleProps) {
return supertest
.get('/api/detection_engine/rules')
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.query(props.query);
},
readTags() {
return supertest
.get('/api/detection_engine/tags')
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana');
},
/**
* Assigns users to alerts.
*/
setAlertAssignees(props: SetAlertAssigneesProps) {
return supertest
.post('/api/detection_engine/signals/assignees')
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.send(props.body as object);
},
/**
* Suggests user profiles.
*/
suggestUserProfiles(props: SuggestUserProfilesProps) {
return supertest
.post('/internal/detection_engine/users/_find')
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.query(props.query);
},
/**
* Update a single rule
*/
updateRule(props: UpdateRuleProps) {
return supertest
.put('/api/detection_engine/rules')
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
.send(props.body as object);
},
};
}
export interface BulkCreateRulesProps {
body: BulkCreateRulesRequestBodyInput;
}
export interface BulkDeleteRulesProps {
body: BulkDeleteRulesRequestBodyInput;
}
export interface BulkPatchRulesProps {
body: BulkPatchRulesRequestBodyInput;
}
export interface BulkUpdateRulesProps {
body: BulkUpdateRulesRequestBodyInput;
}
export interface CreateRuleProps {
body: CreateRuleRequestBodyInput;
}
export interface DeleteRuleProps {
query: DeleteRuleRequestQueryInput;
}
export interface ExportRulesProps {
query: ExportRulesRequestQueryInput;
body: ExportRulesRequestBodyInput;
}
export interface FindRulesProps {
query: FindRulesRequestQueryInput;
}
export interface GetAgentPolicySummaryProps {
query: GetAgentPolicySummaryRequestQueryInput;
}
export interface GetEndpointSuggestionsProps {
params: GetEndpointSuggestionsRequestParamsInput;
body: GetEndpointSuggestionsRequestBodyInput;
}
export interface GetPolicyResponseProps {
query: GetPolicyResponseRequestQueryInput;
}
export interface GetRuleExecutionEventsProps {
query: GetRuleExecutionEventsRequestQueryInput;
params: GetRuleExecutionEventsRequestParamsInput;
}
export interface GetRuleExecutionResultsProps {
query: GetRuleExecutionResultsRequestQueryInput;
params: GetRuleExecutionResultsRequestParamsInput;
}
export interface ImportRulesProps {
query: ImportRulesRequestQueryInput;
}
export interface PatchRuleProps {
body: PatchRuleRequestBodyInput;
}
export interface PerformBulkActionProps {
query: PerformBulkActionRequestQueryInput;
body: PerformBulkActionRequestBodyInput;
}
export interface ReadRuleProps {
query: ReadRuleRequestQueryInput;
}
export interface SetAlertAssigneesProps {
body: SetAlertAssigneesRequestBodyInput;
}
export interface SuggestUserProfilesProps {
query: SuggestUserProfilesRequestQueryInput;
}
export interface UpdateRuleProps {
body: UpdateRuleRequestBodyInput;
}
/**
* Replaces placeholders in a path string with provided param value
*
* @param path Path string with placeholders for params
* @param params Object with params to replace
* @returns Path string with params replaced
*/
function replaceParams(path: string, params: Record<string, string | number>): string {
let output = path;
Object.entries(params).forEach(([param, value]) => {
output = path.replace(`{${param}}`, `${value}`);
});
return output;
}

View file

@ -4,11 +4,6 @@
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/
import {
DETECTION_ENGINE_RULES_BULK_ACTION,
DETECTION_ENGINE_RULES_URL,
} from '@kbn/security-solution-plugin/common/constants';
import expect from 'expect';
import {
BulkActionTypeEnum,
@ -25,28 +20,10 @@ import { FtrProviderContext } from '../../../../../ftr_provider_context';
export default ({ getService }: FtrProviderContext): void => {
const supertest = getService('supertest');
const securitySolutionApi = getService('securitySolutionApi');
const log = getService('log');
const es = getService('es');
const postDryRunBulkAction = () =>
supertest
.post(DETECTION_ENGINE_RULES_BULK_ACTION)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.query({ dry_run: true });
const fetchRule = (ruleId: string) =>
supertest
.get(`${DETECTION_ENGINE_RULES_URL}?rule_id=${ruleId}`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31');
const findRules = () =>
supertest
.get(`${DETECTION_ENGINE_RULES_URL}/_find`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31');
describe('@ess @serverless @skipInQA perform_bulk_action dry_run', () => {
beforeEach(async () => {
await createAlertsIndex(supertest, log);
@ -60,8 +37,11 @@ export default ({ getService }: FtrProviderContext): void => {
it('should not support export action', async () => {
await createRule(supertest, log, getSimpleRule());
const { body } = await postDryRunBulkAction()
.send({ action: BulkActionTypeEnum.export })
const { body } = await securitySolutionApi
.performBulkAction({
query: { dry_run: true },
body: { action: BulkActionTypeEnum.export },
})
.expect(400);
expect(body).toEqual({
@ -75,8 +55,11 @@ export default ({ getService }: FtrProviderContext): void => {
const testRule = getSimpleRule(ruleId);
await createRule(supertest, log, testRule);
const { body } = await postDryRunBulkAction()
.send({ action: BulkActionTypeEnum.delete })
const { body } = await securitySolutionApi
.performBulkAction({
query: { dry_run: true },
body: { action: BulkActionTypeEnum.delete },
})
.expect(200);
expect(body.attributes.summary).toEqual({ failed: 0, skipped: 0, succeeded: 1, total: 1 });
@ -89,15 +72,18 @@ export default ({ getService }: FtrProviderContext): void => {
});
// Check that rule wasn't deleted
await fetchRule(ruleId).expect(200);
await securitySolutionApi.readRule({ query: { rule_id: ruleId } }).expect(200);
});
it('should handle enable action', async () => {
const ruleId = 'ruleId';
await createRule(supertest, log, getSimpleRule(ruleId));
const { body } = await postDryRunBulkAction()
.send({ action: BulkActionTypeEnum.enable })
const { body } = await securitySolutionApi
.performBulkAction({
query: { dry_run: true },
body: { action: BulkActionTypeEnum.enable },
})
.expect(200);
expect(body.attributes.summary).toEqual({ failed: 0, skipped: 0, succeeded: 1, total: 1 });
@ -110,7 +96,9 @@ export default ({ getService }: FtrProviderContext): void => {
});
// Check that the updates have not been persisted
const { body: ruleBody } = await fetchRule(ruleId).expect(200);
const { body: ruleBody } = await securitySolutionApi
.readRule({ query: { rule_id: ruleId } })
.expect(200);
expect(ruleBody.enabled).toBe(false);
});
@ -118,8 +106,11 @@ export default ({ getService }: FtrProviderContext): void => {
const ruleId = 'ruleId';
await createRule(supertest, log, getSimpleRule(ruleId, true));
const { body } = await postDryRunBulkAction()
.send({ action: BulkActionTypeEnum.disable })
const { body } = await securitySolutionApi
.performBulkAction({
query: { dry_run: true },
body: { action: BulkActionTypeEnum.disable },
})
.expect(200);
expect(body.attributes.summary).toEqual({ failed: 0, skipped: 0, succeeded: 1, total: 1 });
@ -132,7 +123,9 @@ export default ({ getService }: FtrProviderContext): void => {
});
// Check that the updates have not been persisted
const { body: ruleBody } = await fetchRule(ruleId).expect(200);
const { body: ruleBody } = await securitySolutionApi
.readRule({ query: { rule_id: ruleId } })
.expect(200);
expect(ruleBody.enabled).toBe(true);
});
@ -141,8 +134,11 @@ export default ({ getService }: FtrProviderContext): void => {
const ruleToDuplicate = getSimpleRule(ruleId);
await createRule(supertest, log, ruleToDuplicate);
const { body } = await postDryRunBulkAction()
.send({ action: BulkActionTypeEnum.disable })
const { body } = await securitySolutionApi
.performBulkAction({
query: { dry_run: true },
body: { action: BulkActionTypeEnum.disable },
})
.expect(200);
expect(body.attributes.summary).toEqual({ failed: 0, skipped: 0, succeeded: 1, total: 1 });
@ -155,7 +151,9 @@ export default ({ getService }: FtrProviderContext): void => {
});
// Check that the rule wasn't duplicated
const { body: rulesResponse } = await findRules().expect(200);
const { body: rulesResponse } = await securitySolutionApi
.findRules({ query: {} })
.expect(200);
expect(rulesResponse.total).toBe(1);
});
@ -166,15 +164,18 @@ export default ({ getService }: FtrProviderContext): void => {
const tags = ['tag1', 'tag2'];
await createRule(supertest, log, { ...getSimpleRule(ruleId), tags });
const { body } = await postDryRunBulkAction()
.send({
action: BulkActionTypeEnum.edit,
[BulkActionTypeEnum.edit]: [
{
type: BulkActionEditTypeEnum.set_tags,
value: ['reset-tag'],
},
],
const { body } = await securitySolutionApi
.performBulkAction({
query: { dry_run: true },
body: {
action: BulkActionTypeEnum.edit,
[BulkActionTypeEnum.edit]: [
{
type: BulkActionEditTypeEnum.set_tags,
value: ['reset-tag'],
},
],
},
})
.expect(200);
@ -188,29 +189,30 @@ export default ({ getService }: FtrProviderContext): void => {
});
// Check that the updates have not been persisted
const { body: ruleBody } = await fetchRule(ruleId).expect(200);
const { body: ruleBody } = await securitySolutionApi
.readRule({ query: { rule_id: ruleId } })
.expect(200);
expect(ruleBody.tags).toEqual(tags);
});
it('should validate immutable rule edit', async () => {
await installMockPrebuiltRules(supertest, es);
const { body: findBody } = await findRules()
.query({ per_page: 1, filter: 'alert.attributes.params.immutable: true' })
.send()
const { body: findBody } = await securitySolutionApi
.findRules({ query: { per_page: 1, filter: 'alert.attributes.params.immutable: true' } })
.expect(200);
const immutableRule = findBody.data[0];
const { body } = await postDryRunBulkAction()
.send({
ids: [immutableRule.id],
action: BulkActionTypeEnum.edit,
[BulkActionTypeEnum.edit]: [
{
type: BulkActionEditTypeEnum.set_tags,
value: ['reset-tag'],
},
],
const { body } = await securitySolutionApi
.performBulkAction({
query: { dry_run: true },
body: {
ids: [immutableRule.id],
action: BulkActionTypeEnum.edit,
[BulkActionTypeEnum.edit]: [
{ type: BulkActionEditTypeEnum.set_tags, value: ['reset-tag'] },
],
},
})
.expect(500);
@ -247,16 +249,14 @@ export default ({ getService }: FtrProviderContext): void => {
it(`should return error if ${editAction} action is applied to machine learning rule`, async () => {
const mlRule = await createRule(supertest, log, getSimpleMlRule());
const { body } = await postDryRunBulkAction()
.send({
ids: [mlRule.id],
action: BulkActionTypeEnum.edit,
[BulkActionTypeEnum.edit]: [
{
type: editAction,
value: [],
},
],
const { body } = await securitySolutionApi
.performBulkAction({
query: { dry_run: true },
body: {
ids: [mlRule.id],
action: BulkActionTypeEnum.edit,
[BulkActionTypeEnum.edit]: [{ type: editAction, value: [] }],
},
})
.expect(500);

View file

@ -6,11 +6,8 @@
*/
import expect from '@kbn/expect';
import { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common';
import { RuleCreateProps } from '@kbn/security-solution-plugin/common/api/detection_engine';
import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants';
import {
getSimpleRule,
getSimpleRuleOutputWithoutRuleId,
@ -31,6 +28,7 @@ import { EsArchivePathBuilder } from '../../../../../es_archive_path_builder';
export default ({ getService }: FtrProviderContext) => {
const esArchiver = getService('esArchiver');
const supertest = getService('supertest');
const securitySolutionApi = getService('securitySolutionApi');
const log = getService('log');
const es = getService('es');
// TODO: add a new service for loading archiver files similar to "getService('es')"
@ -60,11 +58,8 @@ export default ({ getService }: FtrProviderContext) => {
});
it('should create a single rule with a rule_id', async () => {
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.send(getSimpleRule())
const { body } = await securitySolutionApi
.createRule({ body: getSimpleRule() })
.expect(200);
const bodyToCompare = removeServerGeneratedProperties(body);
@ -85,12 +80,7 @@ export default ({ getService }: FtrProviderContext) => {
query: 'user.name: root or user.name: admin',
};
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.send(rule)
.expect(200);
const { body } = await securitySolutionApi.createRule({ body: rule }).expect(200);
const bodyToCompare = removeServerGeneratedProperties(body);
const expectedRule = updateUsername(
@ -134,11 +124,8 @@ export default ({ getService }: FtrProviderContext) => {
});
it('should create a single rule without a rule_id', async () => {
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.send(getSimpleRuleWithoutRuleId())
const { body } = await securitySolutionApi
.createRule({ body: getSimpleRuleWithoutRuleId() })
.expect(200);
const bodyToCompare = removeServerGeneratedPropertiesIncludingRuleId(body);
@ -151,18 +138,10 @@ export default ({ getService }: FtrProviderContext) => {
});
it('should cause a 409 conflict if we attempt to create the same rule_id twice', async () => {
await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.send(getSimpleRule())
.expect(200);
await securitySolutionApi.createRule({ body: getSimpleRule() }).expect(200);
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.send(getSimpleRule())
const { body } = await securitySolutionApi
.createRule({ body: getSimpleRule() })
.expect(409);
expect(body).to.eql({

View file

@ -7,7 +7,6 @@
import expect from '@kbn/expect';
import { DETECTION_ENGINE_RULES_BULK_CREATE } from '@kbn/security-solution-plugin/common/constants';
import { EsArchivePathBuilder } from '../../../../../es_archive_path_builder';
import { FtrProviderContext } from '../../../../../ftr_provider_context';
import {
@ -28,6 +27,7 @@ import {
export default ({ getService }: FtrProviderContext): void => {
const esArchiver = getService('esArchiver');
const supertest = getService('supertest');
const securitySolutionApi = getService('securitySolutionApi');
const log = getService('log');
const es = getService('es');
// TODO: add a new service for loading archiver files similar to "getService('es')"
@ -57,11 +57,8 @@ export default ({ getService }: FtrProviderContext): void => {
});
it('should create a single rule with a rule_id', async () => {
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_BULK_CREATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([getSimpleRule()])
const { body } = await securitySolutionApi
.bulkCreateRules({ body: [getSimpleRule()] })
.expect(200);
const bodyToCompare = removeServerGeneratedProperties(body[0]);
@ -71,11 +68,8 @@ export default ({ getService }: FtrProviderContext): void => {
});
it('should create a single rule without a rule_id', async () => {
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_BULK_CREATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([getSimpleRuleWithoutRuleId()])
const { body } = await securitySolutionApi
.bulkCreateRules({ body: [getSimpleRuleWithoutRuleId()] })
.expect(200);
const bodyToCompare = removeServerGeneratedPropertiesIncludingRuleId(body[0]);
@ -88,11 +82,8 @@ export default ({ getService }: FtrProviderContext): void => {
});
it('should return a 200 ok but have a 409 conflict if we attempt to create the same rule_id twice', async () => {
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_BULK_CREATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([getSimpleRule(), getSimpleRule()])
const { body } = await securitySolutionApi
.bulkCreateRules({ body: [getSimpleRule(), getSimpleRule()] })
.expect(200);
expect(body).to.eql([
@ -107,18 +98,10 @@ export default ({ getService }: FtrProviderContext): void => {
});
it('should return a 200 ok but have a 409 conflict if we attempt to create the same rule_id that already exists', async () => {
await supertest
.post(DETECTION_ENGINE_RULES_BULK_CREATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([getSimpleRule()])
.expect(200);
await securitySolutionApi.bulkCreateRules({ body: [getSimpleRule()] }).expect(200);
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_BULK_CREATE)
.set('kbn-xsrf', 'foo')
.set('elastic-api-version', '2023-10-31')
.send([getSimpleRule()])
const { body } = await securitySolutionApi
.bulkCreateRules({ body: [getSimpleRule()] })
.expect(200);
expect(body).to.eql([

View file

@ -44,6 +44,7 @@ import {
export default ({ getService }: FtrProviderContext) => {
const supertest = getService('supertest');
const securitySolutionApi = getService('securitySolutionApi');
const supertestWithoutAuth = getService('supertestWithoutAuth');
const log = getService('log');
const es = getService('es');
@ -74,11 +75,8 @@ export default ({ getService }: FtrProviderContext) => {
describe('elastic admin', () => {
it('creates a custom query rule', async () => {
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(getCustomQueryRuleParams())
const { body } = await securitySolutionApi
.createRule({ body: getCustomQueryRuleParams() })
.expect(200);
expect(body).toEqual(
@ -97,11 +95,8 @@ export default ({ getService }: FtrProviderContext) => {
saved_id: 'my-saved-query-id',
});
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(savedQueryRuleParams)
const { body } = await securitySolutionApi
.createRule({ body: savedQueryRuleParams })
.expect(200);
expect(body).toEqual(
@ -135,11 +130,8 @@ export default ({ getService }: FtrProviderContext) => {
it('expects rule runs successfully', async () => {
const {
body: { id },
} = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(getCustomQueryRuleParams({ enabled: true }))
} = await securitySolutionApi
.createRule({ body: getCustomQueryRuleParams({ enabled: true }) })
.expect(200);
await waitForRuleSuccess({ supertest, log, id });
@ -152,16 +144,13 @@ export default ({ getService }: FtrProviderContext) => {
it('expects rule partial failure due to index pattern matching nothing', async () => {
const {
body: { id },
} = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(
getCustomQueryRuleParams({
} = await securitySolutionApi
.createRule({
body: getCustomQueryRuleParams({
index: ['does-not-exist-*'],
enabled: true,
})
)
}),
})
.expect(200);
await waitForRulePartialFailure({
@ -181,16 +170,13 @@ export default ({ getService }: FtrProviderContext) => {
it('expects rule runs successfully with only one index pattern matching existing index', async () => {
const {
body: { id },
} = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(
getCustomQueryRuleParams({
} = await securitySolutionApi
.createRule({
body: getCustomQueryRuleParams({
index: ['does-not-exist-*', 'logs-test'],
enabled: true,
})
)
}),
})
.expect(200);
await waitForRuleSuccess({ supertest, log, id });
@ -205,12 +191,7 @@ export default ({ getService }: FtrProviderContext) => {
index: undefined,
});
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(ruleParams)
.expect(200);
const { body } = await securitySolutionApi.createRule({ body: ruleParams }).expect(200);
expect(body.index).toBeUndefined();
expect(body).toEqual(expect.objectContaining(omit(ruleParams, 'index')));
@ -221,12 +202,7 @@ export default ({ getService }: FtrProviderContext) => {
rule_id: undefined,
});
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(ruleParams)
.expect(200);
const { body } = await securitySolutionApi.createRule({ body: ruleParams }).expect(200);
expect(body).toEqual(
expect.objectContaining({ ...ruleParams, rule_id: expect.any(String) })
@ -234,11 +210,8 @@ export default ({ getService }: FtrProviderContext) => {
});
it('creates a ML rule with legacy machine_learning_job_id', async () => {
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(getMLRuleParams({ machine_learning_job_id: 'some_job_id' }))
const { body } = await securitySolutionApi
.createRule({ body: getMLRuleParams({ machine_learning_job_id: 'some_job_id' }) })
.expect(200);
expect(body).toEqual(
@ -249,29 +222,18 @@ export default ({ getService }: FtrProviderContext) => {
it('creates a ML rule', async () => {
const ruleParams = getMLRuleParams({ machine_learning_job_id: ['some_job_id'] });
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(ruleParams)
.expect(200);
const { body } = await securitySolutionApi.createRule({ body: ruleParams }).expect(200);
expect(body).toEqual(expect.objectContaining(ruleParams));
});
it('causes a 409 conflict if the same rule_id is used twice', async () => {
await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(getCustomQueryRuleParams({ rule_id: 'rule-1' }))
await securitySolutionApi
.createRule({ body: getCustomQueryRuleParams({ rule_id: 'rule-1' }) })
.expect(200);
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(getCustomQueryRuleParams({ rule_id: 'rule-1' }))
const { body } = await securitySolutionApi
.createRule({ body: getCustomQueryRuleParams({ rule_id: 'rule-1' }) })
.expect(409);
expect(body).toEqual({
@ -283,12 +245,9 @@ export default ({ getService }: FtrProviderContext) => {
describe('exception', () => {
it('does NOT create a rule if trying to add more than one default rule exception list', async () => {
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(
getCustomQueryRuleParams({
const { body } = await securitySolutionApi
.createRule({
body: getCustomQueryRuleParams({
exceptions_list: [
{
id: '2',
@ -303,8 +262,8 @@ export default ({ getService }: FtrProviderContext) => {
type: ExceptionListTypeEnum.RULE_DEFAULT,
},
],
})
)
}),
})
.expect(500);
expect(body).toEqual({
@ -314,12 +273,9 @@ export default ({ getService }: FtrProviderContext) => {
});
it('does NOT create a rule when there is an attempt to share non sharable exception ("rule_default" type)', async () => {
const { body: ruleWithException } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(
getCustomQueryRuleParams({
const { body: ruleWithException } = await securitySolutionApi
.createRule({
body: getCustomQueryRuleParams({
rule_id: 'rule-1',
exceptions_list: [
{
@ -329,16 +285,13 @@ export default ({ getService }: FtrProviderContext) => {
type: ExceptionListTypeEnum.RULE_DEFAULT,
},
],
})
)
}),
})
.expect(200);
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(
getCustomQueryRuleParams({
const { body } = await securitySolutionApi
.createRule({
body: getCustomQueryRuleParams({
rule_id: 'rule-2',
exceptions_list: [
{
@ -348,8 +301,8 @@ export default ({ getService }: FtrProviderContext) => {
type: ExceptionListTypeEnum.RULE_DEFAULT,
},
],
})
)
}),
})
.expect(409);
expect(body).toEqual({
@ -359,12 +312,9 @@ export default ({ getService }: FtrProviderContext) => {
});
it('creates a rule when shared exception type is used ("detection" type)', async () => {
await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(
getCustomQueryRuleParams({
await securitySolutionApi
.createRule({
body: getCustomQueryRuleParams({
rule_id: 'rule-1',
exceptions_list: [
{
@ -374,16 +324,13 @@ export default ({ getService }: FtrProviderContext) => {
type: ExceptionListTypeEnum.DETECTION,
},
],
})
)
}),
})
.expect(200);
await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(
getCustomQueryRuleParams({
await securitySolutionApi
.createRule({
body: getCustomQueryRuleParams({
rule_id: 'rule-2',
exceptions_list: [
{
@ -393,8 +340,8 @@ export default ({ getService }: FtrProviderContext) => {
type: ExceptionListTypeEnum.DETECTION,
},
],
})
)
}),
})
.expect(200);
});
});
@ -424,11 +371,11 @@ export default ({ getService }: FtrProviderContext) => {
describe('threshold validation', () => {
it('returns HTTP 400 error when NO threshold field is provided', async () => {
const ruleParams = getThresholdRuleParams();
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(omit(ruleParams, 'threshold'))
const { body } = await securitySolutionApi
.createRule({
// @ts-expect-error we are testing the invalid payload
body: omit(ruleParams, 'threshold'),
})
.expect(400);
expect(body).toEqual({
@ -439,18 +386,15 @@ export default ({ getService }: FtrProviderContext) => {
});
it('returns HTTP 400 error when there are more than 3 threshold fields provided', async () => {
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(
getThresholdRuleParams({
const { body } = await securitySolutionApi
.createRule({
body: getThresholdRuleParams({
threshold: {
field: ['field-1', 'field-2', 'field-3', 'field-4'],
value: 1,
},
})
)
}),
})
.expect(400);
expect(body).toEqual({
@ -460,18 +404,15 @@ export default ({ getService }: FtrProviderContext) => {
});
it('returns HTTP 400 error when threshold value is less than 1', async () => {
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(
getThresholdRuleParams({
const { body } = await securitySolutionApi
.createRule({
body: getThresholdRuleParams({
threshold: {
field: ['field-1'],
value: 0,
},
})
)
}),
})
.expect(400);
expect(body).toEqual({
@ -482,24 +423,21 @@ export default ({ getService }: FtrProviderContext) => {
});
it('returns HTTP 400 error when cardinality is also an agg field', async () => {
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(
getThresholdRuleParams({
const { body } = await securitySolutionApi
.createRule({
body: getThresholdRuleParams({
threshold: {
field: ['process.name'],
field: ['field-1'],
value: 1,
cardinality: [
{
field: 'process.name',
field: 'field-1',
value: 5,
},
],
},
})
)
}),
})
.expect(400);
expect(body).toEqual({
@ -511,17 +449,14 @@ export default ({ getService }: FtrProviderContext) => {
describe('investigation_fields', () => {
it('creates a rule with investigation_fields', async () => {
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(
getCustomQueryRuleParams({
const { body } = await securitySolutionApi
.createRule({
body: getCustomQueryRuleParams({
investigation_fields: {
field_names: ['host.name'],
},
})
)
}),
})
.expect(200);
expect(body.investigation_fields).toEqual({
@ -530,14 +465,13 @@ export default ({ getService }: FtrProviderContext) => {
});
it('does NOT create a rule with legacy investigation_fields', async () => {
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send({
...getCustomQueryRuleParams(),
// type system doesn't allow to use the legacy format as params for getCustomQueryRuleParams()
investigation_fields: ['host.name'],
const { body } = await securitySolutionApi
.createRule({
body: {
...getCustomQueryRuleParams(),
// @ts-expect-error type system doesn't allow to use the legacy format as params for getCustomQueryRuleParams()
investigation_fields: ['host.name'],
},
})
.expect(400);
@ -576,17 +510,14 @@ export default ({ getService }: FtrProviderContext) => {
it('expects partial failure for a rule with timestamp override and index pattern matching no indices', async () => {
const {
body: { id },
} = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(
getCustomQueryRuleParams({
} = await securitySolutionApi
.createRule({
body: getCustomQueryRuleParams({
index: ['myfakeindex-1'],
timestamp_override: 'event.ingested',
enabled: true,
})
)
}),
})
.expect(200);
await waitForAlertToComplete(supertest, log, id);
@ -607,17 +538,14 @@ export default ({ getService }: FtrProviderContext) => {
it('generates two signals with a "partial failure" status', async () => {
const {
body: { id },
} = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(
getCustomQueryRuleParams({
} = await securitySolutionApi
.createRule({
body: getCustomQueryRuleParams({
index: ['myfa*'],
timestamp_override: 'event.ingested',
enabled: true,
})
)
}),
})
.expect(200);
await waitForRulePartialFailure({
@ -643,16 +571,13 @@ export default ({ getService }: FtrProviderContext) => {
[undefined, NOTIFICATION_THROTTLE_NO_ACTIONS, NOTIFICATION_THROTTLE_RULE].forEach(
(throttle) => {
it(`sets each action's frequency attribute to default value when 'throttle' is ${throttle}`, async () => {
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(
getCustomQueryRuleParams({
const { body } = await securitySolutionApi
.createRule({
body: getCustomQueryRuleParams({
throttle,
actions: await getActionsWithoutFrequencies(supertest),
})
)
}),
})
.expect(200);
for (const action of body.actions) {
@ -664,18 +589,15 @@ export default ({ getService }: FtrProviderContext) => {
['300s', '5m', '3h', '4d'].forEach((throttle) => {
it(`transforms correctly 'throttle = ${throttle}' and sets it as a frequency of each action`, async () => {
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(
getCustomQueryRuleParams({
const { body } = await securitySolutionApi
.createRule({
body: getCustomQueryRuleParams({
// Action throttle cannot be shorter than the schedule interval
interval: '5m',
throttle,
actions: await getActionsWithoutFrequencies(supertest),
})
)
}),
})
.expect(200);
for (const action of body.actions) {
@ -701,16 +623,13 @@ export default ({ getService }: FtrProviderContext) => {
].forEach((throttle) => {
it(`does NOT change action frequency when 'throttle' is '${throttle}'`, async () => {
const actionsWithFrequencies = await getActionsWithFrequencies(supertest);
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(
getCustomQueryRuleParams({
const { body } = await securitySolutionApi
.createRule({
body: getCustomQueryRuleParams({
throttle,
actions: actionsWithFrequencies,
})
)
}),
})
.expect(200);
expect(body.actions).toEqual(
@ -725,16 +644,13 @@ export default ({ getService }: FtrProviderContext) => {
(throttle) => {
it(`overrides each action's frequency attribute to default value when 'throttle' is ${throttle}`, async () => {
const someActionsWithFrequencies = await getSomeActionsWithFrequencies(supertest);
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(
getCustomQueryRuleParams({
const { body } = await securitySolutionApi
.createRule({
body: getCustomQueryRuleParams({
throttle,
actions: someActionsWithFrequencies,
})
)
}),
})
.expect(200);
expect(body.actions).toEqual(
@ -749,18 +665,15 @@ export default ({ getService }: FtrProviderContext) => {
['430s', '7m', '1h', '8d'].forEach((throttle) => {
it(`transforms correctly 'throttle = ${throttle}' and overrides frequency attribute of each action`, async () => {
const someActionsWithFrequencies = await getSomeActionsWithFrequencies(supertest);
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(
getCustomQueryRuleParams({
const { body } = await securitySolutionApi
.createRule({
body: getCustomQueryRuleParams({
// Action throttle cannot be shorter than the schedule interval
interval: '5m',
throttle,
actions: someActionsWithFrequencies,
})
)
}),
})
.expect(200);
expect(body.actions).toEqual(

View file

@ -7,7 +7,6 @@
import expect from '@kbn/expect';
import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants';
import { FtrProviderContext } from '../../../../../ftr_provider_context';
import {
getSimpleRule,
@ -27,6 +26,7 @@ import {
export default ({ getService }: FtrProviderContext): void => {
const supertest = getService('supertest');
const securitySolutionApi = getService('securitySolutionApi');
const log = getService('log');
const es = getService('es');
const config = getService('config');
@ -47,10 +47,8 @@ export default ({ getService }: FtrProviderContext): void => {
await createRule(supertest, log, getSimpleRule('rule-1'));
// delete the rule by its rule_id
const { body } = await supertest
.delete(`${DETECTION_ENGINE_RULES_URL}?rule_id=rule-1`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
const { body } = await securitySolutionApi
.deleteRule({ query: { rule_id: 'rule-1' } })
.expect(200);
const bodyToCompare = removeServerGeneratedProperties(body);
@ -63,10 +61,8 @@ export default ({ getService }: FtrProviderContext): void => {
const bodyWithCreatedRule = await createRule(supertest, log, getSimpleRuleWithoutRuleId());
// delete that rule by its auto-generated rule_id
const { body } = await supertest
.delete(`${DETECTION_ENGINE_RULES_URL}?rule_id=${bodyWithCreatedRule.rule_id}`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
const { body } = await securitySolutionApi
.deleteRule({ query: { rule_id: bodyWithCreatedRule.rule_id } })
.expect(200);
const bodyToCompare = removeServerGeneratedPropertiesIncludingRuleId(body);
@ -82,10 +78,8 @@ export default ({ getService }: FtrProviderContext): void => {
const bodyWithCreatedRule = await createRule(supertest, log, getSimpleRule());
// delete that rule by its auto-generated id
const { body } = await supertest
.delete(`${DETECTION_ENGINE_RULES_URL}?id=${bodyWithCreatedRule.id}`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
const { body } = await securitySolutionApi
.deleteRule({ query: { id: bodyWithCreatedRule.id } })
.expect(200);
const bodyToCompare = removeServerGeneratedPropertiesIncludingRuleId(body);
@ -98,10 +92,8 @@ export default ({ getService }: FtrProviderContext): void => {
});
it('should return an error if the id does not exist when trying to delete it', async () => {
const { body } = await supertest
.delete(`${DETECTION_ENGINE_RULES_URL}?id=c1e1b359-7ac1-4e96-bc81-c683c092436f`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
const { body } = await securitySolutionApi
.deleteRule({ query: { id: 'c1e1b359-7ac1-4e96-bc81-c683c092436f' } })
.expect(404);
expect(body).to.eql({
@ -111,10 +103,8 @@ export default ({ getService }: FtrProviderContext): void => {
});
it('should return an error if the rule_id does not exist when trying to delete it', async () => {
const { body } = await supertest
.delete(`${DETECTION_ENGINE_RULES_URL}?rule_id=fake_id`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
const { body } = await securitySolutionApi
.deleteRule({ query: { rule_id: 'fake_id' } })
.expect(404);
expect(body).to.eql({

View file

@ -27,6 +27,7 @@ import {
export default ({ getService }: FtrProviderContext): void => {
const supertest = getService('supertest');
const securitySolutionApi = getService('securitySolutionApi');
const log = getService('log');
const es = getService('es');
const config = getService('config');
@ -47,11 +48,8 @@ export default ({ getService }: FtrProviderContext): void => {
await createRule(supertest, log, getSimpleRule());
// delete the rule in bulk
const { body } = await supertest
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ rule_id: 'rule-1' }])
const { body } = await securitySolutionApi
.bulkDeleteRules({ body: [{ rule_id: 'rule-1' }] })
.expect(200);
const bodyToCompare = removeServerGeneratedProperties(body[0]);
@ -64,11 +62,8 @@ export default ({ getService }: FtrProviderContext): void => {
const bodyWithCreatedRule = await createRule(supertest, log, getSimpleRuleWithoutRuleId());
// delete that rule by its rule_id
const { body } = await supertest
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ rule_id: bodyWithCreatedRule.rule_id }])
const { body } = await securitySolutionApi
.bulkDeleteRules({ body: [{ rule_id: bodyWithCreatedRule.rule_id }] })
.expect(200);
const bodyToCompare = removeServerGeneratedPropertiesIncludingRuleId(body[0]);
@ -84,11 +79,8 @@ export default ({ getService }: FtrProviderContext): void => {
const bodyWithCreatedRule = await createRule(supertest, log, getSimpleRule());
// delete that rule by its id
const { body } = await supertest
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ id: bodyWithCreatedRule.id }])
const { body } = await securitySolutionApi
.bulkDeleteRules({ body: [{ id: bodyWithCreatedRule.id }] })
.expect(200);
const bodyToCompare = removeServerGeneratedPropertiesIncludingRuleId(body[0]);
@ -101,11 +93,8 @@ export default ({ getService }: FtrProviderContext): void => {
});
it('should return an error if the ruled_id does not exist when trying to delete a rule_id', async () => {
const { body } = await supertest
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ rule_id: 'fake_id' }])
const { body } = await securitySolutionApi
.bulkDeleteRules({ body: [{ rule_id: 'fake_id' }] })
.expect(200);
expect(body).to.eql([
@ -120,11 +109,8 @@ export default ({ getService }: FtrProviderContext): void => {
});
it('should return an error if the id does not exist when trying to delete an id', async () => {
const { body } = await supertest
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ id: 'c4e80a0d-e20f-4efc-84c1-08112da5a612' }])
const { body } = await securitySolutionApi
.bulkDeleteRules({ body: [{ id: 'c4e80a0d-e20f-4efc-84c1-08112da5a612' }] })
.expect(200);
expect(body).to.eql([
@ -141,11 +127,10 @@ export default ({ getService }: FtrProviderContext): void => {
it('should delete a single rule using an auto generated rule_id but give an error if the second rule does not exist', async () => {
const bodyWithCreatedRule = await createRule(supertest, log, getSimpleRuleWithoutRuleId());
const { body } = await supertest
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ id: bodyWithCreatedRule.id }, { id: 'c4e80a0d-e20f-4efc-84c1-08112da5a612' }])
const { body } = await securitySolutionApi
.bulkDeleteRules({
body: [{ id: bodyWithCreatedRule.id }, { id: 'c4e80a0d-e20f-4efc-84c1-08112da5a612' }],
})
.expect(200);
const bodyToCompare = removeServerGeneratedPropertiesIncludingRuleId(body[0]);

View file

@ -6,7 +6,6 @@
*/
import expect from '@kbn/expect';
import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants';
import {
getSimpleRule,
getSimpleRuleOutput,
@ -27,6 +26,7 @@ import { FtrProviderContext } from '../../../../../ftr_provider_context';
export default ({ getService }: FtrProviderContext): void => {
const supertest = getService('supertest');
const securitySolutionApi = getService('securitySolutionApi');
const log = getService('log');
const es = getService('es');
// TODO: add a new service for pulling kibana username, similar to getService('es')
@ -48,10 +48,8 @@ export default ({ getService }: FtrProviderContext): void => {
await createRule(supertest, log, getSimpleRule('rule-1'));
// delete the rule by its rule_id
const { body } = await supertest
.delete(`${DETECTION_ENGINE_RULES_URL}?rule_id=rule-1`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
const { body } = await securitySolutionApi
.deleteRule({ query: { rule_id: 'rule-1' } })
.expect(200);
const bodyToCompare = removeServerGeneratedProperties(body);
@ -64,10 +62,8 @@ export default ({ getService }: FtrProviderContext): void => {
const bodyWithCreatedRule = await createRule(supertest, log, getSimpleRuleWithoutRuleId());
// delete that rule by its auto-generated rule_id
const { body } = await supertest
.delete(`${DETECTION_ENGINE_RULES_URL}?rule_id=${bodyWithCreatedRule.rule_id}`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
const { body } = await securitySolutionApi
.deleteRule({ query: { rule_id: bodyWithCreatedRule.rule_id } })
.expect(200);
const bodyToCompare = removeServerGeneratedPropertiesIncludingRuleId(body);
@ -83,10 +79,8 @@ export default ({ getService }: FtrProviderContext): void => {
const bodyWithCreatedRule = await createRule(supertest, log, getSimpleRule());
// delete that rule by its auto-generated id
const { body } = await supertest
.delete(`${DETECTION_ENGINE_RULES_URL}?id=${bodyWithCreatedRule.id}`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
const { body } = await securitySolutionApi
.deleteRule({ query: { id: bodyWithCreatedRule.id } })
.expect(200);
const bodyToCompare = removeServerGeneratedPropertiesIncludingRuleId(body);
@ -99,10 +93,8 @@ export default ({ getService }: FtrProviderContext): void => {
});
it('should return an error if the id does not exist when trying to delete it', async () => {
const { body } = await supertest
.delete(`${DETECTION_ENGINE_RULES_URL}?id=c1e1b359-7ac1-4e96-bc81-c683c092436f`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
const { body } = await securitySolutionApi
.deleteRule({ query: { id: 'c1e1b359-7ac1-4e96-bc81-c683c092436f' } })
.expect(404);
expect(body).to.eql({
@ -112,10 +104,8 @@ export default ({ getService }: FtrProviderContext): void => {
});
it('should return an error if the rule_id does not exist when trying to delete it', async () => {
const { body } = await supertest
.delete(`${DETECTION_ENGINE_RULES_URL}?rule_id=fake_id`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
const { body } = await securitySolutionApi
.deleteRule({ query: { rule_id: 'fake_id' } })
.expect(404);
expect(body).to.eql({

View file

@ -32,6 +32,7 @@ import { FtrProviderContext } from '../../../../../ftr_provider_context';
export default ({ getService }: FtrProviderContext): void => {
const supertest = getService('supertest');
const securitySolutionApi = getService('securitySolutionApi');
const log = getService('log');
const es = getService('es');
// TODO: add a new service for pulling kibana username, similar to getService('es')
@ -44,11 +45,8 @@ export default ({ getService }: FtrProviderContext): void => {
it('should return a warning header', async () => {
await createRule(supertest, log, getSimpleRule());
const { header } = await supertest
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ rule_id: 'rule-1' }])
const { header } = await securitySolutionApi
.bulkDeleteRules({ body: [{ rule_id: 'rule-1' }] })
.expect(200);
expect(header.warning).to.be(
@ -71,11 +69,8 @@ export default ({ getService }: FtrProviderContext): void => {
await createRule(supertest, log, getSimpleRule());
// delete the rule in bulk
const { body } = await supertest
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ rule_id: 'rule-1' }])
const { body } = await securitySolutionApi
.bulkDeleteRules({ body: [{ rule_id: 'rule-1' }] })
.expect(200);
const bodyToCompare = removeServerGeneratedProperties(body[0]);
@ -88,11 +83,8 @@ export default ({ getService }: FtrProviderContext): void => {
const bodyWithCreatedRule = await createRule(supertest, log, getSimpleRuleWithoutRuleId());
// delete that rule by its rule_id
const { body } = await supertest
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ rule_id: bodyWithCreatedRule.rule_id }])
const { body } = await securitySolutionApi
.bulkDeleteRules({ body: [{ rule_id: bodyWithCreatedRule.rule_id }] })
.expect(200);
const bodyToCompare = removeServerGeneratedPropertiesIncludingRuleId(body[0]);
@ -108,11 +100,8 @@ export default ({ getService }: FtrProviderContext): void => {
const bodyWithCreatedRule = await createRule(supertest, log, getSimpleRule());
// delete that rule by its id
const { body } = await supertest
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ id: bodyWithCreatedRule.id }])
const { body } = await securitySolutionApi
.bulkDeleteRules({ body: [{ id: bodyWithCreatedRule.id }] })
.expect(200);
const bodyToCompare = removeServerGeneratedPropertiesIncludingRuleId(body[0]);
@ -125,11 +114,8 @@ export default ({ getService }: FtrProviderContext): void => {
});
it('should return an error if the ruled_id does not exist when trying to delete a rule_id', async () => {
const { body } = await supertest
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ rule_id: 'fake_id' }])
const { body } = await securitySolutionApi
.bulkDeleteRules({ body: [{ rule_id: 'fake_id' }] })
.expect(200);
expect(body).to.eql([
@ -144,11 +130,8 @@ export default ({ getService }: FtrProviderContext): void => {
});
it('should return an error if the id does not exist when trying to delete an id', async () => {
const { body } = await supertest
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ id: 'c4e80a0d-e20f-4efc-84c1-08112da5a612' }])
const { body } = await securitySolutionApi
.bulkDeleteRules({ body: [{ id: 'c4e80a0d-e20f-4efc-84c1-08112da5a612' }] })
.expect(200);
expect(body).to.eql([
@ -165,11 +148,10 @@ export default ({ getService }: FtrProviderContext): void => {
it('should delete a single rule using an auto generated rule_id but give an error if the second rule does not exist', async () => {
const bodyWithCreatedRule = await createRule(supertest, log, getSimpleRuleWithoutRuleId());
const { body } = await supertest
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ id: bodyWithCreatedRule.id }, { id: 'c4e80a0d-e20f-4efc-84c1-08112da5a612' }])
const { body } = await securitySolutionApi
.bulkDeleteRules({
body: [{ id: bodyWithCreatedRule.id }, { id: 'c4e80a0d-e20f-4efc-84c1-08112da5a612' }],
})
.expect(200);
const bodyToCompare = removeServerGeneratedPropertiesIncludingRuleId(body[0]);
@ -354,15 +336,14 @@ export default ({ getService }: FtrProviderContext): void => {
it('DELETE - should delete a single rule with investigation field', async () => {
// delete the rule in bulk
const { body } = await supertest
.delete(DETECTION_ENGINE_RULES_BULK_DELETE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([
{ rule_id: 'rule-with-investigation-field' },
{ rule_id: ruleWithLegacyInvestigationFieldEmptyArray.params.ruleId },
{ rule_id: ruleWithLegacyInvestigationField.params.ruleId },
])
const { body } = await securitySolutionApi
.bulkDeleteRules({
body: [
{ rule_id: 'rule-with-investigation-field' },
{ rule_id: ruleWithLegacyInvestigationFieldEmptyArray.params.ruleId },
{ rule_id: ruleWithLegacyInvestigationField.params.ruleId },
],
})
.expect(200);
const investigationFields = body.map((rule: RuleResponse) => rule.investigation_fields);
expect(investigationFields).to.eql([

View file

@ -8,7 +8,6 @@
import expect from '@kbn/expect';
import { Rule } from '@kbn/alerting-plugin/common';
import { BaseRuleParams } from '@kbn/security-solution-plugin/server/lib/detection_engine/rule_schema';
import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants';
import {
getSimpleRule,
removeServerGeneratedProperties,
@ -27,6 +26,7 @@ import { FtrProviderContext } from '../../../../../ftr_provider_context';
export default ({ getService }: FtrProviderContext): void => {
const supertest = getService('supertest');
const securitySolutionApi = getService('securitySolutionApi');
const log = getService('log');
const es = getService('es');
@ -60,12 +60,8 @@ export default ({ getService }: FtrProviderContext): void => {
});
it('deletes rule with investigation fields as array', async () => {
const { body } = await supertest
.delete(
`${DETECTION_ENGINE_RULES_URL}?rule_id=${ruleWithLegacyInvestigationField.params.ruleId}`
)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
const { body } = await securitySolutionApi
.deleteRule({ query: { rule_id: ruleWithLegacyInvestigationField.params.ruleId } })
.expect(200);
const bodyToCompare = removeServerGeneratedProperties(body);
@ -75,12 +71,10 @@ export default ({ getService }: FtrProviderContext): void => {
});
it('deletes rule with investigation fields as empty array', async () => {
const { body } = await supertest
.delete(
`${DETECTION_ENGINE_RULES_URL}?rule_id=${ruleWithLegacyInvestigationFieldEmptyArray.params.ruleId}`
)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
const { body } = await securitySolutionApi
.deleteRule({
query: { rule_id: ruleWithLegacyInvestigationFieldEmptyArray.params.ruleId },
})
.expect(200);
const bodyToCompare = removeServerGeneratedProperties(body);
@ -88,10 +82,8 @@ export default ({ getService }: FtrProviderContext): void => {
});
it('deletes rule with investigation fields as intended object type', async () => {
const { body } = await supertest
.delete(`${DETECTION_ENGINE_RULES_URL}?rule_id=rule-with-investigation-field`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
const { body } = await securitySolutionApi
.deleteRule({ query: { rule_id: 'rule-with-investigation-field' } })
.expect(200);
const bodyToCompare = removeServerGeneratedProperties(body);

View file

@ -7,7 +7,6 @@
import expect from '@kbn/expect';
import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants';
import { FtrProviderContext } from '../../../../../ftr_provider_context';
import {
getSimpleRule,
@ -26,6 +25,7 @@ import {
export default ({ getService }: FtrProviderContext) => {
const supertest = getService('supertest');
const securitySolutionApi = getService('securitySolutionApi');
const log = getService('log');
const es = getService('es');
const config = getService('config');
@ -46,11 +46,8 @@ export default ({ getService }: FtrProviderContext) => {
await createRule(supertest, log, getSimpleRule('rule-1'));
// patch a simple rule's name
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send({ rule_id: 'rule-1', name: 'some other name' })
const { body } = await securitySolutionApi
.patchRule({ body: { rule_id: 'rule-1', name: 'some other name' } })
.expect(200);
const outputRule = getSimpleRuleOutput();
@ -66,11 +63,8 @@ export default ({ getService }: FtrProviderContext) => {
await createRule(supertest, log, getSimpleRule('rule-1'));
// patch a simple rule's type to machine learning
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send({ rule_id: 'rule-1', type: 'machine_learning' })
const { body } = await securitySolutionApi
.patchRule({ body: { rule_id: 'rule-1', type: 'machine_learning' } })
.expect(403);
expect(body).to.eql({
@ -86,11 +80,8 @@ export default ({ getService }: FtrProviderContext) => {
const createRuleBody = await createRule(supertest, log, rule);
// patch a simple rule's name
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send({ rule_id: createRuleBody.rule_id, name: 'some other name' })
const { body } = await securitySolutionApi
.patchRule({ body: { rule_id: createRuleBody.rule_id, name: 'some other name' } })
.expect(200);
const outputRule = getSimpleRuleOutputWithoutRuleId();
@ -106,11 +97,8 @@ export default ({ getService }: FtrProviderContext) => {
const createdBody = await createRule(supertest, log, getSimpleRule('rule-1'));
// patch a simple rule's name
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send({ id: createdBody.id, name: 'some other name' })
const { body } = await securitySolutionApi
.patchRule({ body: { id: createdBody.id, name: 'some other name' } })
.expect(200);
const outputRule = getSimpleRuleOutput();
@ -126,11 +114,8 @@ export default ({ getService }: FtrProviderContext) => {
await createRule(supertest, log, getSimpleRule('rule-1'));
// patch a simple rule's enabled to false
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send({ rule_id: 'rule-1', enabled: false })
const { body } = await securitySolutionApi
.patchRule({ body: { rule_id: 'rule-1', enabled: false } })
.expect(200);
const outputRule = getSimpleRuleOutput();
@ -145,11 +130,8 @@ export default ({ getService }: FtrProviderContext) => {
await createRule(supertest, log, getSimpleRule('rule-1'));
// patch a simple rule's enabled to false and another property
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send({ rule_id: 'rule-1', severity: 'low', enabled: false })
const { body } = await securitySolutionApi
.patchRule({ body: { rule_id: 'rule-1', severity: 'low', enabled: false } })
.expect(200);
const outputRule = getSimpleRuleOutput();
@ -166,19 +148,15 @@ export default ({ getService }: FtrProviderContext) => {
await createRule(supertest, log, getSimpleRule('rule-1'));
// patch a simple rule's timeline_title
await supertest
.patch(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send({ rule_id: 'rule-1', timeline_title: 'some title', timeline_id: 'some id' })
await securitySolutionApi
.patchRule({
body: { rule_id: 'rule-1', timeline_title: 'some title', timeline_id: 'some id' },
})
.expect(200);
// patch a simple rule's name
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send({ rule_id: 'rule-1', name: 'some other name' })
const { body } = await securitySolutionApi
.patchRule({ body: { rule_id: 'rule-1', name: 'some other name' } })
.expect(200);
const outputRule = getSimpleRuleOutput();
@ -193,11 +171,10 @@ export default ({ getService }: FtrProviderContext) => {
});
it('should give a 404 if it is given a fake id', async () => {
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send({ id: '5096dec6-b6b9-4d8d-8f93-6c2602079d9d', name: 'some other name' })
const { body } = await securitySolutionApi
.patchRule({
body: { id: '5096dec6-b6b9-4d8d-8f93-6c2602079d9d', name: 'some other name' },
})
.expect(404);
expect(body).to.eql({
@ -207,11 +184,8 @@ export default ({ getService }: FtrProviderContext) => {
});
it('should give a 404 if it is given a fake rule_id', async () => {
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send({ rule_id: 'fake_id', name: 'some other name' })
const { body } = await securitySolutionApi
.patchRule({ body: { rule_id: 'fake_id', name: 'some other name' } })
.expect(404);
expect(body).to.eql({

View file

@ -7,7 +7,6 @@
import expect from '@kbn/expect';
import { DETECTION_ENGINE_RULES_BULK_UPDATE } from '@kbn/security-solution-plugin/common/constants';
import { FtrProviderContext } from '../../../../../ftr_provider_context';
import {
getSimpleRule,
@ -26,6 +25,7 @@ import {
export default ({ getService }: FtrProviderContext) => {
const supertest = getService('supertest');
const securitySolutionApi = getService('securitySolutionApi');
const log = getService('log');
const es = getService('es');
const config = getService('config');
@ -46,11 +46,8 @@ export default ({ getService }: FtrProviderContext) => {
await createRule(supertest, log, getSimpleRule('rule-1'));
// patch a simple rule's name
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ rule_id: 'rule-1', name: 'some other name' }])
const { body } = await securitySolutionApi
.bulkPatchRules({ body: [{ rule_id: 'rule-1', name: 'some other name' }] })
.expect(200);
const outputRule = getSimpleRuleOutput();
@ -66,14 +63,13 @@ export default ({ getService }: FtrProviderContext) => {
await createRule(supertest, log, getSimpleRule('rule-2'));
// patch both rule names
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([
{ rule_id: 'rule-1', name: 'some other name' },
{ rule_id: 'rule-2', name: 'some other name' },
])
const { body } = await securitySolutionApi
.bulkPatchRules({
body: [
{ rule_id: 'rule-1', name: 'some other name' },
{ rule_id: 'rule-2', name: 'some other name' },
],
})
.expect(200);
const outputRule1 = getSimpleRuleOutput();
@ -96,11 +92,8 @@ export default ({ getService }: FtrProviderContext) => {
const createRuleBody = await createRule(supertest, log, getSimpleRule('rule-1'));
// patch a simple rule's name
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ id: createRuleBody.id, name: 'some other name' }])
const { body } = await securitySolutionApi
.bulkPatchRules({ body: [{ id: createRuleBody.id, name: 'some other name' }] })
.expect(200);
const outputRule = getSimpleRuleOutput();
@ -116,14 +109,13 @@ export default ({ getService }: FtrProviderContext) => {
const createRule2 = await createRule(supertest, log, getSimpleRule('rule-2'));
// patch both rule names
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([
{ id: createRule1.id, name: 'some other name' },
{ id: createRule2.id, name: 'some other name' },
])
const { body } = await securitySolutionApi
.bulkPatchRules({
body: [
{ id: createRule1.id, name: 'some other name' },
{ id: createRule2.id, name: 'some other name' },
],
})
.expect(200);
const outputRule1 = getSimpleRuleOutputWithoutRuleId('rule-1');
@ -146,11 +138,8 @@ export default ({ getService }: FtrProviderContext) => {
const createdBody = await createRule(supertest, log, getSimpleRule('rule-1'));
// patch a simple rule's name
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ id: createdBody.id, name: 'some other name' }])
const { body } = await securitySolutionApi
.bulkPatchRules({ body: [{ id: createdBody.id, name: 'some other name' }] })
.expect(200);
const outputRule = getSimpleRuleOutput();
@ -166,11 +155,8 @@ export default ({ getService }: FtrProviderContext) => {
await createRule(supertest, log, getSimpleRule('rule-1'));
// patch a simple rule's enabled to false
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ rule_id: 'rule-1', enabled: false }])
const { body } = await securitySolutionApi
.bulkPatchRules({ body: [{ rule_id: 'rule-1', enabled: false }] })
.expect(200);
const outputRule = getSimpleRuleOutput();
@ -185,11 +171,8 @@ export default ({ getService }: FtrProviderContext) => {
await createRule(supertest, log, getSimpleRule('rule-1'));
// patch a simple rule's enabled to false and another property
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ rule_id: 'rule-1', severity: 'low', enabled: false }])
const { body } = await securitySolutionApi
.bulkPatchRules({ body: [{ rule_id: 'rule-1', severity: 'low', enabled: false }] })
.expect(200);
const outputRule = getSimpleRuleOutput();
@ -206,19 +189,15 @@ export default ({ getService }: FtrProviderContext) => {
await createRule(supertest, log, getSimpleRule('rule-1'));
// patch a simple rule's timeline_title
await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ rule_id: 'rule-1', timeline_title: 'some title', timeline_id: 'some id' }])
await securitySolutionApi
.bulkPatchRules({
body: [{ rule_id: 'rule-1', timeline_title: 'some title', timeline_id: 'some id' }],
})
.expect(200);
// patch a simple rule's name
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ rule_id: 'rule-1', name: 'some other name' }])
const { body } = await securitySolutionApi
.bulkPatchRules({ body: [{ rule_id: 'rule-1', name: 'some other name' }] })
.expect(200);
const outputRule = getSimpleRuleOutput();
@ -233,11 +212,10 @@ export default ({ getService }: FtrProviderContext) => {
});
it('should return a 200 but give a 404 in the message if it is given a fake id', async () => {
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ id: '5096dec6-b6b9-4d8d-8f93-6c2602079d9d', name: 'some other name' }])
const { body } = await securitySolutionApi
.bulkPatchRules({
body: [{ id: '5096dec6-b6b9-4d8d-8f93-6c2602079d9d', name: 'some other name' }],
})
.expect(200);
expect(body).to.eql([
@ -252,11 +230,8 @@ export default ({ getService }: FtrProviderContext) => {
});
it('should return a 200 but give a 404 in the message if it is given a fake rule_id', async () => {
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ rule_id: 'fake_id', name: 'some other name' }])
const { body } = await securitySolutionApi
.bulkPatchRules({ body: [{ rule_id: 'fake_id', name: 'some other name' }] })
.expect(200);
expect(body).to.eql([
@ -271,14 +246,13 @@ export default ({ getService }: FtrProviderContext) => {
await createRule(supertest, log, getSimpleRule('rule-1'));
// patch one rule name and give a fake id for the second
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([
{ rule_id: 'rule-1', name: 'some other name' },
{ rule_id: 'fake_id', name: 'some other name' },
])
const { body } = await securitySolutionApi
.bulkPatchRules({
body: [
{ rule_id: 'rule-1', name: 'some other name' },
{ rule_id: 'fake_id', name: 'some other name' },
],
})
.expect(200);
const outputRule = getSimpleRuleOutput();
@ -303,14 +277,13 @@ export default ({ getService }: FtrProviderContext) => {
const createdBody = await createRule(supertest, log, getSimpleRule('rule-1'));
// patch one rule name and give a fake id for the second
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([
{ id: createdBody.id, name: 'some other name' },
{ id: '5096dec6-b6b9-4d8d-8f93-6c2602079d9d', name: 'some other name' },
])
const { body } = await securitySolutionApi
.bulkPatchRules({
body: [
{ id: createdBody.id, name: 'some other name' },
{ id: '5096dec6-b6b9-4d8d-8f93-6c2602079d9d', name: 'some other name' },
],
})
.expect(200);
const outputRule = getSimpleRuleOutput();

View file

@ -7,7 +7,6 @@
import expect from '@kbn/expect';
import { DETECTION_ENGINE_RULES_BULK_UPDATE } from '@kbn/security-solution-plugin/common/constants';
import { ExceptionListTypeEnum } from '@kbn/securitysolution-io-ts-list-types';
import { Rule } from '@kbn/alerting-plugin/common';
import { BaseRuleParams } from '@kbn/security-solution-plugin/server/lib/detection_engine/rule_schema';
@ -37,6 +36,7 @@ import { FtrProviderContext } from '../../../../../ftr_provider_context';
export default ({ getService }: FtrProviderContext) => {
const supertest = getService('supertest');
const securitySolutionApi = getService('securitySolutionApi');
const log = getService('log');
const es = getService('es');
// TODO: add a new service for pulling kibana username, similar to getService('es')
@ -53,11 +53,8 @@ export default ({ getService }: FtrProviderContext) => {
it('should return a warning header', async () => {
await createRule(supertest, log, getSimpleRule('rule-1'));
const { header } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ rule_id: 'rule-1', name: 'some other name' }])
const { header } = await securitySolutionApi
.bulkPatchRules({ body: [{ rule_id: 'rule-1', name: 'some other name' }] })
.expect(200);
expect(header.warning).to.be(
@ -80,11 +77,8 @@ export default ({ getService }: FtrProviderContext) => {
await createRule(supertest, log, getSimpleRule('rule-1'));
// patch a simple rule's name
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ rule_id: 'rule-1', name: 'some other name' }])
const { body } = await securitySolutionApi
.bulkPatchRules({ body: [{ rule_id: 'rule-1', name: 'some other name' }] })
.expect(200);
const outputRule = updateUsername(getSimpleRuleOutput(), ELASTICSEARCH_USERNAME);
@ -100,14 +94,13 @@ export default ({ getService }: FtrProviderContext) => {
await createRule(supertest, log, getSimpleRule('rule-2'));
// patch both rule names
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([
{ rule_id: 'rule-1', name: 'some other name' },
{ rule_id: 'rule-2', name: 'some other name' },
])
const { body } = await securitySolutionApi
.bulkPatchRules({
body: [
{ rule_id: 'rule-1', name: 'some other name' },
{ rule_id: 'rule-2', name: 'some other name' },
],
})
.expect(200);
const outputRule1 = updateUsername(getSimpleRuleOutput('rule-1'), ELASTICSEARCH_USERNAME);
@ -130,11 +123,8 @@ export default ({ getService }: FtrProviderContext) => {
const createRuleBody = await createRule(supertest, log, getSimpleRule('rule-1'));
// patch a simple rule's name
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ id: createRuleBody.id, name: 'some other name' }])
const { body } = await securitySolutionApi
.bulkPatchRules({ body: [{ id: createRuleBody.id, name: 'some other name' }] })
.expect(200);
const outputRule = updateUsername(getSimpleRuleOutput(), ELASTICSEARCH_USERNAME);
@ -149,14 +139,13 @@ export default ({ getService }: FtrProviderContext) => {
const createRule2 = await createRule(supertest, log, getSimpleRule('rule-2'));
// patch both rule names
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([
{ id: createRule1.id, name: 'some other name' },
{ id: createRule2.id, name: 'some other name' },
])
const { body } = await securitySolutionApi
.bulkPatchRules({
body: [
{ id: createRule1.id, name: 'some other name' },
{ id: createRule2.id, name: 'some other name' },
],
})
.expect(200);
const outputRule1 = updateUsername(
@ -208,14 +197,13 @@ export default ({ getService }: FtrProviderContext) => {
).to.eql([rule1.id, rule2.id].sort());
// patch a simple rule's name
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([
{ id: rule1.id, enabled: false },
{ id: rule2.id, enabled: false },
])
const { body } = await securitySolutionApi
.bulkPatchRules({
body: [
{ id: rule1.id, enabled: false },
{ id: rule2.id, enabled: false },
],
})
.expect(200);
// legacy sidecar action should be gone
@ -252,11 +240,8 @@ export default ({ getService }: FtrProviderContext) => {
const createdBody = await createRule(supertest, log, getSimpleRule('rule-1'));
// patch a simple rule's name
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ id: createdBody.id, name: 'some other name' }])
const { body } = await securitySolutionApi
.bulkPatchRules({ body: [{ id: createdBody.id, name: 'some other name' }] })
.expect(200);
const outputRule = updateUsername(getSimpleRuleOutput(), ELASTICSEARCH_USERNAME);
@ -270,11 +255,8 @@ export default ({ getService }: FtrProviderContext) => {
await createRule(supertest, log, getSimpleRule('rule-1'));
// patch a simple rule's enabled to false
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ rule_id: 'rule-1', enabled: false }])
const { body } = await securitySolutionApi
.bulkPatchRules({ body: [{ rule_id: 'rule-1', enabled: false }] })
.expect(200);
const outputRule = updateUsername(getSimpleRuleOutput(), ELASTICSEARCH_USERNAME);
@ -289,11 +271,8 @@ export default ({ getService }: FtrProviderContext) => {
await createRule(supertest, log, getSimpleRule('rule-1'));
// patch a simple rule's enabled to false and another property
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ rule_id: 'rule-1', severity: 'low', enabled: false }])
const { body } = await securitySolutionApi
.bulkPatchRules({ body: [{ rule_id: 'rule-1', severity: 'low', enabled: false }] })
.expect(200);
const outputRule = updateUsername(getSimpleRuleOutput(), ELASTICSEARCH_USERNAME);
@ -310,19 +289,15 @@ export default ({ getService }: FtrProviderContext) => {
await createRule(supertest, log, getSimpleRule('rule-1'));
// patch a simple rule's timeline_title
await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ rule_id: 'rule-1', timeline_title: 'some title', timeline_id: 'some id' }])
await securitySolutionApi
.bulkPatchRules({
body: [{ rule_id: 'rule-1', timeline_title: 'some title', timeline_id: 'some id' }],
})
.expect(200);
// patch a simple rule's name
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ rule_id: 'rule-1', name: 'some other name' }])
const { body } = await securitySolutionApi
.bulkPatchRules({ body: [{ rule_id: 'rule-1', name: 'some other name' }] })
.expect(200);
const outputRule = updateUsername(getSimpleRuleOutput(), ELASTICSEARCH_USERNAME);
@ -337,11 +312,10 @@ export default ({ getService }: FtrProviderContext) => {
});
it('should return a 200 but give a 404 in the message if it is given a fake id', async () => {
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ id: '5096dec6-b6b9-4d8d-8f93-6c2602079d9d', name: 'some other name' }])
const { body } = await securitySolutionApi
.bulkPatchRules({
body: [{ id: '5096dec6-b6b9-4d8d-8f93-6c2602079d9d', name: 'some other name' }],
})
.expect(200);
expect(body).to.eql([
@ -356,11 +330,8 @@ export default ({ getService }: FtrProviderContext) => {
});
it('should return a 200 but give a 404 in the message if it is given a fake rule_id', async () => {
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([{ rule_id: 'fake_id', name: 'some other name' }])
const { body } = await securitySolutionApi
.bulkPatchRules({ body: [{ rule_id: 'fake_id', name: 'some other name' }] })
.expect(200);
expect(body).to.eql([
@ -375,14 +346,13 @@ export default ({ getService }: FtrProviderContext) => {
await createRule(supertest, log, getSimpleRule('rule-1'));
// patch one rule name and give a fake id for the second
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([
{ rule_id: 'rule-1', name: 'some other name' },
{ rule_id: 'fake_id', name: 'some other name' },
])
const { body } = await securitySolutionApi
.bulkPatchRules({
body: [
{ rule_id: 'rule-1', name: 'some other name' },
{ rule_id: 'fake_id', name: 'some other name' },
],
})
.expect(200);
const outputRule = updateUsername(getSimpleRuleOutput(), ELASTICSEARCH_USERNAME);
@ -407,14 +377,13 @@ export default ({ getService }: FtrProviderContext) => {
const createdBody = await createRule(supertest, log, getSimpleRule('rule-1'));
// patch one rule name and give a fake id for the second
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([
{ id: createdBody.id, name: 'some other name' },
{ id: '5096dec6-b6b9-4d8d-8f93-6c2602079d9d', name: 'some other name' },
])
const { body } = await securitySolutionApi
.bulkPatchRules({
body: [
{ id: createdBody.id, name: 'some other name' },
{ id: '5096dec6-b6b9-4d8d-8f93-6c2602079d9d', name: 'some other name' },
],
})
.expect(200);
const outputRule = updateUsername(getSimpleRuleOutput(), ELASTICSEARCH_USERNAME);
@ -449,23 +418,22 @@ export default ({ getService }: FtrProviderContext) => {
],
});
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([
{
rule_id: 'rule-1',
exceptions_list: [
{
id: '2',
list_id: '123',
namespace_type: 'single',
type: ExceptionListTypeEnum.RULE_DEFAULT,
},
],
},
])
const { body } = await securitySolutionApi
.bulkPatchRules({
body: [
{
rule_id: 'rule-1',
exceptions_list: [
{
id: '2',
list_id: '123',
namespace_type: 'single',
type: ExceptionListTypeEnum.RULE_DEFAULT,
},
],
},
],
})
.expect(200);
expect(body).to.eql([
@ -483,34 +451,33 @@ export default ({ getService }: FtrProviderContext) => {
await createRule(supertest, log, getSimpleRule('rule-1'));
await createRule(supertest, log, getSimpleRule('rule-2'));
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([
{
rule_id: 'rule-1',
exceptions_list: [
{
id: '2',
list_id: '123',
namespace_type: 'single',
type: ExceptionListTypeEnum.RULE_DEFAULT,
},
],
},
{
rule_id: 'rule-2',
exceptions_list: [
{
id: '2',
list_id: '123',
namespace_type: 'single',
type: ExceptionListTypeEnum.RULE_DEFAULT,
},
],
},
])
const { body } = await securitySolutionApi
.bulkPatchRules({
body: [
{
rule_id: 'rule-1',
exceptions_list: [
{
id: '2',
list_id: '123',
namespace_type: 'single',
type: ExceptionListTypeEnum.RULE_DEFAULT,
},
],
},
{
rule_id: 'rule-2',
exceptions_list: [
{
id: '2',
list_id: '123',
namespace_type: 'single',
type: ExceptionListTypeEnum.RULE_DEFAULT,
},
],
},
],
})
.expect(200);
expect(body).to.eql([
@ -555,17 +522,17 @@ export default ({ getService }: FtrProviderContext) => {
});
it('errors if trying to patch investigation fields using legacy format', async () => {
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([
{
rule_id: ruleWithLegacyInvestigationField.params.ruleId,
name: 'some other name',
investigation_fields: ['foobar'],
},
])
const { body } = await securitySolutionApi
.bulkPatchRules({
body: [
{
rule_id: ruleWithLegacyInvestigationField.params.ruleId,
name: 'some other name',
// @ts-expect-error we are testing the invalid payload
investigation_fields: ['foobar'],
},
],
})
.expect(400);
expect(body.message).to.eql(
@ -575,13 +542,12 @@ export default ({ getService }: FtrProviderContext) => {
it('should patch a rule with a legacy investigation field and transform field in response', async () => {
// patch a simple rule's name
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([
{ rule_id: ruleWithLegacyInvestigationField.params.ruleId, name: 'some other name' },
])
const { body } = await securitySolutionApi
.bulkPatchRules({
body: [
{ rule_id: ruleWithLegacyInvestigationField.params.ruleId, name: 'some other name' },
],
})
.expect(200);
const bodyToCompareLegacyField = removeServerGeneratedProperties(body[0]);
@ -607,16 +573,15 @@ export default ({ getService }: FtrProviderContext) => {
it('should patch a rule with a legacy investigation field - empty array - and transform field in response', async () => {
// patch a simple rule's name
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([
{
rule_id: ruleWithLegacyInvestigationFieldEmptyArray.params.ruleId,
name: 'some other name 2',
},
])
const { body } = await securitySolutionApi
.bulkPatchRules({
body: [
{
rule_id: ruleWithLegacyInvestigationFieldEmptyArray.params.ruleId,
name: 'some other name 2',
},
],
})
.expect(200);
const bodyToCompareLegacyFieldEmptyArray = removeServerGeneratedProperties(body[0]);
@ -647,16 +612,15 @@ export default ({ getService }: FtrProviderContext) => {
});
// patch a simple rule's name
const { body } = await supertest
.patch(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([
{
rule_id: 'rule-1',
name: 'some other name 3',
},
])
const { body } = await securitySolutionApi
.bulkPatchRules({
body: [
{
rule_id: 'rule-1',
name: 'some other name 3',
},
],
})
.expect(200);
const bodyToCompare = removeServerGeneratedProperties(body[0]);

View file

@ -7,7 +7,6 @@
import expect from '@kbn/expect';
import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants';
import { FtrProviderContext } from '../../../../../ftr_provider_context';
import {
getComplexRule,
@ -21,6 +20,7 @@ import { createRule, deleteAllRules } from '../../../../../../common/utils/secur
export default ({ getService }: FtrProviderContext): void => {
const supertest = getService('supertest');
const securitySolutionApi = getService('securitySolutionApi');
const log = getService('log');
const config = getService('config');
const ELASTICSEARCH_USERNAME = config.get('servers.kibana.username');
@ -31,12 +31,7 @@ export default ({ getService }: FtrProviderContext): void => {
});
it('should return an empty find body correctly if no rules are loaded', async () => {
const { body } = await supertest
.get(`${DETECTION_ENGINE_RULES_URL}/_find`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send()
.expect(200);
const { body } = await securitySolutionApi.findRules({ query: {} }).expect(200);
expect(body).to.eql({
data: [],
@ -50,12 +45,7 @@ export default ({ getService }: FtrProviderContext): void => {
await createRule(supertest, log, getSimpleRule());
// query the single rule from _find
const { body } = await supertest
.get(`${DETECTION_ENGINE_RULES_URL}/_find`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send()
.expect(200);
const { body } = await securitySolutionApi.findRules({ query: {} }).expect(200);
body.data = [removeServerGeneratedProperties(body.data[0])];
const expectedRule = updateUsername(getSimpleRuleOutput(), ELASTICSEARCH_USERNAME);
@ -70,20 +60,10 @@ export default ({ getService }: FtrProviderContext): void => {
it('should return a single rule when a single rule is loaded from a find with everything for the rule added', async () => {
// add a single rule
await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(getComplexRule())
.expect(200);
await securitySolutionApi.createRule({ body: getComplexRule() }).expect(200);
// query and expect that we get back one record in the find
const { body } = await supertest
.get(`${DETECTION_ENGINE_RULES_URL}/_find`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send()
.expect(200);
const { body } = await securitySolutionApi.findRules({ query: {} }).expect(200);
body.data = [removeServerGeneratedProperties(body.data[0])];
const expectedRule = updateUsername(getComplexRuleOutput(), ELASTICSEARCH_USERNAME);

View file

@ -7,7 +7,6 @@
import expect from '@kbn/expect';
import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants';
import { FtrProviderContext } from '../../../../../ftr_provider_context';
import {
getSimpleRule,
@ -27,6 +26,7 @@ import {
export default ({ getService }: FtrProviderContext) => {
const supertest = getService('supertest');
const securitySolutionApi = getService('securitySolutionApi');
const log = getService('log');
const es = getService('es');
const config = getService('config');
@ -46,11 +46,8 @@ export default ({ getService }: FtrProviderContext) => {
it('should be able to read a single rule using rule_id', async () => {
await createRule(supertest, log, getSimpleRule());
const { body } = await supertest
.get(`${DETECTION_ENGINE_RULES_URL}?rule_id=rule-1`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(getSimpleRule())
const { body } = await securitySolutionApi
.readRule({ query: { rule_id: 'rule-1' } })
.expect(200);
const bodyToCompare = removeServerGeneratedProperties(body);
@ -62,11 +59,8 @@ export default ({ getService }: FtrProviderContext) => {
it('should be able to read a single rule using id', async () => {
const createRuleBody = await createRule(supertest, log, getSimpleRule());
const { body } = await supertest
.get(`${DETECTION_ENGINE_RULES_URL}?id=${createRuleBody.id}`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(getSimpleRule())
const { body } = await securitySolutionApi
.readRule({ query: { id: createRuleBody.id } })
.expect(200);
const bodyToCompare = removeServerGeneratedProperties(body);
@ -78,11 +72,8 @@ export default ({ getService }: FtrProviderContext) => {
it('should be able to read a single rule with an auto-generated rule_id', async () => {
const createRuleBody = await createRule(supertest, log, getSimpleRuleWithoutRuleId());
const { body } = await supertest
.get(`${DETECTION_ENGINE_RULES_URL}?rule_id=${createRuleBody.rule_id}`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(getSimpleRule())
const { body } = await securitySolutionApi
.readRule({ query: { rule_id: createRuleBody.rule_id } })
.expect(200);
const bodyToCompare = removeServerGeneratedPropertiesIncludingRuleId(body);
@ -95,11 +86,8 @@ export default ({ getService }: FtrProviderContext) => {
});
it('should return 404 if given a fake id', async () => {
const { body } = await supertest
.get(`${DETECTION_ENGINE_RULES_URL}?id=c1e1b359-7ac1-4e96-bc81-c683c092436f`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(getSimpleRule())
const { body } = await securitySolutionApi
.readRule({ query: { id: 'c1e1b359-7ac1-4e96-bc81-c683c092436f' } })
.expect(404);
expect(body).to.eql({
@ -109,11 +97,8 @@ export default ({ getService }: FtrProviderContext) => {
});
it('should return 404 if given a fake rule_id', async () => {
const { body } = await supertest
.get(`${DETECTION_ENGINE_RULES_URL}?rule_id=fake_id`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(getSimpleRule())
const { body } = await securitySolutionApi
.readRule({ query: { rule_id: 'fake_id' } })
.expect(404);
expect(body).to.eql({

View file

@ -6,11 +6,7 @@
*/
import expect from '@kbn/expect';
import {
ELASTIC_HTTP_VERSION_HEADER,
X_ELASTIC_INTERNAL_ORIGIN_REQUEST,
} from '@kbn/core-http-common';
import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants';
import { X_ELASTIC_INTERNAL_ORIGIN_REQUEST } from '@kbn/core-http-common';
import {
getComplexRule,
getComplexRuleOutput,
@ -25,6 +21,7 @@ import { FtrProviderContext } from '../../../../../ftr_provider_context';
export default ({ getService }: FtrProviderContext): void => {
const supertest = getService('supertest');
const securitySolutionApi = getService('securitySolutionApi');
const log = getService('log');
// TODO: add a new service for pulling kibana username, similar to getService('es')
const config = getService('config');
@ -36,12 +33,7 @@ export default ({ getService }: FtrProviderContext): void => {
});
it('should return an empty find body correctly if no rules are loaded', async () => {
const { body } = await supertest
.get(`${DETECTION_ENGINE_RULES_URL}/_find`)
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.send()
.expect(200);
const { body } = await securitySolutionApi.findRules({ query: {} }).expect(200);
expect(body).to.eql({
data: [],
@ -55,12 +47,7 @@ export default ({ getService }: FtrProviderContext): void => {
await createRule(supertest, log, getSimpleRule());
// query the single rule from _find
const { body } = await supertest
.get(`${DETECTION_ENGINE_RULES_URL}/_find`)
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.send()
.expect(200);
const { body } = await securitySolutionApi.findRules({ query: {} }).expect(200);
body.data = [removeServerGeneratedProperties(body.data[0])];
const expectedRule = updateUsername(getSimpleRuleOutput(), ELASTICSEARCH_USERNAME);
@ -75,20 +62,10 @@ export default ({ getService }: FtrProviderContext): void => {
it('should return a single rule when a single rule is loaded from a find with everything for the rule added', async () => {
// add a single rule
await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.send(getComplexRule())
.expect(200);
await securitySolutionApi.createRule({ body: getComplexRule() }).expect(200);
// query and expect that we get back one record in the find
const { body } = await supertest
.get(`${DETECTION_ENGINE_RULES_URL}/_find`)
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.send()
.expect(200);
const { body } = await securitySolutionApi.findRules({ query: {} }).expect(200);
body.data = [removeServerGeneratedProperties(body.data[0])];
const expectedRule = updateUsername(getComplexRuleOutput(), ELASTICSEARCH_USERNAME);
@ -125,12 +102,7 @@ export default ({ getService }: FtrProviderContext): void => {
await createRule(supertest, log, rule);
// query the single rule from _find
const { body } = await supertest
.get(`${DETECTION_ENGINE_RULES_URL}/_find`)
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.send()
.expect(200);
const { body } = await securitySolutionApi.findRules({ query: {} }).expect(200);
const expectedRule = updateUsername(getSimpleRuleOutput(), ELASTICSEARCH_USERNAME);
const ruleWithActions: ReturnType<typeof getSimpleRuleOutput> = {
@ -178,12 +150,7 @@ export default ({ getService }: FtrProviderContext): void => {
await createRule(supertest, log, rule);
// query the single rule from _find
const { body } = await supertest
.get(`${DETECTION_ENGINE_RULES_URL}/_find`)
.set('kbn-xsrf', 'true')
.set(ELASTIC_HTTP_VERSION_HEADER, '2023-10-31')
.send()
.expect(200);
const { body } = await securitySolutionApi.findRules({ query: {} }).expect(200);
const expectedRule = updateUsername(getSimpleRuleOutput(), ELASTICSEARCH_USERNAME);
const ruleWithActions: ReturnType<typeof getSimpleRuleOutput> = {

View file

@ -6,7 +6,6 @@
*/
import expect from '@kbn/expect';
import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants';
import {
getSimpleRule,
getSimpleRuleOutput,
@ -27,6 +26,7 @@ import { FtrProviderContext } from '../../../../../ftr_provider_context';
export default ({ getService }: FtrProviderContext) => {
const supertest = getService('supertest');
const securitySolutionApi = getService('securitySolutionApi');
const log = getService('log');
const es = getService('es');
// TODO: add a new service for pulling kibana username, similar to getService('es')
@ -47,11 +47,8 @@ export default ({ getService }: FtrProviderContext) => {
it('should be able to read a single rule using rule_id', async () => {
await createRule(supertest, log, getSimpleRule());
const { body } = await supertest
.get(`${DETECTION_ENGINE_RULES_URL}?rule_id=rule-1`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(getSimpleRule())
const { body } = await securitySolutionApi
.readRule({ query: { rule_id: 'rule-1' } })
.expect(200);
const bodyToCompare = removeServerGeneratedProperties(body);
@ -63,11 +60,8 @@ export default ({ getService }: FtrProviderContext) => {
it('should be able to read a single rule using id', async () => {
const createRuleBody = await createRule(supertest, log, getSimpleRule());
const { body } = await supertest
.get(`${DETECTION_ENGINE_RULES_URL}?id=${createRuleBody.id}`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(getSimpleRule())
const { body } = await securitySolutionApi
.readRule({ query: { id: createRuleBody.id } })
.expect(200);
const bodyToCompare = removeServerGeneratedProperties(body);
@ -79,11 +73,8 @@ export default ({ getService }: FtrProviderContext) => {
it('should be able to read a single rule with an auto-generated rule_id', async () => {
const createRuleBody = await createRule(supertest, log, getSimpleRuleWithoutRuleId());
const { body } = await supertest
.get(`${DETECTION_ENGINE_RULES_URL}?rule_id=${createRuleBody.rule_id}`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(getSimpleRule())
const { body } = await securitySolutionApi
.readRule({ query: { rule_id: createRuleBody.rule_id } })
.expect(200);
const bodyToCompare = removeServerGeneratedPropertiesIncludingRuleId(body);
@ -96,11 +87,8 @@ export default ({ getService }: FtrProviderContext) => {
});
it('should return 404 if given a fake id', async () => {
const { body } = await supertest
.get(`${DETECTION_ENGINE_RULES_URL}?id=c1e1b359-7ac1-4e96-bc81-c683c092436f`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(getSimpleRule())
const { body } = await securitySolutionApi
.readRule({ query: { id: 'c1e1b359-7ac1-4e96-bc81-c683c092436f' } })
.expect(404);
expect(body).to.eql({
@ -110,11 +98,8 @@ export default ({ getService }: FtrProviderContext) => {
});
it('should return 404 if given a fake rule_id', async () => {
const { body } = await supertest
.get(`${DETECTION_ENGINE_RULES_URL}?rule_id=fake_id`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(getSimpleRule())
const { body } = await securitySolutionApi
.readRule({ query: { rule_id: 'fake_id' } })
.expect(404);
expect(body).to.eql({
@ -145,11 +130,8 @@ export default ({ getService }: FtrProviderContext) => {
};
const createRuleBody = await createRule(supertest, log, rule);
const { body } = await supertest
.get(`${DETECTION_ENGINE_RULES_URL}?id=${createRuleBody.id}`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(getSimpleRule())
const { body } = await securitySolutionApi
.readRule({ query: { id: createRuleBody.id } })
.expect(200);
const bodyToCompare = removeServerGeneratedProperties(body);
@ -193,11 +175,8 @@ export default ({ getService }: FtrProviderContext) => {
const createRuleBody = await createRule(supertest, log, rule);
const { body } = await supertest
.get(`${DETECTION_ENGINE_RULES_URL}?id=${createRuleBody.id}`)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(getSimpleRule())
const { body } = await securitySolutionApi
.readRule({ query: { id: createRuleBody.id } })
.expect(200);
const bodyToCompare = removeServerGeneratedProperties(body);

View file

@ -7,7 +7,6 @@
import expect from '@kbn/expect';
import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants';
import { FtrProviderContext } from '../../../../../ftr_provider_context';
import {
getSimpleRuleOutput,
@ -28,6 +27,7 @@ import {
export default ({ getService }: FtrProviderContext) => {
const supertest = getService('supertest');
const securitySolutionApi = getService('securitySolutionApi');
const log = getService('log');
const es = getService('es');
const config = getService('config');
@ -53,12 +53,7 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule.name = 'some other name';
delete updatedRule.id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(updatedRule)
.expect(200);
const { body } = await securitySolutionApi.updateRule({ body: updatedRule }).expect(200);
const outputRule = getSimpleRuleOutput();
outputRule.name = 'some other name';
@ -78,12 +73,7 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule.name = 'some other name';
delete updatedRule.id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(updatedRule)
.expect(403);
const { body } = await securitySolutionApi.updateRule({ body: updatedRule }).expect(403);
expect(body).to.eql({
message: 'Your license does not support machine learning. Please upgrade your license.',
@ -102,12 +92,7 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule.name = 'some other name';
delete updatedRule.id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(updatedRule)
.expect(200);
const { body } = await securitySolutionApi.updateRule({ body: updatedRule }).expect(200);
const outputRule = getSimpleRuleOutputWithoutRuleId();
outputRule.name = 'some other name';
@ -127,12 +112,7 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule.id = createdBody.id;
delete updatedRule.rule_id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(updatedRule)
.expect(200);
const { body } = await securitySolutionApi.updateRule({ body: updatedRule }).expect(200);
const outputRule = getSimpleRuleOutput();
outputRule.name = 'some other name';
@ -151,12 +131,7 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule.severity = 'low';
updatedRule.enabled = false;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(updatedRule)
.expect(200);
const { body } = await securitySolutionApi.updateRule({ body: updatedRule }).expect(200);
const outputRule = getSimpleRuleOutput();
outputRule.enabled = false;
@ -176,23 +151,13 @@ export default ({ getService }: FtrProviderContext) => {
ruleUpdate.timeline_id = 'some id';
// update a simple rule's timeline_title
await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(ruleUpdate)
.expect(200);
await securitySolutionApi.updateRule({ body: ruleUpdate }).expect(200);
const ruleUpdate2 = getSimpleRuleUpdate('rule-1');
ruleUpdate2.name = 'some other name';
// update a simple rule's name
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(ruleUpdate2)
.expect(200);
const { body } = await securitySolutionApi.updateRule({ body: ruleUpdate2 }).expect(200);
const outputRule = getSimpleRuleOutput();
outputRule.name = 'some other name';
@ -208,12 +173,7 @@ export default ({ getService }: FtrProviderContext) => {
simpleRule.id = '5096dec6-b6b9-4d8d-8f93-6c2602079d9d';
delete simpleRule.rule_id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(simpleRule)
.expect(404);
const { body } = await securitySolutionApi.updateRule({ body: simpleRule }).expect(404);
expect(body).to.eql({
status_code: 404,
@ -226,12 +186,7 @@ export default ({ getService }: FtrProviderContext) => {
simpleRule.rule_id = 'fake_id';
delete simpleRule.id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(simpleRule)
.expect(404);
const { body } = await securitySolutionApi.updateRule({ body: simpleRule }).expect(404);
expect(body).to.eql({
status_code: 404,

View file

@ -7,10 +7,6 @@
import expect from '@kbn/expect';
import {
DETECTION_ENGINE_RULES_BULK_UPDATE,
DETECTION_ENGINE_RULES_URL,
} from '@kbn/security-solution-plugin/common/constants';
import { FtrProviderContext } from '../../../../../ftr_provider_context';
import {
getSimpleRuleOutput,
@ -30,6 +26,7 @@ import {
export default ({ getService }: FtrProviderContext) => {
const supertest = getService('supertest');
const securitySolutionApi = getService('securitySolutionApi');
const log = getService('log');
const es = getService('es');
const config = getService('config');
@ -53,11 +50,8 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule.name = 'some other name';
// update a simple rule's name
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([updatedRule])
const { body } = await securitySolutionApi
.bulkUpdateRules({ body: [updatedRule] })
.expect(200);
const outputRule = getSimpleRuleOutput();
@ -73,12 +67,7 @@ export default ({ getService }: FtrProviderContext) => {
await createRule(supertest, log, getSimpleRule('rule-1'));
// create a second simple rule
await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(getSimpleRuleUpdate('rule-2'))
.expect(200);
await securitySolutionApi.createRule({ body: getSimpleRule('rule-2') }).expect(200);
const updatedRule1 = getSimpleRuleUpdate('rule-1');
updatedRule1.name = 'some other name';
@ -87,11 +76,8 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule2.name = 'some other name';
// update both rule names
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([updatedRule1, updatedRule2])
const { body } = await securitySolutionApi
.bulkUpdateRules({ body: [updatedRule1, updatedRule2] })
.expect(200);
const outputRule1 = getSimpleRuleOutput();
@ -119,11 +105,8 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule1.name = 'some other name';
delete updatedRule1.rule_id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([updatedRule1])
const { body } = await securitySolutionApi
.bulkUpdateRules({ body: [updatedRule1] })
.expect(200);
const outputRule = getSimpleRuleOutput();
@ -150,11 +133,8 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule2.name = 'some other name';
delete updatedRule2.rule_id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([updatedRule1, updatedRule2])
const { body } = await securitySolutionApi
.bulkUpdateRules({ body: [updatedRule1, updatedRule2] })
.expect(200);
const outputRule1 = getSimpleRuleOutputWithoutRuleId('rule-1');
@ -182,11 +162,8 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule1.name = 'some other name';
delete updatedRule1.rule_id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([updatedRule1])
const { body } = await securitySolutionApi
.bulkUpdateRules({ body: [updatedRule1] })
.expect(200);
const outputRule = getSimpleRuleOutput();
@ -206,11 +183,8 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule1.severity = 'low';
updatedRule1.enabled = false;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([updatedRule1])
const { body } = await securitySolutionApi
.bulkUpdateRules({ body: [updatedRule1] })
.expect(200);
const outputRule = getSimpleRuleOutput();
@ -231,22 +205,14 @@ export default ({ getService }: FtrProviderContext) => {
ruleUpdate.timeline_title = 'some title';
ruleUpdate.timeline_id = 'some id';
await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([ruleUpdate])
.expect(200);
await securitySolutionApi.bulkUpdateRules({ body: [ruleUpdate] }).expect(200);
// update a simple rule's name
const ruleUpdate2 = getSimpleRuleUpdate('rule-1');
ruleUpdate2.name = 'some other name';
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([ruleUpdate2])
const { body } = await securitySolutionApi
.bulkUpdateRules({ body: [ruleUpdate2] })
.expect(200);
const outputRule = getSimpleRuleOutput();
@ -263,11 +229,8 @@ export default ({ getService }: FtrProviderContext) => {
ruleUpdate.id = '1fd52120-d3a9-4e7a-b23c-96c0e1a74ae5';
delete ruleUpdate.rule_id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([ruleUpdate])
const { body } = await securitySolutionApi
.bulkUpdateRules({ body: [ruleUpdate] })
.expect(200);
expect(body).to.eql([
@ -286,11 +249,8 @@ export default ({ getService }: FtrProviderContext) => {
ruleUpdate.rule_id = 'fake_id';
delete ruleUpdate.id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([ruleUpdate])
const { body } = await securitySolutionApi
.bulkUpdateRules({ body: [ruleUpdate] })
.expect(200);
expect(body).to.eql([
@ -313,11 +273,8 @@ export default ({ getService }: FtrProviderContext) => {
delete ruleUpdate.id;
// update one rule name and give a fake id for the second
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([ruleUpdate, ruleUpdate2])
const { body } = await securitySolutionApi
.bulkUpdateRules({ body: [ruleUpdate, ruleUpdate2] })
.expect(200);
const outputRule = getSimpleRuleOutput();
@ -352,11 +309,8 @@ export default ({ getService }: FtrProviderContext) => {
rule2.id = 'b3aa019a-656c-4311-b13b-4d9852e24347';
rule2.name = 'some other name';
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([rule1, rule2])
const { body } = await securitySolutionApi
.bulkUpdateRules({ body: [rule1, rule2] })
.expect(200);
const outputRule = getSimpleRuleOutput();

View file

@ -7,7 +7,6 @@
import expect from '@kbn/expect';
import {
DETECTION_ENGINE_RULES_URL,
NOTIFICATION_DEFAULT_FREQUENCY,
NOTIFICATION_THROTTLE_NO_ACTIONS,
NOTIFICATION_THROTTLE_RULE,
@ -44,6 +43,7 @@ import { FtrProviderContext } from '../../../../../ftr_provider_context';
export default ({ getService }: FtrProviderContext) => {
const supertest = getService('supertest');
const securitySolutionApi = getService('securitySolutionApi');
const log = getService('log');
const es = getService('es');
// TODO: add a new service for pulling kibana username, similar to getService('es')
@ -70,12 +70,7 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule.name = 'some other name';
delete updatedRule.id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(updatedRule)
.expect(200);
const { body } = await securitySolutionApi.updateRule({ body: updatedRule }).expect(200);
const outputRule = updateUsername(getSimpleRuleOutput(), ELASTICSEARCH_USERNAME);
@ -94,12 +89,7 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule.machine_learning_job_id = 'legacy_job_id';
delete updatedRule.id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(updatedRule)
.expect(200);
const { body } = await securitySolutionApi.updateRule({ body: updatedRule }).expect(200);
const outputRule = updateUsername(getSimpleMlRuleOutput(), ELASTICSEARCH_USERNAME);
@ -119,12 +109,7 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule.name = 'some other name';
delete updatedRule.id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(updatedRule)
.expect(200);
const { body } = await securitySolutionApi.updateRule({ body: updatedRule }).expect(200);
const outputRule = updateUsername(getSimpleMlRuleOutput(), ELASTICSEARCH_USERNAME);
outputRule.name = 'some other name';
@ -144,12 +129,7 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule.name = 'some other name';
delete updatedRule.id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(updatedRule)
.expect(200);
const { body } = await securitySolutionApi.updateRule({ body: updatedRule }).expect(200);
const outputRule = updateUsername(
getSimpleRuleOutputWithoutRuleId(),
@ -198,12 +178,7 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule.name = 'some other name';
delete updatedRule.id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(updatedRule)
.expect(200);
const { body } = await securitySolutionApi.updateRule({ body: updatedRule }).expect(200);
const outputRule = updateUsername(
getSimpleRuleOutputWithoutRuleId(),
@ -226,12 +201,7 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule.id = createdBody.id;
delete updatedRule.rule_id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(updatedRule)
.expect(200);
const { body } = await securitySolutionApi.updateRule({ body: updatedRule }).expect(200);
const outputRule = updateUsername(getSimpleRuleOutput(), ELASTICSEARCH_USERNAME);
@ -249,12 +219,7 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule.severity = 'low';
updatedRule.enabled = false;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(updatedRule)
.expect(200);
const { body } = await securitySolutionApi.updateRule({ body: updatedRule }).expect(200);
const outputRule = updateUsername(getSimpleRuleOutput(), ELASTICSEARCH_USERNAME);
@ -274,23 +239,13 @@ export default ({ getService }: FtrProviderContext) => {
ruleUpdate.timeline_id = 'some id';
// update a simple rule's timeline_title
await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(ruleUpdate)
.expect(200);
await securitySolutionApi.updateRule({ body: ruleUpdate }).expect(200);
const ruleUpdate2 = getSimpleRuleUpdate('rule-1');
ruleUpdate2.name = 'some other name';
// update a simple rule's name
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(ruleUpdate2)
.expect(200);
const { body } = await securitySolutionApi.updateRule({ body: ruleUpdate2 }).expect(200);
const outputRule = updateUsername(getSimpleRuleOutput(), ELASTICSEARCH_USERNAME);
@ -306,12 +261,7 @@ export default ({ getService }: FtrProviderContext) => {
simpleRule.id = '5096dec6-b6b9-4d8d-8f93-6c2602079d9d';
delete simpleRule.rule_id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(simpleRule)
.expect(404);
const { body } = await securitySolutionApi.updateRule({ body: simpleRule }).expect(404);
expect(body).to.eql({
status_code: 404,
@ -324,12 +274,7 @@ export default ({ getService }: FtrProviderContext) => {
simpleRule.rule_id = 'fake_id';
delete simpleRule.id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(simpleRule)
.expect(404);
const { body } = await securitySolutionApi.updateRule({ body: simpleRule }).expect(404);
expect(body).to.eql({
status_code: 404,
@ -356,18 +301,13 @@ export default ({ getService }: FtrProviderContext) => {
{
id: '2',
list_id: '456',
namespace_type: 'single',
namespace_type: 'single' as const,
type: ExceptionListTypeEnum.RULE_DEFAULT,
},
],
};
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(ruleUpdate)
.expect(200);
const { body } = await securitySolutionApi.updateRule({ body: ruleUpdate }).expect(200);
expect(body.exceptions_list).to.eql([
{ id: '2', list_id: '456', namespace_type: 'single', type: 'rule_default' },
@ -383,24 +323,19 @@ export default ({ getService }: FtrProviderContext) => {
{
id: '1',
list_id: '123',
namespace_type: 'single',
namespace_type: 'single' as const,
type: ExceptionListTypeEnum.RULE_DEFAULT,
},
{
id: '2',
list_id: '456',
namespace_type: 'single',
namespace_type: 'single' as const,
type: ExceptionListTypeEnum.RULE_DEFAULT,
},
],
};
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(ruleUpdate)
.expect(500);
const { body } = await securitySolutionApi.updateRule({ body: ruleUpdate }).expect(500);
expect(body).to.eql({
message: 'More than one default exception list found on rule',
@ -422,20 +357,19 @@ export default ({ getService }: FtrProviderContext) => {
});
await createRule(supertest, log, getSimpleRule('rule-2'));
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send({
...getSimpleRule('rule-2'),
exceptions_list: [
{
id: '2',
list_id: '123',
namespace_type: 'single',
type: ExceptionListTypeEnum.RULE_DEFAULT,
},
],
const { body } = await securitySolutionApi
.updateRule({
body: {
...getSimpleRule('rule-2'),
exceptions_list: [
{
id: '2',
list_id: '123',
namespace_type: 'single',
type: ExceptionListTypeEnum.RULE_DEFAULT,
},
],
},
})
.expect(409);
@ -464,20 +398,19 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule.id = createdBody.id;
delete updatedRule.rule_id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send({
...updatedRule,
exceptions_list: [
{
id: '2',
list_id: '123',
namespace_type: 'single',
type: ExceptionListTypeEnum.RULE_DEFAULT,
},
],
const { body } = await securitySolutionApi
.updateRule({
body: {
...updatedRule,
exceptions_list: [
{
id: '2',
list_id: '123',
namespace_type: 'single',
type: ExceptionListTypeEnum.RULE_DEFAULT,
},
],
},
})
.expect(409);
@ -493,12 +426,8 @@ export default ({ getService }: FtrProviderContext) => {
await createRule(supertest, log, existingRule);
const { threshold, ...rule } = existingRule;
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(rule)
.expect(400);
// @ts-expect-error we're testing the invalid payload here
const { body } = await securitySolutionApi.updateRule({ body: rule }).expect(400);
expect(body).to.eql({
error: 'Bad Request',
@ -518,12 +447,7 @@ export default ({ getService }: FtrProviderContext) => {
field: ['field-1', 'field-2', 'field-3', 'field-4'],
},
};
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(rule)
.expect(400);
const { body } = await securitySolutionApi.updateRule({ body: rule }).expect(400);
expect(body).to.eql({
message: ['Number of fields must be 3 or less'],
@ -542,12 +466,7 @@ export default ({ getService }: FtrProviderContext) => {
value: 0,
},
};
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(rule)
.expect(400);
const { body } = await securitySolutionApi.updateRule({ body: rule }).expect(400);
expect(body).to.eql({
error: 'Bad Request',
@ -572,12 +491,7 @@ export default ({ getService }: FtrProviderContext) => {
],
},
};
const { body } = await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(rule)
.expect(400);
const { body } = await securitySolutionApi.updateRule({ body: rule }).expect(400);
expect(body).to.eql({
message: ['Cardinality of a field that is being aggregated on is always 1'],
@ -592,11 +506,8 @@ export default ({ getService }: FtrProviderContext) => {
const savedQueryRule = getSimpleSavedQueryRule(ruleId);
await createRule(supertest, log, getSimpleRule(ruleId));
const { body: outputRule } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(savedQueryRule)
const { body: outputRule } = await securitySolutionApi
.updateRule({ body: savedQueryRule })
.expect(200);
expect(outputRule.type).to.be('saved_query');
@ -608,11 +519,8 @@ export default ({ getService }: FtrProviderContext) => {
const savedQueryRule = { ...getSimpleSavedQueryRule(ruleId), query: undefined };
await createRule(supertest, log, getSimpleRule(ruleId));
const { body: outputRule } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(savedQueryRule)
const { body: outputRule } = await securitySolutionApi
.updateRule({ body: savedQueryRule })
.expect(200);
expect(outputRule.type).to.be('saved_query');
@ -624,11 +532,8 @@ export default ({ getService }: FtrProviderContext) => {
const queryRule = getSimpleRule(ruleId);
await createRule(supertest, log, getSimpleSavedQueryRule(ruleId));
const { body: outputRule } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(queryRule)
const { body: outputRule } = await securitySolutionApi
.updateRule({ body: queryRule })
.expect(200);
expect(outputRule.type).to.be('query');
@ -649,11 +554,8 @@ export default ({ getService }: FtrProviderContext) => {
ruleToUpdate.id = ruleId;
delete ruleToUpdate.rule_id;
const { body: updatedRule } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(ruleToUpdate)
const { body: updatedRule } = await securitySolutionApi
.updateRule({ body: ruleToUpdate })
.expect(200);
updatedRule.actions = removeUUIDFromActions(updatedRule.actions);
@ -834,12 +736,7 @@ export default ({ getService }: FtrProviderContext) => {
investigation_fields: { field_names: ['foo', 'bar'] },
};
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(ruleUpdate)
.expect(200);
const { body } = await securitySolutionApi.updateRule({ body: ruleUpdate }).expect(200);
expect(body.investigation_fields.field_names).to.eql(['foo', 'bar']);
});
@ -855,11 +752,7 @@ export default ({ getService }: FtrProviderContext) => {
investigation_fields: undefined,
};
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.send(ruleUpdate)
.expect(200);
const { body } = await securitySolutionApi.updateRule({ body: ruleUpdate }).expect(200);
expect(body.investigation_fields).to.eql(undefined);
});

View file

@ -10,8 +10,6 @@ import { RuleResponse } from '@kbn/security-solution-plugin/common/api/detection
import { Rule } from '@kbn/alerting-plugin/common';
import { BaseRuleParams } from '@kbn/security-solution-plugin/server/lib/detection_engine/rule_schema';
import {
DETECTION_ENGINE_RULES_URL,
DETECTION_ENGINE_RULES_BULK_UPDATE,
NOTIFICATION_THROTTLE_NO_ACTIONS,
NOTIFICATION_THROTTLE_RULE,
NOTIFICATION_DEFAULT_FREQUENCY,
@ -48,6 +46,7 @@ import { FtrProviderContext } from '../../../../../ftr_provider_context';
export default ({ getService }: FtrProviderContext) => {
const supertest = getService('supertest');
const securitySolutionApi = getService('securitySolutionApi');
const log = getService('log');
const es = getService('es');
// TODO: add a new service for pulling kibana username, similar to getService('es')
@ -65,11 +64,8 @@ export default ({ getService }: FtrProviderContext) => {
await createRule(supertest, log, getSimpleRule('rule-1'));
const updatedRule = getSimpleRuleUpdate('rule-1');
const { header } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([updatedRule])
const { header } = await securitySolutionApi
.bulkUpdateRules({ body: [updatedRule] })
.expect(200);
expect(header.warning).to.be(
@ -95,11 +91,8 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule.name = 'some other name';
// update a simple rule's name
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([updatedRule])
const { body } = await securitySolutionApi
.bulkUpdateRules({ body: [updatedRule] })
.expect(200);
const outputRule = updateUsername(getSimpleRuleOutput(), ELASTICSEARCH_USERNAME);
@ -113,12 +106,7 @@ export default ({ getService }: FtrProviderContext) => {
await createRule(supertest, log, getSimpleRule('rule-1'));
// create a second simple rule
await supertest
.post(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(getSimpleRuleUpdate('rule-2'))
.expect(200);
await securitySolutionApi.createRule({ body: getSimpleRuleUpdate('rule-2') }).expect(200);
const updatedRule1 = getSimpleRuleUpdate('rule-1');
updatedRule1.name = 'some other name';
@ -127,11 +115,8 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule2.name = 'some other name';
// update both rule names
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([updatedRule1, updatedRule2])
const { body } = await securitySolutionApi
.bulkUpdateRules({ body: [updatedRule1, updatedRule2] })
.expect(200);
const outputRule1 = updateUsername(getSimpleRuleOutput(), ELASTICSEARCH_USERNAME);
@ -192,11 +177,8 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule2.actions = [action1];
// update both rule names
const { body }: { body: RuleResponse[] } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([updatedRule1, updatedRule2])
const { body }: { body: RuleResponse[] } = await securitySolutionApi
.bulkUpdateRules({ body: [updatedRule1, updatedRule2] })
.expect(200);
// legacy sidecar action should be gone
@ -263,11 +245,8 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule2.name = 'some other name';
// update both rule names
const { body }: { body: RuleResponse[] } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([updatedRule1, updatedRule2])
const { body }: { body: RuleResponse[] } = await securitySolutionApi
.bulkUpdateRules({ body: [updatedRule1, updatedRule2] })
.expect(200);
body.forEach((response) => {
@ -292,11 +271,8 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule1.name = 'some other name';
delete updatedRule1.rule_id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([updatedRule1])
const { body } = await securitySolutionApi
.bulkUpdateRules({ body: [updatedRule1] })
.expect(200);
const outputRule = updateUsername(getSimpleRuleOutput(), ELASTICSEARCH_USERNAME);
@ -321,11 +297,8 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule2.name = 'some other name';
delete updatedRule2.rule_id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([updatedRule1, updatedRule2])
const { body } = await securitySolutionApi
.bulkUpdateRules({ body: [updatedRule1, updatedRule2] })
.expect(200);
const outputRule1 = updateUsername(getSimpleRuleOutput('rule-1'), ELASTICSEARCH_USERNAME);
@ -351,11 +324,8 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule1.name = 'some other name';
delete updatedRule1.rule_id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([updatedRule1])
const { body } = await securitySolutionApi
.bulkUpdateRules({ body: [updatedRule1] })
.expect(200);
const outputRule = updateUsername(getSimpleRuleOutput(), ELASTICSEARCH_USERNAME);
@ -373,11 +343,8 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule1.severity = 'low';
updatedRule1.enabled = false;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([updatedRule1])
const { body } = await securitySolutionApi
.bulkUpdateRules({ body: [updatedRule1] })
.expect(200);
const outputRule = updateUsername(getSimpleRuleOutput(), ELASTICSEARCH_USERNAME);
@ -397,22 +364,14 @@ export default ({ getService }: FtrProviderContext) => {
ruleUpdate.timeline_title = 'some title';
ruleUpdate.timeline_id = 'some id';
await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([ruleUpdate])
.expect(200);
await securitySolutionApi.bulkUpdateRules({ body: [ruleUpdate] }).expect(200);
// update a simple rule's name
const ruleUpdate2 = getSimpleRuleUpdate('rule-1');
ruleUpdate2.name = 'some other name';
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([ruleUpdate2])
const { body } = await securitySolutionApi
.bulkUpdateRules({ body: [ruleUpdate2] })
.expect(200);
const outputRule = updateUsername(getSimpleRuleOutput(), ELASTICSEARCH_USERNAME);
@ -428,11 +387,8 @@ export default ({ getService }: FtrProviderContext) => {
ruleUpdate.id = '1fd52120-d3a9-4e7a-b23c-96c0e1a74ae5';
delete ruleUpdate.rule_id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([ruleUpdate])
const { body } = await securitySolutionApi
.bulkUpdateRules({ body: [ruleUpdate] })
.expect(200);
expect(body).to.eql([
@ -451,11 +407,8 @@ export default ({ getService }: FtrProviderContext) => {
ruleUpdate.rule_id = 'fake_id';
delete ruleUpdate.id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([ruleUpdate])
const { body } = await securitySolutionApi
.bulkUpdateRules({ body: [ruleUpdate] })
.expect(200);
expect(body).to.eql([
@ -478,11 +431,8 @@ export default ({ getService }: FtrProviderContext) => {
delete ruleUpdate.id;
// update one rule name and give a fake id for the second
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([ruleUpdate, ruleUpdate2])
const { body } = await securitySolutionApi
.bulkUpdateRules({ body: [ruleUpdate, ruleUpdate2] })
.expect(200);
const outputRule = updateUsername(getSimpleRuleOutput(), ELASTICSEARCH_USERNAME);
@ -516,11 +466,8 @@ export default ({ getService }: FtrProviderContext) => {
rule2.id = 'b3aa019a-656c-4311-b13b-4d9852e24347';
rule2.name = 'some other name';
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([rule1, rule2])
const { body } = await securitySolutionApi
.bulkUpdateRules({ body: [rule1, rule2] })
.expect(200);
const outputRule = updateUsername(getSimpleRuleOutput(), ELASTICSEARCH_USERNAME);
@ -557,23 +504,22 @@ export default ({ getService }: FtrProviderContext) => {
const rule1 = getSimpleRuleUpdate('rule-1');
rule1.name = 'some other name';
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([
{
...rule1,
exceptions_list: [
{
id: '2',
list_id: '123',
namespace_type: 'single',
type: ExceptionListTypeEnum.RULE_DEFAULT,
},
],
},
])
const { body } = await securitySolutionApi
.bulkUpdateRules({
body: [
{
...rule1,
exceptions_list: [
{
id: '2',
list_id: '123',
namespace_type: 'single',
type: ExceptionListTypeEnum.RULE_DEFAULT,
},
],
},
],
})
.expect(200);
expect(body).to.eql([
@ -597,34 +543,33 @@ export default ({ getService }: FtrProviderContext) => {
const rule2 = getSimpleRuleUpdate('rule-2');
rule2.name = 'some other name';
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([
{
...rule1,
exceptions_list: [
{
id: '2',
list_id: '123',
namespace_type: 'single',
type: ExceptionListTypeEnum.RULE_DEFAULT,
},
],
},
{
...rule2,
exceptions_list: [
{
id: '2',
list_id: '123',
namespace_type: 'single',
type: ExceptionListTypeEnum.RULE_DEFAULT,
},
],
},
])
const { body } = await securitySolutionApi
.bulkUpdateRules({
body: [
{
...rule1,
exceptions_list: [
{
id: '2',
list_id: '123',
namespace_type: 'single',
type: ExceptionListTypeEnum.RULE_DEFAULT,
},
],
},
{
...rule2,
exceptions_list: [
{
id: '2',
list_id: '123',
namespace_type: 'single',
type: ExceptionListTypeEnum.RULE_DEFAULT,
},
],
},
],
})
.expect(200);
expect(body).to.eql([
@ -659,11 +604,8 @@ export default ({ getService }: FtrProviderContext) => {
ruleToUpdate.id = ruleId;
delete ruleToUpdate.rule_id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([ruleToUpdate])
const { body } = await securitySolutionApi
.bulkUpdateRules({ body: [ruleToUpdate] })
.expect(200);
const updatedRule = body[0];
@ -864,18 +806,18 @@ export default ({ getService }: FtrProviderContext) => {
it('errors if trying to update investigation fields using legacy format', async () => {
// update rule
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([
{
...getSimpleRule(),
name: 'New name',
rule_id: ruleWithLegacyInvestigationField.params.ruleId,
investigation_fields: ['client.foo'],
},
])
const { body } = await securitySolutionApi
.bulkUpdateRules({
body: [
{
...getSimpleRule(),
name: 'New name',
rule_id: ruleWithLegacyInvestigationField.params.ruleId,
// @ts-expect-error testing invalid payload here
investigation_fields: ['client.foo'],
},
],
})
.expect(400);
expect(body.message).to.eql(
@ -885,33 +827,32 @@ export default ({ getService }: FtrProviderContext) => {
it('updates a rule with legacy investigation fields and transforms field in response', async () => {
// update rule
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_BULK_UPDATE)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send([
{
...getSimpleRule(),
name: 'New name - used to have legacy investigation fields',
rule_id: ruleWithLegacyInvestigationField.params.ruleId,
},
{
...getSimpleRule(),
name: 'New name - used to have legacy investigation fields, empty array',
rule_id: ruleWithLegacyInvestigationFieldEmptyArray.params.ruleId,
investigation_fields: {
field_names: ['foo'],
const { body } = await securitySolutionApi
.bulkUpdateRules({
body: [
{
...getSimpleRule(),
name: 'New name - used to have legacy investigation fields',
rule_id: ruleWithLegacyInvestigationField.params.ruleId,
},
},
{
...getSimpleRule(),
name: 'New name - never had legacy investigation fields',
rule_id: 'rule-with-investigation-field',
investigation_fields: {
field_names: ['bar'],
{
...getSimpleRule(),
name: 'New name - used to have legacy investigation fields, empty array',
rule_id: ruleWithLegacyInvestigationFieldEmptyArray.params.ruleId,
investigation_fields: {
field_names: ['foo'],
},
},
},
])
{
...getSimpleRule(),
name: 'New name - never had legacy investigation fields',
rule_id: 'rule-with-investigation-field',
investigation_fields: {
field_names: ['bar'],
},
},
],
})
.expect(200);
expect(body[0].investigation_fields).to.eql(undefined);

View file

@ -8,7 +8,6 @@
import expect from '@kbn/expect';
import { Rule } from '@kbn/alerting-plugin/common';
import { BaseRuleParams } from '@kbn/security-solution-plugin/server/lib/detection_engine/rule_schema';
import { DETECTION_ENGINE_RULES_URL } from '@kbn/security-solution-plugin/common/constants';
import {
removeServerGeneratedProperties,
@ -34,6 +33,7 @@ import { FtrProviderContext } from '../../../../../ftr_provider_context';
export default ({ getService }: FtrProviderContext) => {
const supertest = getService('supertest');
const securitySolutionApi = getService('securitySolutionApi');
const log = getService('log');
const es = getService('es');
// TODO: add a new service for pulling kibana username, similar to getService('es')
@ -91,12 +91,7 @@ export default ({ getService }: FtrProviderContext) => {
updatedRule.actions = [action1];
delete updatedRule.id;
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(updatedRule)
.expect(200);
const { body } = await securitySolutionApi.updateRule({ body: updatedRule }).expect(200);
const bodyToCompare = removeServerGeneratedPropertiesIncludingRuleId(body);
@ -160,12 +155,8 @@ export default ({ getService }: FtrProviderContext) => {
investigation_fields: ['foo'],
};
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(updatedRule)
.expect(400);
// @ts-expect-error we are testing the invalid payload
const { body } = await securitySolutionApi.updateRule({ body: updatedRule }).expect(400);
expect(body.message).to.eql(
'[request body]: investigation_fields: Expected object, received array'
@ -176,12 +167,7 @@ export default ({ getService }: FtrProviderContext) => {
// rule_id of a rule with legacy investigation fields set
const updatedRule = getSimpleRuleUpdate(ruleWithLegacyInvestigationField.params.ruleId);
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(updatedRule)
.expect(200);
const { body } = await securitySolutionApi.updateRule({ body: updatedRule }).expect(200);
const bodyToCompare = removeServerGeneratedProperties(body);
expect(bodyToCompare.investigation_fields).to.eql(undefined);
@ -202,12 +188,7 @@ export default ({ getService }: FtrProviderContext) => {
},
};
const { body } = await supertest
.put(DETECTION_ENGINE_RULES_URL)
.set('kbn-xsrf', 'true')
.set('elastic-api-version', '2023-10-31')
.send(updatedRule)
.expect(200);
const { body } = await securitySolutionApi.updateRule({ body: updatedRule }).expect(200);
const bodyToCompare = removeServerGeneratedProperties(body);
expect(bodyToCompare.investigation_fields).to.eql({

View file

@ -29,6 +29,7 @@ const deploymentAgnosticApiIntegrationServices = _.pick(apiIntegrationServices,
'security',
'usageAPI',
'console',
'securitySolutionApi',
]);
export const services = {