mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-10-29 17:52:32 +00:00
* check for renewAfterEpoch before comparing it * add test coverage for regression * add comment. Fixes VAULT-4630 * throw error * add changelog
212 lines
6.9 KiB
JavaScript
212 lines
6.9 KiB
JavaScript
/**
|
|
* Copyright (c) HashiCorp, Inc.
|
|
* SPDX-License-Identifier: BUSL-1.1
|
|
*/
|
|
|
|
import { module, test } from 'qunit';
|
|
import { setupApplicationTest } from 'ember-qunit';
|
|
import { click, currentURL, visit, waitUntil, find, fillIn } from '@ember/test-helpers';
|
|
import { setupMirage } from 'ember-cli-mirage/test-support';
|
|
import { allSupportedAuthBackends, supportedAuthBackends } from 'vault/helpers/supported-auth-backends';
|
|
import VAULT_KEYS from 'vault/tests/helpers/vault-keys';
|
|
|
|
const AUTH_FORM = {
|
|
method: '[data-test-select=auth-method]',
|
|
token: '[data-test-token]',
|
|
login: '[data-test-auth-submit]',
|
|
};
|
|
const ENT_AUTH_METHODS = ['saml'];
|
|
const { rootToken } = VAULT_KEYS;
|
|
|
|
module('Acceptance | auth', function (hooks) {
|
|
setupApplicationTest(hooks);
|
|
setupMirage(hooks);
|
|
|
|
test('auth query params', async function (assert) {
|
|
const backends = supportedAuthBackends();
|
|
assert.expect(backends.length + 1);
|
|
await visit('/vault/auth');
|
|
assert.strictEqual(currentURL(), '/vault/auth?with=token');
|
|
for (const backend of backends.reverse()) {
|
|
await fillIn(AUTH_FORM.method, backend.type);
|
|
assert.strictEqual(
|
|
currentURL(),
|
|
`/vault/auth?with=${backend.type}`,
|
|
`has the correct URL for ${backend.type}`
|
|
);
|
|
}
|
|
});
|
|
|
|
test('it clears token when changing selected auth method', async function (assert) {
|
|
await visit('/vault/auth');
|
|
await fillIn(AUTH_FORM.token, 'token');
|
|
await fillIn(AUTH_FORM.method, 'github');
|
|
await fillIn(AUTH_FORM.method, 'token');
|
|
assert.dom(AUTH_FORM.token).hasNoValue('it clears the token value when toggling methods');
|
|
});
|
|
|
|
module('it sends the right payload when authenticating', function (hooks) {
|
|
hooks.beforeEach(function () {
|
|
this.assertReq = () => {};
|
|
this.server.get('/auth/token/lookup-self', (schema, req) => {
|
|
this.assertReq(req);
|
|
req.passthrough();
|
|
});
|
|
this.server.post('/auth/:mount/login', (schema, req) => {
|
|
// github only
|
|
this.assertReq(req);
|
|
req.passthrough();
|
|
});
|
|
this.server.post('/auth/:mount/oidc/auth_url', (schema, req) => {
|
|
// For JWT and OIDC
|
|
this.assertReq(req);
|
|
req.passthrough();
|
|
});
|
|
this.server.post('/auth/:mount/login/:username', (schema, req) => {
|
|
this.assertReq(req);
|
|
req.passthrough();
|
|
});
|
|
this.server.put('/auth/:mount/sso_service_url', (schema, req) => {
|
|
// SAML only (enterprise)
|
|
this.assertReq(req);
|
|
req.passthrough();
|
|
});
|
|
this.expected = {
|
|
token: {
|
|
url: '/v1/auth/token/lookup-self',
|
|
payload: {
|
|
'X-Vault-Token': 'some-token',
|
|
},
|
|
},
|
|
userpass: {
|
|
url: '/v1/auth/custom-userpass/login/some-username',
|
|
payload: {
|
|
password: 'some-password',
|
|
},
|
|
},
|
|
ldap: {
|
|
url: '/v1/auth/custom-ldap/login/some-username',
|
|
payload: {
|
|
password: 'some-password',
|
|
},
|
|
},
|
|
okta: {
|
|
url: '/v1/auth/custom-okta/login/some-username',
|
|
payload: {
|
|
password: 'some-password',
|
|
},
|
|
},
|
|
jwt: {
|
|
url: '/v1/auth/custom-jwt/oidc/auth_url',
|
|
payload: {
|
|
redirect_uri: 'http://localhost:7357/ui/vault/auth/custom-jwt/oidc/callback',
|
|
role: 'some-role',
|
|
},
|
|
},
|
|
oidc: {
|
|
url: '/v1/auth/custom-oidc/oidc/auth_url',
|
|
payload: {
|
|
redirect_uri: 'http://localhost:7357/ui/vault/auth/custom-oidc/oidc/callback',
|
|
role: 'some-role',
|
|
},
|
|
},
|
|
radius: {
|
|
url: '/v1/auth/custom-radius/login/some-username',
|
|
payload: {
|
|
password: 'some-password',
|
|
},
|
|
},
|
|
github: {
|
|
url: '/v1/auth/custom-github/login',
|
|
payload: {
|
|
token: 'some-token',
|
|
},
|
|
},
|
|
saml: {
|
|
url: '/v1/auth/custom-saml/sso_service_url',
|
|
payload: {
|
|
role: 'some-role',
|
|
},
|
|
},
|
|
};
|
|
});
|
|
|
|
for (const backend of allSupportedAuthBackends().reverse()) {
|
|
test(`for ${backend.type} ${
|
|
ENT_AUTH_METHODS.includes(backend.type) ? '(enterprise)' : ''
|
|
}`, async function (assert) {
|
|
const { type } = backend;
|
|
const expected = this.expected[type];
|
|
const isOidc = ['oidc', 'jwt'].includes(type);
|
|
assert.expect(isOidc ? 6 : 2);
|
|
|
|
this.assertReq = (req) => {
|
|
const body = type === 'token' ? req.requestHeaders : JSON.parse(req.requestBody);
|
|
if (isOidc && !body.role) {
|
|
// OIDC and JWT auth form calls the endpoint every time the role or mount is updated.
|
|
// if role is not provided, it means we haven't filled out the full info yet so don't
|
|
// validate the payload until all data is provided
|
|
// eslint-disable-next-line qunit/no-early-return
|
|
return {};
|
|
}
|
|
assert.strictEqual(req.url, expected.url, `${type} calls the correct URL`);
|
|
Object.keys(expected.payload).forEach((expKey) => {
|
|
assert.strictEqual(
|
|
body[expKey],
|
|
expected.payload[expKey],
|
|
`${type} payload includes ${expKey} with expected value`
|
|
);
|
|
});
|
|
};
|
|
await visit('/vault/auth');
|
|
await fillIn(AUTH_FORM.method, type);
|
|
|
|
if (type !== 'token') {
|
|
// set custom mount
|
|
await click('[data-test-auth-form-options-toggle]');
|
|
await fillIn('[data-test-auth-form-mount-path]', `custom-${type}`);
|
|
}
|
|
backend.formAttributes.forEach(async (key) => {
|
|
// fill in all form items, except JWT which is not rendered
|
|
if (key === 'jwt') return;
|
|
await fillIn(`[data-test-${key}]`, `some-${key}`);
|
|
});
|
|
|
|
await click(AUTH_FORM.login);
|
|
});
|
|
}
|
|
});
|
|
|
|
test('it shows the push notification warning after submit', async function (assert) {
|
|
assert.expect(1);
|
|
|
|
this.server.get(
|
|
'/auth/token/lookup-self',
|
|
async () => {
|
|
assert.ok(
|
|
await waitUntil(() => find('[data-test-auth-message="push"]')),
|
|
'shows push notification message'
|
|
);
|
|
return {};
|
|
},
|
|
{ timing: 1000 }
|
|
);
|
|
await visit('/vault/auth');
|
|
await fillIn(AUTH_FORM.method, 'token');
|
|
await click('[data-test-auth-submit]');
|
|
});
|
|
|
|
test('it does not call renew-self after successful login with non-renewable token', async function (assert) {
|
|
this.server.post(
|
|
'/auth/token/renew-self',
|
|
() => new Error('should not call renew-self directly after logging in')
|
|
);
|
|
|
|
await visit('/vault/auth');
|
|
await fillIn(AUTH_FORM.method, 'token');
|
|
await fillIn(AUTH_FORM.token, rootToken);
|
|
await click('[data-test-auth-submit]');
|
|
assert.strictEqual(currentURL(), '/vault/dashboard');
|
|
});
|
|
});
|