From 8d77bc60b3bc5cd2234e90d76b2ab33eb1be1ae6 Mon Sep 17 00:00:00 2001 From: lisbet-alvarez <107949262+lisbet-alvarez@users.noreply.github.com> Date: Mon, 22 May 2023 15:46:13 -0700 Subject: [PATCH] Icu 9226 disable all actions for ldap accounts within users (#1688) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * refactor: 💡 disable all actions for ldap accounts within users ✅ Closes: ICU-9226 --- .../accounts/account/actions/index.hbs | 2 +- .../auth-method/actions/index.hbs | 2 +- .../form/user/add-accounts/index.hbs | 12 +- .../form/user/add-accounts/index.js | 11 +- .../scopes/scope/users/user/add-accounts.js | 4 +- .../auth-method/accounts/index.hbs | 4 +- .../scopes/scope/users/user/accounts.hbs | 2 +- .../tests/acceptance/users/accounts-test.js | 212 ++++++++++++++---- 8 files changed, 190 insertions(+), 59 deletions(-) diff --git a/ui/admin/app/components/auth-methods/auth-method/accounts/account/actions/index.hbs b/ui/admin/app/components/auth-methods/auth-method/accounts/account/actions/index.hbs index 00e985e8b..e98e75aa7 100644 --- a/ui/admin/app/components/auth-methods/auth-method/accounts/account/actions/index.hbs +++ b/ui/admin/app/components/auth-methods/auth-method/accounts/account/actions/index.hbs @@ -3,7 +3,7 @@ SPDX-License-Identifier: MPL-2.0 }} -{{#if (can 'delete model' @model)}} +{{#if (can 'delete account' @model)}} - + + {{account.id}} + {{account.description}} + {{account.accountName}} diff --git a/ui/admin/app/components/form/user/add-accounts/index.js b/ui/admin/app/components/form/user/add-accounts/index.js index 66797a6a8..a111f71d2 100644 --- a/ui/admin/app/components/form/user/add-accounts/index.js +++ b/ui/admin/app/components/form/user/add-accounts/index.js @@ -4,12 +4,13 @@ */ import Component from '@glimmer/component'; -import { computed, action } from '@ember/object'; +import { action } from '@ember/object'; import { A } from '@ember/array'; +import { inject as service } from '@ember/service'; export default class FormUserAddAccountsComponent extends Component { // =properties - + @service can; /** * Array of selected account IDs. * @type {EmberArray} @@ -21,7 +22,6 @@ export default class FormUserAddAccountsComponent extends Component { * @param {[AccountModel]} filteredAccounts * @type {boolean} */ - @computed('filteredAccounts.length') get hasAvailableAccounts() { return this.filteredAccounts.length > 0; } @@ -30,12 +30,13 @@ export default class FormUserAddAccountsComponent extends Component { * Accounts not already added to the user. * @type {[AccountModel]} */ - @computed('args.{accounts.[],model.account_ids.[]}') get filteredAccounts() { // Get IDs for accounts already added to the current user const alreadyAddedAccountIDs = this.args.model.account_ids; const notAddedAccounts = this.args.accounts.filter( - ({ id }) => !alreadyAddedAccountIDs.includes(id) + (account) => + !alreadyAddedAccountIDs.includes(account.id) && + this.can.can('addAccount user', this.args.model, { account }) ); return notAddedAccounts; } diff --git a/ui/admin/app/routes/scopes/scope/users/user/add-accounts.js b/ui/admin/app/routes/scopes/scope/users/user/add-accounts.js index c36ddae17..d16152ae6 100644 --- a/ui/admin/app/routes/scopes/scope/users/user/add-accounts.js +++ b/ui/admin/app/routes/scopes/scope/users/user/add-accounts.js @@ -27,8 +27,8 @@ export default class ScopesScopeUsersUserAddAccountsRoute extends Route { } /** - * Returns the current target, all host catalogs, and all host sets. - * @return {{target: TargetModel, hostCatalogs: [HostCatalogModel], hostSets: [HostSetModel]}} + * Returns the current user, all auth methods, and all accounts. + * @return {{user: UserModel, authMethods: [AuthMethodModel], accounts: [AccountModel]}} */ async model() { const user = this.modelFor('scopes.scope.users.user'); diff --git a/ui/admin/app/templates/scopes/scope/auth-methods/auth-method/accounts/index.hbs b/ui/admin/app/templates/scopes/scope/auth-methods/auth-method/accounts/index.hbs index 14841ac19..022c16030 100644 --- a/ui/admin/app/templates/scopes/scope/auth-methods/auth-method/accounts/index.hbs +++ b/ui/admin/app/templates/scopes/scope/auth-methods/auth-method/accounts/index.hbs @@ -41,7 +41,7 @@ {{#each @model.accounts as |account|}} - {{#if (can 'read model' account)}} + {{#if (can 'read account' account)}} - {{#if (can 'read model' account)}} + {{#if (can 'read account' account)}} - {{#if (can 'removeAccounts user' @model.user)}} + {{#if (can 'removeAccount user' @model.user account=account)}} item !== 'remove-accounts' ); instances.user.update({ authorized_actions }); - await visit(urls.accounts); - assert.notOk(find('tbody tr .rose-dropdown-button-danger')); + await visit(urls.user); + + await click(`[href="${urls.accounts}"]`); + + assert.dom(REMOVE_ACTION_SELECTOR).doesNotExist(); + }); + + test('cannot remove an ldap account when feature flag disabled', async function (assert) { + assert.expect(2); + const authMethod = this.server.create('auth-method', { + scope: instances.scopes.org, + type: TYPE_AUTH_METHOD_LDAP, + }); + const { id } = this.server.create('account', { + scope: instances.scopes.org, + type: TYPE_AUTH_METHOD_LDAP, + authMethod, + }); + instances.user.update({ accountIds: [id] }); + await visit(urls.user); + + await click(`[href="${urls.accounts}"]`); + + assert.dom(ACCOUNTS_ACTION_SELECTOR).doesNotExist(); + assert.dom(ACCOUNTS_TYPE_SELECTOR).hasText('LDAP'); + }); + + test('can remove an ldap account when feature flag enabled', async function (assert) { + assert.expect(2); + features.enable('ldap-auth-methods'); + const authMethod = this.server.create('auth-method', { + scope: instances.scopes.org, + type: TYPE_AUTH_METHOD_LDAP, + }); + const { id } = this.server.create('account', { + scope: instances.scopes.org, + type: TYPE_AUTH_METHOD_LDAP, + authMethod, + }); + instances.user.update({ accountIds: [id] }); + await visit(urls.user); + + await click(`[href="${urls.accounts}"]`); + + assert.dom(ACCOUNTS_ACTION_SELECTOR).exists(); + assert.dom(ACCOUNTS_TYPE_SELECTOR).hasText('LDAP'); }); test('shows error message on account remove', async function (assert) { @@ -98,24 +164,31 @@ module('Acceptance | users | accounts', function (hooks) { } ); }); - await visit(urls.accounts); - assert.strictEqual(findAll('tbody tr').length, accountsCount); - await click('tbody tr .rose-dropdown-button-danger'); - assert.ok(find('[role="alert"]')); + await visit(urls.user); + + await click(`[href="${urls.accounts}"]`); + assert.dom(TABLE_ROWS_SELECTOR).exists({ count: accountsCount }); + await click(REMOVE_ACTION_SELECTOR); + assert.dom(ERROR_MSG_SELECTOR).isVisible(); }); test('visiting account add accounts', async function (assert) { assert.expect(1); - await visit(urls.addAccounts); - await visit(urls.addAccounts); + await visit(urls.accounts); + + await click(ADD_ACCOUNTS_ACTION_SELECTOR); await a11yAudit(); + assert.strictEqual(currentURL(), urls.addAccounts); }); test('can navigate to add accounts with proper authorization', async function (assert) { assert.expect(1); - await visit(urls.accounts); - assert.ok(find(`[href="${urls.addAccounts}"]`)); + await visit(urls.user); + + await click(`[href="${urls.accounts}"]`); + + assert.dom(`[href="${urls.addAccounts}"]`).exists(); }); test('cannot navigate to add accounts without proper authorization', async function (assert) { @@ -124,38 +197,93 @@ module('Acceptance | users | accounts', function (hooks) { (item) => item !== 'add-accounts' ); instances.user.update({ authorized_actions }); - await visit(urls.accounts); - assert.notOk(find(`[href="${urls.addAccounts}"]`)); + await visit(urls.user); + + await click(`[href="${urls.accounts}"]`); + assert.dom(ADD_ACCOUNTS_ACTION_SELECTOR).doesNotExist(); + }); + + test('cannot add ldap accounts to user when feature flag is disabled', async function (assert) { + assert.expect(1); + const authMethod = this.server.create('auth-method', { + scope: instances.scopes.org, + type: TYPE_AUTH_METHOD_LDAP, + }); + this.server.create('account', { + scope: instances.scopes.org, + type: TYPE_AUTH_METHOD_LDAP, + authMethod, + }); + const accountsAvailableCount = + this.server.schema.accounts.all().length - + instances.user.accountIds.length; + await visit(urls.user); + + await click(`[href="${urls.accounts}"]`); + await click(ADD_ACCOUNTS_ACTION_SELECTOR); + + assert + .dom(TABLE_ROWS_SELECTOR) + .exists({ count: accountsAvailableCount - 1 }); + }); + + test('can add ldap accounts to user when feature flag is enabled', async function (assert) { + assert.expect(1); + features.enable('ldap-auth-methods'); + const authMethod = this.server.create('auth-method', { + scope: instances.scopes.org, + type: TYPE_AUTH_METHOD_LDAP, + }); + this.server.create('account', { + scope: instances.scopes.org, + type: TYPE_AUTH_METHOD_LDAP, + authMethod, + }); + const accountsAvailableCount = + this.server.schema.accounts.all().length - + instances.user.accountIds.length; + await visit(urls.user); + + await click(`[href="${urls.accounts}"]`); + await click(ADD_ACCOUNTS_ACTION_SELECTOR); + + assert.dom(TABLE_ROWS_SELECTOR).exists({ count: accountsAvailableCount }); }); test('select and save accounts to add', async function (assert) { - assert.expect(3); + assert.expect(4); instances.user.update({ accountIds: [] }); - await visit(urls.accounts); - assert.strictEqual(findAll('tbody tr').length, 0); - await click('.rose-layout-page-actions a'); + await visit(urls.user); + + await click(`[href="${urls.accounts}"]`); + assert.dom(TABLE_ROWS_SELECTOR).exists({ count: 0 }); + await click(ADD_ACCOUNTS_ACTION_SELECTOR); assert.strictEqual(currentURL(), urls.addAccounts); // Click three times to select, unselect, then reselect (for coverage) - await click('tbody label'); - await click('tbody label'); - await click('tbody label'); - await click('form [type="submit"]'); + await click(CHECKBOX_SELECTOR); + await click(CHECKBOX_SELECTOR); + await click(CHECKBOX_SELECTOR); + await click(SUBMIT_BTN_SELECTOR); await visit(urls.accounts); - assert.strictEqual(findAll('tbody tr').length, 1); + + assert.dom(TABLE_ROWS_SELECTOR).exists({ count: 1 }); + assert.strictEqual(instances.user.accountIds.length, 1); }); test('select and cancel accounts to add', async function (assert) { assert.expect(4); - await visit(urls.accounts); - assert.strictEqual(findAll('tbody tr').length, accountsCount); - await click('tbody tr .rose-dropdown-button-danger'); - assert.strictEqual(findAll('tbody tr').length, accountsCount - 1); - await click('.rose-layout-page-actions a'); + await visit(urls.user); + + await click(`[href="${urls.accounts}"]`); + assert.dom(TABLE_ROWS_SELECTOR).exists({ count: accountsCount }); + await click(REMOVE_ACTION_SELECTOR); + assert.dom(TABLE_ROWS_SELECTOR).exists({ count: accountsCount - 1 }); + await click(ADD_ACCOUNTS_ACTION_SELECTOR); assert.strictEqual(currentURL(), urls.addAccounts); - await click('tbody label'); - await click('form [type="button"]'); + await click(CHECKBOX_SELECTOR); + await click(CANCEL_BTN_SELECTOR); await visit(urls.accounts); - assert.strictEqual(findAll('tbody tr').length, accountsCount - 1); + assert.dom(TABLE_ROWS_SELECTOR).exists({ count: accountsCount - 1 }); }); test('shows error message on account add', async function (assert) { @@ -174,8 +302,8 @@ module('Acceptance | users | accounts', function (hooks) { }); instances.user.update({ accountIds: [] }); await visit(urls.addAccounts); - await click('tbody label'); - await click('form [type="submit"]'); - assert.ok(find('[role="alert"]')); + await click(CHECKBOX_SELECTOR); + await click(SUBMIT_BTN_SELECTOR); + assert.dom(ERROR_MSG_SELECTOR).isVisible(); }); });