refactor: 💡 account and auth-method abilities (#1691)
* refactor: 💡 account and auth-method abilities * refactor: 💡 add update & delete abilities & unit tests
This commit is contained in:
1 parent
e8a10b3131
commit
6dd0423923
14 files changed
+551
-51
No files matched your search
@@ -11,6 +11,30 @@ import ModelAbility from './model';
|
|||||||
export default class AccountAbility extends ModelAbility {
|
export default class AccountAbility extends ModelAbility {
|
||||||
// =permissions
|
// =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}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -17,4 +17,18 @@ export default class AuthMethodAbility extends ModelAbility {
|
|||||||
get canRead() {
|
get canRead() {
|
||||||
return !this.model.isUnknown && this.hasAuthorizedAction('read');
|
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');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -4,8 +4,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import GeneratedAccountModel from '../generated/models/account';
|
import GeneratedAccountModel from '../generated/models/account';
|
||||||
import { computed } from '@ember/object';
|
import {
|
||||||
import { equal } from '@ember/object/computed';
|
TYPE_AUTH_METHOD_PASSWORD,
|
||||||
|
TYPE_AUTH_METHOD_OIDC,
|
||||||
|
TYPE_AUTH_METHOD_LDAP,
|
||||||
|
TYPES_AUTH_METHOD,
|
||||||
|
} from './auth-method';
|
||||||
|
|
||||||
export default class AccountModel extends GeneratedAccountModel {
|
export default class AccountModel extends GeneratedAccountModel {
|
||||||
// =attributes
|
// =attributes
|
||||||
@@ -13,18 +17,35 @@ export default class AccountModel extends GeneratedAccountModel {
|
|||||||
/**
|
/**
|
||||||
* @type {boolean}
|
* @type {boolean}
|
||||||
*/
|
*/
|
||||||
@equal('type', 'password') isPassword;
|
get isPassword() {
|
||||||
|
return this.type === TYPE_AUTH_METHOD_PASSWORD;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {boolean}
|
* @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.
|
* Convenience for getting username in account.
|
||||||
* @type {string}
|
* @type {string}
|
||||||
*/
|
*/
|
||||||
@computed('{email,full_name,login_name}')
|
|
||||||
get accountName() {
|
get accountName() {
|
||||||
const { email, full_name, login_name } = this;
|
const { email, full_name, login_name } = this;
|
||||||
return email || full_name || login_name;
|
return email || full_name || login_name;
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) HashiCorp, Inc.
|
||||||
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
export { default } from 'api/abilities/auth-method';
|
||||||
@@ -7,6 +7,11 @@ import factory from '../generated/factories/account';
|
|||||||
import { faker } from '@faker-js/faker';
|
import { faker } from '@faker-js/faker';
|
||||||
import permissions from '../helpers/permissions';
|
import permissions from '../helpers/permissions';
|
||||||
import generateId from '../helpers/id';
|
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({
|
export default factory.extend({
|
||||||
authorized_actions: () =>
|
authorized_actions: () =>
|
||||||
@@ -22,9 +27,10 @@ export default factory.extend({
|
|||||||
|
|
||||||
attributes() {
|
attributes() {
|
||||||
switch (this.type) {
|
switch (this.type) {
|
||||||
case 'password':
|
case TYPE_AUTH_METHOD_PASSWORD:
|
||||||
|
case TYPE_AUTH_METHOD_LDAP:
|
||||||
return { login_name: faker.random.words() };
|
return { login_name: faker.random.words() };
|
||||||
case 'oidc':
|
case TYPE_AUTH_METHOD_OIDC:
|
||||||
return {
|
return {
|
||||||
issuer: faker.internet.ip(),
|
issuer: faker.internet.ip(),
|
||||||
subject: 'sub',
|
subject: 'sub',
|
||||||
|
|||||||
@@ -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));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -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));
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -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));
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -5,19 +5,30 @@
|
|||||||
|
|
||||||
import { module, test } from 'qunit';
|
import { module, test } from 'qunit';
|
||||||
import { setupTest } from 'ember-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) {
|
module('Unit | Model | account', function (hooks) {
|
||||||
setupTest(hooks);
|
setupTest(hooks);
|
||||||
|
|
||||||
|
let store;
|
||||||
|
|
||||||
|
hooks.beforeEach(function () {
|
||||||
|
store = this.owner.lookup('service:store');
|
||||||
|
});
|
||||||
|
|
||||||
test('it exists', function (assert) {
|
test('it exists', function (assert) {
|
||||||
let store = this.owner.lookup('service:store');
|
store = this.owner.lookup('service:store');
|
||||||
let model = store.createRecord('account', {});
|
let model = store.createRecord('account', {});
|
||||||
assert.ok(model);
|
assert.ok(model);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('it has an accountName attribute for password account', function (assert) {
|
test('it has an accountName attribute for password account', function (assert) {
|
||||||
assert.expect(2);
|
assert.expect(2);
|
||||||
const store = this.owner.lookup('service:store');
|
store = this.owner.lookup('service:store');
|
||||||
let model = store.createRecord('account', {
|
let model = store.createRecord('account', {
|
||||||
type: 'password',
|
type: 'password',
|
||||||
});
|
});
|
||||||
@@ -25,4 +36,72 @@ module('Unit | Model | account', function (hooks) {
|
|||||||
model.login_name = 'foobar';
|
model.login_name = 'foobar';
|
||||||
assert.strictEqual(model.accountName, '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);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
@@ -61,7 +61,7 @@ module('Unit | Model | auth method', function (hooks) {
|
|||||||
await model.changeState('foobar');
|
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);
|
assert.expect(3);
|
||||||
const modelA = store.createRecord('auth-method', {
|
const modelA = store.createRecord('auth-method', {
|
||||||
type: TYPE_AUTH_METHOD_PASSWORD,
|
type: TYPE_AUTH_METHOD_PASSWORD,
|
||||||
@@ -77,7 +77,7 @@ module('Unit | Model | auth method', function (hooks) {
|
|||||||
assert.false(modelC.isPassword);
|
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);
|
assert.expect(3);
|
||||||
const modelA = store.createRecord('auth-method', {
|
const modelA = store.createRecord('auth-method', {
|
||||||
type: TYPE_AUTH_METHOD_OIDC,
|
type: TYPE_AUTH_METHOD_OIDC,
|
||||||
@@ -93,7 +93,7 @@ module('Unit | Model | auth method', function (hooks) {
|
|||||||
assert.false(modelC.isOIDC);
|
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);
|
assert.expect(3);
|
||||||
const modelA = store.createRecord('auth-method', {
|
const modelA = store.createRecord('auth-method', {
|
||||||
type: TYPE_AUTH_METHOD_LDAP,
|
type: TYPE_AUTH_METHOD_LDAP,
|
||||||
@@ -109,7 +109,7 @@ module('Unit | Model | auth method', function (hooks) {
|
|||||||
assert.false(modelC.isLDAP);
|
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);
|
assert.expect(4);
|
||||||
const modelA = store.createRecord('auth-method', {
|
const modelA = store.createRecord('auth-method', {
|
||||||
type: TYPE_AUTH_METHOD_LDAP,
|
type: TYPE_AUTH_METHOD_LDAP,
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,18 +4,24 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import AuthMethodAbility from 'api/abilities/auth-method';
|
import AuthMethodAbility from 'api/abilities/auth-method';
|
||||||
|
import { inject as service } from '@ember/service';
|
||||||
|
|
||||||
export default class OverrideAuthMethodAbility extends AuthMethodAbility {
|
export default class OverrideAuthMethodAbility extends AuthMethodAbility {
|
||||||
|
//service
|
||||||
|
@service features;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* These override abilities are temporary and just part of Phase 1
|
* These override abilities are temporary and just part of Phase 1
|
||||||
* of LDAP auth method implementation.
|
* of LDAP auth method implementation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
get canRead() {
|
get canRead() {
|
||||||
return !this.model.isLDAP && super.canRead;
|
return this.features.isEnabled('ldap-auth-methods') || !this.model.isLDAP
|
||||||
|
? super.canRead
|
||||||
|
: false;
|
||||||
}
|
}
|
||||||
|
|
||||||
get canMakePrimary() {
|
get canMakePrimary() {
|
||||||
return !this.model.isLDAP;
|
return this.features.isEnabled('ldap-auth-methods') || !this.model.isLDAP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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));
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -8,6 +8,7 @@ import { setupTest } from 'ember-qunit';
|
|||||||
import {
|
import {
|
||||||
TYPE_AUTH_METHOD_LDAP,
|
TYPE_AUTH_METHOD_LDAP,
|
||||||
TYPE_AUTH_METHOD_OIDC,
|
TYPE_AUTH_METHOD_OIDC,
|
||||||
|
TYPE_AUTH_METHOD_PASSWORD,
|
||||||
} from 'api/models/auth-method';
|
} from 'api/models/auth-method';
|
||||||
|
|
||||||
module('Unit | Abilities | auth-method', function (hooks) {
|
module('Unit | Abilities | auth-method', function (hooks) {
|
||||||
@@ -15,49 +16,60 @@ module('Unit | Abilities | auth-method', function (hooks) {
|
|||||||
|
|
||||||
let canService;
|
let canService;
|
||||||
let store;
|
let store;
|
||||||
|
let features;
|
||||||
|
|
||||||
hooks.beforeEach(function () {
|
hooks.beforeEach(function () {
|
||||||
canService = this.owner.lookup('service:can');
|
canService = this.owner.lookup('service:can');
|
||||||
store = this.owner.lookup('service:store');
|
store = this.owner.lookup('service:store');
|
||||||
|
features = this.owner.lookup('service:features');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('cannot read LDAP auth-method when authorized', function (assert) {
|
test('can read LDAP auth-method when authorized and feature flag enabled', function (assert) {
|
||||||
assert.expect(1);
|
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', {
|
const authMethod = store.createRecord('auth-method', {
|
||||||
authorized_actions: ['read'],
|
authorized_actions: ['read'],
|
||||||
type: TYPE_AUTH_METHOD_LDAP,
|
type: TYPE_AUTH_METHOD_LDAP,
|
||||||
});
|
});
|
||||||
assert.false(canService.can('read auth-method', authMethod));
|
assert.false(canService.can('read auth-method', authMethod));
|
||||||
});
|
authMethod.authorized_actions = [];
|
||||||
|
|
||||||
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,
|
|
||||||
});
|
|
||||||
assert.false(canService.can('read auth-method', authMethod));
|
assert.false(canService.can('read auth-method', authMethod));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('can read non-LDAP auth-method when authorized', function (assert) {
|
test('can read non-LDAP auth-method when authorized', function (assert) {
|
||||||
assert.expect(1);
|
assert.expect(2);
|
||||||
const authMethod = store.createRecord('auth-method', {
|
const authMethod = store.createRecord('auth-method', {
|
||||||
authorized_actions: ['read'],
|
authorized_actions: ['read'],
|
||||||
type: TYPE_AUTH_METHOD_OIDC,
|
type: TYPE_AUTH_METHOD_OIDC,
|
||||||
});
|
});
|
||||||
assert.true(canService.can('read auth-method', authMethod));
|
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) {
|
test('cannot read non-LDAP auth-method when unauthorized', function (assert) {
|
||||||
assert.expect(1);
|
assert.expect(2);
|
||||||
const authMethod = store.createRecord('auth-method', {
|
const authMethod = store.createRecord('auth-method', {
|
||||||
authorized_actions: [],
|
authorized_actions: [],
|
||||||
type: TYPE_AUTH_METHOD_OIDC,
|
type: TYPE_AUTH_METHOD_OIDC,
|
||||||
});
|
});
|
||||||
assert.false(canService.can('read auth-method', authMethod));
|
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);
|
assert.expect(1);
|
||||||
const authMethod = store.createRecord('auth-method', {
|
const authMethod = store.createRecord('auth-method', {
|
||||||
type: TYPE_AUTH_METHOD_LDAP,
|
type: TYPE_AUTH_METHOD_LDAP,
|
||||||
@@ -65,11 +77,22 @@ module('Unit | Abilities | auth-method', function (hooks) {
|
|||||||
assert.false(canService.can('makePrimary auth-method', authMethod));
|
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);
|
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', {
|
const authMethod = store.createRecord('auth-method', {
|
||||||
type: TYPE_AUTH_METHOD_OIDC,
|
type: TYPE_AUTH_METHOD_OIDC,
|
||||||
});
|
});
|
||||||
assert.true(canService.can('makePrimary auth-method', authMethod));
|
assert.true(canService.can('makePrimary auth-method', authMethod));
|
||||||
|
authMethod.type = TYPE_AUTH_METHOD_PASSWORD;
|
||||||
|
assert.true(canService.can('makePrimary auth-method', authMethod));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
Reference in new issue
Block a user