Skip to content
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

Only link to nav items that user has access to #7590

Merged
merged 9 commits into from
Oct 30, 2019
6 changes: 4 additions & 2 deletions ui/app/helpers/has-permission.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ export default Helper.extend({
}
),

compute([route], { routeParams, capability }) {
compute([route], params) {
let { routeParams } = params;
let permissions = this.permissions;
return permissions.hasNavPermission(route, routeParams, capability);

return permissions.hasNavPermission(route, routeParams);
},
});
14 changes: 9 additions & 5 deletions ui/app/services/permissions.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,12 @@ const API_PATHS_TO_ROUTE_PARAMS = {
};

/*
The Permissions service is used to gate top navigation and sidebar items. It fetches
a users' policy from the resultant-acl endpoint and stores their allowed exact and glob
paths as state. It also has methods for checking whether a user has permission for a given
path.
The Permissions service is used to gate top navigation and sidebar items.
It fetches a users' policy from the resultant-acl endpoint and stores their
allowed exact and glob paths as state. It also has methods for checking whether
a user has permission for a given path.
*/

export default Service.extend({
exactPaths: null,
globPaths: null,
Expand Down Expand Up @@ -88,7 +89,10 @@ export default Service.extend({

hasNavPermission(navItem, routeParams) {
if (routeParams) {
return this.hasPermission(API_PATHS[navItem][routeParams]);
// viewing the entity and groups pages require the list capability, while the others require the default, which is anything other than deny
let capability = routeParams === 'entities' || routeParams === 'groups' ? ['list'] : [null];

return this.hasPermission(API_PATHS[navItem][routeParams], capability);
}
return Object.values(API_PATHS[navItem]).some(path => this.hasPermission(path));
},
Expand Down
22 changes: 15 additions & 7 deletions ui/tests/unit/services/permissions-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,24 +157,32 @@ module('Unit | Service | permissions', function(hooks) {
assert.deepEqual(service.navPathParams('access'), expected);
});

test('hasNavPermission returns true if a policy includes access to at least one path', function(assert) {
test('hasNavPermission returns true if a policy includes the required capabilities for at least one path', function(assert) {
let service = this.owner.lookup('service:permissions');
const accessPaths = {
'sys/auth': {
capabilities: ['deny'],
},
'sys/leases/lookup': {
capabilities: ['read'],
'identity/group/id': {
capabilities: ['list', 'read'],
},
};
service.set('exactPaths', accessPaths);
assert.equal(service.hasNavPermission('access', 'leases'), true);
assert.equal(service.hasNavPermission('access', 'groups'), true);
});

test('hasNavPermission returns false if a policy does not include access to any paths', function(assert) {
test('hasNavPermission returns false if a policy does not include the required capabilities for at least one path', function(assert) {
let service = this.owner.lookup('service:permissions');
service.set('exactPaths', {});
assert.equal(service.hasNavPermission('access'), false);
const accessPaths = {
'sys/auth': {
capabilities: ['deny'],
},
'identity/group/id': {
capabilities: ['read'],
},
};
service.set('exactPaths', accessPaths);
assert.equal(service.hasNavPermission('access', 'groups'), false);
});

test('appends the namespace to the path if there is one', function(assert) {
Expand Down