diff --git a/x-pack/plugins/security_solution/common/entity_analytics/asset_criticality/constants.ts b/x-pack/plugins/security_solution/common/entity_analytics/asset_criticality/constants.ts index 2abc0120df67c3..d089a52f4cc300 100644 --- a/x-pack/plugins/security_solution/common/entity_analytics/asset_criticality/constants.ts +++ b/x-pack/plugins/security_solution/common/entity_analytics/asset_criticality/constants.ts @@ -5,13 +5,11 @@ * 2.0. */ -export const ASSET_CRITICALITY_INTERNAL_URL = `/internal/asset_criticality` as const; +const ASSET_CRITICALITY_INTERNAL_URL = `/internal/asset_criticality` as const; export const ASSET_CRITICALITY_INTERNAL_PRIVILEGES_URL = `${ASSET_CRITICALITY_INTERNAL_URL}/privileges` as const; export const ASSET_CRITICALITY_INTERNAL_STATUS_URL = `${ASSET_CRITICALITY_INTERNAL_URL}/status` as const; -export const ASSET_CRITICALITY_INTERNAL_CSV_UPLOAD_URL = - `${ASSET_CRITICALITY_INTERNAL_URL}/upload_csv` as const; export const ASSET_CRITICALITY_PUBLIC_URL = `/api/asset_criticality` as const; export const ASSET_CRITICALITY_PUBLIC_CSV_UPLOAD_URL = diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/routes/delete.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/routes/delete.ts index c7a0f07400cc85..9ff1e5693228a6 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/routes/delete.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/routes/delete.ts @@ -4,14 +4,12 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { IKibanaResponse, KibanaResponseFactory, Logger } from '@kbn/core/server'; +import type { Logger } from '@kbn/core/server'; import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils'; import { transformError } from '@kbn/securitysolution-es-utils'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; -import type { SecuritySolutionRequestHandlerContext } from '../../../../types'; import { ASSET_CRITICALITY_PUBLIC_URL, - ASSET_CRITICALITY_INTERNAL_URL, APP_ID, ENABLE_ASSET_CRITICALITY_SETTING, API_VERSIONS, @@ -23,79 +21,6 @@ import type { EntityAnalyticsRoutesDeps } from '../../types'; import { AssetCriticalityAuditActions } from '../audit'; import { AUDIT_CATEGORY, AUDIT_OUTCOME, AUDIT_TYPE } from '../../audit'; -type DeleteHandler = ( - context: SecuritySolutionRequestHandlerContext, - request: { - query: DeleteAssetCriticalityRecord; - }, - response: KibanaResponseFactory -) => Promise; - -const handler: (logger: Logger) => DeleteHandler = - (logger) => async (context, request, response) => { - const securitySolution = await context.securitySolution; - - securitySolution.getAuditLogger()?.log({ - message: 'User attempted to un-assign asset criticality from an entity', - event: { - action: AssetCriticalityAuditActions.ASSET_CRITICALITY_UNASSIGN, - category: AUDIT_CATEGORY.DATABASE, - type: AUDIT_TYPE.DELETION, - outcome: AUDIT_OUTCOME.UNKNOWN, - }, - }); - - const siemResponse = buildSiemResponse(response); - try { - await assertAdvancedSettingsEnabled(await context.core, ENABLE_ASSET_CRITICALITY_SETTING); - await checkAndInitAssetCriticalityResources(context, logger); - - const assetCriticalityClient = securitySolution.getAssetCriticalityDataClient(); - await assetCriticalityClient.delete( - { - idField: request.query.id_field, - idValue: request.query.id_value, - }, - request.query.refresh - ); - - return response.ok(); - } catch (e) { - const error = transformError(e); - - return siemResponse.error({ - statusCode: error.statusCode, - body: { message: error.message, full_error: JSON.stringify(e) }, - bypassErrorFormat: true, - }); - } - }; - -export const assetCriticalityInternalDeleteRoute = ( - router: EntityAnalyticsRoutesDeps['router'], - logger: Logger -) => { - router.versioned - .delete({ - access: 'internal', - path: ASSET_CRITICALITY_INTERNAL_URL, - options: { - tags: ['access:securitySolution', `access:${APP_ID}-entity-analytics`], - }, - }) - .addVersion( - { - version: API_VERSIONS.internal.v1, - validate: { - request: { - query: buildRouteValidationWithZod(DeleteAssetCriticalityRecord), - }, - }, - }, - handler(logger) - ); -}; - export const assetCriticalityPublicDeleteRoute = ( router: EntityAnalyticsRoutesDeps['router'], logger: Logger @@ -117,6 +42,43 @@ export const assetCriticalityPublicDeleteRoute = ( }, }, }, - handler(logger) + async (context, request, response) => { + const securitySolution = await context.securitySolution; + + securitySolution.getAuditLogger()?.log({ + message: 'User attempted to un-assign asset criticality from an entity', + event: { + action: AssetCriticalityAuditActions.ASSET_CRITICALITY_UNASSIGN, + category: AUDIT_CATEGORY.DATABASE, + type: AUDIT_TYPE.DELETION, + outcome: AUDIT_OUTCOME.UNKNOWN, + }, + }); + + const siemResponse = buildSiemResponse(response); + try { + await assertAdvancedSettingsEnabled(await context.core, ENABLE_ASSET_CRITICALITY_SETTING); + await checkAndInitAssetCriticalityResources(context, logger); + + const assetCriticalityClient = securitySolution.getAssetCriticalityDataClient(); + await assetCriticalityClient.delete( + { + idField: request.query.id_field, + idValue: request.query.id_value, + }, + request.query.refresh + ); + + return response.ok(); + } catch (e) { + const error = transformError(e); + + return siemResponse.error({ + statusCode: error.statusCode, + body: { message: error.message, full_error: JSON.stringify(e) }, + bypassErrorFormat: true, + }); + } + } ); }; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/routes/get.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/routes/get.ts index 07d0cb3098dbc4..9eb9ee55ba78a8 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/routes/get.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/routes/get.ts @@ -4,13 +4,11 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { IKibanaResponse, KibanaResponseFactory, Logger } from '@kbn/core/server'; +import type { Logger } from '@kbn/core/server'; import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils'; import { transformError } from '@kbn/securitysolution-es-utils'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; -import type { SecuritySolutionRequestHandlerContext } from '../../../../types'; import { - ASSET_CRITICALITY_INTERNAL_URL, ASSET_CRITICALITY_PUBLIC_URL, APP_ID, ENABLE_ASSET_CRITICALITY_SETTING, @@ -22,77 +20,6 @@ import { assertAdvancedSettingsEnabled } from '../../utils/assert_advanced_setti import type { EntityAnalyticsRoutesDeps } from '../../types'; import { AssetCriticalityAuditActions } from '../audit'; import { AUDIT_CATEGORY, AUDIT_OUTCOME, AUDIT_TYPE } from '../../audit'; -type GetHandler = ( - context: SecuritySolutionRequestHandlerContext, - request: { - query: AssetCriticalityRecordIdParts; - }, - response: KibanaResponseFactory -) => Promise; - -const handler: (logger: Logger) => GetHandler = (logger) => async (context, request, response) => { - const siemResponse = buildSiemResponse(response); - try { - await assertAdvancedSettingsEnabled(await context.core, ENABLE_ASSET_CRITICALITY_SETTING); - await checkAndInitAssetCriticalityResources(context, logger); - - const securitySolution = await context.securitySolution; - const assetCriticalityClient = securitySolution.getAssetCriticalityDataClient(); - const record = await assetCriticalityClient.get({ - idField: request.query.id_field, - idValue: request.query.id_value, - }); - - if (!record) { - return response.notFound(); - } - - securitySolution.getAuditLogger()?.log({ - message: 'User accessed the criticality level for an entity', - event: { - action: AssetCriticalityAuditActions.ASSET_CRITICALITY_GET, - category: AUDIT_CATEGORY.DATABASE, - type: AUDIT_TYPE.ACCESS, - outcome: AUDIT_OUTCOME.SUCCESS, - }, - }); - - return response.ok({ body: record }); - } catch (e) { - const error = transformError(e); - - return siemResponse.error({ - statusCode: error.statusCode, - body: { message: error.message, full_error: JSON.stringify(e) }, - bypassErrorFormat: true, - }); - } -}; - -export const assetCriticalityInternalGetRoute = ( - router: EntityAnalyticsRoutesDeps['router'], - logger: Logger -) => { - router.versioned - .get({ - access: 'internal', - path: ASSET_CRITICALITY_INTERNAL_URL, - options: { - tags: ['access:securitySolution', `access:${APP_ID}-entity-analytics`], - }, - }) - .addVersion( - { - version: API_VERSIONS.internal.v1, - validate: { - request: { - query: buildRouteValidationWithZod(AssetCriticalityRecordIdParts), - }, - }, - }, - handler(logger) - ); -}; export const assetCriticalityPublicGetRoute = ( router: EntityAnalyticsRoutesDeps['router'], @@ -115,6 +42,43 @@ export const assetCriticalityPublicGetRoute = ( }, }, }, - handler(logger) + async (context, request, response) => { + const siemResponse = buildSiemResponse(response); + try { + await assertAdvancedSettingsEnabled(await context.core, ENABLE_ASSET_CRITICALITY_SETTING); + await checkAndInitAssetCriticalityResources(context, logger); + + const securitySolution = await context.securitySolution; + const assetCriticalityClient = securitySolution.getAssetCriticalityDataClient(); + const record = await assetCriticalityClient.get({ + idField: request.query.id_field, + idValue: request.query.id_value, + }); + + if (!record) { + return response.notFound(); + } + + securitySolution.getAuditLogger()?.log({ + message: 'User accessed the criticality level for an entity', + event: { + action: AssetCriticalityAuditActions.ASSET_CRITICALITY_GET, + category: AUDIT_CATEGORY.DATABASE, + type: AUDIT_TYPE.ACCESS, + outcome: AUDIT_OUTCOME.SUCCESS, + }, + }); + + return response.ok({ body: record }); + } catch (e) { + const error = transformError(e); + + return siemResponse.error({ + statusCode: error.statusCode, + body: { message: error.message, full_error: JSON.stringify(e) }, + bypassErrorFormat: true, + }); + } + } ); }; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/routes/register_asset_criticality_routes.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/routes/register_asset_criticality_routes.ts index 07899be6b91758..c7134ee0eafb6d 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/routes/register_asset_criticality_routes.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/routes/register_asset_criticality_routes.ts @@ -5,14 +5,11 @@ * 2.0. */ import { assetCriticalityInternalStatusRoute } from './status'; -import { assetCriticalityPublicUpsertRoute, assetCriticalityInternalUpsertRoute } from './upsert'; -import { assetCriticalityInternalGetRoute, assetCriticalityPublicGetRoute } from './get'; -import { assetCriticalityPublicDeleteRoute, assetCriticalityInternalDeleteRoute } from './delete'; +import { assetCriticalityPublicUpsertRoute } from './upsert'; +import { assetCriticalityPublicGetRoute } from './get'; +import { assetCriticalityPublicDeleteRoute } from './delete'; import { assetCriticalityInternalPrivilegesRoute } from './privileges'; -import { - assetCriticalityInternalCSVUploadRoute, - assetCriticalityPublicCSVUploadRoute, -} from './upload_csv'; +import { assetCriticalityPublicCSVUploadRoute } from './upload_csv'; import { assetCriticalityPublicListRoute } from './list'; import type { EntityAnalyticsRoutesDeps } from '../../types'; import { assetCriticalityPublicBulkUploadRoute } from './bulk_upload'; @@ -24,13 +21,8 @@ export const registerAssetCriticalityRoutes = ({ getStartServices, }: EntityAnalyticsRoutesDeps) => { // Internal routes - assetCriticalityInternalCSVUploadRoute(router, logger, config, getStartServices); - assetCriticalityInternalDeleteRoute(router, logger); - assetCriticalityInternalGetRoute(router, logger); assetCriticalityInternalPrivilegesRoute(router, logger, getStartServices); assetCriticalityInternalStatusRoute(router, logger); - assetCriticalityInternalUpsertRoute(router, logger); - // Public routes assetCriticalityPublicCSVUploadRoute(router, logger, config, getStartServices); assetCriticalityPublicBulkUploadRoute(router, logger, config); diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/routes/upload_csv.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/routes/upload_csv.ts index 28c8333c5f5963..fd2bf980048a49 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/routes/upload_csv.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/routes/upload_csv.ts @@ -4,18 +4,16 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { IKibanaResponse, KibanaResponseFactory, Logger } from '@kbn/core/server'; +import type { Logger } from '@kbn/core/server'; import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils'; import { schema } from '@kbn/config-schema'; import Papa from 'papaparse'; import { transformError } from '@kbn/securitysolution-es-utils'; -import type internal from 'stream'; import type { AssetCriticalityBulkUploadResponse } from '../../../../../common/api/entity_analytics'; import { CRITICALITY_CSV_MAX_SIZE_BYTES_WITH_TOLERANCE } from '../../../../../common/entity_analytics/asset_criticality'; import type { ConfigType } from '../../../../config'; -import type { HapiReadableStream, SecuritySolutionRequestHandlerContext } from '../../../../types'; +import type { HapiReadableStream } from '../../../../types'; import { - ASSET_CRITICALITY_INTERNAL_CSV_UPLOAD_URL, ASSET_CRITICALITY_PUBLIC_CSV_UPLOAD_URL, APP_ID, ENABLE_ASSET_CRITICALITY_SETTING, @@ -29,134 +27,6 @@ import type { EntityAnalyticsRoutesDeps } from '../../types'; import { AssetCriticalityAuditActions } from '../audit'; import { AUDIT_CATEGORY, AUDIT_OUTCOME, AUDIT_TYPE } from '../../audit'; -type CSVUploadHandler = ( - context: SecuritySolutionRequestHandlerContext, - request: { - body: { file: internal.Stream }; - }, - response: KibanaResponseFactory -) => Promise; - -const handler: ( - logger: Logger, - getStartServices: EntityAnalyticsRoutesDeps['getStartServices'], - config: ConfigType -) => CSVUploadHandler = (logger, getStartServices, config) => async (context, request, response) => { - const { errorRetries, maxBulkRequestBodySizeBytes } = - config.entityAnalytics.assetCriticality.csvUpload; - - const securitySolution = await context.securitySolution; - securitySolution.getAuditLogger()?.log({ - message: 'User attempted to assign many asset criticalities via file upload', - event: { - action: AssetCriticalityAuditActions.ASSET_CRITICALITY_BULK_UPDATE, - category: AUDIT_CATEGORY.DATABASE, - type: AUDIT_TYPE.CREATION, - outcome: AUDIT_OUTCOME.UNKNOWN, - }, - }); - - const start = new Date(); - const siemResponse = buildSiemResponse(response); - const [coreStart] = await getStartServices(); - const telemetry = coreStart.analytics; - - try { - await assertAdvancedSettingsEnabled(await context.core, ENABLE_ASSET_CRITICALITY_SETTING); - await checkAndInitAssetCriticalityResources(context, logger); - const assetCriticalityClient = securitySolution.getAssetCriticalityDataClient(); - const fileStream = request.body.file as HapiReadableStream; - - logger.debug(`Parsing asset criticality CSV file ${fileStream.hapi.filename}`); - - const csvStream = Papa.parse(Papa.NODE_STREAM_INPUT, { - header: false, - dynamicTyping: true, - skipEmptyLines: true, - }); - - const recordsStream = fileStream.pipe(csvStream).pipe(transformCSVToUpsertRecords()); - - const { errors, stats } = await assetCriticalityClient.bulkUpsertFromStream({ - recordsStream, - retries: errorRetries, - flushBytes: maxBulkRequestBodySizeBytes, - }); - const end = new Date(); - - const tookMs = end.getTime() - start.getTime(); - logger.debug( - () => `Asset criticality CSV upload completed in ${tookMs}ms ${JSON.stringify(stats)}` - ); - - // type assignment here to ensure that the response body stays in sync with the API schema - const resBody: AssetCriticalityBulkUploadResponse = { errors, stats }; - - const [eventType, event] = createAssetCriticalityProcessedFileEvent({ - startTime: start, - endTime: end, - result: stats, - }); - - telemetry.reportEvent(eventType, event); - - return response.ok({ body: resBody }); - } catch (e) { - logger.error(`Error during asset criticality csv upload: ${e}`); - try { - const end = new Date(); - - const [eventType, event] = createAssetCriticalityProcessedFileEvent({ - startTime: start, - endTime: end, - }); - - telemetry.reportEvent(eventType, event); - } catch (error) { - logger.error(`Error reporting telemetry event: ${error}`); - } - - const error = transformError(e); - return siemResponse.error({ - statusCode: error.statusCode, - body: error.message, - }); - } -}; - -export const assetCriticalityInternalCSVUploadRoute = ( - router: EntityAnalyticsRoutesDeps['router'], - logger: Logger, - config: ConfigType, - getStartServices: EntityAnalyticsRoutesDeps['getStartServices'] -) => { - router.versioned - .post({ - access: 'internal', - path: ASSET_CRITICALITY_INTERNAL_CSV_UPLOAD_URL, - options: { - tags: ['access:securitySolution', `access:${APP_ID}-entity-analytics`], - body: { - output: 'stream', - accepts: 'multipart/form-data', - maxBytes: CRITICALITY_CSV_MAX_SIZE_BYTES_WITH_TOLERANCE, - }, - }, - }) - .addVersion( - { - version: API_VERSIONS.internal.v1, - validate: { - request: { - body: schema.object({ - file: schema.stream(), - }), - }, - }, - }, - handler(logger, getStartServices, config) - ); -}; export const assetCriticalityPublicCSVUploadRoute = ( router: EntityAnalyticsRoutesDeps['router'], logger: Logger, @@ -187,6 +57,87 @@ export const assetCriticalityPublicCSVUploadRoute = ( }, }, }, - handler(logger, getStartServices, config) + async (context, request, response) => { + const { errorRetries, maxBulkRequestBodySizeBytes } = + config.entityAnalytics.assetCriticality.csvUpload; + + const securitySolution = await context.securitySolution; + securitySolution.getAuditLogger()?.log({ + message: 'User attempted to assign many asset criticalities via file upload', + event: { + action: AssetCriticalityAuditActions.ASSET_CRITICALITY_BULK_UPDATE, + category: AUDIT_CATEGORY.DATABASE, + type: AUDIT_TYPE.CREATION, + outcome: AUDIT_OUTCOME.UNKNOWN, + }, + }); + + const start = new Date(); + const siemResponse = buildSiemResponse(response); + const [coreStart] = await getStartServices(); + const telemetry = coreStart.analytics; + + try { + await assertAdvancedSettingsEnabled(await context.core, ENABLE_ASSET_CRITICALITY_SETTING); + await checkAndInitAssetCriticalityResources(context, logger); + const assetCriticalityClient = securitySolution.getAssetCriticalityDataClient(); + const fileStream = request.body.file as HapiReadableStream; + + logger.debug(`Parsing asset criticality CSV file ${fileStream.hapi.filename}`); + + const csvStream = Papa.parse(Papa.NODE_STREAM_INPUT, { + header: false, + dynamicTyping: true, + skipEmptyLines: true, + }); + + const recordsStream = fileStream.pipe(csvStream).pipe(transformCSVToUpsertRecords()); + + const { errors, stats } = await assetCriticalityClient.bulkUpsertFromStream({ + recordsStream, + retries: errorRetries, + flushBytes: maxBulkRequestBodySizeBytes, + }); + const end = new Date(); + + const tookMs = end.getTime() - start.getTime(); + logger.debug( + () => `Asset criticality CSV upload completed in ${tookMs}ms ${JSON.stringify(stats)}` + ); + + // type assignment here to ensure that the response body stays in sync with the API schema + const resBody: AssetCriticalityBulkUploadResponse = { errors, stats }; + + const [eventType, event] = createAssetCriticalityProcessedFileEvent({ + startTime: start, + endTime: end, + result: stats, + }); + + telemetry.reportEvent(eventType, event); + + return response.ok({ body: resBody }); + } catch (e) { + logger.error(`Error during asset criticality csv upload: ${e}`); + try { + const end = new Date(); + + const [eventType, event] = createAssetCriticalityProcessedFileEvent({ + startTime: start, + endTime: end, + }); + + telemetry.reportEvent(eventType, event); + } catch (error) { + logger.error(`Error reporting telemetry event: ${error}`); + } + + const error = transformError(e); + return siemResponse.error({ + statusCode: error.statusCode, + body: error.message, + }); + } + } ); }; diff --git a/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/routes/upsert.ts b/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/routes/upsert.ts index cb3c36f450e430..dcd551223d075a 100644 --- a/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/routes/upsert.ts +++ b/x-pack/plugins/security_solution/server/lib/entity_analytics/asset_criticality/routes/upsert.ts @@ -4,14 +4,12 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import type { IKibanaResponse, KibanaResponseFactory, Logger } from '@kbn/core/server'; +import type { Logger } from '@kbn/core/server'; import { buildSiemResponse } from '@kbn/lists-plugin/server/routes/utils'; import { transformError } from '@kbn/securitysolution-es-utils'; import { buildRouteValidationWithZod } from '@kbn/zod-helpers'; -import type { SecuritySolutionRequestHandlerContext } from '../../../../types'; import { ASSET_CRITICALITY_PUBLIC_URL, - ASSET_CRITICALITY_INTERNAL_URL, APP_ID, ENABLE_ASSET_CRITICALITY_SETTING, API_VERSIONS, @@ -23,84 +21,6 @@ import { AssetCriticalityAuditActions } from '../audit'; import { AUDIT_CATEGORY, AUDIT_OUTCOME, AUDIT_TYPE } from '../../audit'; import { assertAdvancedSettingsEnabled } from '../../utils/assert_advanced_setting_enabled'; -type UpsertHandler = ( - context: SecuritySolutionRequestHandlerContext, - request: { - body: CreateSingleAssetCriticalityRequest; - }, - response: KibanaResponseFactory -) => Promise; - -const handler: (logger: Logger) => UpsertHandler = - (logger) => async (context, request, response) => { - const siemResponse = buildSiemResponse(response); - try { - await assertAdvancedSettingsEnabled(await context.core, ENABLE_ASSET_CRITICALITY_SETTING); - await checkAndInitAssetCriticalityResources(context, logger); - - const securitySolution = await context.securitySolution; - const assetCriticalityClient = securitySolution.getAssetCriticalityDataClient(); - - const assetCriticalityRecord = { - idField: request.body.id_field, - idValue: request.body.id_value, - criticalityLevel: request.body.criticality_level, - }; - - const result = await assetCriticalityClient.upsert( - assetCriticalityRecord, - request.body.refresh - ); - - securitySolution.getAuditLogger()?.log({ - message: 'User attempted to assign the asset criticality level for an entity', - event: { - action: AssetCriticalityAuditActions.ASSET_CRITICALITY_UPDATE, - category: AUDIT_CATEGORY.DATABASE, - type: AUDIT_TYPE.CREATION, - outcome: AUDIT_OUTCOME.UNKNOWN, - }, - }); - - return response.ok({ - body: result, - }); - } catch (e) { - const error = transformError(e); - - return siemResponse.error({ - statusCode: error.statusCode, - body: { message: error.message, full_error: JSON.stringify(e) }, - bypassErrorFormat: true, - }); - } - }; - -export const assetCriticalityInternalUpsertRoute = ( - router: EntityAnalyticsRoutesDeps['router'], - logger: Logger -) => { - router.versioned - .post({ - access: 'internal', - path: ASSET_CRITICALITY_INTERNAL_URL, - options: { - tags: ['access:securitySolution', `access:${APP_ID}-entity-analytics`], - }, - }) - .addVersion( - { - version: API_VERSIONS.internal.v1, - validate: { - request: { - body: buildRouteValidationWithZod(CreateSingleAssetCriticalityRequest), - }, - }, - }, - handler(logger) - ); -}; - export const assetCriticalityPublicUpsertRoute = ( router: EntityAnalyticsRoutesDeps['router'], logger: Logger @@ -122,6 +42,48 @@ export const assetCriticalityPublicUpsertRoute = ( }, }, }, - handler(logger) + async (context, request, response) => { + const siemResponse = buildSiemResponse(response); + try { + await assertAdvancedSettingsEnabled(await context.core, ENABLE_ASSET_CRITICALITY_SETTING); + await checkAndInitAssetCriticalityResources(context, logger); + + const securitySolution = await context.securitySolution; + const assetCriticalityClient = securitySolution.getAssetCriticalityDataClient(); + + const assetCriticalityRecord = { + idField: request.body.id_field, + idValue: request.body.id_value, + criticalityLevel: request.body.criticality_level, + }; + + const result = await assetCriticalityClient.upsert( + assetCriticalityRecord, + request.body.refresh + ); + + securitySolution.getAuditLogger()?.log({ + message: 'User attempted to assign the asset criticality level for an entity', + event: { + action: AssetCriticalityAuditActions.ASSET_CRITICALITY_UPDATE, + category: AUDIT_CATEGORY.DATABASE, + type: AUDIT_TYPE.CREATION, + outcome: AUDIT_OUTCOME.UNKNOWN, + }, + }); + + return response.ok({ + body: result, + }); + } catch (e) { + const error = transformError(e); + + return siemResponse.error({ + statusCode: error.statusCode, + body: { message: error.message, full_error: JSON.stringify(e) }, + bypassErrorFormat: true, + }); + } + } ); };