diff --git a/changelog/16466.txt b/changelog/16466.txt new file mode 100644 index 000000000..1b5fb3c79 --- /dev/null +++ b/changelog/16466.txt @@ -0,0 +1,3 @@ +```release-note:bug +ui: Fix issue logging in with JWT auth method +``` diff --git a/ui/app/components/auth-form.js b/ui/app/components/auth-form.js index 8497d76ff..6d4208ce2 100644 --- a/ui/app/components/auth-form.js +++ b/ui/app/components/auth-form.js @@ -260,10 +260,9 @@ export default Component.extend(DEFAULTS, { this.setProperties({ error: null, }); - // if callback from oidc or jwt we have a token at this point - let backend = ['oidc', 'jwt'].includes(this.providerName) - ? this.getAuthBackend('token') - : this.selectedAuthBackend || {}; + // if callback from oidc we have a token at this point + let backend = + this.providerName === 'oidc' ? this.getAuthBackend('token') : this.selectedAuthBackend || {}; let backendMeta = BACKENDS.find( (b) => (b.type || '').toLowerCase() === (backend.type || '').toLowerCase() ); diff --git a/ui/tests/acceptance/jwt-auth-method-test.js b/ui/tests/acceptance/jwt-auth-method-test.js new file mode 100644 index 000000000..6e5d4d032 --- /dev/null +++ b/ui/tests/acceptance/jwt-auth-method-test.js @@ -0,0 +1,92 @@ +import { module, test } from 'qunit'; +import { setupApplicationTest } from 'ember-qunit'; +import { click, visit, fillIn } from '@ember/test-helpers'; +import { setupMirage } from 'ember-cli-mirage/test-support'; +import sinon from 'sinon'; +import { Response } from 'miragejs'; +import { ERROR_JWT_LOGIN } from 'vault/components/auth-jwt'; + +module('Acceptance | jwt auth method', function (hooks) { + setupApplicationTest(hooks); + setupMirage(hooks); + + hooks.beforeEach(function () { + this.stub = sinon.stub(); + this.server.post( + '/auth/:path/oidc/auth_url', + () => + new Response( + 400, + { 'Content-Type': 'application/json' }, + JSON.stringify({ errors: [ERROR_JWT_LOGIN] }) + ) + ); + this.server.get('/auth/foo/oidc/callback', () => ({ + auth: { client_token: 'root' }, + })); + }); + + test('it works correctly with default name and no role', async function (assert) { + assert.expect(6); + this.server.post('/auth/jwt/login', (schema, req) => { + const { jwt, role } = JSON.parse(req.requestBody); + assert.ok(true, 'request made to auth/jwt/login after submit'); + assert.equal(jwt, 'my-test-jwt-token', 'JWT token is sent in body'); + assert.equal(role, undefined, 'role is not sent in body when not filled in'); + req.passthrough(); + }); + await visit('/vault/auth'); + await fillIn('[data-test-select="auth-method"]', 'jwt'); + assert.dom('[data-test-role]').exists({ count: 1 }, 'Role input exists'); + assert.dom('[data-test-jwt]').exists({ count: 1 }, 'JWT input exists'); + await fillIn('[data-test-jwt]', 'my-test-jwt-token'); + await click('[data-test-auth-submit]'); + assert.dom('[data-test-error]').exists('Failed login'); + }); + + test('it works correctly with default name and a role', async function (assert) { + assert.expect(7); + this.server.post('/auth/jwt/login', (schema, req) => { + const { jwt, role } = JSON.parse(req.requestBody); + assert.ok(true, 'request made to auth/jwt/login after login'); + assert.equal(jwt, 'my-test-jwt-token', 'JWT token is sent in body'); + assert.equal(role, 'some-role', 'role is sent in the body when filled in'); + req.passthrough(); + }); + await visit('/vault/auth'); + await fillIn('[data-test-select="auth-method"]', 'jwt'); + assert.dom('[data-test-role]').exists({ count: 1 }, 'Role input exists'); + assert.dom('[data-test-jwt]').exists({ count: 1 }, 'JWT input exists'); + await fillIn('[data-test-role]', 'some-role'); + await fillIn('[data-test-jwt]', 'my-test-jwt-token'); + assert.dom('[data-test-jwt]').exists({ count: 1 }, 'JWT input exists'); + await click('[data-test-auth-submit]'); + assert.dom('[data-test-error]').exists('Failed login'); + }); + + test('it works correctly with custom endpoint and a role', async function (assert) { + assert.expect(6); + this.server.get('/sys/internal/ui/mounts', () => ({ + data: { + auth: { + 'test-jwt/': { description: '', options: {}, type: 'jwt' }, + }, + }, + })); + this.server.post('/auth/test-jwt/login', (schema, req) => { + const { jwt, role } = JSON.parse(req.requestBody); + assert.ok(true, 'request made to auth/custom-jwt-login after login'); + assert.equal(jwt, 'my-test-jwt-token', 'JWT token is sent in body'); + assert.equal(role, 'some-role', 'role is sent in body when filled in'); + req.passthrough(); + }); + await visit('/vault/auth'); + await click('[data-test-auth-method-link="jwt"]'); + assert.dom('[data-test-role]').exists({ count: 1 }, 'Role input exists'); + assert.dom('[data-test-jwt]').exists({ count: 1 }, 'JWT input exists'); + await fillIn('[data-test-role]', 'some-role'); + await fillIn('[data-test-jwt]', 'my-test-jwt-token'); + await click('[data-test-auth-submit]'); + assert.dom('[data-test-error]').exists('Failed login'); + }); +}); diff --git a/ui/tests/acceptance/secrets/backend/pki/cert-test.js b/ui/tests/acceptance/secrets/backend/pki/cert-test.js index 5b7adfc77..0824cd9ce 100644 --- a/ui/tests/acceptance/secrets/backend/pki/cert-test.js +++ b/ui/tests/acceptance/secrets/backend/pki/cert-test.js @@ -1,4 +1,4 @@ -import { currentRouteName, settled } from '@ember/test-helpers'; +import { currentRouteName, currentURL, settled } from '@ember/test-helpers'; import { module, test } from 'qunit'; import { setupApplicationTest } from 'ember-qunit'; import editPage from 'vault/tests/pages/secrets/backend/pki/edit-role'; @@ -52,11 +52,12 @@ elRplAzrMF4= }; test('it issues a cert', async function (assert) { - assert.expect(9); - await setup(assert); + assert.expect(10); + const mount = await setup(assert); await settled(); await generatePage.issueCert('foo'); await settled(); + assert.equal(currentURL(), `/vault/secrets/${mount}/credentials/role?action=issue`); assert.dom(SELECTORS.certificate).exists('displays masked certificate'); assert.dom(SELECTORS.commonName).exists('displays common name'); assert.dom(SELECTORS.issueDate).exists('displays issue date'); @@ -84,13 +85,14 @@ elRplAzrMF4= }); test('it views a cert', async function (assert) { - assert.expect(11); + assert.expect(12); const path = await setup(assert); await generatePage.issueCert('foo'); await settled(); await listPage.visitRoot({ backend: path, tab: 'cert' }); await settled(); - assert.ok(listPage.secrets.length > 0, 'lists certs'); + assert.equal(currentURL(), `/vault/secrets/${path}/list?tab=cert`); + assert.equal(listPage.secrets.length, 2, 'lists certs'); await listPage.secrets.objectAt(0).click(); await settled(); assert.equal(currentRouteName(), 'vault.cluster.secrets.backend.show', 'navigates to the show page');