Skip to content

Commit

Permalink
[SECURITY_SOLUTION][ENDPOINT] Fix created_by for Trusted Apps Creat…
Browse files Browse the repository at this point in the history
…e api to reflect current logged in user (#76557)

* Fix: use exceptionLists client from route handler context
* Adjust test to use `listMock`
* Remove exceptionListClient service from `EndpointAppContextService`
* Added UT for Trusted Apps to validate that ExceptionListClient from context is used

Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
  • Loading branch information
paul-tavares and elasticmachine authored Sep 8, 2020
1 parent 851c125 commit bb2aa42
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,10 @@ import {
import { AgentService, IngestManagerStartContract } from '../../../ingest_manager/server';
import { getPackagePolicyCreateCallback } from './ingest_integration';
import { ManifestManager } from './services/artifacts';
import { ExceptionListClient } from '../../../lists/server';

export type EndpointAppContextServiceStartContract = Partial<
Pick<IngestManagerStartContract, 'agentService'>
> & {
exceptionsListService: ExceptionListClient;
logger: Logger;
manifestManager?: ManifestManager;
registerIngestCallback?: IngestManagerStartContract['registerExternalCallback'];
Expand All @@ -32,11 +30,9 @@ export class EndpointAppContextService {
private agentService: AgentService | undefined;
private manifestManager: ManifestManager | undefined;
private savedObjectsStart: SavedObjectsServiceStart | undefined;
private exceptionsListService: ExceptionListClient | undefined;

public start(dependencies: EndpointAppContextServiceStartContract) {
this.agentService = dependencies.agentService;
this.exceptionsListService = dependencies.exceptionsListService;
this.manifestManager = dependencies.manifestManager;
this.savedObjectsStart = dependencies.savedObjectsStart;

Expand All @@ -54,13 +50,6 @@ export class EndpointAppContextService {
return this.agentService;
}

public getExceptionsList() {
if (!this.exceptionsListService) {
throw new Error('exceptionsListService not set');
}
return this.exceptionsListService;
}

public getManifestManager(): ManifestManager | undefined {
return this.manifestManager;
}
Expand Down
2 changes: 0 additions & 2 deletions x-pack/plugins/security_solution/server/endpoint/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import {
import { ManifestManager } from './services/artifacts/manifest_manager/manifest_manager';
import { getManifestManagerMock } from './services/artifacts/manifest_manager/manifest_manager.mock';
import { EndpointAppContext } from './types';
import { listMock } from '../../../lists/server/mocks';

/**
* Creates a mocked EndpointAppContext.
Expand Down Expand Up @@ -59,7 +58,6 @@ export const createMockEndpointAppContextServiceStartContract = (): jest.Mocked<
> => {
return {
agentService: createMockAgentService(),
exceptionsListService: listMock.getExceptionListClient(),
logger: loggingSystemMock.create().get('mock_endpoint_app_context'),
savedObjectsStart: savedObjectsServiceMock.createStartContract(),
manifestManager: getManifestManagerMock(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { RequestHandler } from 'kibana/server';
import { RequestHandler, RequestHandlerContext } from 'kibana/server';
import {
GetTrustedAppsListRequest,
GetTrustedListAppsResponse,
Expand All @@ -14,16 +14,26 @@ import { EndpointAppContext } from '../../types';
import { exceptionItemToTrustedAppItem, newTrustedAppItemToExceptionItem } from './utils';
import { ENDPOINT_TRUSTED_APPS_LIST_ID } from '../../../../../lists/common/constants';
import { DeleteTrustedAppsRequestParams } from './types';
import { ExceptionListClient } from '../../../../../lists/server';

const exceptionListClientFromContext = (context: RequestHandlerContext): ExceptionListClient => {
const exceptionLists = context.lists?.getExceptionListClient();

if (!exceptionLists) {
throw new Error('Exception List client not found');
}

return exceptionLists;
};

export const getTrustedAppsDeleteRouteHandler = (
endpointAppContext: EndpointAppContext
): RequestHandler<DeleteTrustedAppsRequestParams, undefined, undefined> => {
const logger = endpointAppContext.logFactory.get('trusted_apps');

return async (context, req, res) => {
const exceptionsListService = endpointAppContext.service.getExceptionsList();

try {
const exceptionsListService = exceptionListClientFromContext(context);
const { id } = req.params;
const response = await exceptionsListService.deleteExceptionListItem({
id,
Expand All @@ -49,10 +59,10 @@ export const getTrustedAppsListRouteHandler = (
const logger = endpointAppContext.logFactory.get('trusted_apps');

return async (context, req, res) => {
const exceptionsListService = endpointAppContext.service.getExceptionsList();
const { page, per_page: perPage } = req.query;

try {
const exceptionsListService = exceptionListClientFromContext(context);
// Ensure list is created if it does not exist
await exceptionsListService.createTrustedAppsList();
const results = await exceptionsListService.findExceptionListItem({
Expand Down Expand Up @@ -83,11 +93,11 @@ export const getTrustedAppsCreateRouteHandler = (
): RequestHandler<undefined, undefined, PostTrustedAppCreateRequest> => {
const logger = endpointAppContext.logFactory.get('trusted_apps');

return async (constext, req, res) => {
const exceptionsListService = endpointAppContext.service.getExceptionsList();
return async (context, req, res) => {
const newTrustedApp = req.body;

try {
const exceptionsListService = exceptionListClientFromContext(context);
// Ensure list is created if it does not exist
await exceptionsListService.createTrustedAppsList();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,23 @@ import {
import { xpackMocks } from '../../../../../../mocks';
import { ENDPOINT_TRUSTED_APPS_LIST_ID } from '../../../../../lists/common/constants';
import { EndpointAppContext } from '../../types';
import { ExceptionListClient } from '../../../../../lists/server';
import { getExceptionListItemSchemaMock } from '../../../../../lists/common/schemas/response/exception_list_item_schema.mock';
import { ExceptionListClient, ListClient } from '../../../../../lists/server';
import { listMock } from '../../../../../lists/server/mocks';
import { ExceptionListItemSchema } from '../../../../../lists/common/schemas/response';
import { DeleteTrustedAppsRequestParams } from './types';
import { getExceptionListItemSchemaMock } from '../../../../../lists/common/schemas/response/exception_list_item_schema.mock';

type RequestHandlerContextWithLists = ReturnType<typeof xpackMocks.createRequestHandlerContext> & {
lists?: {
getListClient: () => jest.Mocked<ListClient>;
getExceptionListClient: () => jest.Mocked<ExceptionListClient>;
};
};

describe('when invoking endpoint trusted apps route handlers', () => {
let routerMock: jest.Mocked<IRouter>;
let endpointAppContextService: EndpointAppContextService;
let context: ReturnType<typeof xpackMocks.createRequestHandlerContext>;
let context: RequestHandlerContextWithLists;
let response: ReturnType<typeof httpServerMock.createResponseFactory>;
let exceptionsListClient: jest.Mocked<ExceptionListClient>;
let endpointAppContext: EndpointAppContext;
Expand All @@ -41,7 +49,7 @@ describe('when invoking endpoint trusted apps route handlers', () => {
routerMock = httpServiceMock.createRouter();
endpointAppContextService = new EndpointAppContextService();
const startContract = createMockEndpointAppContextServiceStartContract();
exceptionsListClient = startContract.exceptionsListService as jest.Mocked<ExceptionListClient>;
exceptionsListClient = listMock.getExceptionListClient() as jest.Mocked<ExceptionListClient>;
endpointAppContextService.start(startContract);
endpointAppContext = {
...createMockEndpointAppContext(),
Expand All @@ -50,7 +58,13 @@ describe('when invoking endpoint trusted apps route handlers', () => {
registerTrustedAppsRoutes(routerMock, endpointAppContext);

// For use in individual API calls
context = xpackMocks.createRequestHandlerContext();
context = {
...xpackMocks.createRequestHandlerContext(),
lists: {
getListClient: jest.fn(),
getExceptionListClient: jest.fn().mockReturnValue(exceptionsListClient),
},
};
response = httpServerMock.createResponseFactory();
});

Expand All @@ -74,6 +88,12 @@ describe('when invoking endpoint trusted apps route handlers', () => {
)!;
});

it('should use ExceptionListClient from route handler context', async () => {
const request = createListRequest();
await routeHandler(context, request, response);
expect(context.lists?.getExceptionListClient).toHaveBeenCalled();
});

it('should create the Trusted Apps List first', async () => {
const request = createListRequest();
await routeHandler(context, request, response);
Expand Down Expand Up @@ -155,6 +175,12 @@ describe('when invoking endpoint trusted apps route handlers', () => {
});
});

it('should use ExceptionListClient from route handler context', async () => {
const request = createPostRequest();
await routeHandler(context, request, response);
expect(context.lists?.getExceptionListClient).toHaveBeenCalled();
});

it('should create trusted app list first', async () => {
const request = createPostRequest();
await routeHandler(context, request, response);
Expand Down Expand Up @@ -238,6 +264,11 @@ describe('when invoking endpoint trusted apps route handlers', () => {
});
});

it('should use ExceptionListClient from route handler context', async () => {
await routeHandler(context, request, response);
expect(context.lists?.getExceptionListClient).toHaveBeenCalled();
});

it('should return 200 on successful delete', async () => {
await routeHandler(context, request, response);
expect(exceptionsListClient.deleteExceptionListItem).toHaveBeenCalledWith({
Expand Down
1 change: 0 additions & 1 deletion x-pack/plugins/security_solution/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,6 @@ export class Plugin implements IPlugin<PluginSetup, PluginStart, SetupPlugins, S

this.endpointAppContextService.start({
agentService: plugins.ingestManager?.agentService,
exceptionsListService: this.lists!.getExceptionListClient(savedObjectsClient, 'kibana'),
logger: this.logger,
manifestManager,
registerIngestCallback,
Expand Down

0 comments on commit bb2aa42

Please sign in to comment.