ui: add "read client" ability

This commit is contained in:
Luiz Aoqui
2021-12-13 16:56:58 -05:00
committed by Jai Bhagat
parent 1a9b70688a
commit 0eff35dde0
2 changed files with 51 additions and 13 deletions

View File

@@ -7,6 +7,9 @@ import classic from 'ember-classic-decorator';
export default class Client extends AbstractAbility {
// Map abilities to policy options (which are coarse for nodes)
// instead of specific behaviors.
@or('bypassAuthorization', 'selfTokenIsManagement', 'policiesIncludeNodeRead')
canRead;
@or(
'bypassAuthorization',
'selfTokenIsManagement',
@@ -15,14 +18,28 @@ export default class Client extends AbstractAbility {
canWrite;
@computed('token.selfTokenPolicies.[]')
get policiesIncludeNodeWrite() {
// For each policy record, extract the Node policy
const policies = (this.get('token.selfTokenPolicies') || [])
.toArray()
.map((policy) => get(policy, 'rulesJSON.Node.Policy'))
.compact();
get policiesIncludeNodeRead() {
return policiesIncludePermissions(this.get('token.selfTokenPolicies'), [
'read',
'write',
]);
}
// Node write is allowed if any policy allows it
return policies.some((policy) => policy === 'write');
@computed('token.selfTokenPolicies.[]')
get policiesIncludeNodeWrite() {
return policiesIncludePermissions(this.get('token.selfTokenPolicies'), [
'write',
]);
}
}
function policiesIncludePermissions(policies = [], permissions = []) {
// For each policy record, extract the Node policy
const nodePolicies = policies
.toArray()
.map((policy) => get(policy, 'rulesJSON.Node.Policy'))
.compact();
// Check for requested permissions
return nodePolicies.some((policy) => permissions.includes(policy));
}

View File

@@ -8,26 +8,28 @@ module('Unit | Ability | client', function (hooks) {
setupTest(hooks);
setupAbility('client')(hooks);
test('it permits client write when ACLs are disabled', function (assert) {
test('it permits client read and write when ACLs are disabled', function (assert) {
const mockToken = Service.extend({
aclEnabled: false,
});
this.owner.register('service:token', mockToken);
assert.ok(this.ability.canRead);
assert.ok(this.ability.canWrite);
});
test('it permits client write for management tokens', function (assert) {
test('it permits client read and write for management tokens', function (assert) {
const mockToken = Service.extend({
aclEnabled: true,
selfToken: { type: 'management' },
});
this.owner.register('service:token', mockToken);
assert.ok(this.ability.canRead);
assert.ok(this.ability.canWrite);
});
test('it permits client write for tokens with a policy that has node-write', function (assert) {
test('it permits client read and write for tokens with a policy that has node-write', function (assert) {
const mockToken = Service.extend({
aclEnabled: true,
selfToken: { type: 'client' },
@@ -43,10 +45,11 @@ module('Unit | Ability | client', function (hooks) {
});
this.owner.register('service:token', mockToken);
assert.ok(this.ability.canRead);
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) {
test('it permits client read and write for tokens with a policy that allows write and another policy that disallows it', function (assert) {
const mockToken = Service.extend({
aclEnabled: true,
selfToken: { type: 'client' },
@@ -69,10 +72,11 @@ module('Unit | Ability | client', function (hooks) {
});
this.owner.register('service:token', mockToken);
assert.ok(this.ability.canRead);
assert.ok(this.ability.canWrite);
});
test('it blocks client write for tokens with a policy that does not allow node-write', function (assert) {
test('it permits client read and blocks client write for tokens with a policy that does not allow node-write', function (assert) {
const mockToken = Service.extend({
aclEnabled: true,
selfToken: { type: 'client' },
@@ -88,6 +92,23 @@ module('Unit | Ability | client', function (hooks) {
});
this.owner.register('service:token', mockToken);
assert.ok(this.ability.canRead);
assert.notOk(this.ability.canWrite);
});
test('it blocks client read and write for tokens without a node policy', function (assert) {
const mockToken = Service.extend({
aclEnabled: true,
selfToken: { type: 'client' },
selfTokenPolicies: [
{
rulesJSON: {},
},
],
});
this.owner.register('service:token', mockToken);
assert.notOk(this.ability.canRead);
assert.notOk(this.ability.canWrite);
});
});