Add an ability for client permissions

This commit is contained in:
Michael Lange 2020-01-27 15:19:03 -08:00
parent 1d8f1ee473
commit 1fae4083eb
2 changed files with 113 additions and 0 deletions

View File

@ -0,0 +1,25 @@
import { Ability } from 'ember-can';
import { inject as service } from '@ember/service';
import { computed, get } from '@ember/object';
import { equal, or } from '@ember/object/computed';
export default Ability.extend({
token: service(),
// Map abilities to policy options (which are coarse for nodes)
// instead of specific behaviors.
canWrite: or('selfTokenIsManagement', 'policiesIncludeNodeWrite'),
selfTokenIsManagement: equal('token.selfToken.type', 'management'),
policiesIncludeNodeWrite: computed('token.selfTokenPolicies.[]', function() {
// For each policy record, extract the Node policy
const policies = (this.get('token.selfTokenPolicies') || [])
.toArray()
.map(policy => get(policy, 'rulesJSON.Node.Policy'))
.compact();
// Node write is allowed if any policy allows it
return policies.some(policy => policy === 'write');
}),
});

View File

@ -0,0 +1,88 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import Service from '@ember/service';
function setupAbility(ability, hooks) {
hooks.beforeEach(function() {
this.ability = this.owner.lookup(`ability:${ability}`);
});
hooks.afterEach(function() {
delete this.ability;
});
}
module('Unit | Ability | client', function(hooks) {
setupTest(hooks);
setupAbility('client', hooks);
test('it permits client write for management tokens', function(assert) {
const mockToken = Service.extend({
selfToken: { type: 'management' },
});
this.owner.register('service:token', mockToken);
assert.ok(this.ability.canWrite);
});
test('it permits client write for tokens with a policy that has node-write', function(assert) {
const mockToken = Service.extend({
selfToken: { type: 'client' },
selfTokenPolicies: [
{
rulesJSON: {
Node: {
Policy: 'write',
},
},
},
],
});
this.owner.register('service:token', mockToken);
assert.ok(this.ability.canWrite);
});
test('it permits client write for tokens with a policy that allows write and another policy that disallows it', function(assert) {
const mockToken = Service.extend({
selfToken: { type: 'client' },
selfTokenPolicies: [
{
rulesJSON: {
Node: {
Policy: 'write',
},
},
},
{
rulesJSON: {
Node: {
Policy: 'read',
},
},
},
],
});
this.owner.register('service:token', mockToken);
assert.ok(this.ability.canWrite);
});
test('it blocks client write for tokens with a policy that does not allow node-write', function(assert) {
const mockToken = Service.extend({
selfToken: { type: 'client' },
selfTokenPolicies: [
{
rulesJSON: {
Node: {
Policy: 'read',
},
},
},
],
});
this.owner.register('service:token', mockToken);
assert.notOk(this.ability.canWrite);
});
});