feat: 🎸 add feature to display and authenticate with global
This commit is contained in:
7 files changed
+63
-37
No files matched your search
@@ -15,15 +15,15 @@ export default class ScopesIndexRoute extends Route {
|
||||
* @param {[ScopeModel]} model
|
||||
* @param {?ScopeModel} model.firstObject
|
||||
*/
|
||||
redirect({ firstObject }) {
|
||||
redirect() {
|
||||
const authenticatedScopeID = get(
|
||||
this.session,
|
||||
'data.authenticated.scope.id'
|
||||
);
|
||||
if (authenticatedScopeID) {
|
||||
this.transitionTo('scopes.scope', authenticatedScopeID);
|
||||
} else if (firstObject) {
|
||||
this.transitionTo('scopes.scope', firstObject.id);
|
||||
} else {
|
||||
this.transitionTo('scopes.scope', 'global');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,12 @@
|
||||
import Route from '@ember/routing/route';
|
||||
import { inject as service } from '@ember/service';
|
||||
|
||||
export default class ScopesScopeRoute extends Route {
|
||||
|
||||
// =services
|
||||
|
||||
@service intl;
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
@@ -14,11 +20,18 @@ export default class ScopesScopeRoute extends Route {
|
||||
* @return {Promise{ScopeModel}}
|
||||
*/
|
||||
model({ scope_id: id }) {
|
||||
// Since only global and org scopes are authenticatable, we can infer type
|
||||
// from ID because global has a fixed ID.
|
||||
const scopeType = id === 'global' ? 'global' : 'org';
|
||||
return this.store.findRecord('scope', id).catch(() => {
|
||||
const maybeExistingScope = this.store.peekRecord('scope', id);
|
||||
// TODO it's unclear if creating a temporary unsaved scope is reliable
|
||||
// we may need to revert to a POJO.
|
||||
return maybeExistingScope || this.store.createRecord('scope', { id });
|
||||
const scopeOptions = { id, scopeType };
|
||||
if (scopeType === 'global') {
|
||||
scopeOptions.name = this.intl.t('titles.global');
|
||||
}
|
||||
return maybeExistingScope ||
|
||||
this.store.createRecord('scope', scopeOptions);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
@@ -7,12 +7,6 @@ export default class ScopesScopeAuthenticateRoute extends Route {
|
||||
|
||||
@service session;
|
||||
|
||||
// =attributes
|
||||
|
||||
// TODO: this assumes we're in an org scope, but the "landing"
|
||||
// for global scope is probably different.
|
||||
routeIfAlreadyAuthenticated = 'scopes.scope.projects';
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
@@ -37,7 +31,12 @@ export default class ScopesScopeAuthenticateRoute extends Route {
|
||||
|
||||
redirect() {
|
||||
if (this.session.isAuthenticated) {
|
||||
this.transitionTo(this.routeIfAlreadyAuthenticated);
|
||||
const scope = this.modelFor('scopes.scope');
|
||||
if (scope.isGlobal) {
|
||||
this.transitionTo('scopes.scope.orgs');
|
||||
} else {
|
||||
this.transitionTo('scopes.scope.projects');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,10 +9,6 @@ export default class ScopesScopeAuthenticateMethodRoute extends Route {
|
||||
@service notify;
|
||||
@service intl;
|
||||
|
||||
// =attributes
|
||||
|
||||
routeAfterAuthentication = 'scopes.scope.projects';
|
||||
|
||||
// =methods
|
||||
|
||||
/**
|
||||
@@ -55,7 +51,11 @@ export default class ScopesScopeAuthenticateMethodRoute extends Route {
|
||||
requestCookies,
|
||||
{ scope, authMethod }
|
||||
);
|
||||
this.transitionTo(this.routeAfterAuthentication);
|
||||
if (scope.isGlobal) {
|
||||
this.transitionTo('scopes.scope.orgs');
|
||||
} else {
|
||||
this.transitionTo('scopes.scope.projects');
|
||||
}
|
||||
} catch (e) {
|
||||
const errorMessage = this.intl.t('errors.titles.authentication-failed');
|
||||
this.notify.error(errorMessage, { closeAfter: null });
|
||||
|
||||
@@ -2,7 +2,12 @@ export default function(server) {
|
||||
|
||||
// Scope resources
|
||||
|
||||
const globalScope = server.create('scope', { id: 'global' }); // creates a global scope
|
||||
// creates a global scope
|
||||
const globalScope = server.create('scope', {
|
||||
id: 'global',
|
||||
type: 'global',
|
||||
name: 'Global'
|
||||
});
|
||||
const orgScope = server.createList('scope', 3, {
|
||||
type: 'org',
|
||||
scope: { id: globalScope.id, type: globalScope.type }
|
||||
|
||||
@@ -23,8 +23,11 @@ module('Acceptance | authentication', function (hooks) {
|
||||
let scope;
|
||||
let authMethod;
|
||||
let authMethodID;
|
||||
let globalAuthenticateURL;
|
||||
let authenticateURL;
|
||||
let authMethodAuthenticateURL;
|
||||
let authMethodGlobalAuthenticateURL;
|
||||
let orgsURL;
|
||||
let projectsURL;
|
||||
|
||||
hooks.beforeEach(function () {
|
||||
@@ -45,21 +48,14 @@ module('Acceptance | authentication', function (hooks) {
|
||||
authMethodID = authMethod.id;
|
||||
scopesURL = `/scopes`;
|
||||
orgScopeURL = `/scopes/${orgScopeID}`;
|
||||
globalAuthenticateURL = `/scopes/global/authenticate`;
|
||||
authenticateURL = `/scopes/${orgScopeID}/authenticate`;
|
||||
authMethodGlobalAuthenticateURL = `/scopes/global/authenticate/${authMethodID}`;
|
||||
authMethodAuthenticateURL = `/scopes/${orgScopeID}/authenticate/${authMethodID}`;
|
||||
orgsURL = `/scopes/global/orgs`;
|
||||
projectsURL = `/scopes/${orgScopeID}/projects`;
|
||||
});
|
||||
|
||||
|
||||
test('visiting scopes when there are none shows a message', async function (assert) {
|
||||
assert.expect(2);
|
||||
this.server.get('/scopes', () => new Response(404));
|
||||
await visit(scopesURL);
|
||||
await a11yAudit();
|
||||
assert.equal(currentURL(), scopesURL);
|
||||
assert.ok(find('.rose-message'));
|
||||
});
|
||||
|
||||
test('visiting auth methods authenticate route redirects to first auth method', async function (assert) {
|
||||
assert.expect(1);
|
||||
await visit(authenticateURL);
|
||||
@@ -96,19 +92,19 @@ module('Acceptance | authentication', function (hooks) {
|
||||
assert.equal(currentURL(), authMethodAuthenticateURL);
|
||||
});
|
||||
|
||||
test('visiting any authentication parent route while unauthenticated redirects to first authenticate method', async function (assert) {
|
||||
test('visiting any authentication parent route while unauthenticated redirects to first global authenticate method', async function (assert) {
|
||||
assert.expect(3);
|
||||
await visit(indexURL);
|
||||
assert.equal(currentURL(), authMethodAuthenticateURL);
|
||||
assert.equal(currentURL(), authMethodGlobalAuthenticateURL);
|
||||
await visit(scopesURL);
|
||||
assert.equal(currentURL(), authMethodAuthenticateURL);
|
||||
assert.equal(currentURL(), authMethodGlobalAuthenticateURL);
|
||||
assert.notOk(currentSession().isAuthenticated);
|
||||
});
|
||||
|
||||
test('visiting projects while unauthenticated redirects to first authenticate method', async function (assert) {
|
||||
test('visiting projects while unauthenticated redirects to first global authenticate method', async function (assert) {
|
||||
assert.expect(2);
|
||||
await visit(projectsURL);
|
||||
assert.equal(currentURL(), authMethodAuthenticateURL);
|
||||
assert.equal(currentURL(), authMethodGlobalAuthenticateURL);
|
||||
assert.notOk(currentSession().isAuthenticated);
|
||||
});
|
||||
|
||||
@@ -119,7 +115,7 @@ module('Acceptance | authentication', function (hooks) {
|
||||
assert.equal(currentURL(), authMethodAuthenticateURL);
|
||||
});
|
||||
|
||||
test('visiting any authentication parent route while already authenticated redirects to projects', async function (assert) {
|
||||
test('visiting any authentication parent route while already authenticated with an org redirects to projects', async function (assert) {
|
||||
assert.expect(6);
|
||||
authenticateSession({ scope });
|
||||
await visit(indexURL);
|
||||
@@ -135,6 +131,18 @@ module('Acceptance | authentication', function (hooks) {
|
||||
assert.ok(currentSession().isAuthenticated);
|
||||
});
|
||||
|
||||
test('visiting index or scopes routes while already authenticated with global redirects to orgs', async function (assert) {
|
||||
assert.expect(4);
|
||||
authenticateSession({ scope: { id: globalScope.id, type: globalScope.type } });
|
||||
await visit(indexURL);
|
||||
assert.equal(currentURL(), orgsURL);
|
||||
await visit(scopesURL);
|
||||
assert.equal(currentURL(), orgsURL);
|
||||
await visit(globalAuthenticateURL);
|
||||
assert.equal(currentURL(), orgsURL);
|
||||
assert.ok(currentSession().isAuthenticated);
|
||||
});
|
||||
|
||||
test('failed authentication shows a notification message', async function (assert) {
|
||||
assert.expect(3);
|
||||
await visit(authMethodAuthenticateURL);
|
||||
@@ -157,7 +165,7 @@ module('Acceptance | authentication', function (hooks) {
|
||||
assert.ok(currentSession().isAuthenticated);
|
||||
});
|
||||
|
||||
test('deauthentication redirects to first authenticate method', async function (assert) {
|
||||
test('deauthentication redirects to first global authenticate method', async function (assert) {
|
||||
assert.expect(3);
|
||||
await visit(authMethodAuthenticateURL);
|
||||
await fillIn('[name="identification"]', 'test');
|
||||
@@ -166,6 +174,6 @@ module('Acceptance | authentication', function (hooks) {
|
||||
assert.ok(currentSession().isAuthenticated);
|
||||
await click('.rose-button-header-dropdown');
|
||||
assert.notOk(currentSession().isAuthenticated);
|
||||
assert.equal(currentURL(), authMethodAuthenticateURL);
|
||||
assert.equal(currentURL(), authMethodGlobalAuthenticateURL);
|
||||
});
|
||||
});
|
||||
@@ -52,6 +52,7 @@ titles:
|
||||
grants: Permissions
|
||||
new-grant: New Grant
|
||||
principals: Principals
|
||||
global: Global
|
||||
descriptions:
|
||||
host-catalogs: Overview of collections of hosts and host sets.
|
||||
empty-set: There are no items to display yet. You may be able to add items or try back later.
|
||||
|
||||
Reference in new issue
Block a user