diff --git a/.buildkite/ftr_security_serverless_configs.yml b/.buildkite/ftr_security_serverless_configs.yml index 2ca6a9636e1ed..98bc658f36103 100644 --- a/.buildkite/ftr_security_serverless_configs.yml +++ b/.buildkite/ftr_security_serverless_configs.yml @@ -116,6 +116,7 @@ disabled: - x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/configs/serverless.config.ts - x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/basic_license_essentials_tier/configs/serverless.config.ts - x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/entity_store/trial_license_complete_tier/configs/serverless.config.ts + - x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/monitoring/basic_license_essentials_tier/configs/serverless.config.ts - x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/monitoring/trial_license_complete_tier/configs/serverless.config.ts - x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/entity_details/trial_license_complete_tier/configs/serverless.config.ts - x-pack/solutions/security/test/security_solution_api_integration/test_suites/lists_and_exception_lists/exception_lists_items/trial_license_complete_tier/configs/serverless.config.ts diff --git a/.buildkite/ftr_security_stateful_configs.yml b/.buildkite/ftr_security_stateful_configs.yml index 6d4626aa01442..a0a1987ba49a1 100644 --- a/.buildkite/ftr_security_stateful_configs.yml +++ b/.buildkite/ftr_security_stateful_configs.yml @@ -101,6 +101,7 @@ enabled: - x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/trial_license_complete_tier/configs/ess.config.ts - x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/risk_engine/basic_license_essentials_tier/configs/ess.config.ts - x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/entity_store/trial_license_complete_tier/configs/ess.config.ts + - x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/monitoring/basic_license_essentials_tier/configs/ess.config.ts - x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/monitoring/trial_license_complete_tier/configs/ess.config.ts - x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/entity_details/trial_license_complete_tier/configs/ess.config.ts - x-pack/solutions/security/test/security_solution_api_integration/test_suites/lists_and_exception_lists/exception_lists_items/trial_license_complete_tier/configs/ess.config.ts diff --git a/x-pack/solutions/security/plugins/security_solution/common/entity_analytics/privileged_user_monitoring/constants.ts b/x-pack/solutions/security/plugins/security_solution/common/entity_analytics/privileged_user_monitoring/constants.ts index 922652808c03d..ee11ead9d7611 100644 --- a/x-pack/solutions/security/plugins/security_solution/common/entity_analytics/privileged_user_monitoring/constants.ts +++ b/x-pack/solutions/security/plugins/security_solution/common/entity_analytics/privileged_user_monitoring/constants.ts @@ -16,6 +16,7 @@ export const PRIVMON_USERS_CSV_MAX_SIZE_BYTES_WITH_TOLERANCE = PRIVMON_USERS_CSV_MAX_SIZE_BYTES + PRIVMON_USERS_CSV_SIZE_TOLERANCE_BYTES; const MONITORING_URL = `/api/entity_analytics/monitoring` as const; +const PAD_URL = `/api/entity_analytics/privileged_user_monitoring/pad` as const; // Monitoring users URLs export const MONITORING_USERS_URL = `${MONITORING_URL}/users` as const; @@ -40,3 +41,7 @@ export const MONITORING_ENGINE_INIT_URL = `${MONITORING_ENGINE_URL}/init` as con export const MONITORING_ENGINE_SCHEDULE_NOW_URL = `${MONITORING_ENGINE_URL}/schedule_now` as const; export const MONITORING_ENGINE_DELETE_URL = `${MONITORING_ENGINE_URL}/delete` as const; export const MONITORING_ENGINE_DISABLE_URL = `${MONITORING_ENGINE_URL}/disable` as const; + +// Privileged Access Detection (PAD) URLs +export const PAD_INSTALL_URL = `${PAD_URL}/install` as const; +export const PAD_STATUS_URL = `${PAD_URL}/status` as const; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/engine/initialisation_service.test.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/engine/initialisation_service.test.ts index cf29a57a1a03b..d0f76a53dab9f 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/engine/initialisation_service.test.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/engine/initialisation_service.test.ts @@ -54,6 +54,7 @@ jest.mock('../saved_objects', () => { })), }; }); + describe('Privileged User Monitoring: Index Sync Service', () => { const mockSavedObjectClient = savedObjectsClientMock.create(); const clusterClientMock = elasticsearchServiceMock.createScopedClusterClient(); diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/create_index.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/create_index.ts index 39e7dd04ef36e..6aa208179dacb 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/create_index.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/create_index.ts @@ -15,6 +15,7 @@ import type { EntityAnalyticsRoutesDeps } from '../../types'; import { createDataSourcesService } from '../data_sources/data_sources_service'; import { PrivilegeMonitoringApiKeyType } from '../auth/saved_object'; import { monitoringEntitySourceType } from '../saved_objects'; +import { withMinimumLicense } from '../../utils/with_minimum_license'; export const createPrivilegeMonitoringIndicesRoute = ( router: EntityAnalyticsRoutesDeps['router'], @@ -40,7 +41,7 @@ export const createPrivilegeMonitoringIndicesRoute = ( }, }, - async (context, request, response): Promise> => { + withMinimumLicense(async (context, request, response): Promise> => { const secSol = await context.securitySolution; const siemResponse = buildSiemResponse(response); const indexName = request.body.name; @@ -68,6 +69,6 @@ export const createPrivilegeMonitoringIndicesRoute = ( body: error.message, }); } - } + }, 'platinum') ); }; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/delete.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/delete.ts index b6cd5da8145b1..6046f49c29052 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/delete.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/delete.ts @@ -21,6 +21,7 @@ import { } from '../../../../../common/constants'; import type { EntityAnalyticsRoutesDeps } from '../../types'; import { createEngineCrudService } from '../engine/crud_service'; +import { withMinimumLicense } from '../../utils/with_minimum_license'; export const deletePrivilegeMonitoringEngineRoute = ( router: EntityAnalyticsRoutesDeps['router'], @@ -51,29 +52,31 @@ export const deletePrivilegeMonitoringEngineRoute = ( }, }, }, + withMinimumLicense( + async ( + context, + request, + response + ): Promise> => { + const siemResponse = buildSiemResponse(response); + const secSol = await context.securitySolution; - async ( - context, - request, - response - ): Promise> => { - const siemResponse = buildSiemResponse(response); - const secSol = await context.securitySolution; - - try { - const dataClient = secSol.getPrivilegeMonitoringDataClient(); - const soClient = dataClient.getScopedSoClient(request); - const service = createEngineCrudService(dataClient, soClient); - const body = await service.delete(request.query.data); - return response.ok({ body }); - } catch (e) { - const error = transformError(e); - logger.error(`Error deleting privilege monitoring engine: ${error.message}`); - return siemResponse.error({ - statusCode: error.statusCode, - body: error.message, - }); - } - } + try { + const dataClient = secSol.getPrivilegeMonitoringDataClient(); + const soClient = dataClient.getScopedSoClient(request); + const service = createEngineCrudService(dataClient, soClient); + const body = await service.delete(request.query.data); + return response.ok({ body }); + } catch (e) { + const error = transformError(e); + logger.error(`Error deleting privilege monitoring engine: ${error.message}`); + return siemResponse.error({ + statusCode: error.statusCode, + body: error.message, + }); + } + }, + 'platinum' + ) ); }; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/disable.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/disable.ts index 334c72e5ed112..5006d2e4eedfb 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/disable.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/disable.ts @@ -16,6 +16,7 @@ import { } from '../../../../../common/constants'; import type { EntityAnalyticsRoutesDeps } from '../../types'; import { createEngineStatusService } from '../engine/status_service'; +import { withMinimumLicense } from '../../utils/with_minimum_license'; export const disablePrivilegeMonitoringEngineRoute = ( router: EntityAnalyticsRoutesDeps['router'], @@ -42,29 +43,31 @@ export const disablePrivilegeMonitoringEngineRoute = ( version: API_VERSIONS.public.v1, validate: {}, }, + withMinimumLicense( + async ( + context, + request, + response + ): Promise> => { + const siemResponse = buildSiemResponse(response); + const secSol = await context.securitySolution; - async ( - context, - request, - response - ): Promise> => { - const siemResponse = buildSiemResponse(response); - const secSol = await context.securitySolution; - - try { - const dataClient = secSol.getPrivilegeMonitoringDataClient(); - const soClient = dataClient.getScopedSoClient(request); - const statusService = createEngineStatusService(dataClient, soClient); - const body = await statusService.disable(); - return response.ok({ body }); - } catch (e) { - const error = transformError(e); - logger.error(`Error disabling privilege monitoring engine: ${error.message}`); - return siemResponse.error({ - statusCode: error.statusCode, - body: error.message, - }); - } - } + try { + const dataClient = secSol.getPrivilegeMonitoringDataClient(); + const soClient = dataClient.getScopedSoClient(request); + const statusService = createEngineStatusService(dataClient, soClient); + const body = await statusService.disable(); + return response.ok({ body }); + } catch (e) { + const error = transformError(e); + logger.error(`Error disabling privilege monitoring engine: ${error.message}`); + return siemResponse.error({ + statusCode: error.statusCode, + body: error.message, + }); + } + }, + 'platinum' + ) ); }; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/health.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/health.ts index ccea9603c0b90..9aed76fcf847d 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/health.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/health.ts @@ -13,6 +13,7 @@ import { API_VERSIONS, APP_ID, PRIVMON_HEALTH_URL } from '../../../../../common/ import type { EntityAnalyticsRoutesDeps } from '../../types'; import { createEngineStatusService } from '../engine/status_service'; import { PRIVILEGE_MONITORING_ENGINE_STATUS } from '../constants'; +import { withMinimumLicense } from '../../utils/with_minimum_license'; export const healthCheckPrivilegeMonitoringRoute = ( router: EntityAnalyticsRoutesDeps['router'], @@ -34,45 +35,48 @@ export const healthCheckPrivilegeMonitoringRoute = ( validate: {}, }, - async (context, request, response): Promise> => { - const siemResponse = buildSiemResponse(response); - const secSol = await context.securitySolution; + withMinimumLicense( + async (context, request, response): Promise> => { + const siemResponse = buildSiemResponse(response); + const secSol = await context.securitySolution; - const dataClient = secSol.getPrivilegeMonitoringDataClient(); - const soClient = dataClient.getScopedSoClient(request); - const config = secSol.getConfig(); - const maxUsersAllowed = - config.entityAnalytics.monitoring.privileges.users.maxPrivilegedUsersAllowed; + const dataClient = secSol.getPrivilegeMonitoringDataClient(); + const soClient = dataClient.getScopedSoClient(request); + const config = secSol.getConfig(); + const maxUsersAllowed = + config.entityAnalytics.monitoring.privileges.users.maxPrivilegedUsersAllowed; - const statusService = createEngineStatusService(dataClient, soClient); + const statusService = createEngineStatusService(dataClient, soClient); - try { - const body = await statusService.get(); + try { + const body = await statusService.get(); - // Only include user count if engine status is "started" - if (body.status === PRIVILEGE_MONITORING_ENGINE_STATUS.STARTED) { - const userCountResponse = await statusService.getCurrentUserCount(); - return response.ok({ - body: { - ...body, - users: { - current_count: userCountResponse.count, - max_allowed: maxUsersAllowed, + // Only include user count if engine status is "started" + if (body.status === PRIVILEGE_MONITORING_ENGINE_STATUS.STARTED) { + const userCountResponse = await statusService.getCurrentUserCount(); + return response.ok({ + body: { + ...body, + users: { + current_count: userCountResponse.count, + max_allowed: maxUsersAllowed, + }, }, - }, + }); + } else { + return response.ok({ body }); + } + } catch (e) { + const error = transformError(e); + + logger.error(`Error checking privilege monitoring health: ${error.message}`); + return siemResponse.error({ + statusCode: error.statusCode, + body: error.message, }); - } else { - return response.ok({ body }); } - } catch (e) { - const error = transformError(e); - - logger.error(`Error checking privilege monitoring health: ${error.message}`); - return siemResponse.error({ - statusCode: error.statusCode, - body: error.message, - }); - } - } + }, + 'platinum' + ) ); }; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/init.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/init.ts index 49fdb344634a0..ade780da69428 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/init.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/init.ts @@ -15,6 +15,7 @@ import { createInitialisationService } from '../engine/initialisation_service'; import { PrivilegeMonitoringApiKeyType } from '../auth/saved_object'; import { monitoringEntitySourceType } from '../saved_objects'; import { PRIVILEGE_MONITORING_ENGINE_STATUS } from '../constants'; +import { withMinimumLicense } from '../../utils/with_minimum_license'; export const initPrivilegeMonitoringEngineRoute = ( router: EntityAnalyticsRoutesDeps['router'], @@ -36,40 +37,42 @@ export const initPrivilegeMonitoringEngineRoute = ( version: API_VERSIONS.public.v1, validate: {}, }, + withMinimumLicense( + async ( + context, + request, + response + ): Promise> => { + const siemResponse = buildSiemResponse(response); + const secSol = await context.securitySolution; - async ( - context, - request, - response - ): Promise> => { - const siemResponse = buildSiemResponse(response); - const secSol = await context.securitySolution; + const dataClient = secSol.getPrivilegeMonitoringDataClient(); + const soClient = dataClient.getScopedSoClient(request, { + includedHiddenTypes: [ + PrivilegeMonitoringApiKeyType.name, + monitoringEntitySourceType.name, + ], + }); + const service = createInitialisationService(dataClient, soClient); - const dataClient = secSol.getPrivilegeMonitoringDataClient(); - const soClient = dataClient.getScopedSoClient(request, { - includedHiddenTypes: [ - PrivilegeMonitoringApiKeyType.name, - monitoringEntitySourceType.name, - ], - }); - const service = createInitialisationService(dataClient, soClient); + try { + const initResult = await service.init(); - try { - const initResult = await service.init(); + if (initResult.status === PRIVILEGE_MONITORING_ENGINE_STATUS.ERROR) { + return siemResponse.error({ statusCode: 500, body: initResult }); + } - if (initResult.status === PRIVILEGE_MONITORING_ENGINE_STATUS.ERROR) { - return siemResponse.error({ statusCode: 500, body: initResult }); + return response.ok({ body: initResult }); + } catch (e) { + const error = transformError(e); + logger.error(`Error initializing privilege monitoring engine: ${error.message}`); + return siemResponse.error({ + statusCode: error.statusCode, + body: error.message, + }); } - - return response.ok({ body: initResult }); - } catch (e) { - const error = transformError(e); - logger.error(`Error initializing privilege monitoring engine: ${error.message}`); - return siemResponse.error({ - statusCode: error.statusCode, - body: error.message, - }); - } - } + }, + 'platinum' + ) ); }; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/monitoring_entity_source/create.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/monitoring_entity_source/create.ts index 043ae36459287..09946307e9e6a 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/monitoring_entity_source/create.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/monitoring_entity_source/create.ts @@ -24,6 +24,7 @@ import { createEngineStatusService } from '../../engine/status_service'; import { PrivilegeMonitoringApiKeyType } from '../../auth/saved_object'; import { monitoringEntitySourceType } from '../../saved_objects/monitoring_entity_source_type'; import { PRIVILEGE_MONITORING_ENGINE_STATUS } from '../../constants'; +import { withMinimumLicense } from '../../../utils/with_minimum_license'; export const createMonitoringEntitySourceRoute = ( router: EntityAnalyticsRoutesDeps['router'], @@ -48,50 +49,57 @@ export const createMonitoringEntitySourceRoute = ( }, }, }, - async (context, request, response): Promise> => { - const siemResponse = buildSiemResponse(response); - const monitoringSource = request.body; - try { - if (monitoringSource.type !== 'index') { - // currently we own the integration sources so we don't allow creation of other types - // we might allow this in the future if we have a way to manage the integration sources - return siemResponse.error({ - statusCode: 400, - body: 'Cannot currently create entity source of type other than index', - }); - } + withMinimumLicense( + async ( + context, + request, + response + ): Promise> => { + const siemResponse = buildSiemResponse(response); + const monitoringSource = request.body; + try { + if (monitoringSource.type !== 'index') { + // currently we own the integration sources so we don't allow creation of other types + // we might allow this in the future if we have a way to manage the integration sources + return siemResponse.error({ + statusCode: 400, + body: 'Cannot currently create entity source of type other than index', + }); + } - const secSol = await context.securitySolution; - const client = secSol.getMonitoringEntitySourceDataClient(); + const secSol = await context.securitySolution; + const client = secSol.getMonitoringEntitySourceDataClient(); - const body = await client.create(monitoringSource); - const privMonDataClient = await secSol.getPrivilegeMonitoringDataClient(); - const soClient = privMonDataClient.getScopedSoClient(request, { - includedHiddenTypes: [ - PrivilegeMonitoringApiKeyType.name, - monitoringEntitySourceType.name, - ], - }); + const body = await client.create(monitoringSource); + const privMonDataClient = await secSol.getPrivilegeMonitoringDataClient(); + const soClient = privMonDataClient.getScopedSoClient(request, { + includedHiddenTypes: [ + PrivilegeMonitoringApiKeyType.name, + monitoringEntitySourceType.name, + ], + }); - const statusService = createEngineStatusService(privMonDataClient, soClient); - const engineStatus = await statusService.get(); + const statusService = createEngineStatusService(privMonDataClient, soClient); + const engineStatus = await statusService.get(); - try { - if (engineStatus.status === PRIVILEGE_MONITORING_ENGINE_STATUS.STARTED) { - await statusService.scheduleNow(); + try { + if (engineStatus.status === PRIVILEGE_MONITORING_ENGINE_STATUS.STARTED) { + await statusService.scheduleNow(); + } + } catch (e) { + logger.warn(`[Privilege Monitoring] Error scheduling task, received ${e.message}`); } + return response.ok({ body }); } catch (e) { - logger.warn(`[Privilege Monitoring] Error scheduling task, received ${e.message}`); + const error = transformError(e); + logger.error(`Error creating monitoring entity source sync config: ${error.message}`); + return siemResponse.error({ + statusCode: error.statusCode, + body: error.message, + }); } - return response.ok({ body }); - } catch (e) { - const error = transformError(e); - logger.error(`Error creating monitoring entity source sync config: ${error.message}`); - return siemResponse.error({ - statusCode: error.statusCode, - body: error.message, - }); - } - } + }, + 'platinum' + ) ); }; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/monitoring_entity_source/delete.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/monitoring_entity_source/delete.ts index 55cd77709df1f..eddfba261c72d 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/monitoring_entity_source/delete.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/monitoring_entity_source/delete.ts @@ -17,6 +17,7 @@ import { } from '../../../../../../common/constants'; import type { EntityAnalyticsRoutesDeps } from '../../../types'; import { DeleteEntitySourceRequestParams } from '../../../../../../common/api/entity_analytics'; +import { withMinimumLicense } from '../../../utils/with_minimum_license'; export const deleteMonitoringEntitySourceRoute = ( router: EntityAnalyticsRoutesDeps['router'], @@ -42,7 +43,7 @@ export const deleteMonitoringEntitySourceRoute = ( }, }, }, - async (context, request, response): Promise => { + withMinimumLicense(async (context, request, response): Promise => { const siemResponse = buildSiemResponse(response); try { @@ -70,6 +71,6 @@ export const deleteMonitoringEntitySourceRoute = ( body: error.message, }); } - } + }, 'platinum') ); }; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/monitoring_entity_source/get.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/monitoring_entity_source/get.ts index 4fd86b9e7a5d7..7eeeebe3d7d6c 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/monitoring_entity_source/get.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/monitoring_entity_source/get.ts @@ -20,6 +20,7 @@ import { type GetEntitySourceResponse, GetEntitySourceRequestParams, } from '../../../../../../common/api/entity_analytics'; +import { withMinimumLicense } from '../../../utils/with_minimum_license'; export const getMonitoringEntitySourceRoute = ( router: EntityAnalyticsRoutesDeps['router'], @@ -45,22 +46,25 @@ export const getMonitoringEntitySourceRoute = ( }, }, }, - async (context, request, response): Promise> => { - const siemResponse = buildSiemResponse(response); + withMinimumLicense( + async (context, request, response): Promise> => { + const siemResponse = buildSiemResponse(response); - try { - const secSol = await context.securitySolution; - const client = secSol.getMonitoringEntitySourceDataClient(); - const body = await client.get(request.params.id); - return response.ok({ body }); - } catch (e) { - const error = transformError(e); - logger.error(`Error getting monitoring entity source sync config: ${error.message}`); - return siemResponse.error({ - statusCode: error.statusCode, - body: error.message, - }); - } - } + try { + const secSol = await context.securitySolution; + const client = secSol.getMonitoringEntitySourceDataClient(); + const body = await client.get(request.params.id); + return response.ok({ body }); + } catch (e) { + const error = transformError(e); + logger.error(`Error getting monitoring entity source sync config: ${error.message}`); + return siemResponse.error({ + statusCode: error.statusCode, + body: error.message, + }); + } + }, + 'platinum' + ) ); }; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/monitoring_entity_source/list.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/monitoring_entity_source/list.ts index ca041ac0b35c3..e2094648dcca0 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/monitoring_entity_source/list.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/monitoring_entity_source/list.ts @@ -19,6 +19,7 @@ import { ListEntitySourcesRequestQuery, type ListEntitySourcesResponse, } from '../../../../../../common/api/entity_analytics'; +import { withMinimumLicense } from '../../../utils/with_minimum_license'; export const listMonitoringEntitySourceRoute = ( router: EntityAnalyticsRoutesDeps['router'], @@ -43,23 +44,26 @@ export const listMonitoringEntitySourceRoute = ( }, }, }, - async (context, request, response): Promise> => { - const siemResponse = buildSiemResponse(response); + withMinimumLicense( + async (context, request, response): Promise> => { + const siemResponse = buildSiemResponse(response); - try { - const secSol = await context.securitySolution; - const client = secSol.getMonitoringEntitySourceDataClient(); - const body = await client.list(request.query); + try { + const secSol = await context.securitySolution; + const client = secSol.getMonitoringEntitySourceDataClient(); + const body = await client.list(request.query); - return response.ok({ body }); - } catch (e) { - const error = transformError(e); - logger.error(`Error listing monitoring entity sources: ${error.message}`); - return siemResponse.error({ - statusCode: error.statusCode, - body: error.message, - }); - } - } + return response.ok({ body }); + } catch (e) { + const error = transformError(e); + logger.error(`Error listing monitoring entity sources: ${error.message}`); + return siemResponse.error({ + statusCode: error.statusCode, + body: error.message, + }); + } + }, + 'platinum' + ) ); }; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/monitoring_entity_source/update.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/monitoring_entity_source/update.ts index 1d25d32d4109d..ec00eeaa77e94 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/monitoring_entity_source/update.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/monitoring_entity_source/update.ts @@ -25,6 +25,7 @@ import { createEngineStatusService } from '../../engine/status_service'; import { PrivilegeMonitoringApiKeyType } from '../../auth/saved_object'; import { monitoringEntitySourceType } from '../../saved_objects/monitoring_entity_source_type'; import { PRIVILEGE_MONITORING_ENGINE_STATUS } from '../../constants'; +import { withMinimumLicense } from '../../../utils/with_minimum_license'; export const updateMonitoringEntitySourceRoute = ( router: EntityAnalyticsRoutesDeps['router'], @@ -51,42 +52,49 @@ export const updateMonitoringEntitySourceRoute = ( }, }, }, - async (context, request, response): Promise> => { - const siemResponse = buildSiemResponse(response); + withMinimumLicense( + async ( + context, + request, + response + ): Promise> => { + const siemResponse = buildSiemResponse(response); - try { - const secSol = await context.securitySolution; - const client = secSol.getMonitoringEntitySourceDataClient(); - const body = await client.update({ ...request.body, id: request.params.id }); + try { + const secSol = await context.securitySolution; + const client = secSol.getMonitoringEntitySourceDataClient(); + const body = await client.update({ ...request.body, id: request.params.id }); - const privMonDataClient = secSol.getPrivilegeMonitoringDataClient(); - const soClient = privMonDataClient.getScopedSoClient(request, { - includedHiddenTypes: [ - PrivilegeMonitoringApiKeyType.name, - monitoringEntitySourceType.name, - ], - }); + const privMonDataClient = secSol.getPrivilegeMonitoringDataClient(); + const soClient = privMonDataClient.getScopedSoClient(request, { + includedHiddenTypes: [ + PrivilegeMonitoringApiKeyType.name, + monitoringEntitySourceType.name, + ], + }); - const statusService = createEngineStatusService(privMonDataClient, soClient); - const engineStatus = await statusService.get(); + const statusService = createEngineStatusService(privMonDataClient, soClient); + const engineStatus = await statusService.get(); - try { - if (engineStatus.status === PRIVILEGE_MONITORING_ENGINE_STATUS.STARTED) { - await statusService.scheduleNow(); + try { + if (engineStatus.status === PRIVILEGE_MONITORING_ENGINE_STATUS.STARTED) { + await statusService.scheduleNow(); + } + } catch (e) { + logger.warn(`[Privilege Monitoring] Error scheduling task, received ${e.message}`); } + + return response.ok({ body }); } catch (e) { - logger.warn(`[Privilege Monitoring] Error scheduling task, received ${e.message}`); + const error = transformError(e); + logger.error(`Error creating monitoring entity source sync config: ${error.message}`); + return siemResponse.error({ + statusCode: error.statusCode, + body: error.message, + }); } - - return response.ok({ body }); - } catch (e) { - const error = transformError(e); - logger.error(`Error creating monitoring entity source sync config: ${error.message}`); - return siemResponse.error({ - statusCode: error.statusCode, - body: error.message, - }); - } - } + }, + 'platinum' + ) ); }; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/privileged_access_detection/pad_get_installation_status.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/privileged_access_detection/pad_get_installation_status.ts index 7ac7561128d97..9d8fe5f63c42c 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/privileged_access_detection/pad_get_installation_status.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/privileged_access_detection/pad_get_installation_status.ts @@ -10,9 +10,10 @@ import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils'; import { transformError } from '@kbn/securitysolution-es-utils'; import type { GetPrivilegedAccessDetectionPackageStatusResponse } from '../../../../../../common/api/entity_analytics'; -import { API_VERSIONS, APP_ID } from '../../../../../../common/constants'; +import { API_VERSIONS, APP_ID, PAD_STATUS_URL } from '../../../../../../common/constants'; import type { EntityAnalyticsRoutesDeps } from '../../../types'; +import { withMinimumLicense } from '../../../utils/with_minimum_license'; export const padGetStatusRoute = ( router: EntityAnalyticsRoutesDeps['router'], @@ -22,7 +23,7 @@ export const padGetStatusRoute = ( router.versioned .get({ access: 'public', - path: '/api/entity_analytics/privileged_user_monitoring/pad/status', + path: PAD_STATUS_URL, security: { authz: { requiredPrivileges: ['securitySolution', `${APP_ID}-entity-analytics`], @@ -34,30 +35,32 @@ export const padGetStatusRoute = ( version: API_VERSIONS.public.v1, validate: {}, }, + withMinimumLicense( + async ( + context, + request, + response + ): Promise> => { + const siemResponse = buildSiemResponse(response); + const secSol = await context.securitySolution; - async ( - context, - request, - response - ): Promise> => { - const siemResponse = buildSiemResponse(response); - const secSol = await context.securitySolution; - - try { - const clientResponse = await secSol.getPadPackageInstallationClient().getStatus(); - return response.ok({ - body: { - ...clientResponse, - }, - }); - } catch (e) { - const error = transformError(e); - logger.error(`Error with PAD installation: ${error.message}`); - return siemResponse.error({ - statusCode: error.statusCode, - body: error.message, - }); - } - } + try { + const clientResponse = await secSol.getPadPackageInstallationClient().getStatus(); + return response.ok({ + body: { + ...clientResponse, + }, + }); + } catch (e) { + const error = transformError(e); + logger.error(`Error with PAD installation: ${error.message}`); + return siemResponse.error({ + statusCode: error.statusCode, + body: error.message, + }); + } + }, + 'platinum' + ) ); }; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/privileged_access_detection/pad_install.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/privileged_access_detection/pad_install.ts index ffea35435580a..b390a60aceb3f 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/privileged_access_detection/pad_install.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/privileged_access_detection/pad_install.ts @@ -10,9 +10,10 @@ import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils'; import { transformError } from '@kbn/securitysolution-es-utils'; import type { InstallPrivilegedAccessDetectionPackageResponse } from '../../../../../../common/api/entity_analytics'; -import { API_VERSIONS, APP_ID } from '../../../../../../common/constants'; +import { API_VERSIONS, APP_ID, PAD_INSTALL_URL } from '../../../../../../common/constants'; import type { EntityAnalyticsRoutesDeps } from '../../../types'; +import { withMinimumLicense } from '../../../utils/with_minimum_license'; export const padInstallRoute = ( router: EntityAnalyticsRoutesDeps['router'], @@ -22,7 +23,7 @@ export const padInstallRoute = ( router.versioned .post({ access: 'public', - path: '/api/entity_analytics/privileged_user_monitoring/pad/install', + path: PAD_INSTALL_URL, security: { authz: { requiredPrivileges: ['securitySolution', `${APP_ID}-entity-analytics`], @@ -34,32 +35,34 @@ export const padInstallRoute = ( version: API_VERSIONS.public.v1, validate: {}, }, + withMinimumLicense( + async ( + context, + request, + response + ): Promise> => { + const siemResponse = buildSiemResponse(response); + const secSol = await context.securitySolution; - async ( - context, - request, - response - ): Promise> => { - const siemResponse = buildSiemResponse(response); - const secSol = await context.securitySolution; - - try { - const clientResponse = await secSol - .getPadPackageInstallationClient() - .installPrivilegedAccessDetectionPackage(); - return response.ok({ - body: { - ...clientResponse, - }, - }); - } catch (e) { - const error = transformError(e); - logger.error(`Error PAD installation: ${error.message}`); - return siemResponse.error({ - statusCode: error.statusCode, - body: error.message, - }); - } - } + try { + const clientResponse = await secSol + .getPadPackageInstallationClient() + .installPrivilegedAccessDetectionPackage(); + return response.ok({ + body: { + ...clientResponse, + }, + }); + } catch (e) { + const error = transformError(e); + logger.error(`Error PAD installation: ${error.message}`); + return siemResponse.error({ + statusCode: error.statusCode, + body: error.message, + }); + } + }, + 'platinum' + ) ); }; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/privileges.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/privileges.ts index 011ab2d3dda28..8d8b595f9b5bf 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/privileges.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/privileges.ts @@ -12,6 +12,7 @@ import type { PrivMonPrivilegesResponse } from '../../../../../common/api/entity import { API_VERSIONS, APP_ID, PRIVMON_PRIVILEGE_CHECK_API } from '../../../../../common/constants'; import type { EntityAnalyticsRoutesDeps } from '../../types'; import { getReadPrivilegeUserMonitoringPrivileges } from '../privilege_monitoring_privileges'; +import { withMinimumLicense } from '../../utils/with_minimum_license'; export const privilegesCheckPrivilegeMonitoringRoute = ( router: EntityAnalyticsRoutesDeps['router'], @@ -34,24 +35,27 @@ export const privilegesCheckPrivilegeMonitoringRoute = ( validate: {}, }, - async (context, request, response): Promise> => { - const siemResponse = buildSiemResponse(response); - const secSol = await context.securitySolution; - const spaceId = secSol.getSpaceId(); - const [_, { security }] = await getStartServices(); + withMinimumLicense( + async (context, request, response): Promise> => { + const siemResponse = buildSiemResponse(response); + const secSol = await context.securitySolution; + const spaceId = secSol.getSpaceId(); + const [_, { security }] = await getStartServices(); - try { - const body = await getReadPrivilegeUserMonitoringPrivileges(request, security, spaceId); - return response.ok({ body }); - } catch (e) { - const error = transformError(e); + try { + const body = await getReadPrivilegeUserMonitoringPrivileges(request, security, spaceId); + return response.ok({ body }); + } catch (e) { + const error = transformError(e); - logger.error(`Error checking privilege monitoring privileges: ${error.message}`); - return siemResponse.error({ - statusCode: error.statusCode, - body: error.message, - }); - } - } + logger.error(`Error checking privilege monitoring privileges: ${error.message}`); + return siemResponse.error({ + statusCode: error.statusCode, + body: error.message, + }); + } + }, + 'platinum' + ) ); }; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/schedule_now.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/schedule_now.ts index a388d79695714..dbc77b636da35 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/schedule_now.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/schedule_now.ts @@ -18,6 +18,7 @@ import type { EntityAnalyticsRoutesDeps } from '../../types'; import { createEngineStatusService } from '../engine/status_service'; import { PrivilegeMonitoringApiKeyType } from '../auth/saved_object'; import { monitoringEntitySourceType } from '../saved_objects'; +import { withMinimumLicense } from '../../utils/with_minimum_license'; export const scheduleNowMonitoringEngineRoute = ( router: EntityAnalyticsRoutesDeps['router'], @@ -39,40 +40,42 @@ export const scheduleNowMonitoringEngineRoute = ( version: API_VERSIONS.public.v1, validate: {}, }, + withMinimumLicense( + async ( + context, + request, + response + ): Promise> => { + const siemResponse = buildSiemResponse(response); + const secSol = await context.securitySolution; - async ( - context, - request, - response - ): Promise> => { - const siemResponse = buildSiemResponse(response); - const secSol = await context.securitySolution; - - const dataClient = secSol.getPrivilegeMonitoringDataClient(); - const soClient = dataClient.getScopedSoClient(request, { - includedHiddenTypes: [ - PrivilegeMonitoringApiKeyType.name, - monitoringEntitySourceType.name, - ], - }); - const service = createEngineStatusService(dataClient, soClient); - - try { - const result = await service.scheduleNow(); - logger.debug(`Privilege monitoring engine scheduled: ${result}`); - return response.ok({ - body: { - success: true, - }, - }); - } catch (e) { - const error = transformError(e); - logger.error(`Error scheduling privilege monitoring engine: ${error.message}`); - return siemResponse.error({ - statusCode: error.statusCode, - body: error.message, + const dataClient = secSol.getPrivilegeMonitoringDataClient(); + const soClient = dataClient.getScopedSoClient(request, { + includedHiddenTypes: [ + PrivilegeMonitoringApiKeyType.name, + monitoringEntitySourceType.name, + ], }); - } - } + const service = createEngineStatusService(dataClient, soClient); + + try { + const result = await service.scheduleNow(); + logger.debug(`Privilege monitoring engine scheduled: ${result}`); + return response.ok({ + body: { + success: true, + }, + }); + } catch (e) { + const error = transformError(e); + logger.error(`Error scheduling privilege monitoring engine: ${error.message}`); + return siemResponse.error({ + statusCode: error.statusCode, + body: error.message, + }); + } + }, + 'platinum' + ) ); }; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/search_indices.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/search_indices.ts index bbcdfeaae4501..db93087f2916e 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/search_indices.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/search_indices.ts @@ -16,6 +16,7 @@ import { SearchPrivilegesIndicesRequestQuery } from '../../../../../common/api/e import { createDataSourcesService } from '../data_sources/data_sources_service'; import { PrivilegeMonitoringApiKeyType } from '../auth/saved_object'; import { monitoringEntitySourceType } from '../saved_objects'; +import { withMinimumLicense } from '../../utils/with_minimum_license'; // Return a subset of all indices that contain the user.name field const LIMIT = 20; @@ -43,8 +44,7 @@ export const searchPrivilegeMonitoringIndicesRoute = ( }, }, }, - - async (context, request, response): Promise> => { + withMinimumLicense(async (context, request, response): Promise> => { const secSol = await context.securitySolution; const siemResponse = buildSiemResponse(response); const query = request.query.searchQuery; @@ -74,6 +74,6 @@ export const searchPrivilegeMonitoringIndicesRoute = ( body: error.message, }); } - } + }, 'platinum') ); }; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/users/create.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/users/create.ts index 668dd7c79c960..af9946708a229 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/users/create.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/users/create.ts @@ -16,6 +16,7 @@ import { import { API_VERSIONS, APP_ID, MONITORING_USERS_URL } from '../../../../../../common/constants'; import type { EntityAnalyticsRoutesDeps } from '../../../types'; import { createPrivilegedUsersCrudService } from '../../users/privileged_users_crud'; +import { withMinimumLicense } from '../../../utils/with_minimum_license'; export const createUserRoute = (router: EntityAnalyticsRoutesDeps['router'], logger: Logger) => { router.versioned @@ -37,32 +38,35 @@ export const createUserRoute = (router: EntityAnalyticsRoutesDeps['router'], log }, }, }, - async (context, request, response): Promise> => { - const siemResponse = buildSiemResponse(response); + withMinimumLicense( + async (context, request, response): Promise> => { + const siemResponse = buildSiemResponse(response); - try { - const secSol = await context.securitySolution; - const { elasticsearch } = await context.core; - const crudService = createPrivilegedUsersCrudService({ - esClient: elasticsearch.client.asCurrentUser, - index: getPrivilegedMonitorUsersIndex(secSol.getSpaceId()), - logger: secSol.getLogger(), - }); + try { + const secSol = await context.securitySolution; + const { elasticsearch } = await context.core; + const crudService = createPrivilegedUsersCrudService({ + esClient: elasticsearch.client.asCurrentUser, + index: getPrivilegedMonitorUsersIndex(secSol.getSpaceId()), + logger: secSol.getLogger(), + }); - const config = secSol.getConfig(); - const maxUsersAllowed = - config.entityAnalytics.monitoring.privileges.users.maxPrivilegedUsersAllowed; + const config = secSol.getConfig(); + const maxUsersAllowed = + config.entityAnalytics.monitoring.privileges.users.maxPrivilegedUsersAllowed; - const body = await crudService.create(request.body, 'api', maxUsersAllowed); - return response.ok({ body }); - } catch (e) { - const error = transformError(e); - logger.error(`Error creating user: ${error.message}`); - return siemResponse.error({ - statusCode: error.statusCode, - body: error.message, - }); - } - } + const body = await crudService.create(request.body, 'api', maxUsersAllowed); + return response.ok({ body }); + } catch (e) { + const error = transformError(e); + logger.error(`Error creating user: ${error.message}`); + return siemResponse.error({ + statusCode: error.statusCode, + body: error.message, + }); + } + }, + 'platinum' + ) ); }; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/users/delete.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/users/delete.ts index 28e486536e9f0..af74d66a0f876 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/users/delete.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/users/delete.ts @@ -16,6 +16,7 @@ import { import { API_VERSIONS, APP_ID, MONITORING_USERS_URL } from '../../../../../../common/constants'; import type { EntityAnalyticsRoutesDeps } from '../../../types'; import { createPrivilegedUsersCrudService } from '../../users/privileged_users_crud'; +import { withMinimumLicense } from '../../../utils/with_minimum_license'; export const deleteUserRoute = (router: EntityAnalyticsRoutesDeps['router'], logger: Logger) => { router.versioned @@ -37,28 +38,31 @@ export const deleteUserRoute = (router: EntityAnalyticsRoutesDeps['router'], log }, }, }, - async (context, request, response): Promise> => { - const siemResponse = buildSiemResponse(response); + withMinimumLicense( + async (context, request, response): Promise> => { + const siemResponse = buildSiemResponse(response); - try { - const secSol = await context.securitySolution; - const { elasticsearch } = await context.core; - const crudService = createPrivilegedUsersCrudService({ - esClient: elasticsearch.client.asCurrentUser, - index: getPrivilegedMonitorUsersIndex(secSol.getSpaceId()), - logger: secSol.getLogger(), - }); + try { + const secSol = await context.securitySolution; + const { elasticsearch } = await context.core; + const crudService = createPrivilegedUsersCrudService({ + esClient: elasticsearch.client.asCurrentUser, + index: getPrivilegedMonitorUsersIndex(secSol.getSpaceId()), + logger: secSol.getLogger(), + }); - await crudService.delete(request.params.id); - return response.ok({ body: { acknowledged: true } }); - } catch (e) { - const error = transformError(e); - logger.error(`Error deleting user: ${error.message}`); - return siemResponse.error({ - statusCode: error.statusCode, - body: error.message, - }); - } - } + await crudService.delete(request.params.id); + return response.ok({ body: { acknowledged: true } }); + } catch (e) { + const error = transformError(e); + logger.error(`Error deleting user: ${error.message}`); + return siemResponse.error({ + statusCode: error.statusCode, + body: error.message, + }); + } + }, + 'platinum' + ) ); }; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/users/list.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/users/list.ts index 6ef19a8df6862..694d8d3927057 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/users/list.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/users/list.ts @@ -21,6 +21,7 @@ import { } from '../../../../../../common/constants'; import type { EntityAnalyticsRoutesDeps } from '../../../types'; import { createPrivilegedUsersCrudService } from '../../users/privileged_users_crud'; +import { withMinimumLicense } from '../../../utils/with_minimum_license'; export const listUsersRoute = (router: EntityAnalyticsRoutesDeps['router'], logger: Logger) => { router.versioned @@ -42,27 +43,30 @@ export const listUsersRoute = (router: EntityAnalyticsRoutesDeps['router'], logg }, }, }, - async (context, request, response): Promise> => { - const siemResponse = buildSiemResponse(response); - try { - const secSol = await context.securitySolution; - const { elasticsearch } = await context.core; - const crudService = createPrivilegedUsersCrudService({ - esClient: elasticsearch.client.asCurrentUser, - index: getPrivilegedMonitorUsersIndex(secSol.getSpaceId()), - logger: secSol.getLogger(), - }); + withMinimumLicense( + async (context, request, response): Promise> => { + const siemResponse = buildSiemResponse(response); + try { + const secSol = await context.securitySolution; + const { elasticsearch } = await context.core; + const crudService = createPrivilegedUsersCrudService({ + esClient: elasticsearch.client.asCurrentUser, + index: getPrivilegedMonitorUsersIndex(secSol.getSpaceId()), + logger: secSol.getLogger(), + }); - const body = await crudService.list(request.query.kql); - return response.ok({ body }); - } catch (e) { - const error = transformError(e); - logger.error(`Error listing users: ${error.message}`); - return siemResponse.error({ - statusCode: error.statusCode, - body: error.message, - }); - } - } + const body = await crudService.list(request.query.kql); + return response.ok({ body }); + } catch (e) { + const error = transformError(e); + logger.error(`Error listing users: ${error.message}`); + return siemResponse.error({ + statusCode: error.statusCode, + body: error.message, + }); + } + }, + 'platinum' + ) ); }; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/users/update.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/users/update.ts index d4486df7de856..0f3a6ca1d27ca 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/users/update.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/users/update.ts @@ -17,6 +17,7 @@ import { import { API_VERSIONS, APP_ID, MONITORING_USERS_URL } from '../../../../../../common/constants'; import type { EntityAnalyticsRoutesDeps } from '../../../types'; import { createPrivilegedUsersCrudService } from '../../users/privileged_users_crud'; +import { withMinimumLicense } from '../../../utils/with_minimum_license'; export const updateUserRoute = (router: EntityAnalyticsRoutesDeps['router'], logger: Logger) => { router.versioned @@ -39,7 +40,7 @@ export const updateUserRoute = (router: EntityAnalyticsRoutesDeps['router'], log }, }, }, - async (context, request, response): Promise => { + withMinimumLicense(async (context, request, response): Promise => { const siemResponse = buildSiemResponse(response); try { @@ -62,6 +63,6 @@ export const updateUserRoute = (router: EntityAnalyticsRoutesDeps['router'], log body: error.message, }); } - } + }, 'platinum') ); }; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/users/upload_csv.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/users/upload_csv.ts index 490de6c4814b7..9f988d9e06f45 100644 --- a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/users/upload_csv.ts +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/users/upload_csv.ts @@ -21,6 +21,7 @@ import { API_VERSIONS, APP_ID } from '../../../../../../common/constants'; import type { EntityAnalyticsRoutesDeps } from '../../../types'; import { createPrivilegedUsersCsvService } from '../../users/csv_upload'; import { checkAndInitPrivilegeMonitoringResources } from '../../check_and_init_privmon_resources'; +import { withMinimumLicense } from '../../../utils/with_minimum_license'; export const uploadUsersCSVRoute = ( router: EntityAnalyticsRoutesDeps['router'], @@ -55,37 +56,40 @@ export const uploadUsersCSVRoute = ( }, }, }, - async ( - context, - request, - response - ): Promise> => { - const { errorRetries, maxBulkRequestBodySizeBytes } = - config.entityAnalytics.monitoring.privileges.users.csvUpload; + withMinimumLicense( + async ( + context, + request, + response + ): Promise> => { + const { errorRetries, maxBulkRequestBodySizeBytes } = + config.entityAnalytics.monitoring.privileges.users.csvUpload; - const siemResponse = buildSiemResponse(response); + const siemResponse = buildSiemResponse(response); - try { - const secSol = await context.securitySolution; - const fileStream = request.body.file as HapiReadableStream; + try { + const secSol = await context.securitySolution; + const fileStream = request.body.file as HapiReadableStream; - const dataClient = secSol.getPrivilegeMonitoringDataClient(); - const csvService = createPrivilegedUsersCsvService(dataClient); - await checkAndInitPrivilegeMonitoringResources(context, logger); - const body = await csvService.bulkUpload(fileStream, { - retries: errorRetries, - flushBytes: maxBulkRequestBodySizeBytes, - }); + const dataClient = secSol.getPrivilegeMonitoringDataClient(); + const csvService = createPrivilegedUsersCsvService(dataClient); + await checkAndInitPrivilegeMonitoringResources(context, logger); + const body = await csvService.bulkUpload(fileStream, { + retries: errorRetries, + flushBytes: maxBulkRequestBodySizeBytes, + }); - return response.ok({ body }); - } catch (e) { - const error = transformError(e); - logger.error(`Error uploading users via CSV: ${error.message}`); - return siemResponse.error({ - statusCode: error.statusCode, - body: error.message, - }); - } - } + return response.ok({ body }); + } catch (e) { + const error = transformError(e); + logger.error(`Error uploading users via CSV: ${error.message}`); + return siemResponse.error({ + statusCode: error.statusCode, + body: error.message, + }); + } + }, + 'platinum' + ) ); }; diff --git a/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/utils/with_minimum_license.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/utils/with_minimum_license.ts new file mode 100644 index 0000000000000..77c2e1cae3bf5 --- /dev/null +++ b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/utils/with_minimum_license.ts @@ -0,0 +1,40 @@ +/* + * 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 { RequestHandler, RouteMethod } from '@kbn/core/server'; +import { i18n } from '@kbn/i18n'; +import type { LicenseType } from '@kbn/licensing-types'; +import type { SecuritySolutionRequestHandlerContext } from '../../../types'; + +const LICENSE_ERROR_MESSAGE = i18n.translate( + 'xpack.securitySolution.entityAnalytics.api.licenseError', + { + defaultMessage: 'Your license does not support this feature.', + } +); + +/** + * Wraps a request handler with a check for the license. If the license is not valid, it will + * return a 403 error with a message. + */ +export const withMinimumLicense = < + P = unknown, + Q = unknown, + B = unknown, + Method extends RouteMethod = never +>( + handler: RequestHandler, + minimumLicenseRequired: LicenseType = 'enterprise' +): RequestHandler => { + return async (context, req, res) => { + const { license } = await context.licensing; + if (!license.hasAtLeast(minimumLicenseRequired)) { + return res.forbidden({ body: LICENSE_ERROR_MESSAGE }); + } + return handler(context, req, res); + }; +}; diff --git a/x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/monitoring/basic_license_essentials_tier/api_feature_access.ts b/x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/monitoring/basic_license_essentials_tier/api_feature_access.ts new file mode 100644 index 0000000000000..e6be47f37db3c --- /dev/null +++ b/x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/monitoring/basic_license_essentials_tier/api_feature_access.ts @@ -0,0 +1,119 @@ +/* + * 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 expect from 'expect'; +import { privilegeMonitoringRouteHelpersFactory } from '../../utils'; +import type { FtrProviderContext } from '../../../../ftr_provider_context'; + +const licenseMessage = 'Your license does not support this feature.'; +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertest'); + const privilegedUserMonitoringRoutes = privilegeMonitoringRouteHelpersFactory(supertest); + + describe('@ess Basic License API Access', () => { + it('should not be able to access init engine api due to license', async () => { + const response = await privilegedUserMonitoringRoutes.init(403); + expect(response.body.message).toEqual(licenseMessage); + }); + + it('should not be able to access disable engine api due to license', async () => { + const response = await privilegedUserMonitoringRoutes.disable(403); + expect(response.body.message).toEqual(licenseMessage); + }); + + it('should not be able to access schedule now api due to license', async () => { + const response = await privilegedUserMonitoringRoutes.scheduleNow(403); + expect(response.body.message).toEqual(licenseMessage); + }); + + it('should not be able to access delete engine api due to license', async () => { + const response = await privilegedUserMonitoringRoutes.delete(403); + expect(response.body.message).toEqual(licenseMessage); + }); + + it('should not be able to access health check api due to license', async () => { + const response = await privilegedUserMonitoringRoutes.healthCheck(403); + expect(response.body.message).toEqual(licenseMessage); + }); + + it('should not be able to access privilege check api due to license', async () => { + const response = await privilegedUserMonitoringRoutes.privilegeCheck(403); + expect(response.body.message).toEqual(licenseMessage); + }); + + it('should not be able to access create indices api due to license', async () => { + const response = await privilegedUserMonitoringRoutes.createIndices( + { name: 'test', mode: 'standard' }, + 403 + ); + expect(response.body.message).toEqual(licenseMessage); + }); + + it('should not be able to access create user api due to license', async () => { + const response = await privilegedUserMonitoringRoutes.createUser({}, 403); + expect(response.body.message).toEqual(licenseMessage); + }); + + it('should not be able to access list users api due to license', async () => { + const response = await privilegedUserMonitoringRoutes.listUsers(403); + expect(response.body.message).toEqual(licenseMessage); + }); + + it('should not be able to access update user api due to license', async () => { + const response = await privilegedUserMonitoringRoutes.updateUser({}, 403); + expect(response.body.message).toEqual(licenseMessage); + }); + + it('should not be able to access upload user CSV api due to license', async () => { + const response = await privilegedUserMonitoringRoutes.uploadUsersCSV('test', 403); + expect(response.body.message).toEqual(licenseMessage); + }); + + it('should not be able to access delete user api due to license', async () => { + const response = await privilegedUserMonitoringRoutes.deleteUser('test', 403); + expect(response.body.message).toEqual(licenseMessage); + }); + + it('should not be able to access privileged access detection install api due to license', async () => { + const response = await privilegedUserMonitoringRoutes.padInstall(403); + expect(response.body.message).toEqual(licenseMessage); + }); + + it('should not be able to access privileged access detection status api due to license', async () => { + const response = await privilegedUserMonitoringRoutes.padStatus(403); + expect(response.body.message).toEqual(licenseMessage); + }); + + it('should not be able to access create source api due to license', async () => { + const response = await privilegedUserMonitoringRoutes.createSource( + { type: 'index', name: 'test' }, + 403 + ); + expect(response.body.message).toEqual(licenseMessage); + }); + + it('should not be able to access get source api due to license', async () => { + const response = await privilegedUserMonitoringRoutes.getSource('test', 403); + expect(response.body.message).toEqual(licenseMessage); + }); + + it('should not be able to access update source api due to license', async () => { + const response = await privilegedUserMonitoringRoutes.updateSource('test', {}, 403); + expect(response.body.message).toEqual(licenseMessage); + }); + + it('should not be able to access list source api due to license', async () => { + const response = await privilegedUserMonitoringRoutes.listSource(403); + expect(response.body.message).toEqual(licenseMessage); + }); + + it('should not be able to access delete source api due to license', async () => { + const response = await privilegedUserMonitoringRoutes.deleteSource('test', 403); + expect(response.body.message).toEqual(licenseMessage); + }); + }); +}; diff --git a/x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/monitoring/basic_license_essentials_tier/api_feature_access_serverless.ts b/x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/monitoring/basic_license_essentials_tier/api_feature_access_serverless.ts new file mode 100644 index 0000000000000..09c20ee2a1120 --- /dev/null +++ b/x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/monitoring/basic_license_essentials_tier/api_feature_access_serverless.ts @@ -0,0 +1,92 @@ +/* + * 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 { privilegeMonitoringRouteHelpersFactory } from '../../utils'; +import type { FtrProviderContext } from '../../../../ftr_provider_context'; + +export default ({ getService }: FtrProviderContext) => { + const supertest = getService('supertest'); + const privilegedUserMonitoringRoutes = privilegeMonitoringRouteHelpersFactory(supertest); + + describe('@serverless Essentials Tier API Access', () => { + it('should not find init engine api', async () => { + await privilegedUserMonitoringRoutes.init(404); + }); + + it('should not find disable engine api', async () => { + await privilegedUserMonitoringRoutes.disable(404); + }); + + it('should not find schedule now api', async () => { + await privilegedUserMonitoringRoutes.scheduleNow(404); + }); + + it('should not find delete engine api', async () => { + await privilegedUserMonitoringRoutes.delete(404); + }); + + it('should not find health check api', async () => { + await privilegedUserMonitoringRoutes.healthCheck(404); + }); + + it('should not find privilege check api', async () => { + await privilegedUserMonitoringRoutes.privilegeCheck(404); + }); + + it('should not find create indices api', async () => { + await privilegedUserMonitoringRoutes.createIndices({ name: 'test', mode: 'standard' }, 404); + }); + + it('should not find create user api', async () => { + await privilegedUserMonitoringRoutes.createUser({}, 404); + }); + + it('should not find list users api', async () => { + await privilegedUserMonitoringRoutes.listUsers(404); + }); + + it('should not find update user api', async () => { + await privilegedUserMonitoringRoutes.updateUser({}, 404); + }); + + it('should not find upload user CSV api', async () => { + await privilegedUserMonitoringRoutes.uploadUsersCSV('test', 404); + }); + + it('should not find delete user api', async () => { + await privilegedUserMonitoringRoutes.deleteUser('test', 404); + }); + + it('should not find privileged access detection install api', async () => { + await privilegedUserMonitoringRoutes.padInstall(404); + }); + + it('should not find privileged access detection status api', async () => { + await privilegedUserMonitoringRoutes.padStatus(404); + }); + + it('should not find create source api', async () => { + await privilegedUserMonitoringRoutes.createSource({ type: 'index', name: 'test' }, 404); + }); + + it('should not find get source api', async () => { + await privilegedUserMonitoringRoutes.getSource('test', 404); + }); + + it('should not find update source api', async () => { + await privilegedUserMonitoringRoutes.updateSource('test', {}, 404); + }); + + it('should not find list source api', async () => { + await privilegedUserMonitoringRoutes.listSource(404); + }); + + it('should not find delete source api', async () => { + await privilegedUserMonitoringRoutes.deleteSource('test', 404); + }); + }); +}; diff --git a/x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/monitoring/basic_license_essentials_tier/configs/ess.config.ts b/x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/monitoring/basic_license_essentials_tier/configs/ess.config.ts new file mode 100644 index 0000000000000..fa1e3e4f17e9e --- /dev/null +++ b/x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/monitoring/basic_license_essentials_tier/configs/ess.config.ts @@ -0,0 +1,30 @@ +/* + * 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 { FtrConfigProviderContext } from '@kbn/test'; +export default async function ({ readConfigFile }: FtrConfigProviderContext) { + const functionalConfig = await readConfigFile( + require.resolve('../../../../../config/ess/config.base.basic') + ); + + return { + ...functionalConfig.getAll(), + kbnTestServer: { + ...functionalConfig.get('kbnTestServer'), + serverArgs: [ + ...functionalConfig.get('kbnTestServer.serverArgs'), + '--xpack.securitySolution.entityAnalytics.monitoring.privileges.users.maxPrivilegedUsersAllowed=100', + `--xpack.securitySolution.enableExperimental=${JSON.stringify([])}`, + ], + }, + testFiles: [require.resolve('..')], + junit: { + reportName: + 'Entity Analytics - Privilege Monitoring Integration Tests - ESS Env - Basic License', + }, + }; +} diff --git a/x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/monitoring/basic_license_essentials_tier/configs/serverless.config.ts b/x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/monitoring/basic_license_essentials_tier/configs/serverless.config.ts new file mode 100644 index 0000000000000..a40c294e0bdeb --- /dev/null +++ b/x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/monitoring/basic_license_essentials_tier/configs/serverless.config.ts @@ -0,0 +1,24 @@ +/* + * 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 { createTestConfig } from '../../../../../config/serverless/config.base'; + +export default createTestConfig({ + kbnTestServerArgs: [ + `--xpack.securitySolutionServerless.productTypes=${JSON.stringify([ + { product_line: 'security', product_tier: 'essentials' }, + { product_line: 'endpoint', product_tier: 'essentials' }, + { product_line: 'cloud', product_tier: 'essentials' }, + ])}`, + '--xpack.securitySolution.entityAnalytics.monitoring.privileges.users.maxPrivilegedUsersAllowed=100', + ], + testFiles: [require.resolve('..')], + junit: { + reportName: + 'Entity Analytics - Privilege Monitoring Integration Tests - Serverless Env - Essentials Tier', + }, +}); diff --git a/x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/monitoring/basic_license_essentials_tier/index.ts b/x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/monitoring/basic_license_essentials_tier/index.ts new file mode 100644 index 0000000000000..c9da650ca41c5 --- /dev/null +++ b/x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/monitoring/basic_license_essentials_tier/index.ts @@ -0,0 +1,15 @@ +/* + * 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 { FtrProviderContext } from '../../../../ftr_provider_context'; + +export default function ({ loadTestFile }: FtrProviderContext) { + describe('Entity Analytics - Privilege Monitoring', function () { + loadTestFile(require.resolve('./api_feature_access')); + loadTestFile(require.resolve('./api_feature_access_serverless')); + }); +} diff --git a/x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/utils/index.ts b/x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/utils/index.ts index 3b17faa11ec0c..93f7b55e9e2e8 100644 --- a/x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/utils/index.ts +++ b/x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/utils/index.ts @@ -11,3 +11,4 @@ export * from './asset_criticality'; export * from './entity_store'; export * from './elastic_asset_checker'; export * from './entity_analytics'; +export * from './privilege_monitoring'; diff --git a/x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/utils/privilege_monitoring.ts b/x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/utils/privilege_monitoring.ts index 06f2846c84264..b3af2ee60dca6 100644 --- a/x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/utils/privilege_monitoring.ts +++ b/x-pack/solutions/security/test/security_solution_api_integration/test_suites/entity_analytics/utils/privilege_monitoring.ts @@ -4,12 +4,248 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ +import type SuperTest from 'supertest'; import { X_ELASTIC_INTERNAL_ORIGIN_REQUEST } from '@kbn/core-http-common'; import type { SupertestWithoutAuthProviderType } from '@kbn/ftr-common-functional-services'; import { API_VERSIONS, + MONITORING_ENGINE_DELETE_URL, + MONITORING_ENGINE_DISABLE_URL, + MONITORING_ENGINE_INIT_URL, + MONITORING_ENGINE_SCHEDULE_NOW_URL, + MONITORING_ENTITY_LIST_SOURCES_URL, + MONITORING_ENTITY_SOURCE_URL, + MONITORING_USERS_CSV_UPLOAD_URL, + MONITORING_USERS_LIST_URL, + MONITORING_USERS_URL, + PAD_INSTALL_URL, + PAD_STATUS_URL, + PRIVMON_HEALTH_URL, + PRIVMON_INDICES_URL, PRIVMON_PRIVILEGE_CHECK_API, } from '@kbn/security-solution-plugin/common/constants'; +import { routeWithNamespace } from '@kbn/detections-response-ftr-services'; + +const assertStatusCode = (statusCode: number, response: SuperTest.Response) => { + if (response.status !== statusCode) { + throw new Error( + `Expected status code ${statusCode}, but got ${response.statusCode} \n` + response.text + ); + } +}; + +export const privilegeMonitoringRouteHelpersFactory = ( + supertest: SuperTest.Agent, + namespace?: string +) => { + return { + init: async (expectStatusCode: number = 200) => { + const response = await supertest + .post(routeWithNamespace(MONITORING_ENGINE_INIT_URL, namespace)) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1) + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') + .send(); + assertStatusCode(expectStatusCode, response); + return response; + }, + disable: async (expectStatusCode: number = 200) => { + const response = await supertest + .post(routeWithNamespace(MONITORING_ENGINE_DISABLE_URL, namespace)) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1) + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') + .send(); + assertStatusCode(expectStatusCode, response); + return response; + }, + scheduleNow: async (expectStatusCode: number = 200) => { + const response = await supertest + .post(routeWithNamespace(MONITORING_ENGINE_SCHEDULE_NOW_URL, namespace)) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1) + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') + .send(); + assertStatusCode(expectStatusCode, response); + return response; + }, + delete: async (expectStatusCode: number = 200) => { + const response = await supertest + .delete(routeWithNamespace(MONITORING_ENGINE_DELETE_URL, namespace)) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1) + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') + .send(); + assertStatusCode(expectStatusCode, response); + return response; + }, + healthCheck: async (expectStatusCode: number = 200) => { + const response = await supertest + .get(routeWithNamespace(PRIVMON_HEALTH_URL, namespace)) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1) + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') + .send(); + assertStatusCode(expectStatusCode, response); + return response; + }, + privilegeCheck: async (expectStatusCode: number = 200) => { + const response = await supertest + .get(routeWithNamespace(PRIVMON_PRIVILEGE_CHECK_API, namespace)) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1) + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') + .send(); + assertStatusCode(expectStatusCode, response); + return response; + }, + createIndices: async (requestBody: Record, expectStatusCode: number = 200) => { + const response = await supertest + .put(routeWithNamespace(PRIVMON_INDICES_URL, namespace)) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1) + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') + .send(requestBody); + assertStatusCode(expectStatusCode, response); + return response; + }, + searchIndices: async (expectStatusCode: number = 200) => { + const response = await supertest + .get(routeWithNamespace(PRIVMON_INDICES_URL, namespace)) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1) + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') + .send(); + assertStatusCode(expectStatusCode, response); + return response; + }, + createUser: async (requestBody: Record, expectStatusCode: number = 200) => { + const response = await supertest + .post(routeWithNamespace(MONITORING_USERS_URL, namespace)) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1) + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') + .send(requestBody); + assertStatusCode(expectStatusCode, response); + return response; + }, + listUsers: async (expectStatusCode: number = 200) => { + const response = await supertest + .get(routeWithNamespace(MONITORING_USERS_LIST_URL, namespace)) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1) + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') + .send(); + assertStatusCode(expectStatusCode, response); + return response; + }, + updateUser: async (requestBody: Record, expectStatusCode: number = 200) => { + const response = await supertest + .put(routeWithNamespace(MONITORING_USERS_LIST_URL, namespace)) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1) + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') + .send(requestBody); + assertStatusCode(expectStatusCode, response); + return response; + }, + uploadUsersCSV: async (fileContent: string | Buffer, expectStatusCode: number = 200) => { + const file = fileContent instanceof Buffer ? fileContent : Buffer.from(fileContent); + const response = await supertest + .post(routeWithNamespace(MONITORING_USERS_CSV_UPLOAD_URL, namespace)) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1) + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') + .attach('file', file, { filename: 'users.csv', contentType: 'text/csv' }); + assertStatusCode(expectStatusCode, response); + return response; + }, + deleteUser: async (id: string, expectStatusCode: number = 200) => { + const response = await supertest + .delete(routeWithNamespace(`${MONITORING_USERS_URL}/${id}`, namespace)) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1) + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') + .send(); + assertStatusCode(expectStatusCode, response); + return response; + }, + padInstall: async (expectStatusCode: number = 200) => { + const response = await supertest + .post(routeWithNamespace(PAD_INSTALL_URL, namespace)) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1) + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') + .send(); + assertStatusCode(expectStatusCode, response); + return response; + }, + padStatus: async (expectStatusCode: number = 200) => { + const response = await supertest + .get(routeWithNamespace(PAD_STATUS_URL, namespace)) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1) + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') + .send(); + assertStatusCode(expectStatusCode, response); + return response; + }, + createSource: async (requestBody: Record, expectStatusCode: number = 200) => { + const response = await supertest + .post(routeWithNamespace(MONITORING_ENTITY_SOURCE_URL, namespace)) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1) + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') + .send(requestBody); + assertStatusCode(expectStatusCode, response); + return response; + }, + getSource: async (id: string, expectStatusCode: number = 200) => { + const response = await supertest + .get(routeWithNamespace(`${MONITORING_ENTITY_SOURCE_URL}/${id}`, namespace)) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1) + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') + .send(); + assertStatusCode(expectStatusCode, response); + return response; + }, + updateSource: async ( + id: string, + requestBody: Record, + expectStatusCode: number = 200 + ) => { + const response = await supertest + .put(routeWithNamespace(`${MONITORING_ENTITY_SOURCE_URL}/${id}`, namespace)) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1) + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') + .send(requestBody); + assertStatusCode(expectStatusCode, response); + return response; + }, + listSource: async (expectStatusCode: number = 200) => { + const response = await supertest + .get(routeWithNamespace(MONITORING_ENTITY_LIST_SOURCES_URL, namespace)) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1) + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') + .send(); + assertStatusCode(expectStatusCode, response); + return response; + }, + deleteSource: async (id: string, expectStatusCode: number = 200) => { + const response = await supertest + .delete(routeWithNamespace(`${MONITORING_ENTITY_SOURCE_URL}/${id}`, namespace)) + .set('kbn-xsrf', 'true') + .set('elastic-api-version', API_VERSIONS.public.v1) + .set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana') + .send(); + assertStatusCode(expectStatusCode, response); + return response; + }, + }; +}; export const privilegeMonitoringRouteHelpersFactoryNoAuth = ( supertestWithoutAuth: SupertestWithoutAuthProviderType