[6.x] [ML] Privileges refactor (#18652)

This commit is contained in:
James Gowdy 2018-04-30 13:14:53 +01:00 committed by GitHub
parent 0c2f46a1ef
commit 641f9da5af
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 62 additions and 79 deletions

View file

@ -7,8 +7,9 @@
import { JOB_STATE, DATAFEED_STATE } from 'plugins/ml/../common/constants/states';
import { createPermissionFailureMessage } from 'plugins/ml/privilege/check_privilege';
export function buttonsEnabledChecks(permissions, job, createPermissionFailureMessage, mlNodesAvailable) {
export function buttonsEnabledChecks(permissions, job, mlNodesAvailable) {
const NO_ML_NODES_ERROR = 'No ML nodes available';
function startButtonWrapperClass() {

View file

@ -9,7 +9,7 @@ import moment from 'moment';
import { toLocaleString, detectorToString } from 'plugins/ml/util/string_utils';
import { JOB_STATE, DATAFEED_STATE } from 'plugins/ml/../common/constants/states';
import { ML_DATA_PREVIEW_COUNT } from 'plugins/ml/../common/util/job_utils';
import { permissionCheckProvider } from 'plugins/ml/privilege/check_privilege';
import { checkPermission } from 'plugins/ml/privilege/check_privilege';
import numeral from '@elastic/numeral';
import chrome from 'ui/chrome';
import angular from 'angular';
@ -18,7 +18,7 @@ import template from './expanded_row.html';
import { uiModules } from 'ui/modules';
const module = uiModules.get('apps/ml');
module.directive('mlJobListExpandedRow', function ($location, mlMessageBarService, mlJobService, mlClipboardService, Private) {
module.directive('mlJobListExpandedRow', function ($location, mlMessageBarService, mlJobService, mlClipboardService) {
return {
restrict: 'AE',
replace: false,
@ -38,7 +38,6 @@ module.directive('mlJobListExpandedRow', function ($location, mlMessageBarServic
const DATA_FORMAT = '0.0 b';
$scope.urlBasePath = chrome.getBasePath();
const { checkPermission } = Private(permissionCheckProvider);
$scope.permissions = {
canPreviewDatafeed: checkPermission('canPreviewDatafeed')
};

View file

@ -19,7 +19,7 @@ import { toLocaleString, mlEscape } from 'plugins/ml/util/string_utils';
import uiRoutes from 'ui/routes';
import { checkLicense } from 'plugins/ml/license/check_license';
import { checkGetJobsPrivilege, permissionCheckProvider } from 'plugins/ml/privilege/check_privilege';
import { checkGetJobsPrivilege, checkPermission, createPermissionFailureMessage } from 'plugins/ml/privilege/check_privilege';
import { addItemToRecentlyAccessed } from 'plugins/ml/util/recently_accessed';
import { getMlNodeCount, mlNodesAvailable, permissionToViewMlNodeCount } from 'plugins/ml/ml_nodes_check/check_ml_nodes';
@ -89,7 +89,6 @@ module.controller('MlJobsList',
$scope.isCloud = isRunningOnCloud();
$scope.cloudId = getCloudId();
const { checkPermission, createPermissionFailureMessage } = Private(permissionCheckProvider);
$scope.createPermissionFailureMessage = createPermissionFailureMessage;
$scope.permissions = {
canCreateJob: checkPermission('canCreateJob'),
@ -285,7 +284,7 @@ module.controller('MlJobsList',
rowScope.enableTimeSeries = isTimeSeriesViewJob(job);
rowScope.addItemToRecentlyAccessed = addItemToRecentlyAccessed;
rowScope.checks = buttonsEnabledChecks($scope.permissions, job, createPermissionFailureMessage, $scope.mlNodesAvailable);
rowScope.checks = buttonsEnabledChecks($scope.permissions, job, $scope.mlNodesAvailable);
rowScopes.push(rowScope);
const jobDescription = job.description || '';

View file

@ -12,6 +12,8 @@ import _ from 'lodash';
import chrome from 'ui/chrome';
let licenseHasExpired = true;
export function checkLicense(Private, Promise, kbnBaseUrl) {
const xpackInfo = Private(XPackInfoProvider);
const features = xpackInfo.get('features.ml');
@ -27,7 +29,7 @@ export function checkLicense(Private, Promise, kbnBaseUrl) {
return Promise.halt();
}
const licenseHasExpired = features.hasExpired || false;
licenseHasExpired = features.hasExpired || false;
// If the license has expired ML app will still work for 7 days and then
// the job management endpoints (e.g. create job, start datafeed) will be restricted.
@ -61,3 +63,7 @@ export function checkLicenseExpired(Private, Promise, kbnBaseUrl, kbnUrl) {
return Promise.halt();
});
}
export function getLicenseHasExpired() {
return licenseHasExpired;
}

View file

@ -7,15 +7,19 @@
import { privilegesProvider } from 'plugins/ml/privilege/get_privileges';
import { getLicenseHasExpired } from 'plugins/ml/license/check_license';
let privileges = {};
export function checkGetJobsPrivilege(Private, Promise, kbnUrl) {
const mlPrivilegeService = Private(privilegesProvider);
return new Promise((resolve, reject) => {
mlPrivilegeService.getPrivileges()
.then((privileges) => {
// the minimum privilege for using ML is being able to get the jobs list.
// all other functionality is controlled by the return privileges object
.then((priv) => {
privileges = priv;
// the minimum privilege for using ML is being able to get the jobs list.
// all other functionality is controlled by the return privileges object
if (privileges.canGetJobs) {
return resolve(privileges);
} else {
@ -31,12 +35,13 @@ export function checkCreateJobsPrivilege(Private, Promise, kbnUrl) {
return new Promise((resolve, reject) => {
mlPrivilegeService.getPrivileges()
.then((privileges) => {
.then((priv) => {
privileges = priv;
if (privileges.canCreateJob) {
return resolve(privileges);
} else {
// if the user has no permission to create a job,
// redirect them back to the Jobs Management page
// if the user has no permission to create a job,
// redirect them back to the Jobs Management page
kbnUrl.redirect('/jobs');
return reject();
}
@ -44,44 +49,34 @@ export function checkCreateJobsPrivilege(Private, Promise, kbnUrl) {
});
}
// permission check provider, requires privileges and CheckLicense from $route
// these need to have been loaded for the page, which currently happens for all pages
export function permissionCheckProvider($route) {
const privileges = $route.current.locals.privileges;
const licenseDetails = $route.current.locals.CheckLicense;
// check the privilege type and the license to see whether a user has permission to access a feature.
// takes the name of the privilege variable as specified in get_privileges.js
function checkPermission(privilegeType) {
return (privileges[privilegeType] === true && licenseDetails.hasExpired !== true);
}
// create the text for the button's tooltips if the user's license has
// expired or if they don't have the privilege to press that button
function createPermissionFailureMessage(privilegeType) {
let message = '';
if (licenseDetails.hasExpired) {
message = 'Your license has expired.';
} else if (privilegeType === 'canCreateJob') {
message = 'You do not have permission to create Machine Learning jobs.';
} else if (privilegeType === 'canStartStopDatafeed') {
message = 'You do not have permission to start or stop datafeeds.';
} else if (privilegeType === 'canUpdateJob') {
message = 'You do not have permission to edit jobs.';
} else if (privilegeType === 'canDeleteJob') {
message = 'You do not have permission to delete jobs.';
} else if (privilegeType === 'canCreateCalendar') {
message = 'You do not have permission to create calendars.';
} else if (privilegeType === 'canDeleteCalendar') {
message = 'You do not have permission to delete calendars.';
} else if (privilegeType === 'canForecastJob') {
message = 'You do not have permission to run forecasts.';
}
return `${message} Please contact your administrator.`;
}
return {
checkPermission,
createPermissionFailureMessage
};
// check the privilege type and the license to see whether a user has permission to access a feature.
// takes the name of the privilege variable as specified in get_privileges.js
export function checkPermission(privilegeType) {
const licenseHasExpired = getLicenseHasExpired();
return (privileges[privilegeType] === true && licenseHasExpired !== true);
}
// create the text for the button's tooltips if the user's license has
// expired or if they don't have the privilege to press that button
export function createPermissionFailureMessage(privilegeType) {
let message = '';
const licenseHasExpired = getLicenseHasExpired();
if (licenseHasExpired) {
message = 'Your license has expired.';
} else if (privilegeType === 'canCreateJob') {
message = 'You do not have permission to create Machine Learning jobs.';
} else if (privilegeType === 'canStartStopDatafeed') {
message = 'You do not have permission to start or stop datafeeds.';
} else if (privilegeType === 'canUpdateJob') {
message = 'You do not have permission to edit jobs.';
} else if (privilegeType === 'canDeleteJob') {
message = 'You do not have permission to delete jobs.';
} else if (privilegeType === 'canCreateCalendar') {
message = 'You do not have permission to create calendars.';
} else if (privilegeType === 'canDeleteCalendar') {
message = 'You do not have permission to delete calendars.';
} else if (privilegeType === 'canForecastJob') {
message = 'You do not have permission to run forecasts.';
}
return `${message} Please contact your administrator.`;
}

View file

@ -6,7 +6,9 @@
export function buttonsEnabledChecks(permissions, createPermissionFailureMessage, mlNodesAvailable) {
import { createPermissionFailureMessage } from 'plugins/ml/privilege/check_privilege';
export function buttonsEnabledChecks(permissions, mlNodesAvailable) {
const NO_ML_NODES_ERROR = 'No ML nodes available';
function newButtonWrapperClass() {

View file

@ -14,7 +14,7 @@ import 'ui/sortable_column';
import uiRoutes from 'ui/routes';
import { checkLicense } from 'plugins/ml/license/check_license';
import { checkGetJobsPrivilege, permissionCheckProvider } from 'plugins/ml/privilege/check_privilege';
import { checkGetJobsPrivilege, checkPermission } from 'plugins/ml/privilege/check_privilege';
import { getMlNodeCount, mlNodesAvailable } from 'plugins/ml/ml_nodes_check/check_ml_nodes';
import { buttonsEnabledChecks } from 'plugins/ml/settings/scheduled_events/calendars_list/buttons_enabled_checks';
@ -45,7 +45,6 @@ module.controller('MlCalendarsList',
timefilter,
mlConfirmModalService) {
const { checkPermission, createPermissionFailureMessage } = Private(permissionCheckProvider);
$scope.permissions = {
canCreateCalendar: checkPermission('canCreateCalendar'),
canDeleteCalendar: checkPermission('canDeleteCalendar'),
@ -57,7 +56,7 @@ module.controller('MlCalendarsList',
let calendars = []; // Complete list of calendars received from the ML endpoint.
$scope.displayCalendars = []; // List of calendars being displayed after filtering and sorting.
$scope.buttonChecks = buttonsEnabledChecks($scope.permissions, createPermissionFailureMessage, mlNodesAvailable());
$scope.buttonChecks = buttonsEnabledChecks($scope.permissions, mlNodesAvailable());
// Create a pager object to page through long lists of calendars.
const PAGE_SIZE = 20;

View file

@ -386,8 +386,6 @@ class ForecastingModal extends Component {
jobOpeningState={this.state.jobOpeningState}
jobClosingState={this.state.jobClosingState}
messages={this.state.messages}
checkPermission={this.props.checkPermission}
createPermissionFailureMessage={this.props.createPermissionFailureMessage}
/>
}
</div>
@ -403,8 +401,6 @@ ForecastingModal.propTypes = {
jobService: PropTypes.object.isRequired,
fieldsService: PropTypes.object.isRequired,
loadForForecastId: PropTypes.func,
checkPermission: PropTypes.func,
createPermissionFailureMessage: PropTypes.func
};
export { ForecastingModal };

View file

@ -10,7 +10,6 @@ import 'ngreact';
import { uiModules } from 'ui/modules';
const module = uiModules.get('apps/ml', ['react']);
import { permissionCheckProvider } from 'plugins/ml/privilege/check_privilege';
import { FieldsServiceProvider } from 'plugins/ml/services/fields_service';
import { ForecastingModal } from './forecasting_modal';
@ -21,8 +20,6 @@ module.directive('mlForecastingModal', function ($injector, Private) {
const timefilter = $injector.get('timefilter');
const reactDirective = $injector.get('reactDirective');
const { checkPermission, createPermissionFailureMessage } = Private(permissionCheckProvider);
return reactDirective(
ForecastingModal,
undefined,
@ -31,8 +28,6 @@ module.directive('mlForecastingModal', function ($injector, Private) {
forecastService,
jobService,
fieldsService,
checkPermission,
createPermissionFailureMessage,
timefilter
}
);

View file

@ -31,11 +31,10 @@ import {
import { JOB_STATE } from '../../../common/constants/states';
import { ForecastProgress } from './forecast_progress';
import { mlNodesAvailable } from 'plugins/ml/ml_nodes_check/check_ml_nodes';
import { checkPermission, createPermissionFailureMessage } from 'plugins/ml/privilege/check_privilege';
function getRunInputDisabledState(
checkPermission,
createPermissionFailureMessage,
job,
isForecastRequested) {
// Disable the 'run forecast' text field and button if any of the conditions are met:
@ -79,13 +78,9 @@ export function RunControls({
isForecastRequested,
forecastProgress,
jobOpeningState,
jobClosingState,
checkPermission,
createPermissionFailureMessage }) {
jobClosingState }) {
const disabledState = getRunInputDisabledState(
checkPermission,
createPermissionFailureMessage,
job,
isForecastRequested);
@ -175,6 +170,4 @@ RunControls.propType = {
forecastProgress: PropTypes.number,
jobOpeningState: PropTypes.number,
jobClosingState: PropTypes.number,
checkPermission: PropTypes.func,
createPermissionFailureMessage: PropTypes.func
};

View file

@ -26,7 +26,7 @@ import uiRoutes from 'ui/routes';
import 'ui/timefilter';
import { parseInterval } from 'ui/utils/parse_interval';
import { checkLicense } from 'plugins/ml/license/check_license';
import { checkGetJobsPrivilege, permissionCheckProvider } from 'plugins/ml/privilege/check_privilege';
import { checkGetJobsPrivilege, checkPermission } from 'plugins/ml/privilege/check_privilege';
import {
isTimeSeriesViewJob,
isTimeSeriesViewDetector,
@ -100,11 +100,9 @@ module.controller('MlTimeSeriesExplorerController', function (
$scope.showForecast = true; // Toggles display of forecast data in the focus chart
$scope.showForecastCheckbox = false;
const { checkPermission, createPermissionFailureMessage } = Private(permissionCheckProvider);
$scope.permissions = {
canForecastJob: checkPermission('canForecastJob')
};
$scope.createPermissionFailureMessage = createPermissionFailureMessage;
$scope.initializeVis = function () {