feat: 🎸 add feature to display and authenticate with global

This commit is contained in:
Randall Morey committed 2020-08-17 14:43:12 -04:00
1 parent 2a49d4601f
commit 4be7dc7003
7 files changed
+63 -37

No files matched your search

+3 -3
View File
@@ -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');
}
}
}
+16 -3
View File
@@ -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 });
+6 -1
View File
@@ -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 }
+26 -18
View File
@@ -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);
});
});
+1
View File
@@ -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.