"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.ReportingCore = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _common = require("@kbn/spaces-plugin/common"); var Rx = _interopRequireWildcard(require("rxjs")); var _operators = require("rxjs/operators"); var _constants = require("../common/constants"); var _config = require("./config"); var _csv_searchsource = require("./export_types/csv_searchsource"); var _csv_v = require("./export_types/csv_v2"); var _printable_pdf = require("./export_types/printable_pdf"); var _printable_pdf_v = require("./export_types/printable_pdf_v2"); var _png_v = require("./export_types/png_v2"); var _lib = require("./lib"); var _logger = require("./lib/event_logger/logger"); var _tasks = require("./lib/tasks"); var _csv_searchsource_immediate = require("./export_types/csv_searchsource_immediate"); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } /* * 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. */ /** * @internal */ class ReportingCore { // observe async background setupDeps each are done // observe async background startDeps // DEPRECATED. If `false`, the deprecated features have been disableed constructor(core, logger, context) { (0, _defineProperty2.default)(this, "packageInfo", void 0); (0, _defineProperty2.default)(this, "pluginSetupDeps", void 0); (0, _defineProperty2.default)(this, "pluginStartDeps", void 0); (0, _defineProperty2.default)(this, "pluginSetup$", new Rx.ReplaySubject()); (0, _defineProperty2.default)(this, "pluginStart$", new Rx.ReplaySubject()); (0, _defineProperty2.default)(this, "deprecatedAllowedRoles", false); (0, _defineProperty2.default)(this, "executeTask", void 0); (0, _defineProperty2.default)(this, "monitorTask", void 0); (0, _defineProperty2.default)(this, "config", void 0); (0, _defineProperty2.default)(this, "executing", void 0); (0, _defineProperty2.default)(this, "exportTypesRegistry", new _lib.ExportTypesRegistry()); (0, _defineProperty2.default)(this, "getContract", void 0); (0, _defineProperty2.default)(this, "kibanaShuttingDown$", new Rx.ReplaySubject(1)); this.core = core; this.logger = logger; this.context = context; this.packageInfo = context.env.packageInfo; const config = (0, _config.createConfig)(core, context.config.get(), logger); this.config = config; this.getExportTypes().forEach(et => { this.exportTypesRegistry.register(et); }); this.deprecatedAllowedRoles = config.roles.enabled ? config.roles.allow : false; this.executeTask = new _tasks.ExecuteReportTask(this, config, this.logger); this.monitorTask = new _tasks.MonitorReportsTask(this, config, this.logger); this.getContract = () => ({ usesUiCapabilities: () => config.roles.enabled === false, registerExportTypes: id => id, getScreenshots: this.getScreenshots.bind(this), getSpaceId: this.getSpaceId.bind(this) }); this.executing = new Set(); } getKibanaPackageInfo() { return this.packageInfo; } /* * Register setupDeps */ pluginSetup(setupDeps) { this.pluginSetup$.next(true); // trigger the observer this.pluginSetupDeps = setupDeps; // cache this.exportTypesRegistry.getAll().forEach(et => { et.setup(setupDeps); }); const { executeTask, monitorTask } = this; setupDeps.taskManager.registerTaskDefinitions({ [executeTask.TYPE]: executeTask.getTaskDefinition(), [monitorTask.TYPE]: monitorTask.getTaskDefinition() }); } /* * Register startDeps */ async pluginStart(startDeps) { this.pluginStart$.next(startDeps); // trigger the observer this.pluginStartDeps = startDeps; // cache this.exportTypesRegistry.getAll().forEach(et => { et.start({ ...startDeps, reporting: this.getContract() }); }); const { taskManager } = startDeps; const { executeTask, monitorTask } = this; // enable this instance to generate reports and to monitor for pending reports await Promise.all([executeTask.init(taskManager), monitorTask.init(taskManager)]); } pluginStop() { this.kibanaShuttingDown$.next(); } getKibanaShutdown$() { return this.kibanaShuttingDown$.pipe((0, _operators.take)(1)); } /* * Blocks the caller until setup is done */ async pluginSetsUp() { // use deps and config as a cached resolver if (this.pluginSetupDeps && this.config) { return true; } return await Rx.firstValueFrom(this.pluginSetup$.pipe((0, _operators.take)(2))); // once for pluginSetupDeps (sync) and twice for config (async) } /* * Blocks the caller until start is done */ async pluginStartsUp() { return await this.getPluginStartDeps().then(() => true); } /* * Synchronously checks if all async background setup and startup is completed */ pluginIsStarted() { return this.pluginSetupDeps != null && this.config != null && this.pluginStartDeps != null; } /* * Allows config to be set in the background */ setConfig(config) { this.config = config; this.pluginSetup$.next(true); } /** * Validate export types with config settings * only CSV export types should be registered in the export types registry for serverless */ getExportTypes() { const exportTypes = []; if (!this.config.export_types.pdf.enabled || !this.config.export_types.png.enabled) { exportTypes.push(new _csv_searchsource.CsvSearchSourceExportType(this.core, this.config, this.logger, this.context)); exportTypes.push(new _csv_v.CsvV2ExportType(this.core, this.config, this.logger, this.context)); } else { exportTypes.push(new _csv_searchsource.CsvSearchSourceExportType(this.core, this.config, this.logger, this.context)); exportTypes.push(new _csv_v.CsvV2ExportType(this.core, this.config, this.logger, this.context)); exportTypes.push(new _printable_pdf_v.PdfExportType(this.core, this.config, this.logger, this.context)); exportTypes.push(new _png_v.PngExportType(this.core, this.config, this.logger, this.context)); // deprecated export types for tests exportTypes.push(new _printable_pdf.PdfV1ExportType(this.core, this.config, this.logger, this.context)); } return exportTypes; } /** * If xpack.reporting.roles.enabled === true, register Reporting as a feature * that is controlled by user role names */ registerFeature() { const { features } = this.getPluginSetupDeps(); const deprecatedRoles = this.getDeprecatedAllowedRoles(); if (deprecatedRoles !== false) { // refer to roles.allow configuration (deprecated path) const allowedRoles = ['superuser', ...(deprecatedRoles !== null && deprecatedRoles !== void 0 ? deprecatedRoles : [])]; const privileges = allowedRoles.map(role => ({ requiredClusterPrivileges: [], requiredRoles: [role], ui: [] })); // self-register as an elasticsearch feature (deprecated) features.registerElasticsearchFeature({ id: 'reporting', catalogue: ['reporting'], management: { insightsAndAlerting: ['reporting'] }, privileges }); } else { this.logger.debug(`Reporting roles configuration is disabled. Please assign access to Reporting use Kibana feature controls for applications.`); // trigger application to register Reporting as a subfeature features.enableReportingUiCapabilities(); } } /* * Returns configurable server info */ getServerInfo() { const { http } = this.core; const serverInfo = http.getServerInfo(); return { basePath: this.core.http.basePath.serverBasePath, hostname: serverInfo.hostname, name: serverInfo.name, port: serverInfo.port, uuid: this.context.env.instanceUuid, protocol: serverInfo.protocol }; } /* * Gives synchronous access to the config */ getConfig() { return this.config; } /* * If deprecated feature has not been disabled, * this returns an array of allowed role names * that have access to Reporting. */ getDeprecatedAllowedRoles() { return this.deprecatedAllowedRoles; } /* * * Track usage of code paths for telemetry */ getUsageCounter() { var _this$pluginSetupDeps; return (_this$pluginSetupDeps = this.pluginSetupDeps) === null || _this$pluginSetupDeps === void 0 ? void 0 : _this$pluginSetupDeps.usageCounter; } /* * Gives async access to the startDeps */ async getPluginStartDeps() { if (this.pluginStartDeps) { return this.pluginStartDeps; } return await Rx.firstValueFrom(this.pluginStart$); } getExportTypesRegistry() { return this.exportTypesRegistry; } async scheduleTask(report) { return await this.executeTask.scheduleTask(report); } async getStore() { return (await this.getPluginStartDeps()).store; } async getLicenseInfo() { const { license$ } = (await this.getPluginStartDeps()).licensing; const registry = this.getExportTypesRegistry(); return await Rx.firstValueFrom(license$.pipe((0, _operators.map)(license => (0, _lib.checkLicense)(registry, license)))); } /* * Gives synchronous access to the setupDeps */ getPluginSetupDeps() { if (!this.pluginSetupDeps) { throw new Error(`"pluginSetupDeps" dependencies haven't initialized yet`); } return this.pluginSetupDeps; } async getDataViewsService(request) { const { savedObjects } = await this.getPluginStartDeps(); const savedObjectsClient = savedObjects.getScopedClient(request); const { indexPatterns } = await this.getDataService(); const { asCurrentUser: esClient } = (await this.getEsClient()).asScoped(request); const dataViews = await indexPatterns.dataViewsServiceFactory(savedObjectsClient, esClient); return dataViews; } async getDataService() { const startDeps = await this.getPluginStartDeps(); return startDeps.data; } async getEsClient() { const startDeps = await this.getPluginStartDeps(); return startDeps.esClient; } getSpaceId(request, logger = this.logger) { var _this$getPluginSetupD; const spacesService = (_this$getPluginSetupD = this.getPluginSetupDeps().spaces) === null || _this$getPluginSetupD === void 0 ? void 0 : _this$getPluginSetupD.spacesService; if (spacesService) { const spaceId = spacesService === null || spacesService === void 0 ? void 0 : spacesService.getSpaceId(request); if (spaceId !== _common.DEFAULT_SPACE_ID) { logger.info(`Request uses Space ID: ${spaceId}`); return spaceId; } else { logger.debug(`Request uses default Space`); } } } getScreenshots(options) { return Rx.defer(() => this.getPluginStartDeps()).pipe((0, _operators.switchMap)(({ screenshotting }) => { return screenshotting.getScreenshots({ ...options, urls: options.urls.map(url => typeof url === 'string' ? url : [url[0], { [_constants.REPORTING_REDIRECT_LOCATOR_STORE_KEY]: url[1] }]) }); })); } trackReport(reportId) { this.executing.add(reportId); } untrackReport(reportId) { this.executing.delete(reportId); } countConcurrentReports() { return this.executing.size; } getEventLogger(report, task) { const ReportingEventLogger = (0, _logger.reportingEventLoggerFactory)(this.logger); return new ReportingEventLogger(report, task); } async getCsvSearchSourceImmediate() { const startDeps = await this.getPluginStartDeps(); const csvImmediateExport = new _csv_searchsource_immediate.CsvSearchSourceImmediateExportType(this.core, this.config, this.logger, this.context); csvImmediateExport.setup(this.getPluginSetupDeps()); csvImmediateExport.start({ ...startDeps, reporting: this.getContract() }); return csvImmediateExport; } } exports.ReportingCore = ReportingCore;