Consolidate capabilities check for Stack Management (#69437)
Co-authored-by: Elastic Machine <elasticmachine@users.noreply.github.com>
This commit is contained in:
parent
fe1c508d8d
commit
28b70923df
|
@ -17,8 +17,8 @@
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import { i18n } from '@kbn/i18n';
|
import { i18n } from '@kbn/i18n';
|
||||||
import { CoreSetup, CoreStart, Plugin } from 'kibana/public';
|
import { CoreSetup, Plugin } from 'kibana/public';
|
||||||
import { ManagementApp, ManagementSectionId } from '../../management/public';
|
import { ManagementSectionId } from '../../management/public';
|
||||||
import { ComponentRegistry } from './component_registry';
|
import { ComponentRegistry } from './component_registry';
|
||||||
import { AdvancedSettingsSetup, AdvancedSettingsStart, AdvancedSettingsPluginSetup } from './types';
|
import { AdvancedSettingsSetup, AdvancedSettingsStart, AdvancedSettingsPluginSetup } from './types';
|
||||||
|
|
||||||
|
@ -30,11 +30,10 @@ const title = i18n.translate('advancedSettings.advancedSettingsLabel', {
|
||||||
|
|
||||||
export class AdvancedSettingsPlugin
|
export class AdvancedSettingsPlugin
|
||||||
implements Plugin<AdvancedSettingsSetup, AdvancedSettingsStart, AdvancedSettingsPluginSetup> {
|
implements Plugin<AdvancedSettingsSetup, AdvancedSettingsStart, AdvancedSettingsPluginSetup> {
|
||||||
private managementApp?: ManagementApp;
|
|
||||||
public setup(core: CoreSetup, { management }: AdvancedSettingsPluginSetup) {
|
public setup(core: CoreSetup, { management }: AdvancedSettingsPluginSetup) {
|
||||||
const kibanaSection = management.sections.getSection(ManagementSectionId.Kibana);
|
const kibanaSection = management.sections.getSection(ManagementSectionId.Kibana);
|
||||||
|
|
||||||
this.managementApp = kibanaSection.registerApp({
|
kibanaSection.registerApp({
|
||||||
id: 'settings',
|
id: 'settings',
|
||||||
title,
|
title,
|
||||||
order: 3,
|
order: 3,
|
||||||
|
@ -51,11 +50,7 @@ export class AdvancedSettingsPlugin
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public start(core: CoreStart) {
|
public start() {
|
||||||
if (!core.application.capabilities.management.kibana.settings) {
|
|
||||||
this.managementApp!.disable();
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
component: component.start,
|
component: component.start,
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,7 +30,7 @@ export const onRedirectNoIndexPattern = (
|
||||||
navigateToApp: CoreStart['application']['navigateToApp'],
|
navigateToApp: CoreStart['application']['navigateToApp'],
|
||||||
overlays: CoreStart['overlays']
|
overlays: CoreStart['overlays']
|
||||||
) => () => {
|
) => () => {
|
||||||
const canManageIndexPatterns = capabilities.management.kibana.index_patterns;
|
const canManageIndexPatterns = capabilities.management.kibana.indexPatterns;
|
||||||
const redirectTarget = canManageIndexPatterns ? '/management/kibana/indexPatterns' : '/home';
|
const redirectTarget = canManageIndexPatterns ? '/management/kibana/indexPatterns' : '/home';
|
||||||
let timeoutId: NodeJS.Timeout | undefined;
|
let timeoutId: NodeJS.Timeout | undefined;
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ export const indexPatternSavedObjectType: SavedObjectsType = {
|
||||||
getInAppUrl(obj) {
|
getInAppUrl(obj) {
|
||||||
return {
|
return {
|
||||||
path: `/app/management/kibana/indexPatterns/patterns/${encodeURIComponent(obj.id)}`,
|
path: `/app/management/kibana/indexPatterns/patterns/${encodeURIComponent(obj.id)}`,
|
||||||
uiCapabilitiesPath: 'management.kibana.index_patterns',
|
uiCapabilitiesPath: 'management.kibana.indexPatterns',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -24,6 +24,6 @@ export const capabilitiesProvider = () => ({
|
||||||
visualize: true,
|
visualize: true,
|
||||||
console: true,
|
console: true,
|
||||||
advanced_settings: true,
|
advanced_settings: true,
|
||||||
index_patterns: true,
|
indexPatterns: true,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -27,7 +27,7 @@ import {
|
||||||
IndexPatternManagementServiceStart,
|
IndexPatternManagementServiceStart,
|
||||||
} from './service';
|
} from './service';
|
||||||
|
|
||||||
import { ManagementSetup, ManagementApp, ManagementSectionId } from '../../management/public';
|
import { ManagementSetup, ManagementSectionId } from '../../management/public';
|
||||||
|
|
||||||
export interface IndexPatternManagementSetupDependencies {
|
export interface IndexPatternManagementSetupDependencies {
|
||||||
management: ManagementSetup;
|
management: ManagementSetup;
|
||||||
|
@ -57,7 +57,6 @@ export class IndexPatternManagementPlugin
|
||||||
IndexPatternManagementStartDependencies
|
IndexPatternManagementStartDependencies
|
||||||
> {
|
> {
|
||||||
private readonly indexPatternManagementService = new IndexPatternManagementService();
|
private readonly indexPatternManagementService = new IndexPatternManagementService();
|
||||||
private managementApp?: ManagementApp;
|
|
||||||
|
|
||||||
constructor(initializerContext: PluginInitializerContext) {}
|
constructor(initializerContext: PluginInitializerContext) {}
|
||||||
|
|
||||||
|
@ -80,7 +79,7 @@ export class IndexPatternManagementPlugin
|
||||||
return pathInApp && `/patterns${pathInApp}`;
|
return pathInApp && `/patterns${pathInApp}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.managementApp = kibanaSection.registerApp({
|
kibanaSection.registerApp({
|
||||||
id: IPM_APP_ID,
|
id: IPM_APP_ID,
|
||||||
title: sectionsHeader,
|
title: sectionsHeader,
|
||||||
order: 0,
|
order: 0,
|
||||||
|
@ -95,10 +94,6 @@ export class IndexPatternManagementPlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
public start(core: CoreStart, plugins: IndexPatternManagementStartDependencies) {
|
public start(core: CoreStart, plugins: IndexPatternManagementStartDependencies) {
|
||||||
if (!core.application.capabilities.management.kibana.index_patterns) {
|
|
||||||
this.managementApp!.disable();
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.indexPatternManagementService.start();
|
return this.indexPatternManagementService.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,9 +27,15 @@ describe('ManagementService', () => {
|
||||||
managementService = new ManagementSectionsService();
|
managementService = new ManagementSectionsService();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const capabilities = {
|
||||||
|
navLinks: {},
|
||||||
|
catalogue: {},
|
||||||
|
management: {},
|
||||||
|
};
|
||||||
|
|
||||||
test('Provides default sections', () => {
|
test('Provides default sections', () => {
|
||||||
managementService.setup();
|
managementService.setup();
|
||||||
const start = managementService.start();
|
const start = managementService.start({ capabilities });
|
||||||
|
|
||||||
expect(start.getAllSections().length).toEqual(6);
|
expect(start.getAllSections().length).toEqual(6);
|
||||||
expect(start.getSection(ManagementSectionId.Ingest)).toBeDefined();
|
expect(start.getSection(ManagementSectionId.Ingest)).toBeDefined();
|
||||||
|
@ -48,7 +54,7 @@ describe('ManagementService', () => {
|
||||||
expect(setup.getSection('test-section')).not.toBeUndefined();
|
expect(setup.getSection('test-section')).not.toBeUndefined();
|
||||||
|
|
||||||
// Start phase:
|
// Start phase:
|
||||||
const start = managementService.start();
|
const start = managementService.start({ capabilities });
|
||||||
|
|
||||||
expect(start.getSectionsEnabled().length).toEqual(7);
|
expect(start.getSectionsEnabled().length).toEqual(7);
|
||||||
|
|
||||||
|
@ -56,4 +62,38 @@ describe('ManagementService', () => {
|
||||||
|
|
||||||
expect(start.getSectionsEnabled().length).toEqual(6);
|
expect(start.getSectionsEnabled().length).toEqual(6);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Disables items that are not allowed by Capabilities', () => {
|
||||||
|
// Setup phase:
|
||||||
|
const setup = managementService.setup();
|
||||||
|
const testSection = setup.register({ id: 'test-section', title: 'Test Section' });
|
||||||
|
testSection.registerApp({ id: 'test-app-1', title: 'Test App 1', mount: jest.fn() });
|
||||||
|
testSection.registerApp({ id: 'test-app-2', title: 'Test App 2', mount: jest.fn() });
|
||||||
|
testSection.registerApp({ id: 'test-app-3', title: 'Test App 3', mount: jest.fn() });
|
||||||
|
|
||||||
|
expect(setup.getSection('test-section')).not.toBeUndefined();
|
||||||
|
|
||||||
|
// Start phase:
|
||||||
|
managementService.start({
|
||||||
|
capabilities: {
|
||||||
|
navLinks: {},
|
||||||
|
catalogue: {},
|
||||||
|
management: {
|
||||||
|
['test-section']: {
|
||||||
|
'test-app-1': true,
|
||||||
|
'test-app-2': false,
|
||||||
|
// test-app-3 intentionally left undefined. Should be enabled by default
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(testSection.apps).toHaveLength(3);
|
||||||
|
expect(testSection.getAppsEnabled().map((app) => app.id)).toMatchInlineSnapshot(`
|
||||||
|
Array [
|
||||||
|
"test-app-1",
|
||||||
|
"test-app-3",
|
||||||
|
]
|
||||||
|
`);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -21,7 +21,12 @@ import { ReactElement } from 'react';
|
||||||
import { ManagementSection, RegisterManagementSectionArgs } from './utils';
|
import { ManagementSection, RegisterManagementSectionArgs } from './utils';
|
||||||
import { managementSections } from './components/management_sections';
|
import { managementSections } from './components/management_sections';
|
||||||
|
|
||||||
import { ManagementSectionId, SectionsServiceSetup, SectionsServiceStart } from './types';
|
import {
|
||||||
|
ManagementSectionId,
|
||||||
|
SectionsServiceSetup,
|
||||||
|
SectionsServiceStart,
|
||||||
|
SectionsServiceStartDeps,
|
||||||
|
} from './types';
|
||||||
|
|
||||||
export class ManagementSectionsService {
|
export class ManagementSectionsService {
|
||||||
private sections: Map<ManagementSectionId | string, ManagementSection> = new Map();
|
private sections: Map<ManagementSectionId | string, ManagementSection> = new Map();
|
||||||
|
@ -55,7 +60,18 @@ export class ManagementSectionsService {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
start(): SectionsServiceStart {
|
start({ capabilities }: SectionsServiceStartDeps): SectionsServiceStart {
|
||||||
|
this.getAllSections().forEach((section) => {
|
||||||
|
if (capabilities.management.hasOwnProperty(section.id)) {
|
||||||
|
const sectionCapabilities = capabilities.management[section.id];
|
||||||
|
section.apps.forEach((app) => {
|
||||||
|
if (sectionCapabilities.hasOwnProperty(app.id) && sectionCapabilities[app.id] !== true) {
|
||||||
|
app.disable();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
getSection: this.getSection,
|
getSection: this.getSection,
|
||||||
getAllSections: this.getAllSections,
|
getAllSections: this.getAllSections,
|
||||||
|
|
|
@ -82,7 +82,7 @@ export class ManagementPlugin implements Plugin<ManagementSetup, ManagementStart
|
||||||
|
|
||||||
public start(core: CoreStart) {
|
public start(core: CoreStart) {
|
||||||
return {
|
return {
|
||||||
sections: this.managementSections.start(),
|
sections: this.managementSections.start({ capabilities: core.application.capabilities }),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { ReactElement } from 'react';
|
import { ReactElement } from 'react';
|
||||||
import { ScopedHistory } from 'kibana/public';
|
import { ScopedHistory, Capabilities } from 'kibana/public';
|
||||||
import { ManagementSection, RegisterManagementSectionArgs } from './utils';
|
import { ManagementSection, RegisterManagementSectionArgs } from './utils';
|
||||||
import { ChromeBreadcrumb } from '../../../core/public/';
|
import { ChromeBreadcrumb } from '../../../core/public/';
|
||||||
|
|
||||||
|
@ -30,8 +30,12 @@ export interface ManagementStart {
|
||||||
sections: SectionsServiceStart;
|
sections: SectionsServiceStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SectionsServiceStartDeps {
|
||||||
|
capabilities: Capabilities;
|
||||||
|
}
|
||||||
|
|
||||||
export interface SectionsServiceSetup {
|
export interface SectionsServiceSetup {
|
||||||
register: (args: RegisterManagementSectionArgs) => ManagementSection;
|
register: (args: Omit<RegisterManagementSectionArgs, 'capabilities'>) => ManagementSection;
|
||||||
getSection: (sectionId: ManagementSectionId | string) => ManagementSection;
|
getSection: (sectionId: ManagementSectionId | string) => ManagementSection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ export const capabilitiesProvider = () => ({
|
||||||
*/
|
*/
|
||||||
kibana: {
|
kibana: {
|
||||||
settings: true,
|
settings: true,
|
||||||
index_patterns: true,
|
indexPatterns: true,
|
||||||
objects: true,
|
objects: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -70,7 +70,7 @@ describe('canViewInApp', () => {
|
||||||
let uiCapabilities = createCapabilities({
|
let uiCapabilities = createCapabilities({
|
||||||
management: {
|
management: {
|
||||||
kibana: {
|
kibana: {
|
||||||
index_patterns: true,
|
indexPatterns: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -81,7 +81,7 @@ describe('canViewInApp', () => {
|
||||||
uiCapabilities = createCapabilities({
|
uiCapabilities = createCapabilities({
|
||||||
management: {
|
management: {
|
||||||
kibana: {
|
kibana: {
|
||||||
index_patterns: false,
|
indexPatterns: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -30,7 +30,7 @@ export function canViewInApp(uiCapabilities: Capabilities, type: string): boolea
|
||||||
case 'index-pattern':
|
case 'index-pattern':
|
||||||
case 'index-patterns':
|
case 'index-patterns':
|
||||||
case 'indexPatterns':
|
case 'indexPatterns':
|
||||||
return uiCapabilities.management.kibana.index_patterns as boolean;
|
return uiCapabilities.management.kibana.indexPatterns as boolean;
|
||||||
case 'dashboard':
|
case 'dashboard':
|
||||||
case 'dashboards':
|
case 'dashboards':
|
||||||
return uiCapabilities.dashboard.show as boolean;
|
return uiCapabilities.dashboard.show as boolean;
|
||||||
|
|
|
@ -304,7 +304,7 @@ exports[`SavedObjectsTable should render normally 1`] = `
|
||||||
"icon": "indexPatternApp",
|
"icon": "indexPatternApp",
|
||||||
"inAppUrl": Object {
|
"inAppUrl": Object {
|
||||||
"path": "/management/kibana/indexPatterns/patterns/1",
|
"path": "/management/kibana/indexPatterns/patterns/1",
|
||||||
"uiCapabilitiesPath": "management.kibana.index_patterns",
|
"uiCapabilitiesPath": "management.kibana.indexPatterns",
|
||||||
},
|
},
|
||||||
"title": "MyIndexPattern*",
|
"title": "MyIndexPattern*",
|
||||||
},
|
},
|
||||||
|
|
|
@ -456,7 +456,7 @@ exports[`Relationships should render searches normally 1`] = `
|
||||||
"icon": "indexPatternApp",
|
"icon": "indexPatternApp",
|
||||||
"inAppUrl": Object {
|
"inAppUrl": Object {
|
||||||
"path": "/app/management/kibana/indexPatterns/patterns/1",
|
"path": "/app/management/kibana/indexPatterns/patterns/1",
|
||||||
"uiCapabilitiesPath": "management.kibana.index_patterns",
|
"uiCapabilitiesPath": "management.kibana.indexPatterns",
|
||||||
},
|
},
|
||||||
"title": "My Index Pattern",
|
"title": "My Index Pattern",
|
||||||
},
|
},
|
||||||
|
|
|
@ -178,7 +178,7 @@ exports[`Table prevents saved objects from being deleted 1`] = `
|
||||||
"icon": "indexPatternApp",
|
"icon": "indexPatternApp",
|
||||||
"inAppUrl": Object {
|
"inAppUrl": Object {
|
||||||
"path": "/management/kibana/indexPatterns/patterns/1",
|
"path": "/management/kibana/indexPatterns/patterns/1",
|
||||||
"uiCapabilitiesPath": "management.kibana.index_patterns",
|
"uiCapabilitiesPath": "management.kibana.indexPatterns",
|
||||||
},
|
},
|
||||||
"title": "MyIndexPattern*",
|
"title": "MyIndexPattern*",
|
||||||
},
|
},
|
||||||
|
@ -393,7 +393,7 @@ exports[`Table should render normally 1`] = `
|
||||||
"icon": "indexPatternApp",
|
"icon": "indexPatternApp",
|
||||||
"inAppUrl": Object {
|
"inAppUrl": Object {
|
||||||
"path": "/management/kibana/indexPatterns/patterns/1",
|
"path": "/management/kibana/indexPatterns/patterns/1",
|
||||||
"uiCapabilitiesPath": "management.kibana.index_patterns",
|
"uiCapabilitiesPath": "management.kibana.indexPatterns",
|
||||||
},
|
},
|
||||||
"title": "MyIndexPattern*",
|
"title": "MyIndexPattern*",
|
||||||
},
|
},
|
||||||
|
|
|
@ -77,7 +77,7 @@ describe('Relationships', () => {
|
||||||
editUrl: '#/management/kibana/indexPatterns/patterns/1',
|
editUrl: '#/management/kibana/indexPatterns/patterns/1',
|
||||||
inAppUrl: {
|
inAppUrl: {
|
||||||
path: '/management/kibana/indexPatterns/patterns/1',
|
path: '/management/kibana/indexPatterns/patterns/1',
|
||||||
uiCapabilitiesPath: 'management.kibana.index_patterns',
|
uiCapabilitiesPath: 'management.kibana.indexPatterns',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -113,7 +113,7 @@ describe('Relationships', () => {
|
||||||
icon: 'indexPatternApp',
|
icon: 'indexPatternApp',
|
||||||
inAppUrl: {
|
inAppUrl: {
|
||||||
path: '/app/management/kibana/indexPatterns/patterns/1',
|
path: '/app/management/kibana/indexPatterns/patterns/1',
|
||||||
uiCapabilitiesPath: 'management.kibana.index_patterns',
|
uiCapabilitiesPath: 'management.kibana.indexPatterns',
|
||||||
},
|
},
|
||||||
title: 'My Index Pattern',
|
title: 'My Index Pattern',
|
||||||
},
|
},
|
||||||
|
|
|
@ -41,7 +41,7 @@ const defaultProps: TableProps = {
|
||||||
editUrl: '#/management/kibana/indexPatterns/patterns/1',
|
editUrl: '#/management/kibana/indexPatterns/patterns/1',
|
||||||
inAppUrl: {
|
inAppUrl: {
|
||||||
path: '/management/kibana/indexPatterns/patterns/1',
|
path: '/management/kibana/indexPatterns/patterns/1',
|
||||||
uiCapabilitiesPath: 'management.kibana.index_patterns',
|
uiCapabilitiesPath: 'management.kibana.indexPatterns',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -68,7 +68,7 @@ const defaultProps: TableProps = {
|
||||||
editUrl: '#/management/kibana/indexPatterns/patterns/1',
|
editUrl: '#/management/kibana/indexPatterns/patterns/1',
|
||||||
inAppUrl: {
|
inAppUrl: {
|
||||||
path: '/management/kibana/indexPatterns/patterns/1',
|
path: '/management/kibana/indexPatterns/patterns/1',
|
||||||
uiCapabilitiesPath: 'management.kibana.index_patterns',
|
uiCapabilitiesPath: 'management.kibana.indexPatterns',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -158,7 +158,7 @@ describe('SavedObjectsTable', () => {
|
||||||
editUrl: '#/management/kibana/indexPatterns/patterns/1',
|
editUrl: '#/management/kibana/indexPatterns/patterns/1',
|
||||||
inAppUrl: {
|
inAppUrl: {
|
||||||
path: '/management/kibana/indexPatterns/patterns/1',
|
path: '/management/kibana/indexPatterns/patterns/1',
|
||||||
uiCapabilitiesPath: 'management.kibana.index_patterns',
|
uiCapabilitiesPath: 'management.kibana.indexPatterns',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -287,7 +287,7 @@ export default function ({ getService }: FtrProviderContext) {
|
||||||
inAppUrl: {
|
inAppUrl: {
|
||||||
path:
|
path:
|
||||||
'/app/management/kibana/indexPatterns/patterns/8963ca30-3224-11e8-a572-ffca06da1357',
|
'/app/management/kibana/indexPatterns/patterns/8963ca30-3224-11e8-a572-ffca06da1357',
|
||||||
uiCapabilitiesPath: 'management.kibana.index_patterns',
|
uiCapabilitiesPath: 'management.kibana.indexPatterns',
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -87,7 +87,7 @@ export default function ({ getService }: FtrProviderContext) {
|
||||||
inAppUrl: {
|
inAppUrl: {
|
||||||
path:
|
path:
|
||||||
'/app/management/kibana/indexPatterns/patterns/8963ca30-3224-11e8-a572-ffca06da1357',
|
'/app/management/kibana/indexPatterns/patterns/8963ca30-3224-11e8-a572-ffca06da1357',
|
||||||
uiCapabilitiesPath: 'management.kibana.index_patterns',
|
uiCapabilitiesPath: 'management.kibana.indexPatterns',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -128,7 +128,7 @@ export default function ({ getService }: FtrProviderContext) {
|
||||||
inAppUrl: {
|
inAppUrl: {
|
||||||
path:
|
path:
|
||||||
'/app/management/kibana/indexPatterns/patterns/8963ca30-3224-11e8-a572-ffca06da1357',
|
'/app/management/kibana/indexPatterns/patterns/8963ca30-3224-11e8-a572-ffca06da1357',
|
||||||
uiCapabilitiesPath: 'management.kibana.index_patterns',
|
uiCapabilitiesPath: 'management.kibana.indexPatterns',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
relationship: 'child',
|
relationship: 'child',
|
||||||
|
|
|
@ -240,11 +240,11 @@ Array [
|
||||||
"kibana",
|
"kibana",
|
||||||
],
|
],
|
||||||
"catalogue": Array [
|
"catalogue": Array [
|
||||||
"index_patterns",
|
"indexPatterns",
|
||||||
],
|
],
|
||||||
"management": Object {
|
"management": Object {
|
||||||
"kibana": Array [
|
"kibana": Array [
|
||||||
"index_patterns",
|
"indexPatterns",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
"savedObject": Object {
|
"savedObject": Object {
|
||||||
|
@ -265,11 +265,11 @@ Array [
|
||||||
"kibana",
|
"kibana",
|
||||||
],
|
],
|
||||||
"catalogue": Array [
|
"catalogue": Array [
|
||||||
"index_patterns",
|
"indexPatterns",
|
||||||
],
|
],
|
||||||
"management": Object {
|
"management": Object {
|
||||||
"kibana": Array [
|
"kibana": Array [
|
||||||
"index_patterns",
|
"indexPatterns",
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
"savedObject": Object {
|
"savedObject": Object {
|
||||||
|
|
|
@ -294,16 +294,16 @@ export const buildOSSFeatures = ({ savedObjectTypes, includeTimelion }: BuildOSS
|
||||||
order: 1600,
|
order: 1600,
|
||||||
icon: 'indexPatternApp',
|
icon: 'indexPatternApp',
|
||||||
app: ['kibana'],
|
app: ['kibana'],
|
||||||
catalogue: ['index_patterns'],
|
catalogue: ['indexPatterns'],
|
||||||
management: {
|
management: {
|
||||||
kibana: ['index_patterns'],
|
kibana: ['indexPatterns'],
|
||||||
},
|
},
|
||||||
privileges: {
|
privileges: {
|
||||||
all: {
|
all: {
|
||||||
app: ['kibana'],
|
app: ['kibana'],
|
||||||
catalogue: ['index_patterns'],
|
catalogue: ['indexPatterns'],
|
||||||
management: {
|
management: {
|
||||||
kibana: ['index_patterns'],
|
kibana: ['indexPatterns'],
|
||||||
},
|
},
|
||||||
savedObject: {
|
savedObject: {
|
||||||
all: ['index-pattern'],
|
all: ['index-pattern'],
|
||||||
|
@ -313,9 +313,9 @@ export const buildOSSFeatures = ({ savedObjectTypes, includeTimelion }: BuildOSS
|
||||||
},
|
},
|
||||||
read: {
|
read: {
|
||||||
app: ['kibana'],
|
app: ['kibana'],
|
||||||
catalogue: ['index_patterns'],
|
catalogue: ['indexPatterns'],
|
||||||
management: {
|
management: {
|
||||||
kibana: ['index_patterns'],
|
kibana: ['indexPatterns'],
|
||||||
},
|
},
|
||||||
savedObject: {
|
savedObject: {
|
||||||
all: [],
|
all: [],
|
||||||
|
|
|
@ -9,7 +9,6 @@ import { coreMock } from 'src/core/public/mocks';
|
||||||
import { spacesManagerMock } from '../spaces_manager/mocks';
|
import { spacesManagerMock } from '../spaces_manager/mocks';
|
||||||
import { managementPluginMock } from '../../../../../src/plugins/management/public/mocks';
|
import { managementPluginMock } from '../../../../../src/plugins/management/public/mocks';
|
||||||
import { ManagementSection } from 'src/plugins/management/public';
|
import { ManagementSection } from 'src/plugins/management/public';
|
||||||
import { Capabilities } from 'kibana/public';
|
|
||||||
import { PluginsStart } from '../plugin';
|
import { PluginsStart } from '../plugin';
|
||||||
import { CoreSetup } from 'src/core/public';
|
import { CoreSetup } from 'src/core/public';
|
||||||
|
|
||||||
|
@ -58,66 +57,6 @@ describe('ManagementService', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#start', () => {
|
|
||||||
it('disables the spaces management page if the user is not authorized', () => {
|
|
||||||
const mockSpacesManagementPage = { disable: jest.fn() };
|
|
||||||
const mockKibanaSection = ({
|
|
||||||
registerApp: jest.fn().mockReturnValue(mockSpacesManagementPage),
|
|
||||||
} as unknown) as ManagementSection;
|
|
||||||
|
|
||||||
const deps = {
|
|
||||||
management: managementPluginMock.createSetupContract(),
|
|
||||||
getStartServices: coreMock.createSetup().getStartServices as CoreSetup<
|
|
||||||
PluginsStart
|
|
||||||
>['getStartServices'],
|
|
||||||
spacesManager: spacesManagerMock.create(),
|
|
||||||
};
|
|
||||||
|
|
||||||
deps.management.sections.getSection.mockImplementation((id) => {
|
|
||||||
if (id === 'kibana') return mockKibanaSection;
|
|
||||||
throw new Error(`unexpected getSection call: ${id}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
const service = new ManagementService();
|
|
||||||
service.setup(deps);
|
|
||||||
|
|
||||||
const capabilities = ({ spaces: { manage: false } } as unknown) as Capabilities;
|
|
||||||
service.start({ capabilities });
|
|
||||||
|
|
||||||
expect(mockKibanaSection.registerApp).toHaveBeenCalledTimes(1);
|
|
||||||
expect(mockSpacesManagementPage.disable).toHaveBeenCalledTimes(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('does not disable the spaces management page if the user is authorized', () => {
|
|
||||||
const mockSpacesManagementPage = { disable: jest.fn() };
|
|
||||||
const mockKibanaSection = ({
|
|
||||||
registerApp: jest.fn().mockReturnValue(mockSpacesManagementPage),
|
|
||||||
} as unknown) as ManagementSection;
|
|
||||||
|
|
||||||
const deps = {
|
|
||||||
management: managementPluginMock.createSetupContract(),
|
|
||||||
getStartServices: coreMock.createSetup().getStartServices as CoreSetup<
|
|
||||||
PluginsStart
|
|
||||||
>['getStartServices'],
|
|
||||||
spacesManager: spacesManagerMock.create(),
|
|
||||||
};
|
|
||||||
|
|
||||||
deps.management.sections.getSection.mockImplementation((id) => {
|
|
||||||
if (id === 'kibana') return mockKibanaSection;
|
|
||||||
throw new Error(`unexpected getSection call: ${id}`);
|
|
||||||
});
|
|
||||||
|
|
||||||
const service = new ManagementService();
|
|
||||||
service.setup(deps);
|
|
||||||
|
|
||||||
const capabilities = ({ spaces: { manage: true } } as unknown) as Capabilities;
|
|
||||||
service.start({ capabilities });
|
|
||||||
|
|
||||||
expect(mockKibanaSection.registerApp).toHaveBeenCalledTimes(1);
|
|
||||||
expect(mockSpacesManagementPage.disable).toHaveBeenCalledTimes(0);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('#stop', () => {
|
describe('#stop', () => {
|
||||||
it('disables the spaces management page', () => {
|
it('disables the spaces management page', () => {
|
||||||
const mockSpacesManagementPage = { disable: jest.fn() };
|
const mockSpacesManagementPage = { disable: jest.fn() };
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* you may not use this file except in compliance with the Elastic License.
|
* you may not use this file except in compliance with the Elastic License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { StartServicesAccessor, Capabilities } from 'src/core/public';
|
import { StartServicesAccessor } from 'src/core/public';
|
||||||
import {
|
import {
|
||||||
ManagementSetup,
|
ManagementSetup,
|
||||||
ManagementApp,
|
ManagementApp,
|
||||||
|
@ -22,9 +22,6 @@ interface SetupDeps {
|
||||||
securityLicense?: SecurityLicense;
|
securityLicense?: SecurityLicense;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface StartDeps {
|
|
||||||
capabilities: Capabilities;
|
|
||||||
}
|
|
||||||
export class ManagementService {
|
export class ManagementService {
|
||||||
private registeredSpacesManagementApp?: ManagementApp;
|
private registeredSpacesManagementApp?: ManagementApp;
|
||||||
|
|
||||||
|
@ -36,12 +33,6 @@ export class ManagementService {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public start({ capabilities }: StartDeps) {
|
|
||||||
if (!capabilities.spaces.manage) {
|
|
||||||
this.disableSpacesApp();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public stop() {
|
public stop() {
|
||||||
this.disableSpacesApp();
|
this.disableSpacesApp();
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,10 +87,6 @@ export class SpacesPlugin implements Plugin<SpacesPluginSetup, SpacesPluginStart
|
||||||
public start(core: CoreStart, plugins: PluginsStart) {
|
public start(core: CoreStart, plugins: PluginsStart) {
|
||||||
initSpacesNavControl(this.spacesManager, core);
|
initSpacesNavControl(this.spacesManager, core);
|
||||||
|
|
||||||
if (this.managementService) {
|
|
||||||
this.managementService.start({ capabilities: core.application.capabilities });
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
activeSpace$: this.spacesManager.onActiveSpaceChange$,
|
activeSpace$: this.spacesManager.onActiveSpaceChange$,
|
||||||
getActiveSpace: () => this.spacesManager.getActiveSpace(),
|
getActiveSpace: () => this.spacesManager.getActiveSpace(),
|
||||||
|
|
|
@ -138,8 +138,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// FLAKY: https://github.com/elastic/kibana/issues/57377
|
describe('no advanced_settings privileges', function () {
|
||||||
describe.skip('no advanced_settings privileges', function () {
|
|
||||||
before(async () => {
|
before(async () => {
|
||||||
await security.role.create('no_advanced_settings_privileges_role', {
|
await security.role.create('no_advanced_settings_privileges_role', {
|
||||||
elasticsearch: {
|
elasticsearch: {
|
||||||
|
|
|
@ -182,8 +182,10 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
||||||
|
|
||||||
it(`doesn't show Index Patterns in management side-nav`, async () => {
|
it(`doesn't show Index Patterns in management side-nav`, async () => {
|
||||||
await PageObjects.settings.navigateTo();
|
await PageObjects.settings.navigateTo();
|
||||||
await testSubjects.existOrFail('kibana');
|
await testSubjects.existOrFail('managementHome', {
|
||||||
await testSubjects.missingOrFail('index_patterns');
|
timeout: config.get('timeouts.waitFor'),
|
||||||
|
});
|
||||||
|
await testSubjects.missingOrFail('indexPatterns');
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`does not allow navigation to Index Patterns; redirects to management home`, async () => {
|
it(`does not allow navigation to Index Patterns; redirects to management home`, async () => {
|
||||||
|
|
|
@ -310,19 +310,25 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('listing', () => {
|
describe('listing', () => {
|
||||||
it('redirects to Kibana home', async () => {
|
it(`doesn't display management section`, async () => {
|
||||||
|
await PageObjects.settings.navigateTo();
|
||||||
|
await testSubjects.existOrFail('managementHome'); // this ensures we've gotten to the management page
|
||||||
|
await testSubjects.missingOrFail('objects');
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`can't navigate to listing page`, async () => {
|
||||||
await PageObjects.common.navigateToUrl('management', 'kibana/objects', {
|
await PageObjects.common.navigateToUrl('management', 'kibana/objects', {
|
||||||
ensureCurrentUrl: false,
|
ensureCurrentUrl: false,
|
||||||
shouldLoginIfPrompted: false,
|
shouldLoginIfPrompted: false,
|
||||||
shouldUseHashForSubUrl: false,
|
shouldUseHashForSubUrl: false,
|
||||||
});
|
});
|
||||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
|
||||||
await testSubjects.existOrFail('homeApp');
|
await testSubjects.existOrFail('managementHome');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('edit visualization', () => {
|
describe('edit visualization', () => {
|
||||||
it('redirects to Kibana home', async () => {
|
it('redirects to management home', async () => {
|
||||||
await PageObjects.common.navigateToUrl(
|
await PageObjects.common.navigateToUrl(
|
||||||
'management',
|
'management',
|
||||||
'kibana/objects/savedVisualizations/75c3e060-1e7c-11e9-8488-65449e65d0ed',
|
'kibana/objects/savedVisualizations/75c3e060-1e7c-11e9-8488-65449e65d0ed',
|
||||||
|
@ -333,7 +339,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
await PageObjects.header.waitUntilLoadingHasFinished();
|
await PageObjects.header.waitUntilLoadingHasFinished();
|
||||||
await testSubjects.existOrFail('homeApp');
|
await testSubjects.existOrFail('managementHome');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue