From 0ea6da70a74957d32030ea42e4e2ee2af1e43115 Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Thu, 18 Apr 2019 16:32:18 -0700 Subject: [PATCH 1/2] Surface CCR requirement for security when security is not enabled. --- .../public/app/app.js | 30 ++++++++++++++++++- .../server/routes/api/ccr.js | 27 +++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/cross_cluster_replication/public/app/app.js b/x-pack/plugins/cross_cluster_replication/public/app/app.js index d07712727aa77..ca0e88e14bf86 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/app.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/app.js @@ -53,6 +53,7 @@ export class App extends Component { this.state = { isFetchingPermissions: false, fetchPermissionError: undefined, + isSecurityEnabled: false, hasPermission: false, missingClusterPrivileges: [], }; @@ -76,10 +77,11 @@ export class App extends Component { }); try { - const { hasPermission, missingClusterPrivileges } = await loadPermissions(); + const { isSecurityEnabled, hasPermission, missingClusterPrivileges } = await loadPermissions(); this.setState({ isFetchingPermissions: false, + isSecurityEnabled, hasPermission, missingClusterPrivileges, }); @@ -109,6 +111,7 @@ export class App extends Component { const { isFetchingPermissions, fetchPermissionError, + isSecurityEnabled, hasPermission, missingClusterPrivileges, } = this.state; @@ -179,6 +182,31 @@ export class App extends Component { ); } + if (!isSecurityEnabled) { + return ( + + + + } + body={ +

+ +

} + /> +
+ ); + } + if (!hasPermission) { return ( diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/ccr.js b/x-pack/plugins/cross_cluster_replication/server/routes/api/ccr.js index 33012ddbc779f..1ba5cdf62fc8c 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/ccr.js +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/ccr.js @@ -3,6 +3,9 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ + +import Boom from 'boom'; + import { callWithRequestFactory } from '../../lib/call_with_request_factory'; import { isEsErrorFactory } from '../../lib/is_es_error_factory'; import { wrapEsError, wrapUnknownError } from '../../lib/error_wrappers'; @@ -51,6 +54,29 @@ export const registerCcrRoutes = (server) => { pre: [ licensePreRouting ] }, handler: async (request) => { + const xpackMainPlugin = server.plugins.xpack_main; + const xpackInfo = (xpackMainPlugin && xpackMainPlugin.info); + + if (!xpackInfo) { + // xpackInfo is updated via poll, so it may not be available until polling has begun. + // In this rare situation, tell the client the service is temporarily unavailable. + throw new Boom('Security info unavailable', { statusCode: 503 }); + } + + // we assume that `xpack.isAvailable()` always returns `true` because we're inside x-pack + // if for whatever reason it returns `false`, `isSecurityDisabled()` would also return `false` + // which would result in follow-up behavior assuming security is enabled. This is intentional, + // because it results in more defensive behavior. + const securityInfo = (xpackInfo && xpackInfo.isAvailable() && xpackInfo.feature('security')); + if (!securityInfo || !securityInfo.isEnabled()) { + // If security isn't enabled, tell the user it's required. + return { + isSecurityEnabled: false, + hasPermission: false, + missingClusterPrivileges: [], + }; + } + const callWithRequest = callWithRequestFactory(server, request); try { @@ -71,6 +97,7 @@ export const registerCcrRoutes = (server) => { }, []); return { + isSecurityEnabled: true, hasPermission, missingClusterPrivileges, }; From b77940b86dabdc1ca7849100bc07c282f378b8e8 Mon Sep 17 00:00:00 2001 From: CJ Cenizal Date: Thu, 18 Apr 2019 16:47:30 -0700 Subject: [PATCH 2/2] Drop security as a requirement and allow the user to use CCR when it's disabled. --- .../public/app/app.js | 30 +------------------ .../server/routes/api/ccr.js | 10 ++----- 2 files changed, 3 insertions(+), 37 deletions(-) diff --git a/x-pack/plugins/cross_cluster_replication/public/app/app.js b/x-pack/plugins/cross_cluster_replication/public/app/app.js index ca0e88e14bf86..d07712727aa77 100644 --- a/x-pack/plugins/cross_cluster_replication/public/app/app.js +++ b/x-pack/plugins/cross_cluster_replication/public/app/app.js @@ -53,7 +53,6 @@ export class App extends Component { this.state = { isFetchingPermissions: false, fetchPermissionError: undefined, - isSecurityEnabled: false, hasPermission: false, missingClusterPrivileges: [], }; @@ -77,11 +76,10 @@ export class App extends Component { }); try { - const { isSecurityEnabled, hasPermission, missingClusterPrivileges } = await loadPermissions(); + const { hasPermission, missingClusterPrivileges } = await loadPermissions(); this.setState({ isFetchingPermissions: false, - isSecurityEnabled, hasPermission, missingClusterPrivileges, }); @@ -111,7 +109,6 @@ export class App extends Component { const { isFetchingPermissions, fetchPermissionError, - isSecurityEnabled, hasPermission, missingClusterPrivileges, } = this.state; @@ -182,31 +179,6 @@ export class App extends Component { ); } - if (!isSecurityEnabled) { - return ( - - - - } - body={ -

- -

} - /> -
- ); - } - if (!hasPermission) { return ( diff --git a/x-pack/plugins/cross_cluster_replication/server/routes/api/ccr.js b/x-pack/plugins/cross_cluster_replication/server/routes/api/ccr.js index 1ba5cdf62fc8c..e47a3ae329a91 100644 --- a/x-pack/plugins/cross_cluster_replication/server/routes/api/ccr.js +++ b/x-pack/plugins/cross_cluster_replication/server/routes/api/ccr.js @@ -63,16 +63,11 @@ export const registerCcrRoutes = (server) => { throw new Boom('Security info unavailable', { statusCode: 503 }); } - // we assume that `xpack.isAvailable()` always returns `true` because we're inside x-pack - // if for whatever reason it returns `false`, `isSecurityDisabled()` would also return `false` - // which would result in follow-up behavior assuming security is enabled. This is intentional, - // because it results in more defensive behavior. const securityInfo = (xpackInfo && xpackInfo.isAvailable() && xpackInfo.feature('security')); if (!securityInfo || !securityInfo.isEnabled()) { - // If security isn't enabled, tell the user it's required. + // If security isn't enabled, let the user use CCR. return { - isSecurityEnabled: false, - hasPermission: false, + hasPermission: true, missingClusterPrivileges: [], }; } @@ -97,7 +92,6 @@ export const registerCcrRoutes = (server) => { }, []); return { - isSecurityEnabled: true, hasPermission, missingClusterPrivileges, };