diff --git a/x-pack/plugins/security/index.js b/x-pack/plugins/security/index.js index 535fbf8cf82d3..8d3a74c65391b 100644 --- a/x-pack/plugins/security/index.js +++ b/x-pack/plugins/security/index.js @@ -17,14 +17,13 @@ import { authenticateFactory } from './server/lib/auth_redirect'; import { checkLicense } from './server/lib/check_license'; import { initAuthenticator } from './server/lib/authentication/authenticator'; import { mirrorStatusAndInitialize } from './server/lib/mirror_status_and_initialize'; -import { secureSavedObjectsClientWrapper } from './server/lib/saved_objects_client/saved_objects_client_wrapper'; -import { secureSavedObjectsClientOptionsBuilder } from './server/lib/saved_objects_client/secure_options_builder'; import { registerPrivilegesWithCluster } from './server/lib/privileges'; import { createDefaultRoles } from './server/lib/authorization/create_default_roles'; import { initPrivilegesApi } from './server/routes/api/v1/privileges'; import { hasPrivilegesWithServer } from './server/lib/authorization/has_privileges'; import { SecurityAuditLogger } from './server/lib/audit_logger'; import { AuditLogger } from '../../server/lib/audit_logger'; +import { SecureSavedObjectsClient } from './server/lib/saved_objects_client/secure_saved_objects_client'; export const security = (kibana) => new kibana.Plugin({ id: 'security', @@ -103,7 +102,8 @@ export const security = (kibana) => new kibana.Plugin({ await createDefaultRoles(server); }); - server.expose('auditLogger', new SecurityAuditLogger(server.config(), new AuditLogger(server, 'security'))); + const auditLogger = new SecurityAuditLogger(server.config(), new AuditLogger(server, 'security')); + server.expose('auditLogger', auditLogger); // Register a function that is called whenever the xpack info changes, // to re-compute the license check results for this plugin @@ -120,11 +120,33 @@ export const security = (kibana) => new kibana.Plugin({ if (config.get('xpack.security.rbac.enabled')) { const hasPrivilegesWithRequest = hasPrivilegesWithServer(server); - const savedObjectsClientProvider = server.getSavedObjectsClientProvider(); - savedObjectsClientProvider.addClientOptionBuilder(options => - secureSavedObjectsClientOptionsBuilder(server, hasPrivilegesWithRequest, options) - ); - savedObjectsClientProvider.addClientWrapper(secureSavedObjectsClientWrapper); + const { savedObjects } = server; + + savedObjects.setScopedSavedObjectsClientFactory(({ + request, + index, + mappings, + onBeforeWrite + }) => { + const hasPrivileges = hasPrivilegesWithRequest(request); + + const adminCluster = server.plugins.elasticsearch.getCluster('admin'); + const { callWithInternalUser } = adminCluster; + + const repository = new savedObjects.SavedObjectsRepository({ + index, + mappings, + onBeforeWrite, + callCluster: callWithInternalUser + }); + + return new SecureSavedObjectsClient({ + repository, + errors: savedObjects.SavedObjectsClient.errors, + hasPrivileges, + auditLogger, + }); + }); } getUserProvider(server); diff --git a/x-pack/plugins/security/server/lib/saved_objects_client/saved_objects_client_wrapper.js b/x-pack/plugins/security/server/lib/saved_objects_client/saved_objects_client_wrapper.js deleted file mode 100644 index 6f02b232210c4..0000000000000 --- a/x-pack/plugins/security/server/lib/saved_objects_client/saved_objects_client_wrapper.js +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -/*! Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one or more contributor license agreements. - * Licensed under the Elastic License; you may not use this file except in compliance with the Elastic License. */ - -import { SecureSavedObjectsClient } from './secure_saved_objects_client'; - -export function secureSavedObjectsClientWrapper(baseClient, options) { - return new SecureSavedObjectsClient({ - baseClient, - ...options - }); -} diff --git a/x-pack/plugins/security/server/lib/saved_objects_client/secure_options_builder.js b/x-pack/plugins/security/server/lib/saved_objects_client/secure_options_builder.js deleted file mode 100644 index 9eba7621bf5d8..0000000000000 --- a/x-pack/plugins/security/server/lib/saved_objects_client/secure_options_builder.js +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License; - * you may not use this file except in compliance with the Elastic License. - */ - -/*! Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one or more contributor license agreements. - * Licensed under the Elastic License; you may not use this file except in compliance with the Elastic License. */ - -export function secureSavedObjectsClientOptionsBuilder(server, hasPrivilegesWithRequest, options) { - const adminCluster = server.plugins.elasticsearch.getCluster('admin'); - const { callWithInternalUser } = adminCluster; - const auditLogger = server.plugins.security.auditLogger; - - return { - ...options, - callCluster: callWithInternalUser, - hasPrivilegesWithRequest, - auditLogger - }; -} diff --git a/x-pack/plugins/security/server/lib/saved_objects_client/secure_saved_objects_client.js b/x-pack/plugins/security/server/lib/saved_objects_client/secure_saved_objects_client.js index 0a2f9490c1664..65e2d5890fea7 100644 --- a/x-pack/plugins/security/server/lib/saved_objects_client/secure_saved_objects_client.js +++ b/x-pack/plugins/security/server/lib/saved_objects_client/secure_saved_objects_client.js @@ -9,16 +9,15 @@ import { get, uniq } from 'lodash'; export class SecureSavedObjectsClient { constructor(options) { const { - request, - hasPrivilegesWithRequest, - baseClient, + errors, + repository, + hasPrivileges, auditLogger, } = options; - this.errors = baseClient.errors; - - this._client = baseClient; - this._hasPrivileges = hasPrivilegesWithRequest(request); + this.errors = errors; + this._repository = repository; + this._hasPrivileges = hasPrivileges; this._auditLogger = auditLogger; } @@ -29,7 +28,7 @@ export class SecureSavedObjectsClient { options, }); - return await this._client.create(type, attributes, options); + return await this._repository.create(type, attributes, options); } async bulkCreate(objects, options = {}) { @@ -39,7 +38,7 @@ export class SecureSavedObjectsClient { options, }); - return await this._client.bulkCreate(objects, options); + return await this._repository.bulkCreate(objects, options); } async delete(type, id) { @@ -48,7 +47,7 @@ export class SecureSavedObjectsClient { id, }); - return await this._client.delete(type, id); + return await this._repository.delete(type, id); } async find(options = {}) { @@ -56,7 +55,7 @@ export class SecureSavedObjectsClient { options, }); - return await this._client.find(options); + return await this._repository.find(options); } async bulkGet(objects = []) { @@ -65,7 +64,7 @@ export class SecureSavedObjectsClient { objects, }); - return await this._client.bulkGet(objects); + return await this._repository.bulkGet(objects); } async get(type, id) { @@ -74,7 +73,7 @@ export class SecureSavedObjectsClient { id, }); - return await this._client.get(type, id); + return await this._repository.get(type, id); } async update(type, id, attributes, options = {}) { @@ -85,7 +84,7 @@ export class SecureSavedObjectsClient { options, }); - return await this._client.update(type, id, attributes, options); + return await this._repository.update(type, id, attributes, options); } async _performAuthorizationCheck(typeOrTypes, action, args) { @@ -97,7 +96,7 @@ export class SecureSavedObjectsClient { result = await this._hasPrivileges(actions); } catch(error) { const { reason } = get(error, 'body.error', {}); - throw this._client.errors.decorateGeneralError(error, reason); + throw this.errors.decorateGeneralError(error, reason); } if (result.success) { @@ -105,7 +104,7 @@ export class SecureSavedObjectsClient { } else { this._auditLogger.savedObjectsAuthorizationFailure(result.username, action, types, result.missing, args); const msg = `Unable to ${action} ${types.sort().join(',')}, missing ${result.missing.sort().join(',')}`; - throw this._client.errors.decorateForbiddenError(new Error(msg)); + throw this.errors.decorateForbiddenError(new Error(msg)); } } }