diff --git a/ui/core/app/routes/scopes.js b/ui/core/app/routes/scopes.js index 337b319c9..4f53d4955 100644 --- a/ui/core/app/routes/scopes.js +++ b/ui/core/app/routes/scopes.js @@ -5,14 +5,13 @@ export default class ScopesRoute extends Route { // =methods /** - * Attempt to load the specified scope from the API. This is allowed + * Attempt to load all scopes from the API. This is allowed * to fail, since in some cases the user may not have permission to read a * scope directly, but may have permission to read resources under it. - * If the scope fails to load, we still proceed using a temporary scope object - * consisting of only the specified ID. + * If scopes fails to load, we still proceed using an empty array. * @param {object} params * @param {string} params.scope_id - * @return {Promise{ScopeModel}} + * @return {Promise{[ScopeModel]}} */ model() { // NOTE: In the absence of a `scope_id` query parameter, this endpoint is diff --git a/ui/core/app/session-stores/application.js b/ui/core/app/session-stores/application.js index 48b3bc4be..401a98b44 100644 --- a/ui/core/app/session-stores/application.js +++ b/ui/core/app/session-stores/application.js @@ -14,7 +14,7 @@ export default class ApplicationSessionStore extends LocalStorageSessionStore { */ persist(sessionData) { this.addTokenToAuthorization(sessionData); - this.addScopeToSession(sessionData); + //this.addScopeToSession(sessionData); return super.persist(...arguments); } @@ -32,14 +32,6 @@ export default class ApplicationSessionStore extends LocalStorageSessionStore { if (token) adapter.headers.Authorization = `Bearer ${token}`; } - /** - * @param {object} sessionData - */ - addScopeToSession(sessionData) { - const scope = get(this, 'scope'); - const authenticated = get(sessionData, 'authenticated'); - if (scope && authenticated) authenticated.scope = scope; - } } // import CookieSessionStore from 'auth/session-stores/cookie'; diff --git a/ui/core/app/templates/scopes/index.hbs b/ui/core/app/templates/scopes/index.hbs index e2147cab0..22ebdf082 100644 --- a/ui/core/app/templates/scopes/index.hbs +++ b/ui/core/app/templates/scopes/index.hbs @@ -1 +1,22 @@ -{{outlet}} \ No newline at end of file +{{outlet}} + +{{#unless @model}} + + + +
+ + + + {{t "auth.descriptions.no-scopes"}} + + + +
+
+ +
+{{/unless}} diff --git a/ui/core/tests/acceptance/authentication-test.js b/ui/core/tests/acceptance/authentication-test.js index 3481337bb..478e2f1dd 100644 --- a/ui/core/tests/acceptance/authentication-test.js +++ b/ui/core/tests/acceptance/authentication-test.js @@ -2,6 +2,7 @@ import { module, test } from 'qunit'; import { visit, currentURL, fillIn, click, find } from '@ember/test-helpers'; import { setupApplicationTest } from 'ember-qunit'; import setupMirage from 'ember-cli-mirage/test-support/setup-mirage'; +import { Response } from 'miragejs'; import a11yAudit from 'ember-a11y-testing/test-support/audit'; import { currentSession, @@ -49,6 +50,16 @@ module('Acceptance | authentication', function (hooks) { 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); @@ -56,6 +67,35 @@ module('Acceptance | authentication', function (hooks) { assert.equal(currentURL(), authMethodAuthenticateURL); }); + test('visiting auth methods authenticate route when there no methods shows a message', async function (assert) { + assert.expect(2); + authMethod.destroy() + await visit(authenticateURL); + await a11yAudit(); + assert.equal(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); + orgScope.destroy(); + this.server.get('/scopes', ({ scopes }, { queryParams: { scope_id } }) => { + // Default parent scope is global + if (!scope_id) scope_id = 'global'; + const results = scopes.where(scope => { + return scope.scope ? scope.scope.id === scope_id : false + }); + if (!results.length) { + return new Response(404); + } else { + return results; + } + }); + await visit(authMethodAuthenticateURL); + await a11yAudit(); + assert.equal(currentURL(), authMethodAuthenticateURL); + }); + test('visiting any authentication parent route while unauthenticated redirects to first authenticate method', async function (assert) { assert.expect(3); await visit(indexURL); diff --git a/ui/core/tests/unit/session-stores/application.js b/ui/core/tests/unit/session-stores/application-test.js similarity index 75% rename from ui/core/tests/unit/session-stores/application.js rename to ui/core/tests/unit/session-stores/application-test.js index dd7132709..6a3e908bc 100644 --- a/ui/core/tests/unit/session-stores/application.js +++ b/ui/core/tests/unit/session-stores/application-test.js @@ -38,16 +38,4 @@ module('Unit | Session Store | application', function (hooks) { assert.equal(applicationAdapter.headers.foo, 'bar'); assert.equal(applicationAdapter.headers.Authorization, 'Bearer token1234'); }); - - test('it adds an org_id to the session data if authenticating within a scope', async function (assert) { - assert.expect(2); - let sessionData = {}; - sessionStore.set('scope', {}); - sessionStore.persist(sessionData); - assert.notOk(sessionData.authenticated, 'There is no authenticated key'); - sessionData = { authenticated: {} }; - sessionStore.set('scope', { org: { id: 1 } }); - sessionStore.persist(sessionData); - assert.equal(sessionData.authenticated.org_id, 1); - }); }); diff --git a/ui/core/translations/en-us.yaml b/ui/core/translations/en-us.yaml index e563eb166..d2b11942c 100644 --- a/ui/core/translations/en-us.yaml +++ b/ui/core/translations/en-us.yaml @@ -6,16 +6,16 @@ actions: help: Need help? authenticate: Authenticate deauthenticate: Deauthenticate - choose-org: Choose Org - choose-different-org: Choose a Different Org + choose-org: Choose Scope + choose-different-org: Choose a Different Scope auth: titles: - no-orgs: No Organizations Available + no-scopes: No Scopes Available no-methods: No Authentication Method descriptions: - no-orgs: No organizations were found. To authenticate, ask your administrator to create an organization and grant you access. - no-methods: No authentication methods were found for this organization. Switch organizations and try again. - choose-org: Choose an organization to authenticate. + no-scopes: No scopes were found. To authenticate, ask your administrator to create an scope and grant you access. + no-methods: No authentication methods were found for this scope. Switch scopes and try again. + choose-org: Choose a scope to authenticate. authenticating-with-org: "You're authenticating with {name}." method-types: password: Password @@ -84,7 +84,7 @@ notify: save-success: Saved succesfully. delete-success: Deleted successfully. dev: - default-org: Default Org + default-org: Default Scope menu-item: Menu item button-menu-item: Button menu item section: Section