open-vault/ui/tests/acceptance/pki/pki-action-forms-test.js

299 lines
14 KiB
JavaScript

/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/
import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit';
import { click, currentURL, fillIn, typeIn, visit } from '@ember/test-helpers';
import { setupMirage } from 'ember-cli-mirage/test-support';
import { v4 as uuidv4 } from 'uuid';
import authPage from 'vault/tests/pages/auth';
import logout from 'vault/tests/pages/logout';
import enablePage from 'vault/tests/pages/settings/mount-secret-backend';
import { runCommands } from 'vault/tests/helpers/pki/pki-run-commands';
import { SELECTORS as S } from 'vault/tests/helpers/pki/workflow';
import { issuerPemBundle } from 'vault/tests/helpers/pki/values';
module('Acceptance | pki action forms test', function (hooks) {
setupApplicationTest(hooks);
hooks.beforeEach(async function () {
await authPage.login();
// Setup PKI engine
const mountPath = `pki-workflow-${uuidv4()}`;
await enablePage.enable('pki', mountPath);
this.mountPath = mountPath;
await logout.visit();
});
hooks.afterEach(async function () {
await logout.visit();
await authPage.login();
// Cleanup engine
await runCommands([`delete sys/mounts/${this.mountPath}`]);
await logout.visit();
});
module('import', function (hooks) {
setupMirage(hooks);
hooks.beforeEach(function () {
this.pemBundle = issuerPemBundle;
});
test('happy path', async function (assert) {
await authPage.login(this.pkiAdminToken);
await visit(`/vault/secrets/${this.mountPath}/pki/overview`);
assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/overview`);
await click(S.emptyStateLink);
assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/configuration/create`);
assert.dom(S.configuration.title).hasText('Configure PKI');
assert.dom(S.configuration.emptyState).exists({ count: 1 }, 'Shows empty state by default');
await click(S.configuration.optionByKey('import'));
assert.dom(S.configuration.emptyState).doesNotExist();
// Submit before filling out form shows an error
await click('[data-test-pki-import-pem-bundle]');
assert.dom('[data-test-alert-banner="alert"]').hasText('Error please upload your PEM bundle');
// Fill in form data
await click('[data-test-text-toggle]');
await fillIn('[data-test-text-file-textarea]', this.pemBundle);
await click('[data-test-pki-import-pem-bundle]');
assert.strictEqual(
currentURL(),
`/vault/secrets/${this.mountPath}/pki/configuration/create`,
'stays on page on success'
);
assert.dom(S.configuration.title).hasText('View imported items');
assert.dom(S.configuration.importForm).doesNotExist('import form is hidden after save');
assert.dom(S.configuration.importMapping).exists('import mapping is shown after save');
await click('[data-test-done]');
assert.strictEqual(
currentURL(),
`/vault/secrets/${this.mountPath}/pki/overview`,
'redirects to overview when done'
);
});
test('with many imports', async function (assert) {
this.server.post(`${this.mountPath}/config/ca`, () => {
return {
request_id: 'some-config-id',
data: {
imported_issuers: ['my-imported-issuer', 'imported2'],
imported_keys: ['my-imported-key', 'imported3'],
mapping: {
'my-imported-issuer': 'my-imported-key',
imported2: '',
},
},
};
});
await authPage.login(this.pkiAdminToken);
await visit(`/vault/secrets/${this.mountPath}/pki/configuration/create`);
await click(S.configuration.optionByKey('import'));
assert.dom(S.configuration.importForm).exists('import form is shown save');
await click('[data-test-text-toggle]');
await fillIn('[data-test-text-file-textarea]', this.pemBundle);
await click('[data-test-pki-import-pem-bundle]');
assert.strictEqual(
currentURL(),
`/vault/secrets/${this.mountPath}/pki/configuration/create`,
'stays on page on success'
);
assert.dom(S.configuration.title).hasText('View imported items');
assert.dom(S.configuration.importForm).doesNotExist('import form is hidden after save');
assert.dom(S.configuration.importMapping).exists('import mapping is shown after save');
assert.dom(S.configuration.importedIssuer).hasText('my-imported-issuer', 'Issuer value is displayed');
assert.dom(S.configuration.importedKey).hasText('my-imported-key', 'Key value is displayed');
await click('[data-test-done]');
assert.strictEqual(
currentURL(),
`/vault/secrets/${this.mountPath}/pki/overview`,
'redirects to overview when done'
);
});
test('shows imported items when keys is empty', async function (assert) {
this.server.post(`${this.mountPath}/config/ca`, () => {
return {
request_id: 'some-config-id',
data: {
imported_issuers: ['my-imported-issuer', 'my-imported-issuer2'],
imported_keys: null,
mapping: {
'my-imported-issuer': '',
'my-imported-issuer2': '',
},
},
};
});
await authPage.login(this.pkiAdminToken);
await visit(`/vault/secrets/${this.mountPath}/pki/configuration/create`);
await click(S.configuration.optionByKey('import'));
assert.dom(S.configuration.importForm).exists('import form is shown save');
await click('[data-test-text-toggle]');
await fillIn('[data-test-text-file-textarea]', this.pemBundle);
await click('[data-test-pki-import-pem-bundle]');
assert.dom(S.configuration.importForm).doesNotExist('import form is hidden after save');
assert.dom(S.configuration.importMapping).exists('import mapping is shown after save');
assert.dom(S.configuration.importedIssuer).hasText('my-imported-issuer', 'Issuer value is displayed');
assert.dom(S.configuration.importedKey).hasText('None', 'Shows placeholder value for key');
});
test('shows None for imported items if nothing new imported', async function (assert) {
this.server.post(`${this.mountPath}/config/ca`, () => {
return {
request_id: 'some-config-id',
data: {
imported_issuers: null,
imported_keys: null,
mapping: {},
},
};
});
await authPage.login(this.pkiAdminToken);
await visit(`/vault/secrets/${this.mountPath}/pki/configuration/create`);
await click(S.configuration.optionByKey('import'));
assert.dom(S.configuration.importForm).exists('import form is shown save');
await click('[data-test-text-toggle]');
await fillIn('[data-test-text-file-textarea]', this.pemBundle);
await click('[data-test-pki-import-pem-bundle]');
assert.dom(S.configuration.importForm).doesNotExist('import form is hidden after save');
assert.dom(S.configuration.importMapping).exists('import mapping is shown after save');
assert.dom(S.configuration.importedIssuer).hasText('None', 'Shows placeholder value for issuer');
assert.dom(S.configuration.importedKey).hasText('None', 'Shows placeholder value for key');
});
});
module('generate root', function () {
test('happy path', async function (assert) {
const commonName = 'my-common-name';
const issuerName = 'my-first-issuer';
const keyName = 'my-first-key';
await authPage.login();
await visit(`/vault/secrets/${this.mountPath}/pki/overview`);
assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/overview`);
await click(S.emptyStateLink);
assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/configuration/create`);
assert.dom(S.configuration.title).hasText('Configure PKI');
assert.dom(S.configuration.emptyState).exists({ count: 1 }, 'Shows empty state by default');
await click(S.configuration.optionByKey('generate-root'));
assert.dom(S.configuration.emptyState).doesNotExist();
// The URLs section is populated based on params returned from OpenAPI. This test will break when
// the backend adds fields. We should update the count accordingly.
assert.dom(S.configuration.urlField).exists({ count: 4 });
// Fill in form
await fillIn(S.configuration.typeField, 'internal');
await typeIn(S.configuration.inputByName('commonName'), commonName);
await typeIn(S.configuration.inputByName('issuerName'), issuerName);
await click(S.configuration.keyParamsGroupToggle);
await typeIn(S.configuration.inputByName('keyName'), keyName);
await click(S.configuration.generateRootSave);
assert.strictEqual(
currentURL(),
`/vault/secrets/${this.mountPath}/pki/configuration/create`,
'stays on page on success'
);
assert.dom(S.configuration.title).hasText('View root certificate');
assert.dom('[data-test-alert-banner="alert"]').doesNotExist('no private key warning');
assert.dom(S.configuration.title).hasText('View root certificate', 'Updates title on page');
assert.dom(S.configuration.saved.certificate).hasClass('allow-copy', 'copyable certificate is masked');
assert.dom(S.configuration.saved.issuerName).hasText(issuerName);
assert.dom(S.configuration.saved.issuerLink).exists('Issuer link exists');
assert.dom(S.configuration.saved.keyLink).exists('Key link exists');
assert.dom(S.configuration.saved.keyName).hasText(keyName);
assert.dom('[data-test-done]').exists('Done button exists');
// Check that linked issuer has correct common name
await click(S.configuration.saved.issuerLink);
assert.dom(S.issuerDetails.valueByName('Common name')).hasText(commonName);
});
test('type=exported', async function (assert) {
const commonName = 'my-exported-name';
await authPage.login();
await visit(`/vault/secrets/${this.mountPath}/pki/configuration/create`);
await click(S.configuration.optionByKey('generate-root'));
// Fill in form
await fillIn(S.configuration.typeField, 'exported');
await typeIn(S.configuration.inputByName('commonName'), commonName);
await click(S.configuration.generateRootSave);
assert.strictEqual(
currentURL(),
`/vault/secrets/${this.mountPath}/pki/configuration/create`,
'stays on page on success'
);
assert.dom(S.configuration.title).hasText('View root certificate');
assert
.dom('[data-test-alert-banner="alert"]')
.hasText('Next steps The private_key is only available once. Make sure you copy and save it now.');
assert.dom(S.configuration.title).hasText('View root certificate', 'Updates title on page');
assert
.dom(S.configuration.saved.certificate)
.hasClass('allow-copy', 'copyable masked certificate exists');
assert
.dom(S.configuration.saved.issuerName)
.doesNotExist('Issuer name not shown because it was not named');
assert.dom(S.configuration.saved.issuerLink).exists('Issuer link exists');
assert.dom(S.configuration.saved.keyLink).exists('Key link exists');
assert
.dom(S.configuration.saved.privateKey)
.hasClass('allow-copy', 'copyable masked private key exists');
assert.dom(S.configuration.saved.keyName).doesNotExist('Key name not shown because it was not named');
assert.dom('[data-test-done]').exists('Done button exists');
// Check that linked issuer has correct common name
await click(S.configuration.saved.issuerLink);
assert.dom(S.issuerDetails.valueByName('Common name')).hasText(commonName);
});
});
module('generate CSR', function () {
test('happy path', async function (assert) {
await authPage.login();
await visit(`/vault/secrets/${this.mountPath}/pki/overview`);
await click(S.emptyStateLink);
assert.dom(S.configuration.title).hasText('Configure PKI');
await click(S.configuration.optionByKey('generate-csr'));
await fillIn(S.configuration.typeField, 'internal');
await fillIn(S.configuration.inputByName('commonName'), 'my-common-name');
await click('[data-test-save]');
assert.dom(S.configuration.title).hasText('View generated CSR');
await assert.dom(S.configuration.csrDetails).exists('renders CSR details after save');
await click('[data-test-done]');
assert.strictEqual(
currentURL(),
`/vault/secrets/${this.mountPath}/pki/overview`,
'Transitions to overview after viewing csr details'
);
});
test('type = exported', async function (assert) {
await authPage.login();
await visit(`/vault/secrets/${this.mountPath}/pki/overview`);
await click(S.emptyStateLink);
await click(S.configuration.optionByKey('generate-csr'));
await fillIn(S.configuration.typeField, 'exported');
await fillIn(S.configuration.inputByName('commonName'), 'my-common-name');
await click('[data-test-save]');
await assert.dom(S.configuration.csrDetails).exists('renders CSR details after save');
assert.dom(S.configuration.title).hasText('View generated CSR');
assert
.dom('[data-test-alert-banner="alert"]')
.hasText(
'Next steps Copy the CSR below for a parent issuer to sign and then import the signed certificate back into this mount. The private_key is only available once. Make sure you copy and save it now.'
);
assert
.dom(S.configuration.saved.privateKey)
.hasClass('allow-copy', 'copyable masked private key exists');
await click('[data-test-done]');
assert.strictEqual(
currentURL(),
`/vault/secrets/${this.mountPath}/pki/overview`,
'Transitions to overview after viewing csr details'
);
});
});
});