Skip to content

Commit

Permalink
ui: Implement ACLs access based on ACLs (#9835)
Browse files Browse the repository at this point in the history
Adds restrictions to everything within the ACLs (and nspaces) area based on your ACLs (including readonly views etc.)
  • Loading branch information
johncowen authored Mar 11, 2021
1 parent 6fe45c0 commit fa6687b
Show file tree
Hide file tree
Showing 33 changed files with 339 additions and 65 deletions.
9 changes: 6 additions & 3 deletions ui/packages/consul-ui/app/abilities/acl.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import BaseAbility from './base';
import { inject as service } from '@ember/service';

// ACL ability covers all of the ACL things, like tokens, policies, roles and
// auth methods and this therefore should not be deleted once we remove the on
// legacy ACLs related classes
export default class ACLAbility extends BaseAbility {
@service('env') env;

Expand All @@ -13,4 +10,10 @@ export default class ACLAbility extends BaseAbility {
get canRead() {
return this.env.var('CONSUL_ACLS_ENABLED') && super.canRead;
}
get canDuplicate() {
return this.env.var('CONSUL_ACLS_ENABLED') && super.canWrite;
}
get canDelete() {
return this.env.var('CONSUL_ACLS_ENABLED') && this.item.ID !== 'anonymous' && super.canWrite;
}
}
21 changes: 21 additions & 0 deletions ui/packages/consul-ui/app/abilities/auth-method.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import BaseAbility from './base';
import { inject as service } from '@ember/service';

export default class AuthMethodAbility extends BaseAbility {
@service('env') env;

resource = 'acl';
segmented = false;

get canRead() {
return this.env.var('CONSUL_ACLS_ENABLED') && super.canRead;
}

get canCreate() {
return this.env.var('CONSUL_ACLS_ENABLED') && super.canCreate;
}

get canDelete() {
return this.env.var('CONSUL_ACLS_ENABLED') && super.canDelete;
}
}
4 changes: 4 additions & 0 deletions ui/packages/consul-ui/app/abilities/nspace.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ export default class NspaceAbility extends BaseAbility {
return this.canCreate;
}

get canDelete() {
return this.item.Name !== 'default' && super.canDelete;
}

get canChoose() {
return this.env.var('CONSUL_NSPACES_ENABLED') && this.nspaces.length > 0;
}
Expand Down
34 changes: 34 additions & 0 deletions ui/packages/consul-ui/app/abilities/policy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import BaseAbility from './base';
import { inject as service } from '@ember/service';
import { typeOf } from 'consul-ui/helpers/policy/typeof';

export default class PolicyAbility extends BaseAbility {
@service('env') env;

resource = 'acl';
segmented = false;

get canRead() {
return this.env.var('CONSUL_ACLS_ENABLED') && super.canRead;
}

get canWrite() {
return (
this.env.var('CONSUL_ACLS_ENABLED') &&
(typeof this.item === 'undefined' || typeOf([this.item]) !== 'policy-management') &&
super.canRead
);
}

get canCreate() {
return this.env.var('CONSUL_ACLS_ENABLED') && super.canCreate;
}

get canDelete() {
return (
this.env.var('CONSUL_ACLS_ENABLED') &&
(typeof this.item === 'undefined' || typeOf([this.item]) !== 'policy-management') &&
super.canDelete
);
}
}
21 changes: 21 additions & 0 deletions ui/packages/consul-ui/app/abilities/role.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import BaseAbility from './base';
import { inject as service } from '@ember/service';

export default class RoleAbility extends BaseAbility {
@service('env') env;

resource = 'acl';
segmented = false;

get canRead() {
return this.env.var('CONSUL_ACLS_ENABLED') && super.canRead;
}

get canCreate() {
return this.env.var('CONSUL_ACLS_ENABLED') && super.canCreate;
}

get canDelete() {
return this.env.var('CONSUL_ACLS_ENABLED') && super.canDelete;
}
}
33 changes: 33 additions & 0 deletions ui/packages/consul-ui/app/abilities/token.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import BaseAbility from './base';
import { inject as service } from '@ember/service';

import { isLegacy } from 'consul-ui/helpers/token/is-legacy';
import { isAnonymous } from 'consul-ui/helpers/token/is-anonymous';

export default class TokenAbility extends BaseAbility {
@service('env') env;

resource = 'acl';
segmented = false;

get canRead() {
return this.env.var('CONSUL_ACLS_ENABLED') && super.canRead;
}

get canCreate() {
return this.env.var('CONSUL_ACLS_ENABLED') && super.canCreate;
}

get canDelete() {
return (
this.env.var('CONSUL_ACLS_ENABLED') &&
!isAnonymous([this.item]) &&
this.item.AccessorID !== this.token.AccessorID &&
super.canDelete
);
}

get canDuplicate() {
return this.env.var('CONSUL_ACLS_ENABLED') && !isLegacy([this.item]) && super.canWrite;
}
}
2 changes: 2 additions & 0 deletions ui/packages/consul-ui/app/components/child-selector/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
...attributes
>
{{yield}}
{{#if (not disabled)}}
<YieldSlot @name="create">{{yield}}</YieldSlot>
<label class="type-text">
<span><YieldSlot @name="label">{{yield}}</YieldSlot></span>
Expand Down Expand Up @@ -35,6 +36,7 @@
</PowerSelect>
</DataCollection>
</label>
{{/if}}
{{#if (gt items.length 0)}}
<YieldSlot @name="set">{{yield}}</YieldSlot>
{{else}}
Expand Down
12 changes: 10 additions & 2 deletions ui/packages/consul-ui/app/components/consul/acl/list/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,13 @@
</BlockSlot>
<BlockSlot @name="menu" as |confirm send keypressClick|>
<li role="none">
<a data-test-edit role="menuitem" tabindex="-1" href={{href-to 'dc.acls.edit' item.ID}}>Edit</a>
<a data-test-edit role="menuitem" tabindex="-1" href={{href-to 'dc.acls.edit' item.ID}}>
{{#if (can "write acl" item=item)}}
Edit
{{else}}
View
{{/if}}
</a>
</li>
{{#if (eq item.ID token.SecretID) }}
<li role="none">
Expand Down Expand Up @@ -87,10 +93,12 @@
</div>
</li>
{{/if}}
{{#if (can "duplicate acl" item=item)}}
<li role="none">
<button role="menuitem" tabindex="-1" type="button" data-test-clone {{action @onclone item}}>Duplicate</button>
</li>
{{# if (not-eq item.ID 'anonymous') }}
{{/if}}
{{#if (can "delete acl" item=item)}}
<li role="none" class="dangerous">
<label for={{concat confirm 'delete'}} role="menuitem" tabindex="-1" onkeypress={{keypressClick}} data-test-delete>Delete</label>
<div role="menu">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,14 @@ as |item|>
<Actions as |Action|>
<Action data-test-edit-action @href={{href-to 'dc.nspaces.edit' item.Name}}>
<BlockSlot @name="label">
{{#if (can "write nspace" item=item)}}
Edit
{{else}}
View
{{/if}}
</BlockSlot>
</Action>
{{#if (not-eq item.Name 'default') }}
{{#if (can "delete nspace" item=item)}}
<Action data-test-delete-action @onclick={{action @ondelete item}} class="dangerous">
<BlockSlot @name="label">
Delete
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,14 @@ as |item|>
<Actions as |Action|>
<Action data-test-edit-action @href={{href-to 'dc.acls.policies.edit' item.ID}}>
<BlockSlot @name="label">
{{#if (eq (policy/typeof item) 'policy-management')}}
View
{{else}}
{{#if (can "write policy" item=item)}}
Edit
{{else}}
View
{{/if}}
</BlockSlot>
</Action>
{{#if (not-eq (policy/typeof item) 'policy-management')}}
{{#if (can "delete policy" item=item)}}
<Action data-test-delete-action @onclick={{action @ondelete item}} class="dangerous">
<BlockSlot @name="label">
Delete
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,14 @@ as |item|>
<Actions as |Action|>
<Action data-test-edit-action @href={{href-to 'dc.acls.roles.edit' item.ID}}>
<BlockSlot @name="label">
{{#if (can "write role" item=item)}}
Edit
{{else}}
View
{{/if}}
</BlockSlot>
</Action>
{{#if (can "delete role" item=item)}}
<Action data-test-delete-action @onclick={{action @ondelete item}} class="dangerous">
<BlockSlot @name="label">
Delete
Expand All @@ -42,6 +47,7 @@ as |item|>
</Confirmation>
</BlockSlot>
</Action>
{{/if}}
</Actions>
</BlockSlot>
</ListCollection>
17 changes: 13 additions & 4 deletions ui/packages/consul-ui/app/components/consul/token/list/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,25 @@ as |item|>
</dl>
</BlockSlot>
<BlockSlot @name="actions" as |Actions|>

<Actions as |Action|>
<Action data-test-edit-action @href={{href-to 'dc.acls.tokens.edit' item.AccessorID}}>
<BlockSlot @name="label">
{{#if (can "write token" item=item)}}
Edit
{{else}}
View
{{/if}}
</BlockSlot>
</Action>
{{#if (not (token/is-legacy item))}}
{{#if (can "duplicate token" item=item)}}
<Action data-test-clone-action @onclick={{action @onclone item}}>
<BlockSlot @name="label">
Duplicate
</BlockSlot>
</Action>
{{/if}}
{{/if}}

{{#if (eq item.AccessorID token.AccessorID)}}
<Action data-test-logout-action class="dangerous" @onclick={{action @onlogout item}}>
<BlockSlot @name="label">
Expand Down Expand Up @@ -86,7 +92,9 @@ as |item|>
</BlockSlot>
</Action>
{{/if}}
{{#if (not (or (token/is-anonymous item) (eq item.AccessorID @token.AccessorID)))}}


{{#if (can "delete token" item=item token=@token)}}
<Action data-test-delete-action @onclick={{action @ondelete item}} class="dangerous">
<BlockSlot @name="label">
Delete
Expand All @@ -107,7 +115,8 @@ as |item|>
</Confirmation>
</BlockSlot>
</Action>
{{/if}}
{{/if}}

</Actions>
</BlockSlot>
</ListCollection>
5 changes: 4 additions & 1 deletion ui/packages/consul-ui/app/components/policy-form/index.hbs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
{{yield}}
<fieldset ...attributes>
<fieldset
disabled={{if (not (can "write policy" item=item)) "disabled"}}
...attributes
>
{{#yield-slot name='template'}}
{{else}}
<header>
Expand Down
13 changes: 12 additions & 1 deletion ui/packages/consul-ui/app/components/policy-selector/index.hbs
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
<ChildSelector ...attributes @repo={{repo}} @dc={{dc}} @nspace={{nspace}} @type="policy" @placeholder="Search for policy" @items={{items}}>
<ChildSelector
@disabled={{disabled}}
@repo={{repo}}
@dc={{dc}}
@nspace={{nspace}}
@type="policy"
@placeholder="Search for policy"
@items={{items}}
...attributes
>
{{yield}}
<BlockSlot @name="label">
Apply an existing policy
Expand Down Expand Up @@ -112,6 +121,7 @@
/>
{{/if}}
</label>
{{#if (not disabled)}}
<div>
<ConfirmationDialog @message="Are you sure you want to remove this policy from this token?">
<BlockSlot @name="action" as |confirm|>
Expand All @@ -127,6 +137,7 @@
</BlockSlot>
</ConfirmationDialog>
</div>
{{/if}}
</BlockSlot>
</TabularDetails>

Expand Down
13 changes: 11 additions & 2 deletions ui/packages/consul-ui/app/components/role-form/index.hbs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
{{yield}}
<fieldset class="role-form" data-test-role-form>
<fieldset
disabled={{if (not (can "write role" item=item)) "disabled"}}
class="role-form"
data-test-role-form
>
<label class="type-text{{if item.error.Name ' has-error'}}">
<span>Name</span>
<input type="text" value={{item.Name}} name="role[Name]" autofocus="autofocus" oninput={{action 'change'}} />
Expand All @@ -21,6 +25,11 @@
{{#yield-slot name='policy' params=(block-params item)}}
{{yield}}
{{else}}
<PolicySelector @dc={{dc}} @nspace={{nspace}} @items={{item.Policies}} />
<PolicySelector
@disabled={{not (can "write role" item=item)}}
@dc={{dc}}
@nspace={{nspace}}
@items={{item.Policies}}
/>
{{/yield-slot}}
</fieldset>
Loading

0 comments on commit fa6687b

Please sign in to comment.