[BeatsCM] error on issues dont disable (#25149)

* display error messages for failed checks vs disableing plugin

* update text

* change order of check

* tweak security check

* re-disable on invalid license, update text

* update text

* tweaks

* tweak text
This commit is contained in:
Matt Apperson 2018-11-06 21:33:07 -05:00
parent 36de9e8325
commit 73ce55289b
7 changed files with 61 additions and 18 deletions

View file

@ -58,13 +58,20 @@ export class KibanaFrameworkAdapter implements FrameworkAdapter {
this.rootComponent = component;
};
public hadValidLicense() {
public hasValidLicense() {
if (!this.xpackInfo) {
return false;
}
return this.xpackInfo.get('features.beats_management.licenseValid', false);
}
public licenseExpired() {
if (!this.xpackInfo) {
return false;
}
return this.xpackInfo.get('features.beats_management.licenseExpired', false);
}
public securityEnabled() {
if (!this.xpackInfo) {
return false;
@ -83,8 +90,9 @@ export class KibanaFrameworkAdapter implements FrameworkAdapter {
public registerManagementSection(pluginId: string, displayName: string, basePath: string) {
this.register(this.uiModule);
this.hookAngular(() => {
if (this.hadValidLicense() && this.securityEnabled()) {
if (this.hasValidLicense()) {
const registerSection = () =>
this.management.register(pluginId, {
display: 'Beats', // TODO these need to be config options not hard coded in the adapter
@ -92,7 +100,6 @@ export class KibanaFrameworkAdapter implements FrameworkAdapter {
order: 30,
});
const getSection = () => this.management.getSection(pluginId);
const section = this.management.hasItem(pluginId) ? getSection() : registerSection();
section.register(pluginId, {
@ -132,7 +139,13 @@ export class KibanaFrameworkAdapter implements FrameworkAdapter {
const xpackInfo = Private(this.XPackInfoProvider);
this.xpackInfo = xpackInfo;
this.shieldUser = await $injector.get('ShieldUser').getCurrent().$promise;
if (this.securityEnabled()) {
try {
this.shieldUser = await $injector.get('ShieldUser').getCurrent().$promise;
} catch (e) {
// errors when security disabled, even though we check first because angular
}
}
done();
});

View file

@ -55,6 +55,9 @@ export interface FrameworkAdapter {
scope: string[];
username: string;
};
licenseExpired(): boolean;
securityEnabled(): boolean;
hasValidLicense(): boolean;
setUISettings(key: string, value: any): void;
render(component: React.ReactElement<any>): void;
}

View file

@ -0,0 +1,13 @@
/*
* 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 * as React from 'react';
import { NoDataLayout } from '../components/layouts/no_data';
export const EnforceSecurityPage: React.SFC<any> = () => (
<NoDataLayout title="Security is not enabled" actionSection={[]}>
<p>You must enable security in Kibana and Elasticsearch to use Beats central management.</p>
</NoDataLayout>
);

View file

@ -0,0 +1,16 @@
/*
* 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 * as React from 'react';
import { NoDataLayout } from '../components/layouts/no_data';
export const InvalidLicensePage: React.SFC<any> = () => (
<NoDataLayout title="Expired license" actionSection={[]}>
<p>
Your current license is expired. Enrolled Beats will continue to work, but you need a valid
license to access the Beats Management UI.
</p>
</NoDataLayout>
);

View file

@ -7,7 +7,7 @@ import * as React from 'react';
import { NoDataLayout } from '../components/layouts/no_data';
export const NoAccessPage: React.SFC<any> = () => (
<NoDataLayout title="Access Denied" actionSection={[]}>
<NoDataLayout title="Access denied" actionSection={[]}>
<p>
You are not authorized to access Beats central management. To use Beats central management,
you need the privileges granted by the `beats_admin` role.

View file

@ -6,11 +6,12 @@
import React from 'react';
import { HashRouter, Redirect, Route, Switch } from 'react-router-dom';
import { Header } from './components/layouts/header';
import { BreadcrumbConsumer, RouteWithBreadcrumb } from './components/route_with_breadcrumb';
import { FrontendLibs } from './lib/lib';
import { BeatDetailsPage } from './pages/beat';
import { EnforceSecurityPage } from './pages/enforce_security';
import { InvalidLicensePage } from './pages/invalid_license';
import { MainPages } from './pages/main';
import { NoAccessPage } from './pages/no_access';
import { TagPage } from './pages/tag';
@ -37,6 +38,8 @@ export const PageRouter: React.SFC<{ libs: FrontendLibs }> = ({ libs }) => {
)}
</BreadcrumbConsumer>
<Switch>
{libs.framework.licenseExpired() && <Route render={() => <InvalidLicensePage />} />}
{!libs.framework.securityEnabled() && <Route render={() => <EnforceSecurityPage />} />}
{!libs.framework.getCurrentUser() ||
(!libs.framework.getCurrentUser().roles.includes('beats_admin') &&
!libs.framework.getCurrentUser().roles.includes('superuser') && (

View file

@ -62,9 +62,6 @@ export class KibanaBackendFrameworkAdapter implements BackendFrameworkAdapter {
}
public exposeStaticDir(urlPath: string, dir: string): void {
if (!this.isSecurityEnabled()) {
return;
}
this.server.route({
handler: {
directory: {
@ -101,7 +98,7 @@ export class KibanaBackendFrameworkAdapter implements BackendFrameworkAdapter {
if (
wrappedRequest.user.kind === 'authenticated' &&
!wrappedRequest.user.roles.includes('superuser') &&
(!wrappedRequest.user.roles.includes('superuser') || !wrappedRequest.user.roles) &&
difference(requiredRoles, wrappedRequest.user.roles).length !== 0
) {
return h.response().code(403);
@ -126,13 +123,6 @@ export class KibanaBackendFrameworkAdapter implements BackendFrameworkAdapter {
}
}
private isSecurityEnabled = () => {
return (
this.server.plugins.xpack_main.info.isAvailable() &&
this.server.plugins.xpack_main.info.feature('security').isEnabled()
);
};
// TODO make key a param
private validateConfig() {
// @ts-ignore
@ -172,6 +162,7 @@ export class KibanaBackendFrameworkAdapter implements BackendFrameworkAdapter {
return {
securityEnabled: true,
licenseValid: false,
licenseExpired: false,
message: `Your ${licenseType} license does not support Beats central management features. Please upgrade your license.`,
};
}
@ -180,7 +171,8 @@ export class KibanaBackendFrameworkAdapter implements BackendFrameworkAdapter {
if (!isLicenseActive) {
return {
securityEnabled: true,
licenseValid: false,
licenseValid: true,
licenseExpired: true,
message: `You cannot edit, create, or delete your Beats central management configurations because your ${licenseType} license has expired.`,
};
}
@ -193,6 +185,8 @@ export class KibanaBackendFrameworkAdapter implements BackendFrameworkAdapter {
return {
securityEnabled: false,
licenseValid: true,
licenseExpired: false,
message,
};
}
@ -201,6 +195,7 @@ export class KibanaBackendFrameworkAdapter implements BackendFrameworkAdapter {
return {
securityEnabled: true,
licenseValid: true,
licenseExpired: false,
};
}
}