diff --git a/addons/api/addon/abilities/host-set.js b/addons/api/addon/abilities/host-set.js new file mode 100644 index 000000000..088683178 --- /dev/null +++ b/addons/api/addon/abilities/host-set.js @@ -0,0 +1,22 @@ +import ModelAbility from './model'; + +/** + * Provides abilities for host sets. + */ +export default class UserAbility extends ModelAbility { + // =permissions + + /** + * @type {boolean} + */ + get canAddHosts() { + return this.hasAuthorizedAction('add-hosts'); + } + + /** + * @type {boolean} + */ + get canRemoveHosts() { + return this.hasAuthorizedAction('remove-hosts'); + } +} diff --git a/addons/api/app/abilities/host-set.js b/addons/api/app/abilities/host-set.js new file mode 100644 index 000000000..37ccd5e81 --- /dev/null +++ b/addons/api/app/abilities/host-set.js @@ -0,0 +1 @@ +export { default } from 'api/abilities/host-set'; diff --git a/addons/api/mirage/factories/host-set.js b/addons/api/mirage/factories/host-set.js index def5ff70f..3b88650b7 100644 --- a/addons/api/mirage/factories/host-set.js +++ b/addons/api/mirage/factories/host-set.js @@ -8,6 +8,8 @@ export default factory.extend({ 'read', 'update', 'delete', + 'add-hosts', + 'remove-hosts', ], id: (i) => `host-set-id-${i}`, }); diff --git a/addons/api/tests/unit/abilities/host-set-test.js b/addons/api/tests/unit/abilities/host-set-test.js new file mode 100644 index 000000000..24b0efa15 --- /dev/null +++ b/addons/api/tests/unit/abilities/host-set-test.js @@ -0,0 +1,28 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Abilities | Host Set', function (hooks) { + setupTest(hooks); + + test('it reflects when a given host set resource may add hosts based on authorized_actions', function (assert) { + assert.expect(2); + const service = this.owner.lookup('service:can'); + const model = { + authorized_actions: ['add-hosts'], + }; + assert.ok(service.can('addHosts hostSet', model)); + model.authorized_actions = []; + assert.notOk(service.can('addHosts hostSet', model)); + }); + + test('it reflects when a given hostSet resource may remove hosts based on authorized_actions', function (assert) { + assert.expect(2); + const service = this.owner.lookup('service:can'); + const model = { + authorized_actions: ['remove-hosts'], + }; + assert.ok(service.can('removeHosts hostSet', model)); + model.authorized_actions = []; + assert.notOk(service.can('removeHosts hostSet', model)); + }); +}); diff --git a/ui/admin/app/templates/scopes/scope/host-catalogs/host-catalog/host-sets/host-set/-actions.hbs b/ui/admin/app/templates/scopes/scope/host-catalogs/host-catalog/host-sets/host-set/-actions.hbs index d78e1b940..d0bae064d 100644 --- a/ui/admin/app/templates/scopes/scope/host-catalogs/host-catalog/host-sets/host-set/-actions.hbs +++ b/ui/admin/app/templates/scopes/scope/host-catalogs/host-catalog/host-sets/host-set/-actions.hbs @@ -3,16 +3,18 @@ @dropdownRight={{true}} as |dropdown| > - - {{t 'resources.host-set.actions.create-and-add-host'}} - - - {{t 'resources.host-set.actions.add-hosts'}} - + {{#if (can 'addHosts hostSet' @model)}} + + {{t 'resources.host-set.actions.create-and-add-host'}} + + + {{t 'resources.host-set.actions.add-hosts'}} + + {{/if}} {{#if (can 'delete model' @model)}} - - - {{t 'actions.remove'}} - - + + {{t 'actions.remove'}} + + + {{/if}} {{/each}} diff --git a/ui/admin/tests/acceptance/host-catalogs/host-sets/hosts-test.js b/ui/admin/tests/acceptance/host-catalogs/host-sets/hosts-test.js index 3140961c7..2423c62ca 100644 --- a/ui/admin/tests/acceptance/host-catalogs/host-sets/hosts-test.js +++ b/ui/admin/tests/acceptance/host-catalogs/host-sets/hosts-test.js @@ -99,6 +99,16 @@ module('Acceptance | host-catalogs | host-sets | hosts', function (hooks) { assert.equal(findAll('tbody tr').length, count - 1); }); + test('cannot remove a host without proper authorization', async function (assert) { + assert.expect(1); + const authorized_actions = instances.hostSet.authorized_actions.filter( + (item) => item !== 'remove-hosts' + ); + instances.hostSet.update({ authorized_actions }); + await visit(urls.hostSetHosts); + assert.notOk(find('tbody tr .rose-dropdown-button-danger')); + }); + test('shows error message on host remove error', async function (assert) { assert.expect(2); this.server.post('/host-sets/:idMethod', () => { @@ -126,6 +136,22 @@ module('Acceptance | host-catalogs | host-sets | hosts', function (hooks) { assert.equal(currentURL(), urls.addHosts); }); + test('can navigate to add hosts with proper authorization', async function (assert) { + assert.expect(1); + await visit(urls.hostSet); + assert.ok(find(`[href="${urls.addHosts}"]`)); + }); + + test('cannot navigate to add hosts without proper authorization', async function (assert) { + assert.expect(1); + const authorized_actions = instances.hostSet.authorized_actions.filter( + (item) => item !== 'add-hosts' + ); + instances.hostSet.update({ authorized_actions }); + await visit(urls.hostSet); + assert.notOk(find(`[href="${urls.addHosts}"]`)); + }); + test('select and save hosts to add', async function (assert) { assert.expect(3); instances.hostSet.update({ hostIds: [] });