Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
* 2.0.
*/

export * from './set_alert_assignees/set_alert_assignees_route';
export * from './set_alert_assignees_route.gen';
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
* 2.0.
*/

export * from './set_alert_assignees/set_alert_assignees_route.mock';
export * from './set_alert_assignees_route.mock';

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* 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 { z } from 'zod';

/*
* NOTICE: Do not edit this file manually.
* This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator.
*/

import { NonEmptyString } from '../model/rule_schema/common_attributes.gen';

export type AlertAssignees = z.infer<typeof AlertAssignees>;
export const AlertAssignees = z.object({
/**
* A list of users ids to assign.
*/
add: z.array(NonEmptyString),
/**
* A list of users ids to unassign.
*/
remove: z.array(NonEmptyString),
});

/**
* A list of alerts ids.
*/
export type AlertIds = z.infer<typeof AlertIds>;
export const AlertIds = z.array(NonEmptyString).min(1);

export type SetAlertAssigneesRequestBody = z.infer<typeof SetAlertAssigneesRequestBody>;
export const SetAlertAssigneesRequestBody = z.object({
/**
* Details about the assignees to assign and unassign.
*/
assignees: AlertAssignees,
/**
* List of alerts ids to assign and unassign passed assignees.
*/
ids: AlertIds,
});
export type SetAlertAssigneesRequestBodyInput = z.input<typeof SetAlertAssigneesRequestBody>;
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* 2.0.
*/

import type { SetAlertAssigneesRequestBody } from './set_alert_assignees_route';
import type { SetAlertAssigneesRequestBody } from './set_alert_assignees_route.gen';

export const getSetAlertAssigneesRequestMock = (
assigneesToAdd: string[] = [],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
openapi: 3.0.0
info:
title: Assign alerts API endpoint
version: '2023-10-31'
paths:
/api/detection_engine/signals/assignees:
summary: Assigns users to alerts
post:
operationId: SetAlertAssignees
x-codegen-enabled: true
description: Assigns users to alerts.
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- assignees
- ids
properties:
assignees:
$ref: '#/components/schemas/AlertAssignees'
description: Details about the assignees to assign and unassign.
ids:
$ref: '#/components/schemas/AlertIds'
description: List of alerts ids to assign and unassign passed assignees.
responses:
200:
description: Indicates a successful call.
400:
description: Invalid request.

components:
schemas:
AlertAssignees:
type: object
required:
- add
- remove
properties:
add:
type: array
items:
$ref: '../model/rule_schema/common_attributes.schema.yaml#/components/schemas/NonEmptyString'
description: A list of users ids to assign.
remove:
type: array
items:
$ref: '../model/rule_schema/common_attributes.schema.yaml#/components/schemas/NonEmptyString'
description: A list of users ids to unassign.

AlertIds:
type: array
items:
$ref: '../model/rule_schema/common_attributes.schema.yaml#/components/schemas/NonEmptyString'
minItems: 1
description: A list of alerts ids.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
/* eslint-disable @typescript-eslint/naming-convention */

import * as t from 'io-ts';
import { NonEmptyArray, NonEmptyString, PositiveInteger } from '@kbn/securitysolution-io-ts-types';
import { PositiveInteger } from '@kbn/securitysolution-io-ts-types';

export const file_name = t.string;
export type FileName = t.TypeOf<typeof file_name>;
Expand Down Expand Up @@ -42,9 +42,6 @@ export const signal_status_query = t.object;
export const alert_tag_ids = t.array(t.string);
export type AlertTagIds = t.TypeOf<typeof alert_tag_ids>;

export const alert_ids = NonEmptyArray(NonEmptyString);
export type AlertIds = t.TypeOf<typeof alert_ids>;

export const indexRecord = t.record(
t.string,
t.type({
Expand Down Expand Up @@ -111,12 +108,5 @@ export const alert_tags = t.type({

export type AlertTags = t.TypeOf<typeof alert_tags>;

export const alert_assignees = t.type({
add: t.array(NonEmptyString),
remove: t.array(NonEmptyString),
});

export type AlertAssignees = t.TypeOf<typeof alert_assignees>;

export const user_search_term = t.string;
export type UserSearchTerm = t.TypeOf<typeof user_search_term>;
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@
* 2.0.
*/

export * from './suggest_user_profiles/suggest_user_profiles_route';
export * from './suggest_user_profiles_route.gen';

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* 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 { z } from 'zod';

/*
* NOTICE: Do not edit this file manually.
* This file is automatically generated by the OpenAPI Generator, @kbn/openapi-generator.
*/

export type SuggestUserProfilesRequestQuery = z.infer<typeof SuggestUserProfilesRequestQuery>;
export const SuggestUserProfilesRequestQuery = z.object({
/**
* Query string used to match name-related fields in user profiles. The following fields are treated as name-related: username, full_name and email
*/
searchTerm: z.string().optional(),
});
export type SuggestUserProfilesRequestQueryInput = z.input<typeof SuggestUserProfilesRequestQuery>;
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
openapi: 3.0.0
info:
title: Suggest user profiles API endpoint
version: '2023-10-31'
paths:
/api/detection_engine/signals/_find:
summary: Suggests user profiles based on provided search term
post:
operationId: SuggestUserProfiles
x-codegen-enabled: true
description: Suggests user profiles.
parameters:
- name: searchTerm
in: query
required: false
description: "Query string used to match name-related fields in user profiles. The following fields are treated as name-related: username, full_name and email"
schema:
type: string
responses:
200:
description: Indicates a successful call.
400:
description: Invalid request.
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,9 @@ describe('setAlertAssigneesRoute', () => {

const result = server.validate(request);

expect(result.badRequest).toHaveBeenCalledWith('Invalid value "[]" supplied to "ids"');
expect(result.badRequest).toHaveBeenCalledWith(
'ids: Array must contain at least 1 element(s)'
);
});

test('rejects if empty string provided as an alert id', async () => {
Expand All @@ -89,7 +91,9 @@ describe('setAlertAssigneesRoute', () => {

const result = server.validate(request);

expect(result.badRequest).toHaveBeenCalledWith('Invalid value "" supplied to "ids"');
expect(result.badRequest).toHaveBeenCalledWith(
'ids.0: String must contain at least 1 character(s), ids.0: Invalid'
);
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,14 @@

import { transformError } from '@kbn/securitysolution-es-utils';
import { uniq } from 'lodash/fp';
import type { SetAlertAssigneesRequestBodyDecoded } from '../../../../../common/api/detection_engine/alert_assignees';
import { setAlertAssigneesRequestBody } from '../../../../../common/api/detection_engine/alert_assignees';
import { SetAlertAssigneesRequestBody } from '../../../../../common/api/detection_engine/alert_assignees';
import type { SecuritySolutionPluginRouter } from '../../../../types';
import {
DEFAULT_ALERTS_INDEX,
DETECTION_ENGINE_ALERT_ASSIGNEES_URL,
} from '../../../../../common/constants';
import { buildSiemResponse } from '../utils';
import { buildRouteValidation } from '../../../../utils/build_validation/route_validation';
import { buildRouteValidationWithZod } from '../../../../utils/build_validation/route_validation';
import { validateAlertAssigneesArrays } from './helpers';

export const setAlertAssigneesRoute = (router: SecuritySolutionPluginRouter) => {
Expand All @@ -32,10 +31,7 @@ export const setAlertAssigneesRoute = (router: SecuritySolutionPluginRouter) =>
version: '2023-10-31',
validate: {
request: {
body: buildRouteValidation<
typeof setAlertAssigneesRequestBody,
SetAlertAssigneesRequestBodyDecoded
>(setAlertAssigneesRequestBody),
body: buildRouteValidationWithZod(SetAlertAssigneesRequestBody),
},
},
},
Expand All @@ -44,7 +40,6 @@ export const setAlertAssigneesRoute = (router: SecuritySolutionPluginRouter) =>
const core = await context.core;
const securitySolution = await context.securitySolution;
const esClient = core.elasticsearch.client.asCurrentUser;
const siemClient = securitySolution?.getAppClient();
const siemResponse = buildSiemResponse(response);
const validationErrors = validateAlertAssigneesArrays(assignees);
const spaceId = securitySolution?.getSpaceId() ?? 'default';
Expand All @@ -53,10 +48,6 @@ export const setAlertAssigneesRoute = (router: SecuritySolutionPluginRouter) =>
return siemResponse.error({ statusCode: 400, body: validationErrors });
}

if (!siemClient) {
return siemResponse.error({ statusCode: 404 });
}

const assigneesToAdd = uniq(assignees.add);
const assigneesToRemove = uniq(assignees.remove);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,8 @@ import type { SecuritySolutionPluginRouter } from '../../../../types';
import { DETECTION_ENGINE_ALERT_SUGGEST_USERS_URL } from '../../../../../common/constants';
import { buildSiemResponse } from '../utils';
import type { StartPlugins } from '../../../../plugin';
import { buildRouteValidation } from '../../../../utils/build_validation/route_validation';

import type { SuggestUserProfilesRequestQueryDecoded } from '../../../../../common/api/detection_engine/users';
import { suggestUserProfilesRequestQuery } from '../../../../../common/api/detection_engine/users';
import { buildRouteValidationWithZod } from '../../../../utils/build_validation/route_validation';
import { SuggestUserProfilesRequestQuery } from '../../../../../common/api/detection_engine/users';

export const suggestUserProfilesRoute = (
router: SecuritySolutionPluginRouter,
Expand All @@ -34,10 +32,7 @@ export const suggestUserProfilesRoute = (
version: '2023-10-31',
validate: {
request: {
query: buildRouteValidation<
typeof suggestUserProfilesRequestQuery,
SuggestUserProfilesRequestQueryDecoded
>(suggestUserProfilesRequestQuery),
query: buildRouteValidationWithZod(SuggestUserProfilesRequestQuery),
},
},
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export default ({ getService }: FtrProviderContext) => {

expect(body).to.eql({
error: 'Bad Request',
message: '[request body]: Invalid value "[]" supplied to "ids"',
message: '[request body]: ids: Array must contain at least 1 element(s)',
statusCode: 400,
});
});
Expand All @@ -64,7 +64,8 @@ export default ({ getService }: FtrProviderContext) => {

expect(body).to.eql({
error: 'Bad Request',
message: '[request body]: Invalid value "" supplied to "ids"',
message:
'[request body]: ids.1: String must contain at least 1 character(s), ids.1: Invalid',
statusCode: 400,
});
});
Expand Down