"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.createInternalConfigurationSubClient = exports.createConfigurationSubClient = void 0; exports.get = get; exports.getConnectors = getConnectors; exports.update = update; var _pMap = _interopRequireDefault(require("p-map")); var _boom = _interopRequireDefault(require("@hapi/boom")); var _server = require("@kbn/core/server"); var _common = require("@kbn/actions-plugin/common"); var _api = require("../../../common/types/api"); var _api2 = require("../../../common/api"); var _constants = require("../../../common/constants"); var _error = require("../../common/error"); var _get_mappings = require("./get_mappings"); var _authorization = require("../../authorization"); var _utils = require("../utils"); var _create_mappings = require("./create_mappings"); var _update_mappings = require("./update_mappings"); var _runtime_types = require("../../../common/api/runtime_types"); var _domain = require("../../../common/types/domain"); /* * 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. */ /** * These functions should not be exposed on the plugin contract. They are for internal use to support the CRUD of * configurations. * * @ignore */ const createInternalConfigurationSubClient = clientArgs => { const configureSubClient = { getMappings: params => (0, _get_mappings.getMappings)(params, clientArgs), createMappings: params => (0, _create_mappings.createMappings)(params, clientArgs), updateMappings: params => (0, _update_mappings.updateMappings)(params, clientArgs) }; return Object.freeze(configureSubClient); }; /** * Creates an API object for interacting with the configuration entities * * @ignore */ exports.createInternalConfigurationSubClient = createInternalConfigurationSubClient; const createConfigurationSubClient = (clientArgs, casesInternalClient) => { return Object.freeze({ get: params => get(params, clientArgs, casesInternalClient), getConnectors: () => getConnectors(clientArgs), update: (configurationId, configuration) => update(configurationId, configuration, clientArgs, casesInternalClient), create: configuration => create(configuration, clientArgs, casesInternalClient) }); }; exports.createConfigurationSubClient = createConfigurationSubClient; async function get(params, clientArgs, casesClientInternal) { const { unsecuredSavedObjectsClient, services: { caseConfigureService }, logger, authorization } = clientArgs; try { const queryParams = (0, _api2.decodeWithExcessOrThrow)(_api.GetConfigurationFindRequestRt)(params); const { filter: authorizationFilter, ensureSavedObjectsAreAuthorized } = await authorization.getAuthorizationFilter(_authorization.Operations.findConfigurations); const filter = (0, _utils.combineAuthorizedAndOwnerFilter)(queryParams.owner, authorizationFilter, _authorization.Operations.findConfigurations.savedObjectType); let error = null; const myCaseConfigure = await caseConfigureService.find({ unsecuredSavedObjectsClient, options: { filter } }); ensureSavedObjectsAreAuthorized(myCaseConfigure.saved_objects.map(configuration => ({ id: configuration.id, owner: configuration.attributes.owner }))); const configurations = await (0, _pMap.default)(myCaseConfigure.saved_objects, async configuration => { var _configuration$attrib, _configuration$versio; const { connector, ...caseConfigureWithoutConnector } = (_configuration$attrib = configuration === null || configuration === void 0 ? void 0 : configuration.attributes) !== null && _configuration$attrib !== void 0 ? _configuration$attrib : { connector: null }; let mappings = null; if (connector != null) { try { mappings = await casesClientInternal.configuration.getMappings({ connector }); } catch (e) { error = e.isBoom ? e.output.payload.message : `Failed to retrieve mapping for ${connector.name}`; } } return { ...caseConfigureWithoutConnector, connector, mappings: mappings != null ? mappings.mappings : [], version: (_configuration$versio = configuration.version) !== null && _configuration$versio !== void 0 ? _configuration$versio : '', error, id: configuration.id }; }); return (0, _runtime_types.decodeOrThrow)(_domain.ConfigurationsRt)(configurations); } catch (error) { throw (0, _error.createCaseError)({ message: `Failed to get case configure: ${error}`, error, logger }); } } async function getConnectors({ actionsClient, logger }) { try { const actionTypes = (await actionsClient.listTypes()).reduce((types, type) => { types[type.id] = type; return types; }, {}); const res = (await actionsClient.getAll()).filter(action => isConnectorSupported(action, actionTypes)).slice(0, _constants.MAX_SUPPORTED_CONNECTORS_RETURNED); return (0, _runtime_types.decodeOrThrow)(_api.FindActionConnectorResponseRt)(res); } catch (error) { throw (0, _error.createCaseError)({ message: `Failed to get connectors: ${error}`, error, logger }); } } function isConnectorSupported(action, actionTypes) { var _actionTypes$action$a, _actionTypes$action$a2, _actionTypes$action$a3; return ((_actionTypes$action$a = (_actionTypes$action$a2 = actionTypes[action.actionTypeId]) === null || _actionTypes$action$a2 === void 0 ? void 0 : _actionTypes$action$a2.supportedFeatureIds) !== null && _actionTypes$action$a !== void 0 ? _actionTypes$action$a : []).includes(_common.CasesConnectorFeatureId) && ((_actionTypes$action$a3 = actionTypes[action.actionTypeId]) === null || _actionTypes$action$a3 === void 0 ? void 0 : _actionTypes$action$a3.enabledInLicense); } async function update(configurationId, req, clientArgs, casesClientInternal) { const { services: { caseConfigureService }, logger, unsecuredSavedObjectsClient, user, authorization } = clientArgs; try { var _patch$attributes$con, _patch$version; const request = (0, _api2.decodeWithExcessOrThrow)(_api.ConfigurationPatchRequestRt)(req); const { version, ...queryWithoutVersion } = request; const configuration = await caseConfigureService.get({ unsecuredSavedObjectsClient, configurationId }); await authorization.ensureAuthorized({ operation: _authorization.Operations.updateConfiguration, entities: [{ owner: configuration.attributes.owner, id: configuration.id }] }); if (version !== configuration.version) { throw _boom.default.conflict('This configuration has been updated. Please refresh before saving additional updates.'); } let error = null; const updateDate = new Date().toISOString(); let mappings = []; const { connector, ...queryWithoutVersionAndConnector } = queryWithoutVersion; try { const resMappings = await casesClientInternal.configuration.getMappings({ connector: connector != null ? connector : configuration.attributes.connector }); mappings = resMappings !== null ? resMappings.mappings : []; if (connector != null) { if (resMappings !== null) { mappings = (await casesClientInternal.configuration.updateMappings({ connector, mappingId: resMappings.id, refresh: false })).mappings; } else { mappings = (await casesClientInternal.configuration.createMappings({ connector, owner: configuration.attributes.owner, refresh: false })).mappings; } } } catch (e) { error = e.isBoom ? e.output.payload.message : `Error creating mapping for ${connector != null ? connector.name : configuration.attributes.connector.name}`; } const patch = await caseConfigureService.patch({ unsecuredSavedObjectsClient, configurationId: configuration.id, updatedAttributes: { ...queryWithoutVersionAndConnector, ...(connector != null && { connector }), updated_at: updateDate, updated_by: user }, originalConfiguration: configuration }); const res = { ...configuration.attributes, ...patch.attributes, connector: (_patch$attributes$con = patch.attributes.connector) !== null && _patch$attributes$con !== void 0 ? _patch$attributes$con : configuration.attributes.connector, mappings, version: (_patch$version = patch.version) !== null && _patch$version !== void 0 ? _patch$version : '', error, id: patch.id }; return (0, _runtime_types.decodeOrThrow)(_domain.ConfigurationRt)(res); } catch (error) { throw (0, _error.createCaseError)({ message: `Failed to get patch configure in route: ${error}`, error, logger }); } } async function create(configRequest, clientArgs, casesClientInternal) { const { unsecuredSavedObjectsClient, services: { caseConfigureService }, logger, user, authorization } = clientArgs; try { var _post$version; const validatedConfigurationRequest = (0, _api2.decodeWithExcessOrThrow)(_api.ConfigurationRequestRt)(configRequest); let error = null; const { filter: authorizationFilter, ensureSavedObjectsAreAuthorized } = await authorization.getAuthorizationFilter( /** * The operation is createConfiguration because the procedure is part of * the create route. The user should have all * permissions to delete the results. */ _authorization.Operations.createConfiguration); const filter = (0, _utils.combineAuthorizedAndOwnerFilter)(validatedConfigurationRequest.owner, authorizationFilter, _authorization.Operations.createConfiguration.savedObjectType); const myCaseConfigure = await caseConfigureService.find({ unsecuredSavedObjectsClient, options: { filter } }); ensureSavedObjectsAreAuthorized(myCaseConfigure.saved_objects.map(conf => ({ id: conf.id, owner: conf.attributes.owner }))); if (myCaseConfigure.saved_objects.length > 0) { const deleteConfigurationMapper = async c => caseConfigureService.delete({ unsecuredSavedObjectsClient, configurationId: c.id, refresh: false }); // Ensuring we don't too many concurrent deletions running. await (0, _pMap.default)(myCaseConfigure.saved_objects, deleteConfigurationMapper, { concurrency: _constants.MAX_CONCURRENT_SEARCHES }); } const savedObjectID = _server.SavedObjectsUtils.generateId(); await authorization.ensureAuthorized({ operation: _authorization.Operations.createConfiguration, entities: [{ owner: validatedConfigurationRequest.owner, id: savedObjectID }] }); const creationDate = new Date().toISOString(); let mappings = []; try { mappings = (await casesClientInternal.configuration.createMappings({ connector: validatedConfigurationRequest.connector, owner: validatedConfigurationRequest.owner, refresh: false })).mappings; } catch (e) { error = e.isBoom ? e.output.payload.message : `Error creating mapping for ${validatedConfigurationRequest.connector.name}`; } const post = await caseConfigureService.post({ unsecuredSavedObjectsClient, attributes: { ...validatedConfigurationRequest, connector: validatedConfigurationRequest.connector, created_at: creationDate, created_by: user, updated_at: null, updated_by: null }, id: savedObjectID }); const res = { ...post.attributes, // Reserve for future implementations connector: post.attributes.connector, mappings, version: (_post$version = post.version) !== null && _post$version !== void 0 ? _post$version : '', error, id: post.id }; return (0, _runtime_types.decodeOrThrow)(_domain.ConfigurationRt)(res); } catch (error) { throw (0, _error.createCaseError)({ message: `Failed to create case configuration: ${error}`, error, logger }); } }