Add capability check when adding plugin entries to admin nav
So far, when adding entries for plugins to the admin navigation, they were always visible for all logged in users. In some cases, this might not be desirable. This change adds an optional parameter to the AdminApi().addMenuLink() API for plugins, that allows to set a capability a user must have to see the menu entry. If no capability is set, the menu entry will be visible to all logged in users as before. Change-Id: I463d6ec8b9fcf360318255f7785bdf8cc52b00bb
This commit is contained in:

committed by
David Pursehouse

parent
e46d5ae7fd
commit
7880b0bc64
@@ -4,7 +4,7 @@ This API is provided by link:pg-plugin-dev.html#plugin-admin[plugin.admin()]
|
||||
and provides customization of the admin menu.
|
||||
|
||||
== addMenuLink
|
||||
`adminApi.addMenuLink(text, url, opt_external)`
|
||||
`adminApi.addMenuLink(text, url, opt_external, opt_capabilities)`
|
||||
|
||||
Add a new link to the end of the admin navigation menu.
|
||||
|
||||
|
@@ -18,8 +18,6 @@ limitations under the License.
|
||||
(function(window) {
|
||||
'use strict';
|
||||
|
||||
const ACCOUNT_CAPABILITIES = ['createProject', 'createGroup', 'viewPlugins'];
|
||||
|
||||
const ADMIN_LINKS = [{
|
||||
name: 'Repositories',
|
||||
noBaseUrl: true,
|
||||
@@ -65,7 +63,7 @@ limitations under the License.
|
||||
return Promise.resolve(this._filterLinks(link => link.viewableToAll,
|
||||
getAdminMenuLinks, opt_options));
|
||||
}
|
||||
return getAccountCapabilities(ACCOUNT_CAPABILITIES)
|
||||
return getAccountCapabilities()
|
||||
.then(capabilities => {
|
||||
return this._filterLinks(link => {
|
||||
return !link.capability ||
|
||||
@@ -97,9 +95,10 @@ limitations under the License.
|
||||
links.push(...getAdminMenuLinks().map(link => ({
|
||||
url: link.url,
|
||||
name: link.text,
|
||||
capability: link.capability || null,
|
||||
noBaseUrl: !isExernalLink(link),
|
||||
view: null,
|
||||
viewableToAll: true,
|
||||
viewableToAll: !link.capability,
|
||||
target: isExernalLink(link) ? '_blank' : null,
|
||||
})));
|
||||
|
||||
|
@@ -308,5 +308,61 @@ limitations under the License.
|
||||
testAdminLinks(account, options, expected, done);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
suite('view plugin screen with plugin capability', () => {
|
||||
const account = {
|
||||
name: 'test-user',
|
||||
};
|
||||
let expected;
|
||||
|
||||
setup(() => {
|
||||
capabilityStub.returns(Promise.resolve({pluginCapability: true}));
|
||||
expected = {};
|
||||
});
|
||||
|
||||
test('with plugin with capabilities', done => {
|
||||
let options;
|
||||
const generatedLinks = [
|
||||
{text: 'without capability', url: '/without'},
|
||||
{text: 'with capability', url: '/with', capability: 'pluginCapability'},
|
||||
];
|
||||
menuLinkStub.returns(generatedLinks);
|
||||
expected = Object.assign(expected, {
|
||||
totalLength: 4,
|
||||
pluginGeneratedLinks: generatedLinks,
|
||||
});
|
||||
testAdminLinks(account, options, expected, done);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
suite('view plugin screen without plugin capability', () => {
|
||||
const account = {
|
||||
name: 'test-user',
|
||||
};
|
||||
let expected;
|
||||
|
||||
setup(() => {
|
||||
capabilityStub.returns(Promise.resolve({}));
|
||||
expected = {};
|
||||
});
|
||||
|
||||
test('with plugin with capabilities', done => {
|
||||
let options;
|
||||
const generatedLinks = [
|
||||
{text: 'without capability', url: '/without'},
|
||||
{text: 'with capability',
|
||||
url: '/with',
|
||||
capability: 'pluginCapability'},
|
||||
];
|
||||
menuLinkStub.returns(generatedLinks);
|
||||
expected = Object.assign(expected, {
|
||||
totalLength: 3,
|
||||
pluginGeneratedLinks: [generatedLinks[0]],
|
||||
});
|
||||
testAdminLinks(account, options, expected, done);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
@@ -158,6 +158,7 @@ limitations under the License.
|
||||
return element.reload().then(() => {
|
||||
assert.equal(element._filteredLinks.length, 3);
|
||||
assert.deepEqual(element._filteredLinks[1], {
|
||||
capability: null,
|
||||
url: '/internal/link/url',
|
||||
name: 'internal link text',
|
||||
noBaseUrl: true,
|
||||
@@ -166,6 +167,7 @@ limitations under the License.
|
||||
target: null,
|
||||
});
|
||||
assert.deepEqual(element._filteredLinks[2], {
|
||||
capability: null,
|
||||
url: 'http://external/link/url',
|
||||
name: 'external link text',
|
||||
noBaseUrl: false,
|
||||
|
@@ -30,8 +30,8 @@
|
||||
* @param {string} text
|
||||
* @param {string} url
|
||||
*/
|
||||
GrAdminApi.prototype.addMenuLink = function(text, url) {
|
||||
this._menuLinks.push({text, url});
|
||||
GrAdminApi.prototype.addMenuLink = function(text, url, opt_capability) {
|
||||
this._menuLinks.push({text, url, capability: opt_capability || null});
|
||||
};
|
||||
|
||||
GrAdminApi.prototype.getMenuLinks = function() {
|
||||
|
@@ -54,7 +54,15 @@ limitations under the License.
|
||||
adminApi.addMenuLink('text', 'url');
|
||||
const links = adminApi.getMenuLinks();
|
||||
assert.equal(links.length, 1);
|
||||
assert.deepEqual(links[0], {text: 'text', url: 'url'});
|
||||
assert.deepEqual(links[0], {text: 'text', url: 'url', capability: null});
|
||||
});
|
||||
|
||||
test('addMenuLinkWithCapability', () => {
|
||||
adminApi.addMenuLink('text', 'url', 'capability');
|
||||
const links = adminApi.getMenuLinks();
|
||||
assert.equal(links.length, 1);
|
||||
assert.deepEqual(links[0],
|
||||
{text: 'text', url: 'url', capability: 'capability'});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
Reference in New Issue
Block a user