Skip to content

Commit b6d317e

Browse files
[SECURITY_SOLUTION][ENDPOINT] Fix created_by for Trusted Apps Create api to reflect current logged in user (#76557) (#76974)
* 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> Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
1 parent 56162d7 commit b6d317e

File tree

5 files changed

+52
-25
lines changed

5 files changed

+52
-25
lines changed

x-pack/plugins/security_solution/server/endpoint/endpoint_app_context_services.ts

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,10 @@ import {
1212
import { AgentService, IngestManagerStartContract } from '../../../ingest_manager/server';
1313
import { getPackagePolicyCreateCallback } from './ingest_integration';
1414
import { ManifestManager } from './services/artifacts';
15-
import { ExceptionListClient } from '../../../lists/server';
1615

1716
export type EndpointAppContextServiceStartContract = Partial<
1817
Pick<IngestManagerStartContract, 'agentService'>
1918
> & {
20-
exceptionsListService: ExceptionListClient;
2119
logger: Logger;
2220
manifestManager?: ManifestManager;
2321
registerIngestCallback?: IngestManagerStartContract['registerExternalCallback'];
@@ -32,11 +30,9 @@ export class EndpointAppContextService {
3230
private agentService: AgentService | undefined;
3331
private manifestManager: ManifestManager | undefined;
3432
private savedObjectsStart: SavedObjectsServiceStart | undefined;
35-
private exceptionsListService: ExceptionListClient | undefined;
3633

3734
public start(dependencies: EndpointAppContextServiceStartContract) {
3835
this.agentService = dependencies.agentService;
39-
this.exceptionsListService = dependencies.exceptionsListService;
4036
this.manifestManager = dependencies.manifestManager;
4137
this.savedObjectsStart = dependencies.savedObjectsStart;
4238

@@ -54,13 +50,6 @@ export class EndpointAppContextService {
5450
return this.agentService;
5551
}
5652

57-
public getExceptionsList() {
58-
if (!this.exceptionsListService) {
59-
throw new Error('exceptionsListService not set');
60-
}
61-
return this.exceptionsListService;
62-
}
63-
6453
public getManifestManager(): ManifestManager | undefined {
6554
return this.manifestManager;
6655
}

x-pack/plugins/security_solution/server/endpoint/mocks.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import {
2121
import { ManifestManager } from './services/artifacts/manifest_manager/manifest_manager';
2222
import { getManifestManagerMock } from './services/artifacts/manifest_manager/manifest_manager.mock';
2323
import { EndpointAppContext } from './types';
24-
import { listMock } from '../../../lists/server/mocks';
2524

2625
/**
2726
* Creates a mocked EndpointAppContext.
@@ -59,7 +58,6 @@ export const createMockEndpointAppContextServiceStartContract = (): jest.Mocked<
5958
> => {
6059
return {
6160
agentService: createMockAgentService(),
62-
exceptionsListService: listMock.getExceptionListClient(),
6361
logger: loggingSystemMock.create().get('mock_endpoint_app_context'),
6462
savedObjectsStart: savedObjectsServiceMock.createStartContract(),
6563
manifestManager: getManifestManagerMock(),

x-pack/plugins/security_solution/server/endpoint/routes/trusted_apps/handlers.ts

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
* you may not use this file except in compliance with the Elastic License.
55
*/
66

7-
import { RequestHandler } from 'kibana/server';
7+
import { RequestHandler, RequestHandlerContext } from 'kibana/server';
88
import {
99
GetTrustedAppsListRequest,
1010
GetTrustedListAppsResponse,
@@ -14,16 +14,26 @@ import { EndpointAppContext } from '../../types';
1414
import { exceptionItemToTrustedAppItem, newTrustedAppItemToExceptionItem } from './utils';
1515
import { ENDPOINT_TRUSTED_APPS_LIST_ID } from '../../../../../lists/common/constants';
1616
import { DeleteTrustedAppsRequestParams } from './types';
17+
import { ExceptionListClient } from '../../../../../lists/server';
18+
19+
const exceptionListClientFromContext = (context: RequestHandlerContext): ExceptionListClient => {
20+
const exceptionLists = context.lists?.getExceptionListClient();
21+
22+
if (!exceptionLists) {
23+
throw new Error('Exception List client not found');
24+
}
25+
26+
return exceptionLists;
27+
};
1728

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

2334
return async (context, req, res) => {
24-
const exceptionsListService = endpointAppContext.service.getExceptionsList();
25-
2635
try {
36+
const exceptionsListService = exceptionListClientFromContext(context);
2737
const { id } = req.params;
2838
const response = await exceptionsListService.deleteExceptionListItem({
2939
id,
@@ -49,10 +59,10 @@ export const getTrustedAppsListRouteHandler = (
4959
const logger = endpointAppContext.logFactory.get('trusted_apps');
5060

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

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

86-
return async (constext, req, res) => {
87-
const exceptionsListService = endpointAppContext.service.getExceptionsList();
96+
return async (context, req, res) => {
8897
const newTrustedApp = req.body;
8998

9099
try {
100+
const exceptionsListService = exceptionListClientFromContext(context);
91101
// Ensure list is created if it does not exist
92102
await exceptionsListService.createTrustedAppsList();
93103

x-pack/plugins/security_solution/server/endpoint/routes/trusted_apps/trusted_apps.test.ts

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,23 @@ import {
2424
import { xpackMocks } from '../../../../../../mocks';
2525
import { ENDPOINT_TRUSTED_APPS_LIST_ID } from '../../../../../lists/common/constants';
2626
import { EndpointAppContext } from '../../types';
27-
import { ExceptionListClient } from '../../../../../lists/server';
28-
import { getExceptionListItemSchemaMock } from '../../../../../lists/common/schemas/response/exception_list_item_schema.mock';
27+
import { ExceptionListClient, ListClient } from '../../../../../lists/server';
28+
import { listMock } from '../../../../../lists/server/mocks';
2929
import { ExceptionListItemSchema } from '../../../../../lists/common/schemas/response';
3030
import { DeleteTrustedAppsRequestParams } from './types';
31+
import { getExceptionListItemSchemaMock } from '../../../../../lists/common/schemas/response/exception_list_item_schema.mock';
32+
33+
type RequestHandlerContextWithLists = ReturnType<typeof xpackMocks.createRequestHandlerContext> & {
34+
lists?: {
35+
getListClient: () => jest.Mocked<ListClient>;
36+
getExceptionListClient: () => jest.Mocked<ExceptionListClient>;
37+
};
38+
};
3139

3240
describe('when invoking endpoint trusted apps route handlers', () => {
3341
let routerMock: jest.Mocked<IRouter>;
3442
let endpointAppContextService: EndpointAppContextService;
35-
let context: ReturnType<typeof xpackMocks.createRequestHandlerContext>;
43+
let context: RequestHandlerContextWithLists;
3644
let response: ReturnType<typeof httpServerMock.createResponseFactory>;
3745
let exceptionsListClient: jest.Mocked<ExceptionListClient>;
3846
let endpointAppContext: EndpointAppContext;
@@ -41,7 +49,7 @@ describe('when invoking endpoint trusted apps route handlers', () => {
4149
routerMock = httpServiceMock.createRouter();
4250
endpointAppContextService = new EndpointAppContextService();
4351
const startContract = createMockEndpointAppContextServiceStartContract();
44-
exceptionsListClient = startContract.exceptionsListService as jest.Mocked<ExceptionListClient>;
52+
exceptionsListClient = listMock.getExceptionListClient() as jest.Mocked<ExceptionListClient>;
4553
endpointAppContextService.start(startContract);
4654
endpointAppContext = {
4755
...createMockEndpointAppContext(),
@@ -50,7 +58,13 @@ describe('when invoking endpoint trusted apps route handlers', () => {
5058
registerTrustedAppsRoutes(routerMock, endpointAppContext);
5159

5260
// For use in individual API calls
53-
context = xpackMocks.createRequestHandlerContext();
61+
context = {
62+
...xpackMocks.createRequestHandlerContext(),
63+
lists: {
64+
getListClient: jest.fn(),
65+
getExceptionListClient: jest.fn().mockReturnValue(exceptionsListClient),
66+
},
67+
};
5468
response = httpServerMock.createResponseFactory();
5569
});
5670

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

91+
it('should use ExceptionListClient from route handler context', async () => {
92+
const request = createListRequest();
93+
await routeHandler(context, request, response);
94+
expect(context.lists?.getExceptionListClient).toHaveBeenCalled();
95+
});
96+
7797
it('should create the Trusted Apps List first', async () => {
7898
const request = createListRequest();
7999
await routeHandler(context, request, response);
@@ -155,6 +175,12 @@ describe('when invoking endpoint trusted apps route handlers', () => {
155175
});
156176
});
157177

178+
it('should use ExceptionListClient from route handler context', async () => {
179+
const request = createPostRequest();
180+
await routeHandler(context, request, response);
181+
expect(context.lists?.getExceptionListClient).toHaveBeenCalled();
182+
});
183+
158184
it('should create trusted app list first', async () => {
159185
const request = createPostRequest();
160186
await routeHandler(context, request, response);
@@ -238,6 +264,11 @@ describe('when invoking endpoint trusted apps route handlers', () => {
238264
});
239265
});
240266

267+
it('should use ExceptionListClient from route handler context', async () => {
268+
await routeHandler(context, request, response);
269+
expect(context.lists?.getExceptionListClient).toHaveBeenCalled();
270+
});
271+
241272
it('should return 200 on successful delete', async () => {
242273
await routeHandler(context, request, response);
243274
expect(exceptionsListClient.deleteExceptionListItem).toHaveBeenCalledWith({

x-pack/plugins/security_solution/server/plugin.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -315,7 +315,6 @@ export class Plugin implements IPlugin<PluginSetup, PluginStart, SetupPlugins, S
315315

316316
this.endpointAppContextService.start({
317317
agentService: plugins.ingestManager?.agentService,
318-
exceptionsListService: this.lists!.getExceptionListClient(savedObjectsClient, 'kibana'),
319318
logger: this.logger,
320319
manifestManager,
321320
registerIngestCallback,

0 commit comments

Comments
 (0)