[ui] "can list variables" capability refactor (#13996)
* Check against all your policies' namespaces' secvars' paths' capabilities to see if you can list vars * Changelog and lintfix * Unit tests for list-vars * Removed unused computed dep * Changelog removed
This commit is contained in:
parent
eb933ad27d
commit
4283608bbf
|
@ -1,3 +1,4 @@
|
|||
// @ts-check
|
||||
import { computed, get } from '@ember/object';
|
||||
import { or } from '@ember/object/computed';
|
||||
import AbstractAbility from './abstract';
|
||||
|
@ -20,7 +21,7 @@ export default class Variable extends AbstractAbility {
|
|||
@or(
|
||||
'bypassAuthorization',
|
||||
'selfTokenIsManagement',
|
||||
'policiesSupportVariableView'
|
||||
'policiesSupportVariableList'
|
||||
)
|
||||
canList;
|
||||
|
||||
|
@ -38,10 +39,48 @@ export default class Variable extends AbstractAbility {
|
|||
)
|
||||
canDestroy;
|
||||
|
||||
@computed('rulesForNamespace.@each.capabilities')
|
||||
get policiesSupportVariableView() {
|
||||
return this.rulesForNamespace.some((rules) => {
|
||||
return get(rules, 'SecureVariables');
|
||||
@computed('token.selfTokenPolicies')
|
||||
get policiesSupportVariableList() {
|
||||
return this.policyNamespacesIncludeSecureVariablesCapabilities(
|
||||
this.token.selfTokenPolicies,
|
||||
['list', 'read', 'write', 'destroy']
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Map to your policy's namespaces,
|
||||
* and each of their SecureVariables blocks' paths,
|
||||
* and each of their capabilities.
|
||||
* Then, check to see if any of the permissions you're looking for
|
||||
* are contained within at least one of them.
|
||||
*
|
||||
* @param {Object} policies
|
||||
* @param {string[]} capabilities
|
||||
* @returns {boolean}
|
||||
*/
|
||||
policyNamespacesIncludeSecureVariablesCapabilities(
|
||||
policies = [],
|
||||
capabilities = []
|
||||
) {
|
||||
const namespacesWithSecureVariableCapabilities = policies
|
||||
.toArray()
|
||||
.map((policy) => get(policy, 'rulesJSON.Namespaces'))
|
||||
.flat()
|
||||
.map((namespace = {}) => {
|
||||
return namespace.SecureVariables?.Paths;
|
||||
})
|
||||
.flat()
|
||||
.compact()
|
||||
.map((secVarsBlock = {}) => {
|
||||
return secVarsBlock.Capabilities;
|
||||
})
|
||||
.flat()
|
||||
.compact();
|
||||
|
||||
// Check for requested permissions
|
||||
return namespacesWithSecureVariableCapabilities.some((abilityList) => {
|
||||
return capabilities.includes(abilityList);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -60,9 +60,7 @@ module('Unit | Ability | variable', function (hooks) {
|
|||
Name: 'default',
|
||||
Capabilities: [],
|
||||
SecureVariables: {
|
||||
'Path "*"': {
|
||||
Capabilities: ['list'],
|
||||
},
|
||||
Paths: [{ Capabilities: ['list'], PathSpec: '*' }],
|
||||
},
|
||||
},
|
||||
],
|
||||
|
@ -76,7 +74,7 @@ module('Unit | Ability | variable', function (hooks) {
|
|||
assert.ok(this.ability.canList);
|
||||
});
|
||||
|
||||
test('it permits listing variables when token has SecureVariables alone in its rules', function (assert) {
|
||||
test('it does not permit listing variables when token has SecureVariables alone in its rules', function (assert) {
|
||||
const mockToken = Service.extend({
|
||||
aclEnabled: true,
|
||||
selfToken: { type: 'client' },
|
||||
|
@ -97,6 +95,123 @@ module('Unit | Ability | variable', function (hooks) {
|
|||
|
||||
this.owner.register('service:token', mockToken);
|
||||
|
||||
assert.notOk(this.ability.canList);
|
||||
});
|
||||
|
||||
test('it does not permit listing variables when token has a null SecureVariables block', function (assert) {
|
||||
const mockToken = Service.extend({
|
||||
aclEnabled: true,
|
||||
selfToken: { type: 'client' },
|
||||
selfTokenPolicies: [
|
||||
{
|
||||
rulesJSON: {
|
||||
Namespaces: [
|
||||
{
|
||||
Name: 'default',
|
||||
Capabilities: [],
|
||||
SecureVariables: null,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
this.owner.register('service:token', mockToken);
|
||||
|
||||
assert.notOk(this.ability.canList);
|
||||
});
|
||||
|
||||
test('it does not permit listing variables when token has a SecureVariables block where paths are without capabilities', function (assert) {
|
||||
const mockToken = Service.extend({
|
||||
aclEnabled: true,
|
||||
selfToken: { type: 'client' },
|
||||
selfTokenPolicies: [
|
||||
{
|
||||
rulesJSON: {
|
||||
Namespaces: [
|
||||
{
|
||||
Name: 'default',
|
||||
Capabilities: [],
|
||||
SecureVariables: {
|
||||
Paths: [
|
||||
{ Capabilities: [], PathSpec: '*' },
|
||||
{ Capabilities: [], PathSpec: 'foo' },
|
||||
{ Capabilities: [], PathSpec: 'foo/bar' },
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
this.owner.register('service:token', mockToken);
|
||||
|
||||
assert.notOk(this.ability.canList);
|
||||
});
|
||||
|
||||
test('it does not permit listing variables when token has no SecureVariables block', function (assert) {
|
||||
const mockToken = Service.extend({
|
||||
aclEnabled: true,
|
||||
selfToken: { type: 'client' },
|
||||
selfTokenPolicies: [
|
||||
{
|
||||
rulesJSON: {
|
||||
Namespaces: [
|
||||
{
|
||||
Name: 'default',
|
||||
Capabilities: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
this.owner.register('service:token', mockToken);
|
||||
|
||||
assert.notOk(this.ability.canList);
|
||||
});
|
||||
|
||||
test('it permits listing variables when token multiple namespaces, only one of which having a SecureVariables block', function (assert) {
|
||||
const mockToken = Service.extend({
|
||||
aclEnabled: true,
|
||||
selfToken: { type: 'client' },
|
||||
selfTokenPolicies: [
|
||||
{
|
||||
rulesJSON: {
|
||||
Namespaces: [
|
||||
{
|
||||
Name: 'default',
|
||||
Capabilities: [],
|
||||
SecureVariables: null,
|
||||
},
|
||||
{
|
||||
Name: 'nonsense',
|
||||
Capabilities: [],
|
||||
SecureVariables: {
|
||||
Paths: [{ Capabilities: [], PathSpec: '*' }],
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: 'shenanigans',
|
||||
Capabilities: [],
|
||||
SecureVariables: {
|
||||
Paths: [
|
||||
{ Capabilities: ['list'], PathSpec: 'foo/bar/baz' },
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
this.owner.register('service:token', mockToken);
|
||||
|
||||
assert.ok(this.ability.canList);
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue