diff --git a/.buildkite/ftr_security_serverless_configs.yml b/.buildkite/ftr_security_serverless_configs.yml index 5bea8a4958f2e..8e52530541fee 100644 --- a/.buildkite/ftr_security_serverless_configs.yml +++ b/.buildkite/ftr_security_serverless_configs.yml @@ -117,6 +117,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/lists_and_exception_lists/exception_lists_items/trial_license_complete_tier/configs/serverless.config.ts - x-pack/solutions/security/test/security_solution_api_integration/test_suites/lists_and_exception_lists/authorization/exceptions/lists/essentials_tier/configs/serverless.config.ts diff --git a/.buildkite/ftr_security_stateful_configs.yml b/.buildkite/ftr_security_stateful_configs.yml index 119b2a90bb371..d0b6f74f0ae80 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/lists_and_exception_lists/exception_lists_items/trial_license_complete_tier/configs/ess.config.ts - x-pack/solutions/security/test/security_solution_api_integration/test_suites/lists_and_exception_lists/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 0e6bc6e5bc5f2..ca5a7489b3e22 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 506004f20edf7..1305f1923d662 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 @@ -21,6 +21,7 @@ import { assertAdvancedSettingsEnabled } from '../../utils/assert_advanced_setti 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'], @@ -46,7 +47,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; @@ -79,6 +80,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 5e0bf93b4ef65..c303f452e7ce4 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 @@ -18,6 +18,7 @@ import { import type { EntityAnalyticsRoutesDeps } from '../../types'; import { assertAdvancedSettingsEnabled } from '../../utils/assert_advanced_setting_enabled'; import { createEngineStatusService } from '../engine/status_service'; +import { withMinimumLicense } from '../../utils/with_minimum_license'; export const disablePrivilegeMonitoringEngineRoute = ( router: EntityAnalyticsRoutesDeps['router'], @@ -44,34 +45,36 @@ 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; + await assertAdvancedSettingsEnabled( + await context.core, + ENABLE_PRIVILEGED_USER_MONITORING_SETTING + ); - await assertAdvancedSettingsEnabled( - await context.core, - ENABLE_PRIVILEGED_USER_MONITORING_SETTING - ); - - 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 2665d82eb3bd2..b3f2b5f63af91 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 @@ -19,6 +19,7 @@ import type { EntityAnalyticsRoutesDeps } from '../../types'; import { assertAdvancedSettingsEnabled } from '../../utils/assert_advanced_setting_enabled'; 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'], @@ -40,49 +41,52 @@ 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; - await assertAdvancedSettingsEnabled( - await context.core, - ENABLE_PRIVILEGED_USER_MONITORING_SETTING - ); - const dataClient = secSol.getPrivilegeMonitoringDataClient(); - const soClient = dataClient.getScopedSoClient(request); - const config = secSol.getConfig(); - const maxUsersAllowed = - config.entityAnalytics.monitoring.privileges.users.maxPrivilegedUsersAllowed; + await assertAdvancedSettingsEnabled( + await context.core, + ENABLE_PRIVILEGED_USER_MONITORING_SETTING + ); + 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 8e118f849e5fb..d9f6da62ba013 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 @@ -21,6 +21,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'], @@ -42,45 +43,47 @@ 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; + await assertAdvancedSettingsEnabled( + await context.core, + ENABLE_PRIVILEGED_USER_MONITORING_SETTING + ); - await assertAdvancedSettingsEnabled( - await context.core, - ENABLE_PRIVILEGED_USER_MONITORING_SETTING - ); + 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 e5c09f1511994..1c7ab9fd2396f 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 @@ -26,6 +26,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'], @@ -50,46 +51,53 @@ export const createMonitoringEntitySourceRoute = ( }, }, }, - async (context, request, response): Promise> => { - const siemResponse = buildSiemResponse(response); + withMinimumLicense( + async ( + context, + request, + response + ): Promise> => { + const siemResponse = buildSiemResponse(response); - try { - await assertAdvancedSettingsEnabled( - await context.core, - ENABLE_PRIVILEGED_USER_MONITORING_SETTING - ); + try { + await assertAdvancedSettingsEnabled( + await context.core, + ENABLE_PRIVILEGED_USER_MONITORING_SETTING + ); - const secSol = await context.securitySolution; - const client = secSol.getMonitoringEntitySourceDataClient(); + const secSol = await context.securitySolution; + const client = secSol.getMonitoringEntitySourceDataClient(); - const body = await client.init(request.body); - const privMonDataClient = await secSol.getPrivilegeMonitoringDataClient(); - const soClient = privMonDataClient.getScopedSoClient(request, { - includedHiddenTypes: [ - PrivilegeMonitoringApiKeyType.name, - monitoringEntitySourceType.name, - ], - }); + const body = await client.init(request.body); + 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/get.ts b/x-pack/solutions/security/plugins/security_solution/server/lib/entity_analytics/privilege_monitoring/routes/monitoring_entity_source/get.ts index 44cf73f05d283..2026356833b23 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 @@ -22,6 +22,7 @@ import { GetEntitySourceRequestParams, } from '../../../../../../common/api/entity_analytics'; import { assertAdvancedSettingsEnabled } from '../../../utils/assert_advanced_setting_enabled'; +import { withMinimumLicense } from '../../../utils/with_minimum_license'; export const getMonitoringEntitySourceRoute = ( router: EntityAnalyticsRoutesDeps['router'], @@ -47,26 +48,29 @@ export const getMonitoringEntitySourceRoute = ( }, }, }, - async (context, request, response): Promise> => { - const siemResponse = buildSiemResponse(response); + withMinimumLicense( + async (context, request, response): Promise> => { + const siemResponse = buildSiemResponse(response); - try { - await assertAdvancedSettingsEnabled( - await context.core, - ENABLE_PRIVILEGED_USER_MONITORING_SETTING - ); - 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 { + await assertAdvancedSettingsEnabled( + await context.core, + ENABLE_PRIVILEGED_USER_MONITORING_SETTING + ); + 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 639b98b4d9ccb..78b88c018353a 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 @@ -21,6 +21,7 @@ import { type ListEntitySourcesResponse, } from '../../../../../../common/api/entity_analytics'; import { assertAdvancedSettingsEnabled } from '../../../utils/assert_advanced_setting_enabled'; +import { withMinimumLicense } from '../../../utils/with_minimum_license'; export const listMonitoringEntitySourceRoute = ( router: EntityAnalyticsRoutesDeps['router'], @@ -45,28 +46,31 @@ export const listMonitoringEntitySourceRoute = ( }, }, }, - async (context, request, response): Promise> => { - const siemResponse = buildSiemResponse(response); + withMinimumLicense( + async (context, request, response): Promise> => { + const siemResponse = buildSiemResponse(response); - try { - await assertAdvancedSettingsEnabled( - await context.core, - ENABLE_PRIVILEGED_USER_MONITORING_SETTING - ); + try { + await assertAdvancedSettingsEnabled( + await context.core, + ENABLE_PRIVILEGED_USER_MONITORING_SETTING + ); - const secSol = await context.securitySolution; - const client = secSol.getMonitoringEntitySourceDataClient(); - const body = await client.list(request.query); + 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 5536d5a9d697f..a7236e1261c72 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 @@ -27,6 +27,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'], @@ -53,46 +54,53 @@ export const updateMonitoringEntitySourceRoute = ( }, }, }, - async (context, request, response): Promise> => { - const siemResponse = buildSiemResponse(response); + withMinimumLicense( + async ( + context, + request, + response + ): Promise> => { + const siemResponse = buildSiemResponse(response); - try { - await assertAdvancedSettingsEnabled( - await context.core, - ENABLE_PRIVILEGED_USER_MONITORING_SETTING - ); - const secSol = await context.securitySolution; - const client = secSol.getMonitoringEntitySourceDataClient(); - const body = await client.update({ ...request.body, id: request.params.id }); + try { + await assertAdvancedSettingsEnabled( + await context.core, + ENABLE_PRIVILEGED_USER_MONITORING_SETTING + ); + 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 0a99bfcbe8818..7a95cdb5ce1bd 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 @@ -14,10 +14,12 @@ import { API_VERSIONS, APP_ID, ENABLE_PRIVILEGED_USER_MONITORING_SETTING, + PAD_INSTALL_URL, } from '../../../../../../common/constants'; import type { EntityAnalyticsRoutesDeps } from '../../../types'; import { assertAdvancedSettingsEnabled } from '../../../utils/assert_advanced_setting_enabled'; +import { withMinimumLicense } from '../../../utils/with_minimum_license'; export const padInstallRoute = ( router: EntityAnalyticsRoutesDeps['router'], @@ -27,7 +29,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`], @@ -39,37 +41,39 @@ 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; + await assertAdvancedSettingsEnabled( + await context.core, + ENABLE_PRIVILEGED_USER_MONITORING_SETTING + ); - await assertAdvancedSettingsEnabled( - await context.core, - ENABLE_PRIVILEGED_USER_MONITORING_SETTING - ); - - 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 4ab7d158805fa..adada4506945c 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 @@ -20,6 +20,7 @@ import { assertAdvancedSettingsEnabled } from '../../utils/assert_advanced_setti 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'], @@ -41,45 +42,47 @@ 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; + await assertAdvancedSettingsEnabled( + await context.core, + ENABLE_PRIVILEGED_USER_MONITORING_SETTING + ); - await assertAdvancedSettingsEnabled( - await context.core, - ENABLE_PRIVILEGED_USER_MONITORING_SETTING - ); - - 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 6bf194fa0f21e..9a3120258f9fd 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 @@ -22,6 +22,7 @@ import { assertAdvancedSettingsEnabled } from '../../utils/assert_advanced_setti 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; @@ -49,8 +50,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; @@ -85,6 +85,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 54b384411918b..43ddf125f060f 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 @@ -21,6 +21,7 @@ import { import type { EntityAnalyticsRoutesDeps } from '../../../types'; import { assertAdvancedSettingsEnabled } from '../../../utils/assert_advanced_setting_enabled'; import { createPrivilegedUsersCrudService } from '../../users/privileged_users_crud'; +import { withMinimumLicense } from '../../../utils/with_minimum_license'; export const createUserRoute = (router: EntityAnalyticsRoutesDeps['router'], logger: Logger) => { router.versioned @@ -42,31 +43,34 @@ 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 { - await assertAdvancedSettingsEnabled( - await context.core, - ENABLE_PRIVILEGED_USER_MONITORING_SETTING - ); - const secSol = await context.securitySolution; - const dataClient = secSol.getPrivilegeMonitoringDataClient(); - const config = secSol.getConfig(); - const maxUsersAllowed = - config.entityAnalytics.monitoring.privileges.users.maxPrivilegedUsersAllowed; - const crudService = createPrivilegedUsersCrudService(dataClient); + try { + await assertAdvancedSettingsEnabled( + await context.core, + ENABLE_PRIVILEGED_USER_MONITORING_SETTING + ); + const secSol = await context.securitySolution; + const dataClient = secSol.getPrivilegeMonitoringDataClient(); + const config = secSol.getConfig(); + const maxUsersAllowed = + config.entityAnalytics.monitoring.privileges.users.maxPrivilegedUsersAllowed; + const crudService = createPrivilegedUsersCrudService(dataClient); - 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 76712e62204c8..a307162328c0b 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 @@ -21,6 +21,7 @@ import { import type { EntityAnalyticsRoutesDeps } from '../../../types'; import { assertAdvancedSettingsEnabled } from '../../../utils/assert_advanced_setting_enabled'; import { createPrivilegedUsersCrudService } from '../../users/privileged_users_crud'; +import { withMinimumLicense } from '../../../utils/with_minimum_license'; export const deleteUserRoute = (router: EntityAnalyticsRoutesDeps['router'], logger: Logger) => { router.versioned @@ -42,28 +43,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 { - await assertAdvancedSettingsEnabled( - await context.core, - ENABLE_PRIVILEGED_USER_MONITORING_SETTING - ); - const secSol = await context.securitySolution; - const dataClient = secSol.getPrivilegeMonitoringDataClient(); - const crudService = createPrivilegedUsersCrudService(dataClient); + try { + await assertAdvancedSettingsEnabled( + await context.core, + ENABLE_PRIVILEGED_USER_MONITORING_SETTING + ); + const secSol = await context.securitySolution; + const dataClient = secSol.getPrivilegeMonitoringDataClient(); + const crudService = createPrivilegedUsersCrudService(dataClient); - 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 5aa88bb2e1a86..ddc7dd81ee4ba 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 @@ -22,6 +22,7 @@ import { import type { EntityAnalyticsRoutesDeps } from '../../../types'; import { assertAdvancedSettingsEnabled } from '../../../utils/assert_advanced_setting_enabled'; import { createPrivilegedUsersCrudService } from '../../users/privileged_users_crud'; +import { withMinimumLicense } from '../../../utils/with_minimum_license'; export const listUsersRoute = (router: EntityAnalyticsRoutesDeps['router'], logger: Logger) => { router.versioned @@ -43,28 +44,31 @@ export const listUsersRoute = (router: EntityAnalyticsRoutesDeps['router'], logg }, }, }, - async (context, request, response): Promise> => { - const siemResponse = buildSiemResponse(response); - try { - await assertAdvancedSettingsEnabled( - await context.core, - ENABLE_PRIVILEGED_USER_MONITORING_SETTING - ); + withMinimumLicense( + async (context, request, response): Promise> => { + const siemResponse = buildSiemResponse(response); + try { + await assertAdvancedSettingsEnabled( + await context.core, + ENABLE_PRIVILEGED_USER_MONITORING_SETTING + ); - const secSol = await context.securitySolution; - const dataClient = secSol.getPrivilegeMonitoringDataClient(); - const crudService = createPrivilegedUsersCrudService(dataClient); + const secSol = await context.securitySolution; + const dataClient = secSol.getPrivilegeMonitoringDataClient(); + const crudService = createPrivilegedUsersCrudService(dataClient); - 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 42ea498ffe893..e927b2a19de57 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 @@ -22,6 +22,7 @@ import { import type { EntityAnalyticsRoutesDeps } from '../../../types'; import { assertAdvancedSettingsEnabled } from '../../../utils/assert_advanced_setting_enabled'; import { createPrivilegedUsersCrudService } from '../../users/privileged_users_crud'; +import { withMinimumLicense } from '../../../utils/with_minimum_license'; export const updateUserRoute = (router: EntityAnalyticsRoutesDeps['router'], logger: Logger) => { router.versioned @@ -44,7 +45,7 @@ export const updateUserRoute = (router: EntityAnalyticsRoutesDeps['router'], log }, }, }, - async (context, request, response): Promise => { + withMinimumLicense(async (context, request, response): Promise => { const siemResponse = buildSiemResponse(response); try { @@ -67,6 +68,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 daede5743cba0..2ff72ab1df37b 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 @@ -26,6 +26,7 @@ import type { EntityAnalyticsRoutesDeps } from '../../../types'; import { assertAdvancedSettingsEnabled } from '../../../utils/assert_advanced_setting_enabled'; 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'], @@ -60,42 +61,45 @@ 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 { - await assertAdvancedSettingsEnabled( - await context.core, - ENABLE_PRIVILEGED_USER_MONITORING_SETTING - ); + try { + await assertAdvancedSettingsEnabled( + await context.core, + ENABLE_PRIVILEGED_USER_MONITORING_SETTING + ); - const secSol = await context.securitySolution; - const fileStream = request.body.file as HapiReadableStream; + 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..3bdc0075c117b --- /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,114 @@ +/* + * 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); + }); + }); +}; 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..e9685c5bbce0e --- /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,88 @@ +/* + * 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); + }); + }); +}; 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 d8e78091956d9..f650de30922b1 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 @@ -12,3 +12,4 @@ export * from './entity_store'; export * from './elastic_asset_checker'; export * from './entity_analytics'; export * from './privmon_advanced_settings'; +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..d7ef40510f977 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,238 @@ * 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; + }, + }; +}; export const privilegeMonitoringRouteHelpersFactoryNoAuth = ( supertestWithoutAuth: SupertestWithoutAuthProviderType