"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.ActionsPlugin = void 0; exports.renderActionParameterTemplates = renderActionParameterTemplates; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _coreSavedObjectsServer = require("@kbn/core-saved-objects-server"); var _config = require("./config"); var _custom_host_settings = require("./lib/custom_host_settings"); var _actions_client = require("./actions_client"); var _action_type_registry = require("./action_type_registry"); var _create_execute_function = require("./create_execute_function"); var _usage = require("./usage"); var _lib = require("./lib"); var _actions_config = require("./actions_config"); var _routes = require("./routes"); var _task = require("./usage/task"); var _saved_objects = require("./constants/saved_objects"); var _saved_objects2 = require("./saved_objects"); var _feature = require("./feature"); var _actions_authorization = require("./authorization/actions_authorization"); var _get_authorization_mode_by_source = require("./authorization/get_authorization_mode_by_source"); var _ensure_sufficient_license = require("./lib/ensure_sufficient_license"); var _mustache_renderer = require("./lib/mustache_renderer"); var _alert_history_es_index = require("./preconfigured_connectors/alert_history_es_index/alert_history_es_index"); var _create_alert_history_index_template = require("./preconfigured_connectors/alert_history_es_index/create_alert_history_index_template"); var _common = require("../common"); var _event_log = require("./constants/event_log"); var _connector_token_client = require("./lib/connector_token_client"); var _monitoring = require("./monitoring"); var _is_connector_deprecated = require("./lib/is_connector_deprecated"); var _sub_action_framework = require("./sub_action_framework"); var _sub_action_connector = require("./sub_action_framework/sub_action_connector"); var _case = require("./sub_action_framework/case"); var _unsecured_actions_client = require("./unsecured_actions_client/unsecured_actions_client"); var _create_unsecured_execute_function = require("./create_unsecured_execute_function"); var _create_system_actions = require("./create_system_actions"); /* * 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. */ const includedHiddenTypes = [_saved_objects.ACTION_SAVED_OBJECT_TYPE, _saved_objects.ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE, _saved_objects.ALERT_SAVED_OBJECT_TYPE, _saved_objects.CONNECTOR_TOKEN_SAVED_OBJECT_TYPE]; class ActionsPlugin { constructor(initContext) { (0, _defineProperty2.default)(this, "logger", void 0); (0, _defineProperty2.default)(this, "actionsConfig", void 0); (0, _defineProperty2.default)(this, "taskRunnerFactory", void 0); (0, _defineProperty2.default)(this, "actionTypeRegistry", void 0); (0, _defineProperty2.default)(this, "actionExecutor", void 0); (0, _defineProperty2.default)(this, "licenseState", null); (0, _defineProperty2.default)(this, "security", void 0); (0, _defineProperty2.default)(this, "eventLogService", void 0); (0, _defineProperty2.default)(this, "eventLogger", void 0); (0, _defineProperty2.default)(this, "isESOCanEncrypt", void 0); (0, _defineProperty2.default)(this, "usageCounter", void 0); (0, _defineProperty2.default)(this, "telemetryLogger", void 0); (0, _defineProperty2.default)(this, "inMemoryConnectors", void 0); (0, _defineProperty2.default)(this, "inMemoryMetrics", void 0); (0, _defineProperty2.default)(this, "getUnsecuredSavedObjectsClient", (savedObjects, request) => savedObjects.getScopedClient(request, { excludedExtensions: [_coreSavedObjectsServer.SECURITY_EXTENSION_ID], includedHiddenTypes })); (0, _defineProperty2.default)(this, "instantiateAuthorization", (request, authorizationMode) => { var _this$security, _this$security2; return new _actions_authorization.ActionsAuthorization({ request, authorizationMode, authorization: (_this$security = this.security) === null || _this$security === void 0 ? void 0 : _this$security.authz, authentication: (_this$security2 = this.security) === null || _this$security2 === void 0 ? void 0 : _this$security2.authc }); }); (0, _defineProperty2.default)(this, "getInMemoryConnectors", () => this.inMemoryConnectors); (0, _defineProperty2.default)(this, "setSystemActions", () => { var _this$actionTypeRegis, _this$actionTypeRegis2; const systemConnectors = (0, _create_system_actions.createSystemConnectors)((_this$actionTypeRegis = (_this$actionTypeRegis2 = this.actionTypeRegistry) === null || _this$actionTypeRegis2 === void 0 ? void 0 : _this$actionTypeRegis2.list()) !== null && _this$actionTypeRegis !== void 0 ? _this$actionTypeRegis : []); this.inMemoryConnectors = [...this.inMemoryConnectors, ...systemConnectors]; }); (0, _defineProperty2.default)(this, "throwIfSystemActionsInConfig", () => { const hasSystemActionAsPreconfiguredInConfig = this.inMemoryConnectors.filter(connector => connector.isPreconfigured).some(connector => this.actionTypeRegistry.isSystemActionType(connector.actionTypeId)); if (hasSystemActionAsPreconfiguredInConfig) { throw new Error('Setting system action types in preconfigured connectors are not allowed'); } }); (0, _defineProperty2.default)(this, "createRouteHandlerContext", core => { const { actionTypeRegistry, isESOCanEncrypt, getInMemoryConnectors, actionExecutor, instantiateAuthorization, security, usageCounter, logger } = this; return async function actionsRouteHandlerContext(context, request) { const [{ savedObjects }, { taskManager, encryptedSavedObjects, eventLog }] = await core.getStartServices(); const coreContext = await context.core; const inMemoryConnectors = getInMemoryConnectors(); return { getActionsClient: () => { if (isESOCanEncrypt !== true) { throw new Error(`Unable to create actions client because the Encrypted Saved Objects plugin is missing encryption key. Please set xpack.encryptedSavedObjects.encryptionKey in the kibana.yml or use the bin/kibana-encryption-keys command.`); } const unsecuredSavedObjectsClient = savedObjects.getScopedClient(request, { excludedExtensions: [_coreSavedObjectsServer.SECURITY_EXTENSION_ID], includedHiddenTypes }); return new _actions_client.ActionsClient({ logger, unsecuredSavedObjectsClient, actionTypeRegistry: actionTypeRegistry, kibanaIndices: savedObjects.getAllIndices(), scopedClusterClient: coreContext.elasticsearch.client, inMemoryConnectors, request, authorization: instantiateAuthorization(request), actionExecutor: actionExecutor, ephemeralExecutionEnqueuer: (0, _create_execute_function.createEphemeralExecutionEnqueuerFunction)({ taskManager, actionTypeRegistry: actionTypeRegistry, isESOCanEncrypt: isESOCanEncrypt, inMemoryConnectors }), executionEnqueuer: (0, _create_execute_function.createExecutionEnqueuerFunction)({ taskManager, actionTypeRegistry: actionTypeRegistry, isESOCanEncrypt: isESOCanEncrypt, inMemoryConnectors }), bulkExecutionEnqueuer: (0, _create_execute_function.createBulkExecutionEnqueuerFunction)({ taskManager, actionTypeRegistry: actionTypeRegistry, isESOCanEncrypt: isESOCanEncrypt, inMemoryConnectors }), auditLogger: security === null || security === void 0 ? void 0 : security.audit.asScoped(request), usageCounter, connectorTokenClient: new _connector_token_client.ConnectorTokenClient({ unsecuredSavedObjectsClient, encryptedSavedObjectsClient: encryptedSavedObjects.getClient({ includedHiddenTypes }), logger }), async getEventLogClient() { return eventLog.getClient(request); } }); }, listTypes: actionTypeRegistry.list.bind(actionTypeRegistry) }; }; }); this.logger = initContext.logger.get(); this.actionsConfig = (0, _config.getValidatedConfig)(this.logger, (0, _custom_host_settings.resolveCustomHosts)(this.logger, initContext.config.get())); this.telemetryLogger = initContext.logger.get('usage'); this.inMemoryConnectors = []; this.inMemoryMetrics = new _monitoring.InMemoryMetrics(initContext.logger.get('in_memory_metrics')); } setup(core, plugins) { var _plugins$usageCollect; this.licenseState = new _lib.LicenseState(plugins.licensing.license$); this.isESOCanEncrypt = plugins.encryptedSavedObjects.canEncrypt; if (!this.isESOCanEncrypt) { this.logger.warn('APIs are disabled because the Encrypted Saved Objects plugin is missing encryption key. Please set xpack.encryptedSavedObjects.encryptionKey in the kibana.yml or use the bin/kibana-encryption-keys command.'); } plugins.features.registerKibanaFeature(_feature.ACTIONS_FEATURE); this.eventLogService = plugins.eventLog; plugins.eventLog.registerProviderActions(_event_log.EVENT_LOG_PROVIDER, Object.values(_event_log.EVENT_LOG_ACTIONS)); this.eventLogger = plugins.eventLog.getLogger({ event: { provider: _event_log.EVENT_LOG_PROVIDER } }); const actionExecutor = new _lib.ActionExecutor({ isESOCanEncrypt: this.isESOCanEncrypt }); // get executions count const taskRunnerFactory = new _lib.TaskRunnerFactory(actionExecutor, this.inMemoryMetrics); const actionsConfigUtils = (0, _actions_config.getActionsConfigurationUtilities)(this.actionsConfig); if (this.actionsConfig.preconfiguredAlertHistoryEsIndex) { this.inMemoryConnectors.push((0, _alert_history_es_index.getAlertHistoryEsIndex)()); } for (const preconfiguredId of Object.keys(this.actionsConfig.preconfigured)) { if (preconfiguredId !== _common.AlertHistoryEsIndexConnectorId) { const rawPreconfiguredConnector = { ...this.actionsConfig.preconfigured[preconfiguredId], id: preconfiguredId, isPreconfigured: true, isSystemAction: false }; this.inMemoryConnectors.push({ ...rawPreconfiguredConnector, isDeprecated: (0, _is_connector_deprecated.isConnectorDeprecated)(rawPreconfiguredConnector) }); } else { this.logger.warn(`Preconfigured connectors cannot have the id "${_common.AlertHistoryEsIndexConnectorId}" because this is a reserved id.`); } } const actionTypeRegistry = new _action_type_registry.ActionTypeRegistry({ licensing: plugins.licensing, taskRunnerFactory, taskManager: plugins.taskManager, actionsConfigUtils, licenseState: this.licenseState, inMemoryConnectors: this.inMemoryConnectors }); this.taskRunnerFactory = taskRunnerFactory; this.actionTypeRegistry = actionTypeRegistry; this.actionExecutor = actionExecutor; this.security = plugins.security; (0, _saved_objects2.setupSavedObjects)(core.savedObjects, plugins.encryptedSavedObjects, this.actionTypeRegistry, plugins.taskManager.index, this.inMemoryConnectors); const usageCollection = plugins.usageCollection; if (usageCollection) { (0, _usage.registerActionsUsageCollector)(usageCollection, this.actionsConfig, core.getStartServices().then(([_, { taskManager }]) => taskManager)); } core.http.registerRouteHandlerContext('actions', this.createRouteHandlerContext(core)); if (usageCollection) { const eventLogIndex = this.eventLogService.getIndexPattern(); (0, _task.initializeActionsTelemetry)(this.telemetryLogger, plugins.taskManager, core, this.getInMemoryConnectors, eventLogIndex); } // Usage counter for telemetry this.usageCounter = (_plugins$usageCollect = plugins.usageCollection) === null || _plugins$usageCollect === void 0 ? void 0 : _plugins$usageCollect.createUsageCounter(_common.ACTIONS_FEATURE_ID); if (plugins.monitoringCollection) { (0, _monitoring.registerNodeCollector)({ monitoringCollection: plugins.monitoringCollection, inMemoryMetrics: this.inMemoryMetrics }); (0, _monitoring.registerClusterCollector)({ monitoringCollection: plugins.monitoringCollection, core }); } const subActionFramework = (0, _sub_action_framework.createSubActionConnectorFramework)({ actionTypeRegistry, logger: this.logger, actionsConfigUtils }); // Routes (0, _routes.defineRoutes)({ router: core.http.createRouter(), licenseState: this.licenseState, actionsConfigUtils, usageCounter: this.usageCounter }); return { registerType: actionType => { (0, _ensure_sufficient_license.ensureSufficientLicense)(actionType); actionTypeRegistry.register(actionType); }, registerSubActionConnectorType: connector => { subActionFramework.registerConnector(connector); }, isPreconfiguredConnector: connectorId => { return !!this.inMemoryConnectors.find(inMemoryConnector => inMemoryConnector.isPreconfigured && inMemoryConnector.id === connectorId); }, getSubActionConnectorClass: () => _sub_action_connector.SubActionConnector, getCaseConnectorClass: () => _case.CaseConnector, getActionsHealth: () => { return { hasPermanentEncryptionKey: plugins.encryptedSavedObjects.canEncrypt }; }, getActionsConfigurationUtilities: () => actionsConfigUtils }; } start(core, plugins) { var _plugins$spaces; const { logger, licenseState, actionExecutor, actionTypeRegistry, taskRunnerFactory, isESOCanEncrypt, instantiateAuthorization, getUnsecuredSavedObjectsClient } = this; licenseState === null || licenseState === void 0 ? void 0 : licenseState.setNotifyUsage(plugins.licensing.featureUsage.notifyUsage); const encryptedSavedObjectsClient = plugins.encryptedSavedObjects.getClient({ includedHiddenTypes }); this.throwIfSystemActionsInConfig(); /** * Warning: this call mutates the inMemory collection * * Warning: it maybe possible for the task manager to start before * the system actions are being set. * * Issue: https://github.com/elastic/kibana/issues/160797 */ this.setSystemActions(); const getActionsClientWithRequest = async (request, authorizationContext) => { var _this$security3; if (isESOCanEncrypt !== true) { throw new Error(`Unable to create actions client because the Encrypted Saved Objects plugin is missing encryption key. Please set xpack.encryptedSavedObjects.encryptionKey in the kibana.yml or use the bin/kibana-encryption-keys command.`); } const unsecuredSavedObjectsClient = getUnsecuredSavedObjectsClient(core.savedObjects, request); return new _actions_client.ActionsClient({ logger, unsecuredSavedObjectsClient, actionTypeRegistry: actionTypeRegistry, kibanaIndices: core.savedObjects.getAllIndices(), scopedClusterClient: core.elasticsearch.client.asScoped(request), inMemoryConnectors: this.inMemoryConnectors, request, authorization: instantiateAuthorization(request, await (0, _get_authorization_mode_by_source.getAuthorizationModeBySource)(unsecuredSavedObjectsClient, authorizationContext)), actionExecutor: actionExecutor, ephemeralExecutionEnqueuer: (0, _create_execute_function.createEphemeralExecutionEnqueuerFunction)({ taskManager: plugins.taskManager, actionTypeRegistry: actionTypeRegistry, isESOCanEncrypt: isESOCanEncrypt, inMemoryConnectors: this.inMemoryConnectors }), executionEnqueuer: (0, _create_execute_function.createExecutionEnqueuerFunction)({ taskManager: plugins.taskManager, actionTypeRegistry: actionTypeRegistry, isESOCanEncrypt: isESOCanEncrypt, inMemoryConnectors: this.inMemoryConnectors }), bulkExecutionEnqueuer: (0, _create_execute_function.createBulkExecutionEnqueuerFunction)({ taskManager: plugins.taskManager, actionTypeRegistry: actionTypeRegistry, isESOCanEncrypt: isESOCanEncrypt, inMemoryConnectors: this.inMemoryConnectors }), auditLogger: (_this$security3 = this.security) === null || _this$security3 === void 0 ? void 0 : _this$security3.audit.asScoped(request), usageCounter: this.usageCounter, connectorTokenClient: new _connector_token_client.ConnectorTokenClient({ unsecuredSavedObjectsClient, encryptedSavedObjectsClient, logger: this.logger }), async getEventLogClient() { return plugins.eventLog.getClient(request); } }); }; const getUnsecuredActionsClient = () => { const internalSavedObjectsRepository = core.savedObjects.createInternalRepository([_saved_objects.ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE]); return new _unsecured_actions_client.UnsecuredActionsClient({ internalSavedObjectsRepository, executionEnqueuer: (0, _create_unsecured_execute_function.createBulkUnsecuredExecutionEnqueuerFunction)({ taskManager: plugins.taskManager, connectorTypeRegistry: actionTypeRegistry, inMemoryConnectors: this.inMemoryConnectors }) }); }; // Ensure the public API cannot be used to circumvent authorization // using our legacy exemption mechanism by passing in a legacy SO // as authorizationContext which would then set a Legacy AuthorizationMode const secureGetActionsClientWithRequest = request => getActionsClientWithRequest(request); this.eventLogService.registerSavedObjectProvider('action', request => { const client = secureGetActionsClientWithRequest(request); return objects => objects ? Promise.all(objects.map(async objectItem => /** * TODO: Change with getBulk */ await (await client).get({ id: objectItem.id, throwIfSystemAction: false }))) : Promise.resolve([]); }); const getScopedSavedObjectsClientWithoutAccessToActions = request => core.savedObjects.getScopedClient(request); actionExecutor.initialize({ logger, eventLogger: this.eventLogger, spaces: (_plugins$spaces = plugins.spaces) === null || _plugins$spaces === void 0 ? void 0 : _plugins$spaces.spacesService, security: plugins.security, getServices: this.getServicesFactory(getScopedSavedObjectsClientWithoutAccessToActions, core.elasticsearch, encryptedSavedObjectsClient, request => this.getUnsecuredSavedObjectsClient(core.savedObjects, request)), encryptedSavedObjectsClient, actionTypeRegistry: actionTypeRegistry, inMemoryConnectors: this.inMemoryConnectors, getActionsAuthorizationWithRequest(request) { return instantiateAuthorization(request); } }); taskRunnerFactory.initialize({ logger, actionTypeRegistry: actionTypeRegistry, encryptedSavedObjectsClient, basePathService: core.http.basePath, spaceIdToNamespace: spaceId => (0, _lib.spaceIdToNamespace)(plugins.spaces, spaceId), savedObjectsRepository: core.savedObjects.createInternalRepository([_saved_objects.ACTION_TASK_PARAMS_SAVED_OBJECT_TYPE]) }); this.eventLogService.isEsContextReady().then(() => { (0, _task.scheduleActionsTelemetry)(this.telemetryLogger, plugins.taskManager); }); if (this.actionsConfig.preconfiguredAlertHistoryEsIndex) { (0, _create_alert_history_index_template.createAlertHistoryIndexTemplate)({ client: core.elasticsearch.client.asInternalUser, logger: this.logger }); } return { isActionTypeEnabled: (id, options = { notifyUsage: false }) => { return this.actionTypeRegistry.isActionTypeEnabled(id, options); }, isActionExecutable: (actionId, actionTypeId, options = { notifyUsage: false }) => { return this.actionTypeRegistry.isActionExecutable(actionId, actionTypeId, options); }, getAllTypes: actionTypeRegistry.getAllTypes.bind(actionTypeRegistry), getActionsAuthorizationWithRequest(request) { return instantiateAuthorization(request); }, getActionsClientWithRequest: secureGetActionsClientWithRequest, getUnsecuredActionsClient, inMemoryConnectors: this.inMemoryConnectors, renderActionParameterTemplates: (...args) => renderActionParameterTemplates(actionTypeRegistry, ...args) }; } getServicesFactory(getScopedClient, elasticsearch, encryptedSavedObjectsClient, unsecuredSavedObjectsClient) { return request => { return { savedObjectsClient: getScopedClient(request), scopedClusterClient: elasticsearch.client.asScoped(request).asCurrentUser, connectorTokenClient: new _connector_token_client.ConnectorTokenClient({ unsecuredSavedObjectsClient: unsecuredSavedObjectsClient(request), encryptedSavedObjectsClient, logger: this.logger }) }; }; } stop() { if (this.licenseState) { this.licenseState.clean(); } } } exports.ActionsPlugin = ActionsPlugin; function renderActionParameterTemplates(actionTypeRegistry, actionTypeId, actionId, params, variables) { const actionType = actionTypeRegistry === null || actionTypeRegistry === void 0 ? void 0 : actionTypeRegistry.get(actionTypeId); if (actionType !== null && actionType !== void 0 && actionType.renderParameterTemplates) { return actionType.renderParameterTemplates(params, variables, actionId); } else { return (0, _mustache_renderer.renderMustacheObject)(params, variables); } }