fix: 🐛 filter out scopes with no auth methods (#1115)
* fix: 🐛 filter out scopes with no authenticatable auth methods
This commit is contained in:
1 parent
6c3e5ba4a8
commit
b6a811cbbd
12 files changed
+94
-40
No files matched your search
@@ -57,8 +57,23 @@ export default function () {
|
||||
|
||||
this.get(
|
||||
'/auth-methods',
|
||||
({ authMethods }, { queryParams: { scope_id: scopeId, filter } }) => {
|
||||
const resultSet = authMethods.where({ scopeId });
|
||||
({ authMethods }, { queryParams: { scope_id, recursive, filter } }) => {
|
||||
let resultSet;
|
||||
if (recursive && scope_id === 'global') {
|
||||
resultSet = authMethods.all();
|
||||
} else if (recursive) {
|
||||
resultSet = authMethods.where((authMethod) => {
|
||||
const authMethodModel = authMethods.find(authMethod.id);
|
||||
return (
|
||||
authMethod.scopeId === scope_id ||
|
||||
authMethodModel?.scope?.scope?.id === scope_id
|
||||
);
|
||||
});
|
||||
} else {
|
||||
resultSet = authMethods.where(
|
||||
(authMethod) => authMethod.scopeId === scope_id
|
||||
);
|
||||
}
|
||||
return resultSet.filter(makeBooleanFilter(filter));
|
||||
}
|
||||
);
|
||||
|
||||
@@ -12,6 +12,7 @@ export default factory.extend({
|
||||
'read',
|
||||
'update',
|
||||
'delete',
|
||||
'authenticate',
|
||||
],
|
||||
authorized_collection_actions: () => {
|
||||
return {
|
||||
|
||||
@@ -7,6 +7,7 @@ export default class ScopesScopeAuthenticateController extends Controller {
|
||||
* Moves the global scope to index 0.
|
||||
* @type {Array}
|
||||
*/
|
||||
|
||||
get sortedScopes() {
|
||||
return [
|
||||
...this.model.scopes.filter((scope) => scope.id === 'global'),
|
||||
|
||||
@@ -7,7 +7,7 @@ export default class ScopesScopeAuthenticateRoute extends Route {
|
||||
|
||||
@service session;
|
||||
@service router;
|
||||
|
||||
@service resourceFilterStore;
|
||||
// =methods
|
||||
|
||||
beforeModel() {
|
||||
@@ -20,13 +20,39 @@ export default class ScopesScopeAuthenticateRoute extends Route {
|
||||
* scope and all scopes (for org navigation).
|
||||
* @return {Promise} `{scope, scopes, authMethods}`
|
||||
*/
|
||||
model() {
|
||||
async model() {
|
||||
const { id: scope_id } = this.modelFor('scopes.scope');
|
||||
// Fetch auth methods for the current scope
|
||||
const authMethods = await this.resourceFilterStore.queryBy(
|
||||
'auth-method',
|
||||
{
|
||||
authorized_actions: [{ contains: 'authenticate' }],
|
||||
},
|
||||
{
|
||||
scope_id,
|
||||
}
|
||||
);
|
||||
// Preload all authenticatable auth methods into the store
|
||||
const authMethodsForAllScopes = await this.resourceFilterStore.queryBy(
|
||||
'auth-method',
|
||||
{
|
||||
authorized_actions: [{ contains: 'authenticate' }],
|
||||
},
|
||||
{
|
||||
scope_id: 'global',
|
||||
recursive: true,
|
||||
}
|
||||
);
|
||||
// Fetch org scopes
|
||||
// and filter out any that have no auth methods
|
||||
const scopes = this.modelFor('scopes').filter(
|
||||
({ id: scope_id, isOrg }) =>
|
||||
isOrg && authMethodsForAllScopes.filterBy('scopeID', scope_id).length
|
||||
);
|
||||
return hash({
|
||||
scope: this.modelFor('scopes.scope'),
|
||||
scopes: this.modelFor('scopes').filter((scope) => scope.isOrg),
|
||||
authMethods: this.store.query('auth-method', { scope_id }),
|
||||
|
||||
scopes,
|
||||
authMethods,
|
||||
// for integration testing:
|
||||
// authMethods: A([{
|
||||
// id: 'am_1234567890',
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
'auth.descriptions.authenticating-with-org'
|
||||
name=@model.scope.displayName
|
||||
}}</p>
|
||||
|
||||
<Rose::Dropdown
|
||||
@text={{t 'actions.choose-different-org'}}
|
||||
@icon='flight-icons/svg/org-16'
|
||||
@@ -22,6 +23,7 @@
|
||||
<dropdown.link @route='scopes.scope.authenticate' @model='global'>
|
||||
{{t 'titles.global'}}
|
||||
</dropdown.link>
|
||||
|
||||
{{#each this.sortedScopes as |scope|}}
|
||||
<dropdown.link
|
||||
@route='scopes.scope.authenticate'
|
||||
@@ -29,6 +31,7 @@
|
||||
>
|
||||
{{scope.displayName}}
|
||||
</dropdown.link>
|
||||
|
||||
{{/each}}
|
||||
</Rose::Dropdown>
|
||||
|
||||
@@ -75,19 +78,6 @@
|
||||
{{#if @model.authMethods}}
|
||||
{{outlet}}
|
||||
{{/if}}
|
||||
{{#unless @model.authMethods}}
|
||||
<Rose::Layout::Centered>
|
||||
<Rose::Message
|
||||
@title={{t 'resources.auth-method.messages.none.title'}}
|
||||
@icon='flight-icons/svg/alert-circle-16'
|
||||
as |message|
|
||||
>
|
||||
<message.description>
|
||||
{{t 'resources.auth-method.messages.none.description'}}
|
||||
</message.description>
|
||||
</Rose::Message>
|
||||
</Rose::Layout::Centered>
|
||||
{{/unless}}
|
||||
</:body>
|
||||
</Rose::Frame>
|
||||
</page.body>
|
||||
|
||||
@@ -86,7 +86,11 @@ module('Acceptance | accounts | set password', function (hooks) {
|
||||
'/accounts/:idMethod',
|
||||
(_, { params: { idMethod }, requestBody }) => {
|
||||
const attrs = JSON.parse(requestBody);
|
||||
assert.strictEqual(attrs.password, 'update password', 'new password is set');
|
||||
assert.strictEqual(
|
||||
attrs.password,
|
||||
'update password',
|
||||
'new password is set'
|
||||
);
|
||||
const id = idMethod.split(':')[0];
|
||||
return { id };
|
||||
}
|
||||
|
||||
@@ -113,16 +113,6 @@ module('Acceptance | authentication', function (hooks) {
|
||||
assert.strictEqual(currentURL(), authMethodAuthenticateURL);
|
||||
});
|
||||
|
||||
test('visiting auth methods authenticate route when there no methods shows a message', async function (assert) {
|
||||
assert.expect(2);
|
||||
authMethod.destroy();
|
||||
authMethodOIDC.destroy();
|
||||
await visit(authenticateURL);
|
||||
await a11yAudit();
|
||||
assert.strictEqual(currentURL(), authenticateURL);
|
||||
assert.ok(find('.rose-message'));
|
||||
});
|
||||
|
||||
test('visiting auth method when the scope cannot be loaded is still allowed', async function (assert) {
|
||||
assert.expect(1);
|
||||
this.server.get('/scopes', () => {
|
||||
|
||||
@@ -94,7 +94,10 @@ module('Acceptance | credential-libraries | update', function (hooks) {
|
||||
this.server.schema.credentialLibraries.all().models[0].name,
|
||||
'random string'
|
||||
);
|
||||
assert.strictEqual(find('[name="name"]').value, instances.credentialLibrary.name);
|
||||
assert.strictEqual(
|
||||
find('[name="name"]').value,
|
||||
instances.credentialLibrary.name
|
||||
);
|
||||
});
|
||||
|
||||
test('saving an existing credential library with invalid fields displays error messages', async function (assert) {
|
||||
|
||||
@@ -83,7 +83,10 @@ module('Acceptance | credential-stores | update', function (hooks) {
|
||||
await fillIn('[name="name"]', 'random string');
|
||||
await click('.rose-form-actions [type="button"]');
|
||||
assert.notEqual(instances.credentialStore.name, 'random string');
|
||||
assert.strictEqual(find('[name="name"]').value, instances.credentialStore.name);
|
||||
assert.strictEqual(
|
||||
find('[name="name"]').value,
|
||||
instances.credentialStore.name
|
||||
);
|
||||
});
|
||||
|
||||
test('saving an existing credential store with invalid fields displays error messages', async function (assert) {
|
||||
|
||||
@@ -71,7 +71,10 @@ module('Acceptance | managed-groups | create', function (hooks) {
|
||||
await fillIn('[name="name"]', 'Managed group name');
|
||||
await fillIn('[name="description"]', 'description');
|
||||
await click('form [type="submit"]:not(:disabled)');
|
||||
assert.strictEqual(this.server.db.managedGroups.length, managedGroupsCount + 1);
|
||||
assert.strictEqual(
|
||||
this.server.db.managedGroups.length,
|
||||
managedGroupsCount + 1
|
||||
);
|
||||
});
|
||||
|
||||
test('User can not create a new managed group without proper authorization', async function (assert) {
|
||||
|
||||
@@ -63,7 +63,10 @@ module('Acceptance | managed-groups | delete', function (hooks) {
|
||||
const managedGroupsCount = this.server.db.managedGroups.length;
|
||||
await visit(urls.managedGroup);
|
||||
await click('.rose-layout-page-actions .rose-dropdown-button-danger');
|
||||
assert.strictEqual(this.server.db.managedGroups.length, managedGroupsCount - 1);
|
||||
assert.strictEqual(
|
||||
this.server.db.managedGroups.length,
|
||||
managedGroupsCount - 1
|
||||
);
|
||||
});
|
||||
|
||||
test('User cannot delete a managed-group without proper authorization', async function (assert) {
|
||||
|
||||
@@ -60,7 +60,10 @@ module('Acceptance | roles | grants', function (hooks) {
|
||||
await visit(urls.grants);
|
||||
await a11yAudit();
|
||||
assert.strictEqual(currentURL(), urls.grants);
|
||||
assert.strictEqual(findAll(`${grantsForm} [name="grant"]`).length, grantsCount);
|
||||
assert.strictEqual(
|
||||
findAll(`${grantsForm} [name="grant"]`).length,
|
||||
grantsCount
|
||||
);
|
||||
});
|
||||
|
||||
test('cannot set grants without proper authorization', async function (assert) {
|
||||
@@ -129,7 +132,10 @@ module('Acceptance | roles | grants', function (hooks) {
|
||||
);
|
||||
});
|
||||
await visit(urls.grants);
|
||||
assert.strictEqual(findAll(`${grantsForm} [name="grant"]`).length, grantsCount);
|
||||
assert.strictEqual(
|
||||
findAll(`${grantsForm} [name="grant"]`).length,
|
||||
grantsCount
|
||||
);
|
||||
await fillIn(`${grantsForm} [name="grant"]`, 'id=123,action=delete');
|
||||
await click('.rose-form-actions [type="submit"]:not(:disabled)');
|
||||
assert.ok(find('[role="alert"]'));
|
||||
@@ -180,7 +186,10 @@ module('Acceptance | roles | grants', function (hooks) {
|
||||
);
|
||||
});
|
||||
await visit(urls.grants);
|
||||
assert.strictEqual(findAll(`${grantsForm} [name="grant"]`).length, grantsCount);
|
||||
assert.strictEqual(
|
||||
findAll(`${grantsForm} [name="grant"]`).length,
|
||||
grantsCount
|
||||
);
|
||||
await fillIn(`${newGrantForm} [name="grant"]`, 'id=123,action=delete');
|
||||
await click(`${newGrantForm} [type="submit"]:not(:disabled)`);
|
||||
await click('.rose-form-actions [type="submit"]:not(:disabled)');
|
||||
@@ -203,7 +212,10 @@ module('Acceptance | roles | grants', function (hooks) {
|
||||
await visit(urls.grants);
|
||||
await click(`${grantsForm} button`);
|
||||
await click('.rose-form-actions button:not([type="submit"])');
|
||||
assert.strictEqual(findAll(`${grantsForm} [name="grant"]`).length, grantsCount);
|
||||
assert.strictEqual(
|
||||
findAll(`${grantsForm} [name="grant"]`).length,
|
||||
grantsCount
|
||||
);
|
||||
});
|
||||
|
||||
test('shows error message on grant remove', async function (assert) {
|
||||
@@ -221,7 +233,10 @@ module('Acceptance | roles | grants', function (hooks) {
|
||||
);
|
||||
});
|
||||
await visit(urls.grants);
|
||||
assert.strictEqual(findAll(`${grantsForm} [name="grant"]`).length, grantsCount);
|
||||
assert.strictEqual(
|
||||
findAll(`${grantsForm} [name="grant"]`).length,
|
||||
grantsCount
|
||||
);
|
||||
await click(`${grantsForm} button:not([type="submit"])`);
|
||||
await click('.rose-form-actions [type="submit"]:not(:disabled)');
|
||||
assert.ok(find('[role="alert"]'));
|
||||
|
||||
Reference in new issue
Block a user