From 56c8167d4e393a5edf619dea1e761f56c1fd15d2 Mon Sep 17 00:00:00 2001 From: Melissa Alvarez Date: Thu, 8 Aug 2019 12:04:29 -0400 Subject: [PATCH] Update permission check to manage_ml --- .../plugins/ml/public/management/index.js | 37 +++++++++---------- .../ml/public/privilege/check_privilege.ts | 17 ++++----- .../ml/public/privilege/get_privileges.ts | 15 ++++++++ .../public/services/ml_api_service/index.js | 7 ++++ .../lib/check_privileges/check_privileges.ts | 11 +++++- .../legacy/plugins/ml/server/routes/system.js | 3 +- 6 files changed, 57 insertions(+), 33 deletions(-) diff --git a/x-pack/legacy/plugins/ml/public/management/index.js b/x-pack/legacy/plugins/ml/public/management/index.js index 29272ce99c5e37..f24900f7ecb422 100644 --- a/x-pack/legacy/plugins/ml/public/management/index.js +++ b/x-pack/legacy/plugins/ml/public/management/index.js @@ -10,30 +10,27 @@ * you may not use this file except in compliance with the Elastic License. */ -import { xpackInfo } from 'plugins/xpack_main/services/xpack_info'; import { management } from 'ui/management'; import { i18n } from '@kbn/i18n'; import { JOBS_LIST_PATH } from './management_urls'; import 'plugins/ml/management/jobs_list'; -if (xpackInfo.get('features.ml.showLinks', false) === true) { - management.register('ml', { - display: i18n.translate( - 'xpack.ml.management.mlTitle', { - defaultMessage: 'Machine Learning', - }), - order: 100, - icon: 'machineLearningApp', - }); +management.register('ml', { + display: i18n.translate( + 'xpack.ml.management.mlTitle', { + defaultMessage: 'Machine Learning', + }), + order: 100, + icon: 'machineLearningApp', +}); - management.getSection('ml').register('jobsList', { - name: 'jobsListLink', - order: 10, - display: i18n.translate( - 'xpack.ml.management.jobsListTitle', { - defaultMessage: 'Jobs list', - }), - url: `#${JOBS_LIST_PATH}`, - }); -} +management.getSection('ml').register('jobsList', { + name: 'jobsListLink', + order: 10, + display: i18n.translate( + 'xpack.ml.management.jobsListTitle', { + defaultMessage: 'Jobs list', + }), + url: `#${JOBS_LIST_PATH}`, +}); diff --git a/x-pack/legacy/plugins/ml/public/privilege/check_privilege.ts b/x-pack/legacy/plugins/ml/public/privilege/check_privilege.ts index 695eba29195930..53454ea10150ab 100644 --- a/x-pack/legacy/plugins/ml/public/privilege/check_privilege.ts +++ b/x-pack/legacy/plugins/ml/public/privilege/check_privilege.ts @@ -10,23 +10,20 @@ import { i18n } from '@kbn/i18n'; import { hasLicenseExpired } from '../license/check_license'; import { Privileges, getDefaultPrivileges } from '../../common/types/privileges'; -import { getPrivileges } from './get_privileges'; +import { getPrivileges, getManageMlPrivileges } from './get_privileges'; import { ACCESS_DENIED_PATH } from '../management/management_urls'; let privileges: Privileges = getDefaultPrivileges(); +// manage_ml requires all monitor and admin cluster privileges: https://github.com/elastic/elasticsearch/blob/664a29c8905d8ce9ba8c18aa1ed5c5de93a0eabc/x-pack/plugin/core/src/main/java/org/elasticsearch/xpack/core/security/authz/privilege/ClusterPrivilege.java#L53 export function canGetManagementMlJobs(kbnUrl: any) { return new Promise((resolve, reject) => { - getPrivileges().then(({ capabilities, isPlatinumOrTrialLicense }) => { + getManageMlPrivileges().then(({ capabilities, isPlatinumOrTrialLicense }) => { privileges = capabilities; - const isManageML = - privileges.canGetJobs && - privileges.canCreateJob && - privileges.canUpdateJob && - privileges.canOpenJob && - privileges.canCloseJob && - privileges.canDeleteJob && - privileges.canForecastJob; + // Loop through all privilages to ensure they are all set to true. + const isManageML = Object.keys(privileges).every( + privilegeType => privileges[privilegeType] === true + ); if (isManageML === true && isPlatinumOrTrialLicense === true) { return resolve(); diff --git a/x-pack/legacy/plugins/ml/public/privilege/get_privileges.ts b/x-pack/legacy/plugins/ml/public/privilege/get_privileges.ts index 5822babe6bb090..adca02b434e383 100644 --- a/x-pack/legacy/plugins/ml/public/privilege/get_privileges.ts +++ b/x-pack/legacy/plugins/ml/public/privilege/get_privileges.ts @@ -23,3 +23,18 @@ export function getPrivileges(): Promise { }); }); } + +export function getManageMlPrivileges(): Promise { + return new Promise((resolve, reject) => { + ml.checkManageMLPrivileges() + .then((resp: PrivilegesResponse) => { + if (resp.upgradeInProgress === true) { + setUpgradeInProgress(true); + } + resolve(resp); + }) + .catch(() => { + reject(); + }); + }); +} diff --git a/x-pack/legacy/plugins/ml/public/services/ml_api_service/index.js b/x-pack/legacy/plugins/ml/public/services/ml_api_service/index.js index 29c3369031fb6e..b153aa4e07f68a 100644 --- a/x-pack/legacy/plugins/ml/public/services/ml_api_service/index.js +++ b/x-pack/legacy/plugins/ml/public/services/ml_api_service/index.js @@ -227,6 +227,13 @@ export const ml = { }); }, + checkManageMLPrivileges() { + return http({ + url: `${basePath}/ml_capabilities?ignoreSpaces=true`, + method: 'GET' + }); + }, + getNotificationSettings() { return http({ url: `${basePath}/notification_settings`, diff --git a/x-pack/legacy/plugins/ml/server/lib/check_privileges/check_privileges.ts b/x-pack/legacy/plugins/ml/server/lib/check_privileges/check_privileges.ts index ae73ba5be22bba..b6da6b4fc73255 100644 --- a/x-pack/legacy/plugins/ml/server/lib/check_privileges/check_privileges.ts +++ b/x-pack/legacy/plugins/ml/server/lib/check_privileges/check_privileges.ts @@ -26,7 +26,8 @@ interface Response { export function privilegesProvider( callWithRequest: callWithRequestType, xpackMainPlugin: XPackMainPlugin, - isMlEnabledInSpace: () => Promise + isMlEnabledInSpace: () => Promise, + ignoreSpaces: boolean = false ) { const { isUpgradeInProgress } = upgradeCheckProvider(callWithRequest); async function getPrivileges(): Promise { @@ -37,7 +38,13 @@ export function privilegesProvider( const securityDisabled = isSecurityDisabled(xpackMainPlugin); const license = checkLicense(xpackMainPlugin.info); const isPlatinumOrTrialLicense = license.licenseType === LICENSE_TYPE.FULL; - const mlFeatureEnabledInSpace = await isMlEnabledInSpace(); + let mlFeatureEnabledInSpace; + + if (ignoreSpaces) { + mlFeatureEnabledInSpace = true; + } else { + mlFeatureEnabledInSpace = await isMlEnabledInSpace(); + } const setGettingPrivileges = isPlatinumOrTrialLicense ? setFullGettingPrivileges diff --git a/x-pack/legacy/plugins/ml/server/routes/system.js b/x-pack/legacy/plugins/ml/server/routes/system.js index 8b68271faf02e9..0fc763a0c3a15d 100644 --- a/x-pack/legacy/plugins/ml/server/routes/system.js +++ b/x-pack/legacy/plugins/ml/server/routes/system.js @@ -98,12 +98,13 @@ export function systemRoutes({ async handler(request) { const callWithRequest = callWithRequestFactory(elasticsearchPlugin, request); try { + const ignoreSpaces = request.query && request.query.ignoreSpaces === 'true'; const spacesFeature = xpackMainPlugin.info.feature('spaces'); const { isMlEnabledInSpace } = spacesFeature.isEnabled() ? spacesUtilsProvider(spacesPlugin, request, config) : { isMlEnabledInSpace: async () => true }; // if spaces is disabled force isMlEnabledInSpace to be true - const { getPrivileges } = privilegesProvider(callWithRequest, xpackMainPlugin, isMlEnabledInSpace); + const { getPrivileges } = privilegesProvider(callWithRequest, xpackMainPlugin, isMlEnabledInSpace, ignoreSpaces); return await getPrivileges(); } catch (error) { return wrapError(error);