From 74ba729dc59070dddab3582c5f1b247674fcf07f Mon Sep 17 00:00:00 2001 From: Candace Park Date: Tue, 23 Nov 2021 15:30:23 -0500 Subject: [PATCH 01/13] api changes --- .../server/endpoint/routes/policy/handlers.ts | 17 +++++++++++++++++ .../server/endpoint/routes/policy/index.ts | 16 +++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts index 45b6201c47773..a9277040c72cb 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts @@ -15,6 +15,7 @@ import { import { EndpointAppContext } from '../../types'; import { getAgentPolicySummary, getPolicyResponseByAgentId } from './service'; import { GetAgentSummaryResponse } from '../../../../common/endpoint/types'; +import { GetPackagePoliciesRequest } from '../../../../../fleet/common/types/rest_spec'; export const getHostPolicyResponseHandler = function (): RequestHandler< undefined, @@ -63,3 +64,19 @@ export const getAgentPolicySummaryHandler = function ( }); }; }; + +export const getPolicyListHandler = function ( + endpointAppContext: EndpointAppContext +): RequestHandler { + return async (context, request, response) => { + const soClient = context.core.savedObjects.client; + const packagePolicyService = endpointAppContext.service.getPackagePolicyService(); + const doc = await packagePolicyService.list(soClient, request.query); + if (doc) { + return response.ok({ + body: doc, + }); + } + return response.notFound({ body: 'Failed to retrieve package policy list' }); + }; +}; diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/index.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/index.ts index 50a68debc1125..6a1c69394f873 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/index.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/index.ts @@ -11,9 +11,14 @@ import { GetPolicyResponseSchema, GetAgentPolicySummaryRequestSchema, } from '../../../../common/endpoint/schema/policy'; -import { getHostPolicyResponseHandler, getAgentPolicySummaryHandler } from './handlers'; +import { + getHostPolicyResponseHandler, + getAgentPolicySummaryHandler, + getPolicyListHandler, +} from './handlers'; import { AGENT_POLICY_SUMMARY_ROUTE, + BASE_POLICY_ROUTE, BASE_POLICY_RESPONSE_ROUTE, } from '../../../../common/endpoint/constants'; @@ -37,4 +42,13 @@ export function registerPolicyRoutes(router: IRouter, endpointAppContext: Endpoi }, getAgentPolicySummaryHandler(endpointAppContext) ); + + router.get( + { + path: BASE_POLICY_ROUTE, + validate: false, + options: { authRequired: true }, + }, + getPolicyListHandler(endpointAppContext) + ); } From b19553358a4a1575e4c0c0c860d27bdf60569ecb Mon Sep 17 00:00:00 2001 From: Candace Park Date: Tue, 23 Nov 2021 16:04:21 -0500 Subject: [PATCH 02/13] swap out services url from ingest to our own endpoint api --- .../security_solution/public/management/services/policies.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/public/management/services/policies.ts b/x-pack/plugins/security_solution/public/management/services/policies.ts index 63810ad499c09..e1b68798b704e 100644 --- a/x-pack/plugins/security_solution/public/management/services/policies.ts +++ b/x-pack/plugins/security_solution/public/management/services/policies.ts @@ -10,7 +10,7 @@ import { GetPackagePoliciesRequest, PACKAGE_POLICY_SAVED_OBJECT_TYPE, } from '../../../../fleet/common'; -import { INGEST_API_PACKAGE_POLICIES } from '../pages/policy/store/services/ingest'; +import { BASE_POLICY_ROUTE } from '../../../common/endpoint/constants'; import { GetPolicyListResponse } from '../pages/policy/types'; /** @@ -23,7 +23,7 @@ export const sendGetEndpointSpecificPackagePolicies = ( http: HttpStart, options: HttpFetchOptions & Partial = {} ): Promise => { - return http.get(INGEST_API_PACKAGE_POLICIES, { + return http.get(BASE_POLICY_ROUTE, { ...options, query: { ...options.query, From b4cbe40edaac8d015797a9b8b81677b5159dc06e Mon Sep 17 00:00:00 2001 From: Candace Park Date: Mon, 29 Nov 2021 12:29:26 -0500 Subject: [PATCH 03/13] add request schema, try catch bloack --- .../server/endpoint/routes/policy/handlers.ts | 13 +++++++++---- .../server/endpoint/routes/policy/index.ts | 3 ++- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts index a9277040c72cb..e4ec8938da1d3 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts @@ -16,6 +16,7 @@ import { EndpointAppContext } from '../../types'; import { getAgentPolicySummary, getPolicyResponseByAgentId } from './service'; import { GetAgentSummaryResponse } from '../../../../common/endpoint/types'; import { GetPackagePoliciesRequest } from '../../../../../fleet/common/types/rest_spec'; +import { EndpointError } from '../../../../common/endpoint/errors'; export const getHostPolicyResponseHandler = function (): RequestHandler< undefined, @@ -71,12 +72,16 @@ export const getPolicyListHandler = function ( return async (context, request, response) => { const soClient = context.core.savedObjects.client; const packagePolicyService = endpointAppContext.service.getPackagePolicyService(); - const doc = await packagePolicyService.list(soClient, request.query); - if (doc) { + try { + const listResponse = await packagePolicyService.list(soClient, request.query); + return response.ok({ - body: doc, + body: listResponse, + }); + } catch (error) { + return response.notFound({ + body: new EndpointError('Failed to retrieve package policy list', error), }); } - return response.notFound({ body: 'Failed to retrieve package policy list' }); }; }; diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/index.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/index.ts index 6a1c69394f873..02fb167160791 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/index.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/index.ts @@ -21,6 +21,7 @@ import { BASE_POLICY_ROUTE, BASE_POLICY_RESPONSE_ROUTE, } from '../../../../common/endpoint/constants'; +import { GetPackagePoliciesRequest } from '../../../../../fleet/common/types/rest_spec/package_policy'; export const INITIAL_POLICY_ID = '00000000-0000-0000-0000-000000000000'; @@ -46,7 +47,7 @@ export function registerPolicyRoutes(router: IRouter, endpointAppContext: Endpoi router.get( { path: BASE_POLICY_ROUTE, - validate: false, + validate: GetPackagePoliciesRequest, options: { authRequired: true }, }, getPolicyListHandler(endpointAppContext) From 074a51f9e22c45ecfb8ecf6e9c9f546c0f97b295 Mon Sep 17 00:00:00 2001 From: Candace Park Date: Tue, 30 Nov 2021 16:29:34 -0500 Subject: [PATCH 04/13] copy fleet package policy request schema to security solution --- .../common/endpoint/schema/policy.ts | 19 +++++++++++++++++++ .../server/endpoint/routes/policy/index.ts | 4 ++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/common/endpoint/schema/policy.ts b/x-pack/plugins/security_solution/common/endpoint/schema/policy.ts index 9b02ab073c9ce..962f6a05f4828 100644 --- a/x-pack/plugins/security_solution/common/endpoint/schema/policy.ts +++ b/x-pack/plugins/security_solution/common/endpoint/schema/policy.ts @@ -6,6 +6,7 @@ */ import { schema } from '@kbn/config-schema'; +import type { TypeOf } from '@kbn/config-schema'; export const GetPolicyResponseSchema = { query: schema.object({ @@ -19,3 +20,21 @@ export const GetAgentPolicySummaryRequestSchema = { policy_id: schema.nullable(schema.string()), }), }; + +const ListWithKuerySchema = schema.object({ + page: schema.maybe(schema.number({ defaultValue: 1 })), + perPage: schema.maybe(schema.number({ defaultValue: 20 })), + sortField: schema.maybe(schema.string()), + sortOrder: schema.maybe(schema.oneOf([schema.literal('desc'), schema.literal('asc')])), + showUpgradeable: schema.maybe(schema.boolean()), + kuery: schema.maybe( + schema.oneOf([ + schema.string(), + schema.any(), // KueryNode + ]) + ), +}); + +export const GetEndpointPackagePolicyRequestSchema = { + query: ListWithKuerySchema, +}; diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/index.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/index.ts index 02fb167160791..c4432e9f0163e 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/index.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/index.ts @@ -10,6 +10,7 @@ import { EndpointAppContext } from '../../types'; import { GetPolicyResponseSchema, GetAgentPolicySummaryRequestSchema, + GetEndpointPackagePolicyRequestSchema, } from '../../../../common/endpoint/schema/policy'; import { getHostPolicyResponseHandler, @@ -21,7 +22,6 @@ import { BASE_POLICY_ROUTE, BASE_POLICY_RESPONSE_ROUTE, } from '../../../../common/endpoint/constants'; -import { GetPackagePoliciesRequest } from '../../../../../fleet/common/types/rest_spec/package_policy'; export const INITIAL_POLICY_ID = '00000000-0000-0000-0000-000000000000'; @@ -47,7 +47,7 @@ export function registerPolicyRoutes(router: IRouter, endpointAppContext: Endpoi router.get( { path: BASE_POLICY_ROUTE, - validate: GetPackagePoliciesRequest, + validate: GetEndpointPackagePolicyRequestSchema, options: { authRequired: true }, }, getPolicyListHandler(endpointAppContext) From efb6b8570256ca85e2fc9edd590dccb1ea0893fb Mon Sep 17 00:00:00 2001 From: Candace Park Date: Tue, 30 Nov 2021 16:38:00 -0500 Subject: [PATCH 05/13] add endpoint filtering to handler, throw error if needed --- .../server/endpoint/routes/policy/handlers.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts index e4ec8938da1d3..24dabecb6b123 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts @@ -17,6 +17,8 @@ import { getAgentPolicySummary, getPolicyResponseByAgentId } from './service'; import { GetAgentSummaryResponse } from '../../../../common/endpoint/types'; import { GetPackagePoliciesRequest } from '../../../../../fleet/common/types/rest_spec'; import { EndpointError } from '../../../../common/endpoint/errors'; +import { wrapErrorIfNeeded } from '../../utils'; +import { PACKAGE_POLICY_SAVED_OBJECT_TYPE } from '../../../../../fleet/common'; export const getHostPolicyResponseHandler = function (): RequestHandler< undefined, @@ -72,6 +74,10 @@ export const getPolicyListHandler = function ( return async (context, request, response) => { const soClient = context.core.savedObjects.client; const packagePolicyService = endpointAppContext.service.getPackagePolicyService(); + const endpointFilteredKuery = `${ + request?.query?.kuery ? `${request.query.kuery} and ` : '' + }${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name: endpoint`; + request.query.kuery = endpointFilteredKuery; try { const listResponse = await packagePolicyService.list(soClient, request.query); @@ -79,9 +85,7 @@ export const getPolicyListHandler = function ( body: listResponse, }); } catch (error) { - return response.notFound({ - body: new EndpointError('Failed to retrieve package policy list', error), - }); + throw wrapErrorIfNeeded(error); } }; }; From e8497a1b3bd6fbc825281ca6e68411104118119b Mon Sep 17 00:00:00 2001 From: Candace Park Date: Fri, 3 Dec 2021 00:51:08 -0500 Subject: [PATCH 06/13] modify schema to follow endpoint api patterns, revert policy/service for now --- .../common/endpoint/schema/policy.ts | 5 ++--- .../public/management/services/policies.ts | 4 ++-- .../server/endpoint/routes/policy/handlers.ts | 19 +++++++++++++------ 3 files changed, 17 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/security_solution/common/endpoint/schema/policy.ts b/x-pack/plugins/security_solution/common/endpoint/schema/policy.ts index 962f6a05f4828..dab0845dd252d 100644 --- a/x-pack/plugins/security_solution/common/endpoint/schema/policy.ts +++ b/x-pack/plugins/security_solution/common/endpoint/schema/policy.ts @@ -6,7 +6,6 @@ */ import { schema } from '@kbn/config-schema'; -import type { TypeOf } from '@kbn/config-schema'; export const GetPolicyResponseSchema = { query: schema.object({ @@ -23,8 +22,8 @@ export const GetAgentPolicySummaryRequestSchema = { const ListWithKuerySchema = schema.object({ page: schema.maybe(schema.number({ defaultValue: 1 })), - perPage: schema.maybe(schema.number({ defaultValue: 20 })), - sortField: schema.maybe(schema.string()), + pageSize: schema.maybe(schema.number({ defaultValue: 20 })), + sort: schema.maybe(schema.string()), sortOrder: schema.maybe(schema.oneOf([schema.literal('desc'), schema.literal('asc')])), showUpgradeable: schema.maybe(schema.boolean()), kuery: schema.maybe( diff --git a/x-pack/plugins/security_solution/public/management/services/policies.ts b/x-pack/plugins/security_solution/public/management/services/policies.ts index e1b68798b704e..63810ad499c09 100644 --- a/x-pack/plugins/security_solution/public/management/services/policies.ts +++ b/x-pack/plugins/security_solution/public/management/services/policies.ts @@ -10,7 +10,7 @@ import { GetPackagePoliciesRequest, PACKAGE_POLICY_SAVED_OBJECT_TYPE, } from '../../../../fleet/common'; -import { BASE_POLICY_ROUTE } from '../../../common/endpoint/constants'; +import { INGEST_API_PACKAGE_POLICIES } from '../pages/policy/store/services/ingest'; import { GetPolicyListResponse } from '../pages/policy/types'; /** @@ -23,7 +23,7 @@ export const sendGetEndpointSpecificPackagePolicies = ( http: HttpStart, options: HttpFetchOptions & Partial = {} ): Promise => { - return http.get(BASE_POLICY_ROUTE, { + return http.get(INGEST_API_PACKAGE_POLICIES, { ...options, query: { ...options.query, diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts index 8e3be86a009b7..4c04493dcba1e 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts @@ -11,12 +11,11 @@ import { policyIndexPattern } from '../../../../common/endpoint/constants'; import { GetPolicyResponseSchema, GetAgentPolicySummaryRequestSchema, + GetEndpointPackagePolicyRequestSchema, } from '../../../../common/endpoint/schema/policy'; import { EndpointAppContext } from '../../types'; import { getAgentPolicySummary, getPolicyResponseByAgentId } from './service'; import { GetAgentSummaryResponse } from '../../../../common/endpoint/types'; -import { GetPackagePoliciesRequest } from '../../../../../fleet/common/types/rest_spec'; -import { EndpointError } from '../../../../common/endpoint/errors'; import { wrapErrorIfNeeded } from '../../utils'; import { PACKAGE_POLICY_SAVED_OBJECT_TYPE } from '../../../../../fleet/common'; @@ -71,16 +70,24 @@ export const getAgentPolicySummaryHandler = function ( export const getPolicyListHandler = function ( endpointAppContext: EndpointAppContext -): RequestHandler { +): RequestHandler< + undefined, + TypeOf, + undefined +> { return async (context, request, response) => { const soClient = context.core.savedObjects.client; - const packagePolicyService = endpointAppContext.service.getPackagePolicyService(); + const fleetServices = endpointAppContext.service.getScopedFleetServices(request); const endpointFilteredKuery = `${ request?.query?.kuery ? `${request.query.kuery} and ` : '' }${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name: endpoint`; - request.query.kuery = endpointFilteredKuery; try { - const listResponse = await packagePolicyService.list(soClient, request.query); + const listResponse = await fleetServices.packagePolicy.list(soClient, { + ...request.query, + perPage: request.query.pageSize, + sortField: request.query.sort, + keury: endpointFilteredKuery, + }); return response.ok({ body: listResponse, From 7f672d3ceef28dadabef0d3f9b3af49702512930 Mon Sep 17 00:00:00 2001 From: Candace Park Date: Mon, 6 Dec 2021 17:01:35 -0500 Subject: [PATCH 07/13] adjust kuery to include parentheses --- .../server/endpoint/routes/policy/handlers.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts index 4c04493dcba1e..0218061e012d2 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts @@ -79,8 +79,8 @@ export const getPolicyListHandler = function ( const soClient = context.core.savedObjects.client; const fleetServices = endpointAppContext.service.getScopedFleetServices(request); const endpointFilteredKuery = `${ - request?.query?.kuery ? `${request.query.kuery} and ` : '' - }${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name: endpoint`; + request?.query?.kuery ? `(${request.query.kuery}) AND ` : '' + }(${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name: endpoint)`; try { const listResponse = await fleetServices.packagePolicy.list(soClient, { ...request.query, From c4b4845ff4467f8a193230cc9a20821da9516454 Mon Sep 17 00:00:00 2001 From: Candace Park Date: Tue, 7 Dec 2021 00:17:53 -0500 Subject: [PATCH 08/13] a single passing unit test --- .../endpoint/routes/policy/handlers.test.ts | 110 +++++++++++++++++- 1 file changed, 106 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts index b8efa2636d8c7..44b5022ff715a 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts @@ -11,8 +11,17 @@ import { createMockEndpointAppContextServiceStartContract, createRouteHandlerContext, } from '../../mocks'; -import { createMockAgentClient, createMockAgentService } from '../../../../../fleet/server/mocks'; -import { getHostPolicyResponseHandler, getAgentPolicySummaryHandler } from './handlers'; +import { + createMockAgentClient, + createMockAgentService, + createPackagePolicyServiceMock, +} from '../../../../../fleet/server/mocks'; +import { PackagePolicyServiceInterface } from '../../../../../fleet/server'; +import { + getHostPolicyResponseHandler, + getAgentPolicySummaryHandler, + getPolicyListHandler, +} from './handlers'; import { KibanaResponseFactory, SavedObjectsClientContract, @@ -24,7 +33,11 @@ import { savedObjectsClientMock, } from '../../../../../../../src/core/server/mocks'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { GetHostPolicyResponse, HostPolicyResponse } from '../../../../common/endpoint/types'; +import { + GetHostPolicyResponse, + HostPolicyResponse, + PolicyData, +} from '../../../../common/endpoint/types'; import { EndpointDocGenerator } from '../../../../common/endpoint/generate_data'; import { parseExperimentalConfigValue } from '../../../../common/experimental_features'; import { createMockConfig } from '../../../lib/detection_engine/routes/__mocks__'; @@ -236,6 +249,57 @@ describe('test policy response handler', () => { }); }); }); + describe('test GET policy list handler', () => { + let mockPackagePolicyService: jest.Mocked; + + beforeEach(() => { + mockScopedClient = elasticsearchServiceMock.createScopedClusterClient(); + mockSavedObjectClient = savedObjectsClientMock.create(); + mockResponse = httpServerMock.createResponseFactory(); + mockPackagePolicyService = createPackagePolicyServiceMock(); + mockPackagePolicyService.list.mockImplementation(() => { + return Promise.resolve({ + items: [], + total: 0, + page: 1, + perPage: 1000, + }); + }); + endpointAppContextService = new EndpointAppContextService(); + endpointAppContextService.setup(createMockEndpointAppContextServiceSetupContract()); + endpointAppContextService.start({ + ...createMockEndpointAppContextServiceStartContract(), + ...{ packagePolicyService: mockPackagePolicyService }, + }); + }); + + afterEach(() => endpointAppContextService.stop()); + + it('should return a list of endpoint package policies', async () => { + const response = createPackagePolicySearchResponse( + new EndpointDocGenerator().generatePolicyPackagePolicy() + ); + const policyHandler = getPolicyListHandler({ + logFactory: loggingSystemMock.create(), + service: endpointAppContextService, + config: () => Promise.resolve(createMockConfig()), + experimentalFeatures: parseExperimentalConfigValue(createMockConfig().enableExperimental), + }); + (mockScopedClient.asCurrentUser.search as jest.Mock).mockImplementationOnce(() => + Promise.resolve({ body: response }) + ); + const mockRequest = httpServerMock.createKibanaRequest({ + query: {}, + }); + + await policyHandler( + createRouteHandlerContext(mockScopedClient, mockSavedObjectClient), + mockRequest, + mockResponse + ); + expect(mockResponse.ok).toBeCalled(); + }); + }); }); /** @@ -264,7 +328,7 @@ function createSearchResponse( hits: hostPolicyResponse ? [ { - _index: 'metrics-endpoint.policy-default-1', + _index: 'ingest-package-policies', _id: '8FhM0HEBYyRTvb6lOQnw', _score: null, _source: hostPolicyResponse, @@ -275,3 +339,41 @@ function createSearchResponse( }, } as unknown as estypes.SearchResponse; } + +/** + * Create a SearchResponse with the packagePolicy provided, else return an empty + * SearchResponse + * @param packagePolicy + */ +function createPackagePolicySearchResponse( + packagePolicyResponse?: PolicyData +): estypes.SearchResponse { + return { + took: 15, + timed_out: false, + _shards: { + total: 1, + successful: 1, + skipped: 0, + failed: 0, + }, + hits: { + total: { + value: 5, + relation: 'eq', + }, + max_score: null, + hits: packagePolicyResponse + ? [ + { + _index: 'metrics-endpoint.policy-default-1', + _id: '8FhM0HEBYyRTvb6lOQnw', + _score: null, + _source: packagePolicyResponse, + sort: [1588337587997], + }, + ] + : [], + }, + } as unknown as estypes.SearchResponse; +} From d52464a08ecc3cbb21874d655a04d8c603fab4a1 Mon Sep 17 00:00:00 2001 From: Candace Park Date: Tue, 7 Dec 2021 00:32:41 -0500 Subject: [PATCH 09/13] add another expect, remove unnecessary lines? --- .../endpoint/routes/policy/handlers.test.ts | 25 ++++++------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts index 44b5022ff715a..b2d8ca8693e04 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts @@ -11,12 +11,7 @@ import { createMockEndpointAppContextServiceStartContract, createRouteHandlerContext, } from '../../mocks'; -import { - createMockAgentClient, - createMockAgentService, - createPackagePolicyServiceMock, -} from '../../../../../fleet/server/mocks'; -import { PackagePolicyServiceInterface } from '../../../../../fleet/server'; +import { createMockAgentClient, createMockAgentService } from '../../../../../fleet/server/mocks'; import { getHostPolicyResponseHandler, getAgentPolicySummaryHandler, @@ -250,26 +245,14 @@ describe('test policy response handler', () => { }); }); describe('test GET policy list handler', () => { - let mockPackagePolicyService: jest.Mocked; - beforeEach(() => { mockScopedClient = elasticsearchServiceMock.createScopedClusterClient(); mockSavedObjectClient = savedObjectsClientMock.create(); mockResponse = httpServerMock.createResponseFactory(); - mockPackagePolicyService = createPackagePolicyServiceMock(); - mockPackagePolicyService.list.mockImplementation(() => { - return Promise.resolve({ - items: [], - total: 0, - page: 1, - perPage: 1000, - }); - }); endpointAppContextService = new EndpointAppContextService(); endpointAppContextService.setup(createMockEndpointAppContextServiceSetupContract()); endpointAppContextService.start({ ...createMockEndpointAppContextServiceStartContract(), - ...{ packagePolicyService: mockPackagePolicyService }, }); }); @@ -298,6 +281,12 @@ describe('test policy response handler', () => { mockResponse ); expect(mockResponse.ok).toBeCalled(); + expect(mockResponse.ok.mock.calls[0][0]?.body).toEqual({ + items: [], + total: 0, + page: 1, + perPage: 10, + }); }); }); }); From c885bb5b6e1293022f99005b661b9a1980719491 Mon Sep 17 00:00:00 2001 From: Candace Park Date: Wed, 8 Dec 2021 00:58:40 -0500 Subject: [PATCH 10/13] adding package policy service back, deleting unnecessary code --- .../endpoint/routes/policy/handlers.test.ts | 70 ++++++------------- .../server/endpoint/routes/policy/handlers.ts | 4 +- 2 files changed, 22 insertions(+), 52 deletions(-) diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts index b2d8ca8693e04..2dbdc8d4ef3c1 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts @@ -11,7 +11,11 @@ import { createMockEndpointAppContextServiceStartContract, createRouteHandlerContext, } from '../../mocks'; -import { createMockAgentClient, createMockAgentService } from '../../../../../fleet/server/mocks'; +import { + createMockAgentClient, + createMockAgentService, + createPackagePolicyServiceMock, +} from '../../../../../fleet/server/mocks'; import { getHostPolicyResponseHandler, getAgentPolicySummaryHandler, @@ -28,11 +32,7 @@ import { savedObjectsClientMock, } from '../../../../../../../src/core/server/mocks'; import type * as estypes from '@elastic/elasticsearch/lib/api/typesWithBodyKey'; -import { - GetHostPolicyResponse, - HostPolicyResponse, - PolicyData, -} from '../../../../common/endpoint/types'; +import { GetHostPolicyResponse, HostPolicyResponse } from '../../../../common/endpoint/types'; import { EndpointDocGenerator } from '../../../../common/endpoint/generate_data'; import { parseExperimentalConfigValue } from '../../../../common/experimental_features'; import { createMockConfig } from '../../../lib/detection_engine/routes/__mocks__'; @@ -41,6 +41,7 @@ import { AgentClient, AgentService } from '../../../../../fleet/server/services' import { get } from 'lodash'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { ScopedClusterClientMock } from '../../../../../../../src/core/server/elasticsearch/client/mocks'; +import { PackagePolicyServiceInterface } from '../../../../../fleet/server'; describe('test policy response handler', () => { let endpointAppContextService: EndpointAppContextService; @@ -245,32 +246,38 @@ describe('test policy response handler', () => { }); }); describe('test GET policy list handler', () => { + let mockPackagePolicyService: jest.Mocked; + beforeEach(() => { mockScopedClient = elasticsearchServiceMock.createScopedClusterClient(); mockSavedObjectClient = savedObjectsClientMock.create(); mockResponse = httpServerMock.createResponseFactory(); + mockPackagePolicyService = createPackagePolicyServiceMock(); + mockPackagePolicyService.list.mockImplementation(() => { + return Promise.resolve({ + items: [], + total: 0, + page: 1, + perPage: 10, + }); + }); endpointAppContextService = new EndpointAppContextService(); endpointAppContextService.setup(createMockEndpointAppContextServiceSetupContract()); endpointAppContextService.start({ ...createMockEndpointAppContextServiceStartContract(), + ...{ packagePolicyService: mockPackagePolicyService }, }); }); afterEach(() => endpointAppContextService.stop()); it('should return a list of endpoint package policies', async () => { - const response = createPackagePolicySearchResponse( - new EndpointDocGenerator().generatePolicyPackagePolicy() - ); const policyHandler = getPolicyListHandler({ logFactory: loggingSystemMock.create(), service: endpointAppContextService, config: () => Promise.resolve(createMockConfig()), experimentalFeatures: parseExperimentalConfigValue(createMockConfig().enableExperimental), }); - (mockScopedClient.asCurrentUser.search as jest.Mock).mockImplementationOnce(() => - Promise.resolve({ body: response }) - ); const mockRequest = httpServerMock.createKibanaRequest({ query: {}, }); @@ -281,6 +288,7 @@ describe('test policy response handler', () => { mockResponse ); expect(mockResponse.ok).toBeCalled(); + expect(mockPackagePolicyService.mock.call).toEqual('hi'); expect(mockResponse.ok.mock.calls[0][0]?.body).toEqual({ items: [], total: 0, @@ -328,41 +336,3 @@ function createSearchResponse( }, } as unknown as estypes.SearchResponse; } - -/** - * Create a SearchResponse with the packagePolicy provided, else return an empty - * SearchResponse - * @param packagePolicy - */ -function createPackagePolicySearchResponse( - packagePolicyResponse?: PolicyData -): estypes.SearchResponse { - return { - took: 15, - timed_out: false, - _shards: { - total: 1, - successful: 1, - skipped: 0, - failed: 0, - }, - hits: { - total: { - value: 5, - relation: 'eq', - }, - max_score: null, - hits: packagePolicyResponse - ? [ - { - _index: 'metrics-endpoint.policy-default-1', - _id: '8FhM0HEBYyRTvb6lOQnw', - _score: null, - _source: packagePolicyResponse, - sort: [1588337587997], - }, - ] - : [], - }, - } as unknown as estypes.SearchResponse; -} diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts index 0218061e012d2..4c04493dcba1e 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts @@ -79,8 +79,8 @@ export const getPolicyListHandler = function ( const soClient = context.core.savedObjects.client; const fleetServices = endpointAppContext.service.getScopedFleetServices(request); const endpointFilteredKuery = `${ - request?.query?.kuery ? `(${request.query.kuery}) AND ` : '' - }(${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name: endpoint)`; + request?.query?.kuery ? `${request.query.kuery} and ` : '' + }${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name: endpoint`; try { const listResponse = await fleetServices.packagePolicy.list(soClient, { ...request.query, From d1e827a6849c7d3d4c48b1a2e732c94ec63b2079 Mon Sep 17 00:00:00 2001 From: Candace Park Date: Wed, 8 Dec 2021 15:33:05 -0500 Subject: [PATCH 11/13] finished tests --- .../endpoint/routes/policy/handlers.test.ts | 37 +++++++++++++++---- .../server/endpoint/routes/policy/handlers.ts | 2 +- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts index 2dbdc8d4ef3c1..c9bf540e3afcc 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts @@ -16,6 +16,7 @@ import { createMockAgentService, createPackagePolicyServiceMock, } from '../../../../../fleet/server/mocks'; +import { PACKAGE_POLICY_SAVED_OBJECT_TYPE } from '../../../../../fleet/common'; import { getHostPolicyResponseHandler, getAgentPolicySummaryHandler, @@ -247,6 +248,7 @@ describe('test policy response handler', () => { }); describe('test GET policy list handler', () => { let mockPackagePolicyService: jest.Mocked; + let policyHandler: ReturnType; beforeEach(() => { mockScopedClient = elasticsearchServiceMock.createScopedClusterClient(); @@ -267,17 +269,17 @@ describe('test policy response handler', () => { ...createMockEndpointAppContextServiceStartContract(), ...{ packagePolicyService: mockPackagePolicyService }, }); - }); - - afterEach(() => endpointAppContextService.stop()); - - it('should return a list of endpoint package policies', async () => { - const policyHandler = getPolicyListHandler({ + policyHandler = getPolicyListHandler({ logFactory: loggingSystemMock.create(), service: endpointAppContextService, config: () => Promise.resolve(createMockConfig()), experimentalFeatures: parseExperimentalConfigValue(createMockConfig().enableExperimental), }); + }); + + afterEach(() => endpointAppContextService.stop()); + + it('should return a list of endpoint package policies', async () => { const mockRequest = httpServerMock.createKibanaRequest({ query: {}, }); @@ -287,8 +289,12 @@ describe('test policy response handler', () => { mockRequest, mockResponse ); + expect(mockPackagePolicyService.list.mock.calls[0][1]).toEqual({ + kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name: endpoint`, + perPage: undefined, + sortField: undefined, + }); expect(mockResponse.ok).toBeCalled(); - expect(mockPackagePolicyService.mock.call).toEqual('hi'); expect(mockResponse.ok.mock.calls[0][0]?.body).toEqual({ items: [], total: 0, @@ -296,6 +302,23 @@ describe('test policy response handler', () => { perPage: 10, }); }); + + it('should add endpoint-specific kuery to the requests kuery', async () => { + const mockRequest = httpServerMock.createKibanaRequest({ + query: { kuery: 'some query' }, + }); + + await policyHandler( + createRouteHandlerContext(mockScopedClient, mockSavedObjectClient), + mockRequest, + mockResponse + ); + expect(mockPackagePolicyService.list.mock.calls[0][1]).toEqual({ + kuery: `some query and ${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name: endpoint`, + perPage: undefined, + sortField: undefined, + }); + }); }); }); diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts index 4c04493dcba1e..c3f7d2acef5d4 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts @@ -86,7 +86,7 @@ export const getPolicyListHandler = function ( ...request.query, perPage: request.query.pageSize, sortField: request.query.sort, - keury: endpointFilteredKuery, + kuery: endpointFilteredKuery, }); return response.ok({ From 7a7ae9b0134f821c79ec377ee4f139173a130767 Mon Sep 17 00:00:00 2001 From: Candace Park Date: Tue, 14 Dec 2021 11:16:31 -0500 Subject: [PATCH 12/13] fix change and add parens --- .../server/endpoint/routes/policy/handlers.test.ts | 2 +- .../security_solution/server/endpoint/routes/policy/handlers.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts index c9bf540e3afcc..7e663884d258b 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts @@ -348,7 +348,7 @@ function createSearchResponse( hits: hostPolicyResponse ? [ { - _index: 'ingest-package-policies', + _index: 'metrics-endpoint.policy-default-1', _id: '8FhM0HEBYyRTvb6lOQnw', _score: null, _source: hostPolicyResponse, diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts index c3f7d2acef5d4..9a63f898277a8 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.ts @@ -79,7 +79,7 @@ export const getPolicyListHandler = function ( const soClient = context.core.savedObjects.client; const fleetServices = endpointAppContext.service.getScopedFleetServices(request); const endpointFilteredKuery = `${ - request?.query?.kuery ? `${request.query.kuery} and ` : '' + request?.query?.kuery ? `(${request.query.kuery}) and ` : '' }${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name: endpoint`; try { const listResponse = await fleetServices.packagePolicy.list(soClient, { From 16952763429f62806daee442962a996d0079d2b5 Mon Sep 17 00:00:00 2001 From: Candace Park Date: Tue, 14 Dec 2021 14:57:11 -0500 Subject: [PATCH 13/13] fix jest test --- .../server/endpoint/routes/policy/handlers.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts index 7e663884d258b..527afe23b694d 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/policy/handlers.test.ts @@ -314,7 +314,7 @@ describe('test policy response handler', () => { mockResponse ); expect(mockPackagePolicyService.list.mock.calls[0][1]).toEqual({ - kuery: `some query and ${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name: endpoint`, + kuery: `(some query) and ${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.package.name: endpoint`, perPage: undefined, sortField: undefined, });