From fd8434a823c39a41522aa90b2e98067d8db5a4ed Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Tue, 5 Feb 2019 19:45:14 +0100 Subject: [PATCH] [ML] Fixes annotations integrity check. (#30102) With security enabled, the internal user wouldn't have enough permissions to run the integrity check. This changes the check to use the currently logged in user. Also fixes some typos in messages. --- .../explorer_charts/explorer_chart_info_tooltip.js | 4 ++-- .../components/timeseries_chart/timeseries_chart.js | 6 +++--- .../plugins/ml/server/lib/check_annotations/index.js | 11 ++++------- x-pack/plugins/ml/server/routes/annotations.js | 11 ++++++----- 4 files changed, 15 insertions(+), 17 deletions(-) diff --git a/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_info_tooltip.js b/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_info_tooltip.js index ad53cb12d3ad..3f62b48f74c5 100644 --- a/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_info_tooltip.js +++ b/x-pack/plugins/ml/public/explorer/explorer_charts/explorer_chart_info_tooltip.js @@ -15,8 +15,8 @@ import { injectI18n } from '@kbn/i18n/react'; const CHART_DESCRIPTION = { [CHART_TYPE.EVENT_DISTRIBUTION]: i18n.translate('xpack.ml.explorer.charts.infoTooltip.chartEventDistributionDescription', { - defaultMessage: 'The gray dots depict the distribution of occurences over time for a sample of {byFieldValuesParam} with' + - 'more frequent event types at the top and rarer ones at the bottom.', + defaultMessage: 'The gray dots depict the distribution of occurrences over time for a sample of {byFieldValuesParam} with' + + ' more frequent event types at the top and rarer ones at the bottom.', values: { byFieldValuesParam: 'by_field_values' } }), [CHART_TYPE.POPULATION_DISTRIBUTION]: i18n.translate('xpack.ml.explorer.charts.infoTooltip.chartPopulationDistributionDescription', { diff --git a/x-pack/plugins/ml/public/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js b/x-pack/plugins/ml/public/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js index ee08c9376c8d..1ab54238159f 100644 --- a/x-pack/plugins/ml/public/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js +++ b/x-pack/plugins/ml/public/timeseriesexplorer/components/timeseries_chart/timeseries_chart.js @@ -181,7 +181,7 @@ export const TimeseriesChart = injectI18n(class TimeseriesChart extends React.Co .addDanger( intl.formatMessage({ id: 'xpack.ml.timeSeriesExplorer.timeSeriesChart.errorWithDeletingAnnotationNotificationErrorMessage', - defaultMessage: 'An error occured deleting the annotation for job with ID {jobId}: {error}', + defaultMessage: 'An error occurred deleting the annotation for job with ID {jobId}: {error}', }, { jobId: annotation.job_id, error: JSON.stringify(err) }) ); } @@ -226,14 +226,14 @@ export const TimeseriesChart = injectI18n(class TimeseriesChart extends React.Co toastNotifications.addDanger( intl.formatMessage({ id: 'xpack.ml.timeSeriesExplorer.timeSeriesChart.errorWithCreatingAnnotationNotificationErrorMessage', - defaultMessage: 'An error occured creating the annotation for job with ID {jobId}: {error}', + defaultMessage: 'An error occurred creating the annotation for job with ID {jobId}: {error}', }, { jobId: annotation.job_id, error: JSON.stringify(resp) }) ); } else { toastNotifications.addDanger( intl.formatMessage({ id: 'xpack.ml.timeSeriesExplorer.timeSeriesChart.errorWithUpdatingAnnotationNotificationErrorMessage', - defaultMessage: 'An error occured updating the annotation for job with ID {jobId}: {error}', + defaultMessage: 'An error occurred updating the annotation for job with ID {jobId}: {error}', }, { jobId: annotation.job_id, error: JSON.stringify(resp) }) ); } diff --git a/x-pack/plugins/ml/server/lib/check_annotations/index.js b/x-pack/plugins/ml/server/lib/check_annotations/index.js index 0bd30b3302cd..efcd6ef54bde 100644 --- a/x-pack/plugins/ml/server/lib/check_annotations/index.js +++ b/x-pack/plugins/ml/server/lib/check_annotations/index.js @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { callWithInternalUserFactory } from '../../client/call_with_internal_user_factory'; import { mlLog } from '../../client/log'; import { @@ -20,24 +19,22 @@ import { FEATURE_ANNOTATIONS_ENABLED } from '../../../common/constants/feature_f // - ML_ANNOTATIONS_INDEX_PATTERN index is present // - ML_ANNOTATIONS_INDEX_ALIAS_READ alias is present // - ML_ANNOTATIONS_INDEX_ALIAS_WRITE alias is present -export async function isAnnotationsFeatureAvailable(server) { +export async function isAnnotationsFeatureAvailable(callWithRequest) { if (!FEATURE_ANNOTATIONS_ENABLED) return false; try { - const callWithInternalUser = callWithInternalUserFactory(server); - const indexParams = { index: ML_ANNOTATIONS_INDEX_PATTERN }; - const annotationsIndexExists = await callWithInternalUser('indices.exists', indexParams); + const annotationsIndexExists = await callWithRequest('indices.exists', indexParams); if (!annotationsIndexExists) return false; - const annotationsReadAliasExists = await callWithInternalUser('indices.existsAlias', { + const annotationsReadAliasExists = await callWithRequest('indices.existsAlias', { name: ML_ANNOTATIONS_INDEX_ALIAS_READ }); if (!annotationsReadAliasExists) return false; - const annotationsWriteAliasExists = await callWithInternalUser('indices.existsAlias', { + const annotationsWriteAliasExists = await callWithRequest('indices.existsAlias', { name: ML_ANNOTATIONS_INDEX_ALIAS_WRITE }); if (!annotationsWriteAliasExists) return false; diff --git a/x-pack/plugins/ml/server/routes/annotations.js b/x-pack/plugins/ml/server/routes/annotations.js index e7945cf6b1f9..1978dfbfed88 100644 --- a/x-pack/plugins/ml/server/routes/annotations.js +++ b/x-pack/plugins/ml/server/routes/annotations.js @@ -18,7 +18,8 @@ import { ANNOTATION_USER_UNKNOWN } from '../../common/constants/annotations'; function getAnnotationsFeatureUnavailableErrorMessage() { return Boom.badRequest( i18n.translate('xpack.ml.routes.annotations.annotationsFeatureUnavailableErrorMessage', { - defaultMessage: 'Index and aliases required for the annotations feature have not been created.', + defaultMessage: 'Index and aliases required for the annotations feature have not been' + + ' created or are not accessible for the current user.', }) ); } @@ -41,12 +42,12 @@ export function annotationRoutes(server, commonRouteConfig) { method: 'PUT', path: '/api/ml/annotations/index', async handler(request) { - const annotationsFeatureAvailable = await isAnnotationsFeatureAvailable(server); + const callWithRequest = callWithRequestFactory(server, request); + const annotationsFeatureAvailable = await isAnnotationsFeatureAvailable(callWithRequest); if (annotationsFeatureAvailable === false) { return getAnnotationsFeatureUnavailableErrorMessage(); } - const callWithRequest = callWithRequestFactory(server, request); const { indexAnnotation } = annotationServiceProvider(callWithRequest); const username = _.get(request, 'auth.credentials.username', ANNOTATION_USER_UNKNOWN); return indexAnnotation(request.payload, username) @@ -61,12 +62,12 @@ export function annotationRoutes(server, commonRouteConfig) { method: 'DELETE', path: '/api/ml/annotations/delete/{annotationId}', async handler(request) { - const annotationsFeatureAvailable = await isAnnotationsFeatureAvailable(server); + const callWithRequest = callWithRequestFactory(server, request); + const annotationsFeatureAvailable = await isAnnotationsFeatureAvailable(callWithRequest); if (annotationsFeatureAvailable === false) { return getAnnotationsFeatureUnavailableErrorMessage(); } - const callWithRequest = callWithRequestFactory(server, request); const annotationId = request.params.annotationId; const { deleteAnnotation } = annotationServiceProvider(callWithRequest); return deleteAnnotation(annotationId)