diff --git a/addons/api/addon/abilities/account.js b/addons/api/addon/abilities/account.js index 8d741f157..03ab318a5 100644 --- a/addons/api/addon/abilities/account.js +++ b/addons/api/addon/abilities/account.js @@ -11,6 +11,30 @@ import ModelAbility from './model'; export default class AccountAbility extends ModelAbility { // =permissions + /** + * Only "known" account types may be read. + * @type {boolean} + */ + get canRead() { + return !this.model.isUnknown && this.hasAuthorizedAction('read'); + } + + /** + * Only "known" account types may be updated. + * @type {boolean} + */ + get canUpdate() { + return !this.model.isUnknown && this.hasAuthorizedAction('update'); + } + + /** + * Only "known" account types may be deleted. + * @type {boolean} + */ + get canDelete() { + return !this.model.isUnknown && this.hasAuthorizedAction('delete'); + } + /** * @type {boolean} */ diff --git a/addons/api/addon/abilities/auth-method.js b/addons/api/addon/abilities/auth-method.js index 744f93ac7..421fca156 100644 --- a/addons/api/addon/abilities/auth-method.js +++ b/addons/api/addon/abilities/auth-method.js @@ -17,4 +17,18 @@ export default class AuthMethodAbility extends ModelAbility { get canRead() { return !this.model.isUnknown && this.hasAuthorizedAction('read'); } + + /** + * Only "known" auth method types may be updated. + */ + get canUpdate() { + return !this.model.isUnknown && this.hasAuthorizedAction('update'); + } + + /** + * Only "known" auth method types may be deleted. + */ + get canDelete() { + return !this.model.isUnknown && this.hasAuthorizedAction('delete'); + } } diff --git a/addons/api/addon/models/account.js b/addons/api/addon/models/account.js index 87aacf331..4607433e7 100644 --- a/addons/api/addon/models/account.js +++ b/addons/api/addon/models/account.js @@ -4,8 +4,12 @@ */ import GeneratedAccountModel from '../generated/models/account'; -import { computed } from '@ember/object'; -import { equal } from '@ember/object/computed'; +import { + TYPE_AUTH_METHOD_PASSWORD, + TYPE_AUTH_METHOD_OIDC, + TYPE_AUTH_METHOD_LDAP, + TYPES_AUTH_METHOD, +} from './auth-method'; export default class AccountModel extends GeneratedAccountModel { // =attributes @@ -13,18 +17,35 @@ export default class AccountModel extends GeneratedAccountModel { /** * @type {boolean} */ - @equal('type', 'password') isPassword; + get isPassword() { + return this.type === TYPE_AUTH_METHOD_PASSWORD; + } /** * @type {boolean} */ - @equal('type', 'oidc') isOIDC; + get isOIDC() { + return this.type === TYPE_AUTH_METHOD_OIDC; + } + + /** + * @type {boolean} + */ + get isLDAP() { + return this.type === TYPE_AUTH_METHOD_LDAP; + } + + /** + * @type {boolean} + */ + get isUnknown() { + return !TYPES_AUTH_METHOD.includes(this.type); + } /** * Convenience for getting username in account. * @type {string} */ - @computed('{email,full_name,login_name}') get accountName() { const { email, full_name, login_name } = this; return email || full_name || login_name; diff --git a/addons/api/app/abilities/auth-method.js b/addons/api/app/abilities/auth-method.js new file mode 100644 index 000000000..f81e174f4 --- /dev/null +++ b/addons/api/app/abilities/auth-method.js @@ -0,0 +1,6 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +export { default } from 'api/abilities/auth-method'; diff --git a/addons/api/mirage/factories/account.js b/addons/api/mirage/factories/account.js index ee46ac64e..176e0786d 100644 --- a/addons/api/mirage/factories/account.js +++ b/addons/api/mirage/factories/account.js @@ -7,6 +7,11 @@ import factory from '../generated/factories/account'; import { faker } from '@faker-js/faker'; import permissions from '../helpers/permissions'; import generateId from '../helpers/id'; +import { + TYPE_AUTH_METHOD_PASSWORD, + TYPE_AUTH_METHOD_OIDC, + TYPE_AUTH_METHOD_LDAP, +} from 'api/models/auth-method'; export default factory.extend({ authorized_actions: () => @@ -22,9 +27,10 @@ export default factory.extend({ attributes() { switch (this.type) { - case 'password': + case TYPE_AUTH_METHOD_PASSWORD: + case TYPE_AUTH_METHOD_LDAP: return { login_name: faker.random.words() }; - case 'oidc': + case TYPE_AUTH_METHOD_OIDC: return { issuer: faker.internet.ip(), subject: 'sub', diff --git a/addons/api/tests/unit/abilities/account-test-.js b/addons/api/tests/unit/abilities/account-test-.js deleted file mode 100644 index a631d7518..000000000 --- a/addons/api/tests/unit/abilities/account-test-.js +++ /dev/null @@ -1,22 +0,0 @@ -/** - * Copyright (c) HashiCorp, Inc. - * SPDX-License-Identifier: MPL-2.0 - */ - -import { module, test } from 'qunit'; -import { setupTest } from 'ember-qunit'; - -module('Unit | Abilities | Account', function (hooks) { - setupTest(hooks); - - test('it reflects when a given account may set password based on authorized_actions', function (assert) { - assert.expect(2); - const service = this.owner.lookup('service:can'); - const model = { - authorized_actions: ['set-password'], - }; - assert.ok(service.can('setPassword target', model)); - model.authorized_actions = []; - assert.notOk(service.can('setPassword target', model)); - }); -}); diff --git a/addons/api/tests/unit/abilities/account-test.js b/addons/api/tests/unit/abilities/account-test.js new file mode 100644 index 000000000..8c7824ff8 --- /dev/null +++ b/addons/api/tests/unit/abilities/account-test.js @@ -0,0 +1,124 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; +import { + TYPE_AUTH_METHOD_PASSWORD, + TYPE_AUTH_METHOD_OIDC, + TYPE_AUTH_METHOD_LDAP, +} from 'api/models/auth-method'; + +module('Unit | Abilities | Account', function (hooks) { + setupTest(hooks); + + let canService; + let store; + + hooks.beforeEach(function () { + canService = this.owner.lookup('service:can'); + store = this.owner.lookup('service:store'); + }); + + test('it reflects when a given account may set password based on authorized_actions', function (assert) { + assert.expect(2); + const account = store.createRecord('auth-method', { + authorized_actions: ['set-password'], + }); + assert.true(canService.can('setPassword account', account)); + account.authorized_actions = []; + assert.false(canService.can('setPassword account', account)); + }); + + test('can read known account types when authorized', function (assert) { + assert.expect(4); + const account = store.createRecord('account', { + authorized_actions: ['read'], + type: TYPE_AUTH_METHOD_OIDC, + }); + assert.true(canService.can('read account', account)); + account.type = TYPE_AUTH_METHOD_PASSWORD; + assert.true(canService.can('read account', account)); + account.type = TYPE_AUTH_METHOD_LDAP; + assert.true(canService.can('read account', account)); + account.type = 'no-such-type'; + assert.false(canService.can('read account', account)); + }); + + test('cannot read accounts when unauthorized', function (assert) { + assert.expect(4); + const account = store.createRecord('account', { + authorized_actions: [], + type: TYPE_AUTH_METHOD_OIDC, + }); + assert.false(canService.can('read account', account)); + account.type = TYPE_AUTH_METHOD_PASSWORD; + assert.false(canService.can('read account', account)); + account.type = TYPE_AUTH_METHOD_LDAP; + assert.false(canService.can('read account', account)); + account.type = 'no-such-type'; + assert.false(canService.can('read account', account)); + }); + + test('can delete known account types when authorized', function (assert) { + assert.expect(4); + const account = store.createRecord('account', { + authorized_actions: ['delete'], + type: TYPE_AUTH_METHOD_OIDC, + }); + assert.true(canService.can('delete account', account)); + account.type = TYPE_AUTH_METHOD_PASSWORD; + assert.true(canService.can('delete account', account)); + account.type = TYPE_AUTH_METHOD_LDAP; + assert.true(canService.can('delete account', account)); + account.type = 'no-such-type'; + assert.false(canService.can('delete account', account)); + }); + + test('cannot delete accounts when unauthorized', function (assert) { + assert.expect(4); + const account = store.createRecord('account', { + authorized_actions: ['delete'], + type: TYPE_AUTH_METHOD_OIDC, + }); + assert.true(canService.can('delete account', account)); + account.type = TYPE_AUTH_METHOD_PASSWORD; + assert.true(canService.can('delete account', account)); + account.type = TYPE_AUTH_METHOD_LDAP; + assert.true(canService.can('delete account', account)); + account.type = 'no-such-type'; + assert.false(canService.can('delete account', account)); + }); + + test('can update known account types when authorized', function (assert) { + assert.expect(4); + const account = store.createRecord('account', { + authorized_actions: ['update'], + type: TYPE_AUTH_METHOD_OIDC, + }); + assert.true(canService.can('update account', account)); + account.type = TYPE_AUTH_METHOD_PASSWORD; + assert.true(canService.can('update account', account)); + account.type = TYPE_AUTH_METHOD_LDAP; + assert.true(canService.can('update account', account)); + account.type = 'no-such-type'; + assert.false(canService.can('update account', account)); + }); + + test('cannot update accounts when unauthorized', function (assert) { + assert.expect(4); + const account = store.createRecord('account', { + authorized_actions: [], + type: TYPE_AUTH_METHOD_OIDC, + }); + assert.false(canService.can('update account', account)); + account.type = TYPE_AUTH_METHOD_PASSWORD; + assert.false(canService.can('update account', account)); + account.type = TYPE_AUTH_METHOD_LDAP; + assert.false(canService.can('update account', account)); + account.type = 'no-such-type'; + assert.false(canService.can('update account', account)); + }); +}); diff --git a/addons/api/tests/unit/abilities/auth-method-test.js b/addons/api/tests/unit/abilities/auth-method-test.js new file mode 100644 index 000000000..ade783e69 --- /dev/null +++ b/addons/api/tests/unit/abilities/auth-method-test.js @@ -0,0 +1,114 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; +import { + TYPE_AUTH_METHOD_PASSWORD, + TYPE_AUTH_METHOD_OIDC, + TYPE_AUTH_METHOD_LDAP, +} from 'api/models/auth-method'; + +module('Unit | Abilities | Auth Method', function (hooks) { + setupTest(hooks); + + let canService; + let store; + + hooks.beforeEach(function () { + canService = this.owner.lookup('service:can'); + store = this.owner.lookup('service:store'); + }); + + test('can read known auth method types when authorized', function (assert) { + assert.expect(4); + const authMethod = store.createRecord('auth-method', { + authorized_actions: ['read'], + type: TYPE_AUTH_METHOD_OIDC, + }); + assert.true(canService.can('read auth-method', authMethod)); + authMethod.type = TYPE_AUTH_METHOD_PASSWORD; + assert.true(canService.can('read auth-method', authMethod)); + authMethod.type = TYPE_AUTH_METHOD_LDAP; + assert.true(canService.can('read auth-method', authMethod)); + authMethod.type = 'no-such-type'; + assert.false(canService.can('read auth-method', authMethod)); + }); + + test('cannot read auth methods when unauthorized', function (assert) { + assert.expect(4); + const authMethod = store.createRecord('auth-method', { + authorized_actions: [], + type: TYPE_AUTH_METHOD_OIDC, + }); + assert.false(canService.can('read auth-method', authMethod)); + authMethod.type = TYPE_AUTH_METHOD_PASSWORD; + assert.false(canService.can('read auth-method', authMethod)); + authMethod.type = TYPE_AUTH_METHOD_LDAP; + assert.false(canService.can('read auth-method', authMethod)); + authMethod.type = 'no-such-type'; + assert.false(canService.can('read auth-method', authMethod)); + }); + + test('can delete known auth method types when authorized', function (assert) { + assert.expect(4); + const authMethod = store.createRecord('auth-method', { + authorized_actions: ['delete'], + type: TYPE_AUTH_METHOD_OIDC, + }); + assert.true(canService.can('delete auth-method', authMethod)); + authMethod.type = TYPE_AUTH_METHOD_PASSWORD; + assert.true(canService.can('delete auth-method', authMethod)); + authMethod.type = TYPE_AUTH_METHOD_LDAP; + assert.true(canService.can('delete auth-method', authMethod)); + authMethod.type = 'no-such-type'; + assert.false(canService.can('delete auth-method', authMethod)); + }); + + test('cannot delete auth methods when unauthorized', function (assert) { + assert.expect(4); + const authMethod = store.createRecord('auth-method', { + authorized_actions: ['delete'], + type: TYPE_AUTH_METHOD_OIDC, + }); + assert.true(canService.can('delete auth-method', authMethod)); + authMethod.type = TYPE_AUTH_METHOD_PASSWORD; + assert.true(canService.can('delete auth-method', authMethod)); + authMethod.type = TYPE_AUTH_METHOD_LDAP; + assert.true(canService.can('delete auth-method', authMethod)); + authMethod.type = 'no-such-type'; + assert.false(canService.can('delete auth-method', authMethod)); + }); + + test('can update known auth method types when authorized', function (assert) { + assert.expect(4); + const authMethod = store.createRecord('auth-method', { + authorized_actions: ['update'], + type: TYPE_AUTH_METHOD_OIDC, + }); + assert.true(canService.can('update auth-method', authMethod)); + authMethod.type = TYPE_AUTH_METHOD_PASSWORD; + assert.true(canService.can('update auth-method', authMethod)); + authMethod.type = TYPE_AUTH_METHOD_LDAP; + assert.true(canService.can('update auth-method', authMethod)); + authMethod.type = 'no-such-type'; + assert.false(canService.can('update auth-method', authMethod)); + }); + + test('cannot update auth methods when unauthorized', function (assert) { + assert.expect(4); + const authMethod = store.createRecord('auth-method', { + authorized_actions: [], + type: TYPE_AUTH_METHOD_OIDC, + }); + assert.false(canService.can('update auth-method', authMethod)); + authMethod.type = TYPE_AUTH_METHOD_PASSWORD; + assert.false(canService.can('update auth-method', authMethod)); + authMethod.type = TYPE_AUTH_METHOD_LDAP; + assert.false(canService.can('update auth-method', authMethod)); + authMethod.type = 'no-such-type'; + assert.false(canService.can('update auth-method', authMethod)); + }); +}); diff --git a/addons/api/tests/unit/models/account-test.js b/addons/api/tests/unit/models/account-test.js index 9dfc427a4..71f5db4bc 100644 --- a/addons/api/tests/unit/models/account-test.js +++ b/addons/api/tests/unit/models/account-test.js @@ -5,19 +5,30 @@ import { module, test } from 'qunit'; import { setupTest } from 'ember-qunit'; +import { + TYPE_AUTH_METHOD_PASSWORD, + TYPE_AUTH_METHOD_OIDC, + TYPE_AUTH_METHOD_LDAP, +} from 'api/models/auth-method'; module('Unit | Model | account', function (hooks) { setupTest(hooks); + let store; + + hooks.beforeEach(function () { + store = this.owner.lookup('service:store'); + }); + test('it exists', function (assert) { - let store = this.owner.lookup('service:store'); + store = this.owner.lookup('service:store'); let model = store.createRecord('account', {}); assert.ok(model); }); test('it has an accountName attribute for password account', function (assert) { assert.expect(2); - const store = this.owner.lookup('service:store'); + store = this.owner.lookup('service:store'); let model = store.createRecord('account', { type: 'password', }); @@ -25,4 +36,72 @@ module('Unit | Model | account', function (hooks) { model.login_name = 'foobar'; assert.strictEqual(model.accountName, 'foobar'); }); + + test('it has isPassword property and returns the expected values', function (assert) { + assert.expect(3); + const modelA = store.createRecord('account', { + type: TYPE_AUTH_METHOD_PASSWORD, + }); + const modelB = store.createRecord('account', { + type: TYPE_AUTH_METHOD_OIDC, + }); + const modelC = store.createRecord('account', { + type: TYPE_AUTH_METHOD_LDAP, + }); + assert.true(modelA.isPassword); + assert.false(modelB.isPassword); + assert.false(modelC.isPassword); + }); + + test('it has isOIDC property and returns the expected values', function (assert) { + assert.expect(3); + const modelA = store.createRecord('account', { + type: TYPE_AUTH_METHOD_OIDC, + }); + const modelB = store.createRecord('account', { + type: TYPE_AUTH_METHOD_PASSWORD, + }); + const modelC = store.createRecord('account', { + type: TYPE_AUTH_METHOD_LDAP, + }); + assert.true(modelA.isOIDC); + assert.false(modelB.isOIDC); + assert.false(modelC.isOIDC); + }); + + test('it has isLDAP property and returns the expected values', function (assert) { + assert.expect(3); + const modelA = store.createRecord('account', { + type: TYPE_AUTH_METHOD_LDAP, + }); + const modelB = store.createRecord('account', { + type: TYPE_AUTH_METHOD_PASSWORD, + }); + const modelC = store.createRecord('account', { + type: TYPE_AUTH_METHOD_OIDC, + }); + assert.true(modelA.isLDAP); + assert.false(modelB.isLDAP); + assert.false(modelC.isLDAP); + }); + + test('it has isUnknown property and returns the expected values', function (assert) { + assert.expect(4); + const modelA = store.createRecord('account', { + type: TYPE_AUTH_METHOD_LDAP, + }); + const modelB = store.createRecord('account', { + type: TYPE_AUTH_METHOD_PASSWORD, + }); + const modelC = store.createRecord('account', { + type: TYPE_AUTH_METHOD_OIDC, + }); + const modelD = store.createRecord('account', { + type: 'no-such-type', + }); + assert.false(modelA.isUnknown); + assert.false(modelB.isUnknown); + assert.false(modelC.isUnknown); + assert.true(modelD.isUnknown); + }); }); diff --git a/addons/api/tests/unit/models/auth-method-test.js b/addons/api/tests/unit/models/auth-method-test.js index a908d2280..3ff01039d 100644 --- a/addons/api/tests/unit/models/auth-method-test.js +++ b/addons/api/tests/unit/models/auth-method-test.js @@ -61,7 +61,7 @@ module('Unit | Model | auth method', function (hooks) { await model.changeState('foobar'); }); - test('it has isPassword property and returns the expected values', async function (assert) { + test('it has isPassword property and returns the expected values', function (assert) { assert.expect(3); const modelA = store.createRecord('auth-method', { type: TYPE_AUTH_METHOD_PASSWORD, @@ -77,7 +77,7 @@ module('Unit | Model | auth method', function (hooks) { assert.false(modelC.isPassword); }); - test('it has isOIDC property and returns the expected values', async function (assert) { + test('it has isOIDC property and returns the expected values', function (assert) { assert.expect(3); const modelA = store.createRecord('auth-method', { type: TYPE_AUTH_METHOD_OIDC, @@ -93,7 +93,7 @@ module('Unit | Model | auth method', function (hooks) { assert.false(modelC.isOIDC); }); - test('it has isLDAP property and returns the expected values', async function (assert) { + test('it has isLDAP property and returns the expected values', function (assert) { assert.expect(3); const modelA = store.createRecord('auth-method', { type: TYPE_AUTH_METHOD_LDAP, @@ -109,7 +109,7 @@ module('Unit | Model | auth method', function (hooks) { assert.false(modelC.isLDAP); }); - test('it has isUnknown property and returns the expected values', async function (assert) { + test('it has isUnknown property and returns the expected values', function (assert) { assert.expect(4); const modelA = store.createRecord('auth-method', { type: TYPE_AUTH_METHOD_LDAP, diff --git a/ui/admin/app/abilities/account.js b/ui/admin/app/abilities/account.js new file mode 100644 index 000000000..5f6fcec87 --- /dev/null +++ b/ui/admin/app/abilities/account.js @@ -0,0 +1,25 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import AccountAbility from 'api/abilities/account'; +import { inject as service } from '@ember/service'; + +export default class OverrideAccountAbility extends AccountAbility { + // =service + @service features; + + /** + * These override abilities are temporary and just part of Phase 1 + * of LDAP auth method implementation. + */ + + get canAddAccount() { + return this.features.isEnabled('ldap-auth-methods') || !this.model.isLDAP; + } + + get canRemoveAccount() { + return this.features.isEnabled('ldap-auth-methods') || !this.model.isLDAP; + } +} diff --git a/ui/admin/app/abilities/auth-method.js b/ui/admin/app/abilities/auth-method.js index ebbf9b0cd..61ce714ea 100644 --- a/ui/admin/app/abilities/auth-method.js +++ b/ui/admin/app/abilities/auth-method.js @@ -4,18 +4,24 @@ */ import AuthMethodAbility from 'api/abilities/auth-method'; +import { inject as service } from '@ember/service'; export default class OverrideAuthMethodAbility extends AuthMethodAbility { + //service + @service features; + /** * These override abilities are temporary and just part of Phase 1 * of LDAP auth method implementation. */ get canRead() { - return !this.model.isLDAP && super.canRead; + return this.features.isEnabled('ldap-auth-methods') || !this.model.isLDAP + ? super.canRead + : false; } get canMakePrimary() { - return !this.model.isLDAP; + return this.features.isEnabled('ldap-auth-methods') || !this.model.isLDAP; } } diff --git a/ui/admin/tests/unit/abilities/account-test.js b/ui/admin/tests/unit/abilities/account-test.js new file mode 100644 index 000000000..914bacaaa --- /dev/null +++ b/ui/admin/tests/unit/abilities/account-test.js @@ -0,0 +1,80 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: MPL-2.0 + */ + +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; +import { + TYPE_AUTH_METHOD_LDAP, + TYPE_AUTH_METHOD_OIDC, + TYPE_AUTH_METHOD_PASSWORD, +} from 'api/models/auth-method'; + +module('Unit | Abilities | account', function (hooks) { + setupTest(hooks); + + let canService; + let store; + let features; + + hooks.beforeEach(function () { + canService = this.owner.lookup('service:can'); + store = this.owner.lookup('service:store'); + features = this.owner.lookup('service:features'); + }); + + test('can add ldap account to user when feature flag enabled', function (assert) { + assert.expect(1); + features.enable('ldap-auth-methods'); + const account = store.createRecord('account', { + type: TYPE_AUTH_METHOD_LDAP, + }); + assert.true(canService.can('addAccount account', account)); + }); + + test('can add non-ldap account to user', function (assert) { + assert.expect(2); + const account = store.createRecord('account', { + type: TYPE_AUTH_METHOD_OIDC, + }); + assert.true(canService.can('addAccount account', account)); + account.type = TYPE_AUTH_METHOD_PASSWORD; + assert.true(canService.can('addAccount account', account)); + }); + + test('cannot add ldap account to user when feature flag disabled', function (assert) { + assert.expect(1); + const account = store.createRecord('account', { + type: TYPE_AUTH_METHOD_LDAP, + }); + assert.false(canService.can('addAccount account', account)); + }); + + test('can remove ldap account from user when feature flag enabled', function (assert) { + assert.expect(1); + features.enable('ldap-auth-methods'); + const account = store.createRecord('account', { + type: TYPE_AUTH_METHOD_LDAP, + }); + assert.true(canService.can('removeAccount account', account)); + }); + + test('cannot remove ldap account from user when feature flag disabled', function (assert) { + assert.expect(1); + const account = store.createRecord('account', { + type: TYPE_AUTH_METHOD_LDAP, + }); + assert.false(canService.can('removeAccount account', account)); + }); + + test('can remove non-ldap account from user', function (assert) { + assert.expect(2); + const account = store.createRecord('account', { + type: TYPE_AUTH_METHOD_OIDC, + }); + assert.true(canService.can('removeAccount account', account)); + (account.type = TYPE_AUTH_METHOD_PASSWORD), + assert.true(canService.can('removeAccount account', account)); + }); +}); diff --git a/ui/admin/tests/unit/abilities/auth-method-test.js b/ui/admin/tests/unit/abilities/auth-method-test.js index 22cfa8699..66888a231 100644 --- a/ui/admin/tests/unit/abilities/auth-method-test.js +++ b/ui/admin/tests/unit/abilities/auth-method-test.js @@ -8,6 +8,7 @@ import { setupTest } from 'ember-qunit'; import { TYPE_AUTH_METHOD_LDAP, TYPE_AUTH_METHOD_OIDC, + TYPE_AUTH_METHOD_PASSWORD, } from 'api/models/auth-method'; module('Unit | Abilities | auth-method', function (hooks) { @@ -15,49 +16,60 @@ module('Unit | Abilities | auth-method', function (hooks) { let canService; let store; + let features; hooks.beforeEach(function () { canService = this.owner.lookup('service:can'); store = this.owner.lookup('service:store'); + features = this.owner.lookup('service:features'); }); - test('cannot read LDAP auth-method when authorized', function (assert) { - assert.expect(1); + test('can read LDAP auth-method when authorized and feature flag enabled', function (assert) { + assert.expect(2); + features.enable('ldap-auth-methods'); + const authMethod = store.createRecord('auth-method', { + authorized_actions: ['read'], + type: TYPE_AUTH_METHOD_LDAP, + }); + assert.true(canService.can('read auth-method', authMethod)); + authMethod.authorized_actions = []; + assert.false(canService.can('read auth-method', authMethod)); + }); + + test('cannot read LDAP auth-method when authorized and feature flag disabled', function (assert) { + assert.expect(2); const authMethod = store.createRecord('auth-method', { authorized_actions: ['read'], type: TYPE_AUTH_METHOD_LDAP, }); assert.false(canService.can('read auth-method', authMethod)); - }); - - test('cannot read LDAP auth-method when unauthorized', function (assert) { - assert.expect(1); - const authMethod = store.createRecord('auth-method', { - authorized_actions: [], - type: TYPE_AUTH_METHOD_LDAP, - }); + authMethod.authorized_actions = []; assert.false(canService.can('read auth-method', authMethod)); }); test('can read non-LDAP auth-method when authorized', function (assert) { - assert.expect(1); + assert.expect(2); const authMethod = store.createRecord('auth-method', { authorized_actions: ['read'], type: TYPE_AUTH_METHOD_OIDC, }); assert.true(canService.can('read auth-method', authMethod)); + authMethod.type = TYPE_AUTH_METHOD_PASSWORD; + assert.true(canService.can('read auth-method', authMethod)); }); test('cannot read non-LDAP auth-method when unauthorized', function (assert) { - assert.expect(1); + assert.expect(2); const authMethod = store.createRecord('auth-method', { authorized_actions: [], type: TYPE_AUTH_METHOD_OIDC, }); assert.false(canService.can('read auth-method', authMethod)); + authMethod.type = TYPE_AUTH_METHOD_PASSWORD; + assert.false(canService.can('read auth-method', authMethod)); }); - test('cannot make LDAP auth-method primary', function (assert) { + test('cannot make LDAP auth-method primary when feature flag disabled', function (assert) { assert.expect(1); const authMethod = store.createRecord('auth-method', { type: TYPE_AUTH_METHOD_LDAP, @@ -65,11 +77,22 @@ module('Unit | Abilities | auth-method', function (hooks) { assert.false(canService.can('makePrimary auth-method', authMethod)); }); - test('can make non-LDAP auth-method primary', function (assert) { + test('can make LDAP auth-method primary when feature flag enabled', function (assert) { assert.expect(1); + features.enable('ldap-auth-methods'); + const authMethod = store.createRecord('auth-method', { + type: TYPE_AUTH_METHOD_LDAP, + }); + assert.true(canService.can('makePrimary auth-method', authMethod)); + }); + + test('can make non-LDAP auth-method primary', function (assert) { + assert.expect(2); const authMethod = store.createRecord('auth-method', { type: TYPE_AUTH_METHOD_OIDC, }); assert.true(canService.can('makePrimary auth-method', authMethod)); + authMethod.type = TYPE_AUTH_METHOD_PASSWORD; + assert.true(canService.can('makePrimary auth-method', authMethod)); }); });