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:
Thomas Draebing
2019-08-22 16:46:39 +02:00
committed by David Pursehouse
parent e46d5ae7fd
commit 7880b0bc64
6 changed files with 73 additions and 8 deletions

View File

@@ -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.

View File

@@ -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,
})));

View File

@@ -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>

View File

@@ -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,

View File

@@ -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() {

View File

@@ -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>