-
Notifications
You must be signed in to change notification settings - Fork 8.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enables the feature catalogue registry to be controlled via uiCapabil… #27945
Changes from all commits
a18b4c9
2dd79ee
a8d15a2
9746f98
cbb433e
dcb3dbc
602b809
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
/* | ||
* Licensed to Elasticsearch B.V. under one or more contributor | ||
* license agreements. See the NOTICE file distributed with | ||
* this work for additional information regarding copyright | ||
* ownership. Elasticsearch B.V. licenses this file to you under | ||
* the Apache License, Version 2.0 (the "License"); you may | ||
* not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, | ||
* software distributed under the License is distributed on an | ||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
* KIND, either express or implied. See the License for the | ||
* specific language governing permissions and limitations | ||
* under the License. | ||
*/ | ||
jest.mock('ui/chrome', () => ({ | ||
getInjected: key => { | ||
if (key === 'uiCapabilities') { | ||
return { | ||
navLinks: {}, | ||
management: {}, | ||
catalogue: { | ||
item1: true, | ||
item2: false, | ||
item3: true, | ||
}, | ||
}; | ||
} | ||
throw new Error(`Unexpected call to chrome.getInjected with key ${key}`); | ||
}, | ||
})); | ||
import { FeatureCatalogueCategory, FeatureCatalogueRegistryProvider } from './feature_catalogue'; | ||
|
||
describe('FeatureCatalogueRegistryProvider', () => { | ||
|
||
beforeAll(() => { | ||
FeatureCatalogueRegistryProvider.register(() => { | ||
return { | ||
id: 'item1', | ||
title: 'foo', | ||
description: 'this is foo', | ||
icon: 'savedObjectsApp', | ||
path: '/app/kibana#/management/kibana/objects', | ||
showOnHomePage: true, | ||
category: FeatureCatalogueCategory.ADMIN, | ||
}; | ||
}); | ||
|
||
FeatureCatalogueRegistryProvider.register(() => { | ||
return { | ||
id: 'item2', | ||
title: 'bar', | ||
description: 'this is bar', | ||
icon: 'savedObjectsApp', | ||
path: '/app/kibana#/management/kibana/objects', | ||
showOnHomePage: true, | ||
category: FeatureCatalogueCategory.ADMIN, | ||
}; | ||
}); | ||
|
||
// intentionally not listed in uiCapabilities.catalogue above | ||
FeatureCatalogueRegistryProvider.register(() => { | ||
return { | ||
id: 'item4', | ||
title: 'secret', | ||
description: 'this is a secret', | ||
icon: 'savedObjectsApp', | ||
path: '/app/kibana#/management/kibana/objects', | ||
showOnHomePage: true, | ||
category: FeatureCatalogueCategory.ADMIN, | ||
}; | ||
}); | ||
}); | ||
|
||
it('should not return items hidden by uiCapabilities', () => { | ||
const mockPrivate = entityFn => entityFn(); | ||
const mockInjector = () => null; | ||
|
||
// eslint-disable-next-line new-cap | ||
const foo = FeatureCatalogueRegistryProvider(mockPrivate, mockInjector).inTitleOrder; | ||
expect(foo).toEqual([{ | ||
id: 'item1', | ||
title: 'foo', | ||
description: 'this is foo', | ||
icon: 'savedObjectsApp', | ||
path: '/app/kibana#/management/kibana/objects', | ||
showOnHomePage: true, | ||
category: FeatureCatalogueCategory.ADMIN, | ||
}, { | ||
id: 'item4', | ||
title: 'secret', | ||
description: 'this is a secret', | ||
icon: 'savedObjectsApp', | ||
path: '/app/kibana#/management/kibana/objects', | ||
showOnHomePage: true, | ||
category: FeatureCatalogueCategory.ADMIN, | ||
}]); | ||
}); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -76,6 +76,7 @@ export function apm(kibana) { | |
navLinkId: 'apm', | ||
privileges: { | ||
all: { | ||
catalogue: ['apm'], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What does this do? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This tells the feature controls (the project formerly known as Granular Application Privileges) when to remove the "APM" listing from the Kibana homepage. If the current user doesn't have access** to APM, then we remove the APM listing from the ** determining access is rather tricky for an app like APM, which relies on cluster/index privileges. Here, "access" means that the application is enabled in the user's current space, and that the user's roles haven't disabled the application from appearing with Kibana. This is all still WIP, but that's the idea. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good. Thanks for enlightening me :) |
||
app: ['apm'], | ||
savedObject: { | ||
all: [], | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,6 +42,7 @@ export default async function(server /*options*/) { | |
navLinkId: 'canvas', | ||
privileges: { | ||
all: { | ||
catalogue: ['canvas'], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I had to be consistent with our OG implementation 😄 |
||
app: ['canvas'], | ||
savedObject: { | ||
all: ['canvas'], | ||
|
@@ -50,6 +51,7 @@ export default async function(server /*options*/) { | |
ui: [], | ||
}, | ||
read: { | ||
catalogue: ['canvas'], | ||
app: ['canvas'], | ||
savedObject: { | ||
all: [], | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -88,6 +88,7 @@ describe('usingPrivileges', () => { | |
indices: true, | ||
}, | ||
}, | ||
catalogue: {}, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. All of these test are using an empty There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Catalogue entries, much like management entries, are registered client-side, so the Kibana server doesn't have a complete list of them. The only catalogue entries we deal with are the ones explicitly registered via features. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Gotcha, thanks for the clarification. |
||
fooFeature: { | ||
foo: true, | ||
bar: true, | ||
|
@@ -109,6 +110,7 @@ describe('usingPrivileges', () => { | |
indices: false, | ||
}, | ||
}, | ||
catalogue: {}, | ||
fooFeature: { | ||
foo: false, | ||
bar: false, | ||
|
@@ -169,6 +171,7 @@ describe('usingPrivileges', () => { | |
indices: true, | ||
}, | ||
}, | ||
catalogue: {}, | ||
fooFeature: { | ||
foo: true, | ||
bar: true, | ||
|
@@ -190,6 +193,7 @@ describe('usingPrivileges', () => { | |
indices: false, | ||
}, | ||
}, | ||
catalogue: {}, | ||
fooFeature: { | ||
foo: false, | ||
bar: false, | ||
|
@@ -239,6 +243,7 @@ describe('usingPrivileges', () => { | |
indices: true, | ||
}, | ||
}, | ||
catalogue: {}, | ||
}) | ||
).rejects.toThrowErrorMatchingSnapshot(); | ||
expect(mockServer.log).not.toHaveBeenCalled(); | ||
|
@@ -291,6 +296,7 @@ describe('usingPrivileges', () => { | |
settings: false, | ||
}, | ||
}, | ||
catalogue: {}, | ||
fooFeature: { | ||
foo: true, | ||
bar: true, | ||
|
@@ -314,6 +320,7 @@ describe('usingPrivileges', () => { | |
settings: false, | ||
}, | ||
}, | ||
catalogue: {}, | ||
fooFeature: { | ||
foo: true, | ||
bar: false, | ||
|
@@ -367,6 +374,7 @@ describe('usingPrivileges', () => { | |
indices: false, | ||
}, | ||
}, | ||
catalogue: {}, | ||
fooFeature: { | ||
foo: false, | ||
bar: false, | ||
|
@@ -388,6 +396,7 @@ describe('usingPrivileges', () => { | |
indices: false, | ||
}, | ||
}, | ||
catalogue: {}, | ||
fooFeature: { | ||
foo: false, | ||
bar: false, | ||
|
@@ -427,6 +436,7 @@ describe('all', () => { | |
indices: true, | ||
}, | ||
}, | ||
catalogue: {}, | ||
fooFeature: { | ||
foo: true, | ||
bar: true, | ||
|
@@ -447,6 +457,7 @@ describe('all', () => { | |
indices: false, | ||
}, | ||
}, | ||
catalogue: {}, | ||
fooFeature: { | ||
foo: false, | ||
bar: false, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🥇