Skip to content

Commit

Permalink
[EDR Workflows] Deprecate public endpoint/suggestions api endpoint in…
Browse files Browse the repository at this point in the history
… favour of an internal one (#194832)

New internal GET `/internal/api/endpoint/suggestions/{suggestion_type}`
route.

Current public GET `/api/endpoint/suggestions/{suggestion_type}` route
is set to deprecated.


UI uses now the internal GET
`/internal/api/endpoint/suggestions/{suggestion_type}` api route

---------

Co-authored-by: kibanamachine <[email protected]>
  • Loading branch information
szwarckonrad and kibanamachine authored Oct 8, 2024
1 parent ca1d375 commit ef4755a
Show file tree
Hide file tree
Showing 13 changed files with 91 additions and 9 deletions.
1 change: 1 addition & 0 deletions oas_docs/output/kibana.serverless.staging.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8096,6 +8096,7 @@ paths:
- Security Endpoint Management API
/api/endpoint/suggestions/{suggestion_type}:
post:
deprecated: true
operationId: GetEndpointSuggestions
parameters:
- in: path
Expand Down
1 change: 1 addition & 0 deletions oas_docs/output/kibana.serverless.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8096,6 +8096,7 @@ paths:
- Security Endpoint Management API
/api/endpoint/suggestions/{suggestion_type}:
post:
deprecated: true
operationId: GetEndpointSuggestions
parameters:
- in: path
Expand Down
1 change: 1 addition & 0 deletions oas_docs/output/kibana.staging.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11468,6 +11468,7 @@ paths:
- Security Endpoint Management API
/api/endpoint/suggestions/{suggestion_type}:
post:
deprecated: true
operationId: GetEndpointSuggestions
parameters:
- in: path
Expand Down
1 change: 1 addition & 0 deletions oas_docs/output/kibana.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11468,6 +11468,7 @@ paths:
- Security Endpoint Management API
/api/endpoint/suggestions/{suggestion_type}:
post:
deprecated: true
operationId: GetEndpointSuggestions
parameters:
- in: path
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ info:
paths:
/api/endpoint/suggestions/{suggestion_type}:
post:
deprecated: true
summary: Get suggestions
operationId: GetEndpointSuggestions
x-codegen-enabled: true
Expand Down
3 changes: 3 additions & 0 deletions x-pack/plugins/security_solution/common/endpoint/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export const FILE_STORAGE_DATA_INDEX = getFileDataIndexName('endpoint');

// Location from where all Endpoint related APIs are mounted
export const BASE_ENDPOINT_ROUTE = '/api/endpoint';
export const BASE_INTERNAL_ENDPOINT_ROUTE = `/internal${BASE_ENDPOINT_ROUTE}`;

// Endpoint API routes
export const HOST_METADATA_LIST_ROUTE = `${BASE_ENDPOINT_ROUTE}/metadata`;
Expand All @@ -72,7 +73,9 @@ export const AGENT_POLICY_SUMMARY_ROUTE = `${BASE_POLICY_ROUTE}/summaries`;
export const PROTECTION_UPDATES_NOTE_ROUTE = `${BASE_ENDPOINT_ROUTE}/protection_updates_note/{package_policy_id}`;

/** Suggestions routes */
/** @deprecated public route, use {@link SUGGESTIONS_INTERNAL_ROUTE} internal route */
export const SUGGESTIONS_ROUTE = `${BASE_ENDPOINT_ROUTE}/suggestions/{suggestion_type}`;
export const SUGGESTIONS_INTERNAL_ROUTE = `${BASE_INTERNAL_ENDPOINT_ROUTE}/suggestions/{suggestion_type}`;

/**
* Action Response Routes
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,7 @@ paths:
- Security Endpoint Management API
/api/endpoint/suggestions/{suggestion_type}:
post:
deprecated: true
operationId: GetEndpointSuggestions
parameters:
- in: path
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,7 @@ paths:
- Security Endpoint Management API
/api/endpoint/suggestions/{suggestion_type}:
post:
deprecated: true
operationId: GetEndpointSuggestions
parameters:
- in: path
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* 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 type { HttpSetup } from '@kbn/core-http-browser';
import { EventFiltersApiClient } from './api_client';
import { coreMock } from '@kbn/core/public/mocks';
import { SUGGESTIONS_INTERNAL_ROUTE } from '../../../../../common/endpoint/constants';
import { resolvePathVariables } from '../../../../common/utils/resolve_path_variables';

describe('EventFiltersApiClient', () => {
let fakeHttpServices: jest.Mocked<HttpSetup>;
let eventFiltersApiClient: EventFiltersApiClient;

beforeAll(() => {
fakeHttpServices = coreMock.createStart().http as jest.Mocked<HttpSetup>;
eventFiltersApiClient = new EventFiltersApiClient(fakeHttpServices);
});

beforeEach(() => {
jest.clearAllMocks();
});

it('should call the SUGGESTIONS_INTERNAL_ROUTE with correct URL and body', async () => {
await eventFiltersApiClient.getSuggestions({
field: 'host.name',
query: 'test',
});

expect(fakeHttpServices.post).toHaveBeenCalledWith(
resolvePathVariables(SUGGESTIONS_INTERNAL_ROUTE, { suggestion_type: 'eventFilters' }),
{
version: '1',
body: JSON.stringify({
field: 'host.name',
query: 'test',
}),
}
);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import type {
UpdateExceptionListItemSchema,
} from '@kbn/securitysolution-io-ts-list-types';
import { removeIdFromExceptionItemsEntries } from '@kbn/securitysolution-list-hooks';
import { SUGGESTIONS_INTERNAL_ROUTE } from '../../../../../common/endpoint/constants';
import type { EndpointSuggestionsBody } from '../../../../../common/api/endpoint';
import { SUGGESTIONS_ROUTE } from '../../../../../common/endpoint/constants';
import { resolvePathVariables } from '../../../../common/utils/resolve_path_variables';
import { ExceptionsListApiClient } from '../../../services/exceptions_list/exceptions_list_api_client';
import { EVENT_FILTER_LIST_DEFINITION } from '../constants';
Expand Down Expand Up @@ -55,9 +55,9 @@ export class EventFiltersApiClient extends ExceptionsListApiClient {
*/
async getSuggestions(body: EndpointSuggestionsBody): Promise<string[]> {
const result: string[] = await this.getHttp().post(
resolvePathVariables(SUGGESTIONS_ROUTE, { suggestion_type: 'eventFilters' }),
resolvePathVariables(SUGGESTIONS_INTERNAL_ROUTE, { suggestion_type: 'eventFilters' }),
{
version: this.version,
version: '1',
body: JSON.stringify(body),
}
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ describe('Exceptions List Api Client', () => {
);
});

describe('Wen getting an instance', () => {
describe('When getting an instance', () => {
/**
* ATENTION: Skipping or modifying this test may cause the other test fails because it's creating the initial Singleton instance.
* ATTENTION: Skipping or modifying this test may cause the other test fails because it's creating the initial Singleton instance.
* If you want to run tests individually, add this one to the execution with the .only method
*/
it('New instance is created the first time and the create list method is called', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ import {
} from '.';
import { EndpointActionGenerator } from '../../../../common/endpoint/data_generators/endpoint_action_generator';
import { getEndpointAuthzInitialStateMock } from '../../../../common/endpoint/service/authz/mocks';
import { eventsIndexPattern, SUGGESTIONS_ROUTE } from '../../../../common/endpoint/constants';
import {
eventsIndexPattern,
SUGGESTIONS_INTERNAL_ROUTE,
} from '../../../../common/endpoint/constants';
import { EndpointAppContextService } from '../../endpoint_app_context_services';

jest.mock('@kbn/unified-search-plugin/server/autocomplete/terms_enum', () => {
Expand Down Expand Up @@ -184,15 +187,15 @@ describe('when calling the Suggestions route handler', () => {
routerMock,
'post',
routePrefix,
'2023-10-31'
'1'
);

await routeHandler(ctx as unknown as RequestHandlerContext, mockRequest, mockResponse);
};
});

it('should respond with forbidden', async () => {
await callRoute(SUGGESTIONS_ROUTE, {
await callRoute(SUGGESTIONS_INTERNAL_ROUTE, {
params: { suggestion_type: 'eventFilters' },
authz: { canReadEventFilters: true, canWriteEventFilters: false },
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ import type {
SecuritySolutionRequestHandlerContext,
} from '../../../types';
import type { EndpointAppContext } from '../../types';
import { eventsIndexPattern, SUGGESTIONS_ROUTE } from '../../../../common/endpoint/constants';
import {
eventsIndexPattern,
SUGGESTIONS_INTERNAL_ROUTE,
SUGGESTIONS_ROUTE,
} from '../../../../common/endpoint/constants';
import { withEndpointAuthz } from '../with_endpoint_authz';
import { errorHandler } from '../error_handler';

Expand All @@ -39,6 +43,7 @@ export function registerEndpointSuggestionsRoutes(
access: 'public',
path: SUGGESTIONS_ROUTE,
options: { authRequired: true, tags: ['access:securitySolution'] },
deprecated: true,
})
.addVersion(
{
Expand All @@ -53,6 +58,26 @@ export function registerEndpointSuggestionsRoutes(
getEndpointSuggestionsRequestHandler(config$, getLogger(endpointContext))
)
);

router.versioned
.post({
access: 'internal',
path: SUGGESTIONS_INTERNAL_ROUTE,
options: { authRequired: true, tags: ['access:securitySolution'] },
})
.addVersion(
{
version: '1',
validate: {
request: EndpointSuggestionsSchema,
},
},
withEndpointAuthz(
{ any: ['canWriteEventFilters'] },
endpointContext.logFactory.get('endpointSuggestions'),
getEndpointSuggestionsRequestHandler(config$, getLogger(endpointContext))
)
);
}

export const getEndpointSuggestionsRequestHandler = (
Expand Down

0 comments on commit ef4755a

Please sign in to comment.