mirror of
https://github.com/optim-enterprises-bv/vault.git
synced 2025-10-30 02:02:43 +00:00
UI: fix PKI issuer capabilities (#24686)
This commit is contained in:
3
changelog/24686.txt
Normal file
3
changelog/24686.txt
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
```release-note:bug
|
||||||
|
ui: fix incorrectly calculated capabilities on PKI issuer endpoints
|
||||||
|
```
|
||||||
@@ -135,13 +135,14 @@ export default class PkiIssuerModel extends Model {
|
|||||||
@attr importedKeys;
|
@attr importedKeys;
|
||||||
@attr mapping;
|
@attr mapping;
|
||||||
|
|
||||||
@lazyCapabilities(apiPath`${'backend'}/issuer/${'issuerId'}`) issuerPath;
|
@lazyCapabilities(apiPath`${'backend'}/issuer/${'issuerId'}`, 'backend', 'issuerId') issuerPath;
|
||||||
@lazyCapabilities(apiPath`${'backend'}/root/rotate/exported`) rotateExported;
|
@lazyCapabilities(apiPath`${'backend'}/root/rotate/exported`, 'backend') rotateExported;
|
||||||
@lazyCapabilities(apiPath`${'backend'}/root/rotate/internal`) rotateInternal;
|
@lazyCapabilities(apiPath`${'backend'}/root/rotate/internal`, 'backend') rotateInternal;
|
||||||
@lazyCapabilities(apiPath`${'backend'}/root/rotate/existing`) rotateExisting;
|
@lazyCapabilities(apiPath`${'backend'}/root/rotate/existing`, 'backend') rotateExisting;
|
||||||
@lazyCapabilities(apiPath`${'backend'}/root`, 'backend') deletePath;
|
@lazyCapabilities(apiPath`${'backend'}/root`, 'backend') deletePath;
|
||||||
@lazyCapabilities(apiPath`${'backend'}/intermediate/cross-sign`) crossSignPath;
|
@lazyCapabilities(apiPath`${'backend'}/intermediate/cross-sign`, 'backend') crossSignPath;
|
||||||
@lazyCapabilities(apiPath`${'backend'}/issuer/${'issuerId'}/sign-intermediate`) signIntermediate;
|
@lazyCapabilities(apiPath`${'backend'}/issuer/${'issuerId'}/sign-intermediate`, 'backend', 'issuerId')
|
||||||
|
signIntermediate;
|
||||||
get canRotateIssuer() {
|
get canRotateIssuer() {
|
||||||
return (
|
return (
|
||||||
this.rotateExported.get('canUpdate') !== false ||
|
this.rotateExported.get('canUpdate') !== false ||
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import enablePage from 'vault/tests/pages/settings/mount-secret-backend';
|
|||||||
import { click, currentURL, fillIn, find, isSettled, visit } from '@ember/test-helpers';
|
import { click, currentURL, fillIn, find, isSettled, visit } from '@ember/test-helpers';
|
||||||
import { SELECTORS } from 'vault/tests/helpers/pki/workflow';
|
import { SELECTORS } from 'vault/tests/helpers/pki/workflow';
|
||||||
import { adminPolicy, readerPolicy, updatePolicy } from 'vault/tests/helpers/policy-generator/pki';
|
import { adminPolicy, readerPolicy, updatePolicy } from 'vault/tests/helpers/policy-generator/pki';
|
||||||
import { tokenWithPolicy, runCommands } from 'vault/tests/helpers/pki/pki-run-commands';
|
import { tokenWithPolicy, runCommands, clearRecords } from 'vault/tests/helpers/pki/pki-run-commands';
|
||||||
import { unsupportedPem } from 'vault/tests/helpers/pki/values';
|
import { unsupportedPem } from 'vault/tests/helpers/pki/values';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -25,12 +25,14 @@ module('Acceptance | pki workflow', function (hooks) {
|
|||||||
setupApplicationTest(hooks);
|
setupApplicationTest(hooks);
|
||||||
|
|
||||||
hooks.beforeEach(async function () {
|
hooks.beforeEach(async function () {
|
||||||
|
this.store = this.owner.lookup('service:store');
|
||||||
await authPage.login();
|
await authPage.login();
|
||||||
// Setup PKI engine
|
// Setup PKI engine
|
||||||
const mountPath = `pki-workflow-${uuidv4()}`;
|
const mountPath = `pki-workflow-${uuidv4()}`;
|
||||||
await enablePage.enable('pki', mountPath);
|
await enablePage.enable('pki', mountPath);
|
||||||
this.mountPath = mountPath;
|
this.mountPath = mountPath;
|
||||||
await logout.visit();
|
await logout.visit();
|
||||||
|
clearRecords(this.store);
|
||||||
});
|
});
|
||||||
|
|
||||||
hooks.afterEach(async function () {
|
hooks.afterEach(async function () {
|
||||||
@@ -40,40 +42,50 @@ module('Acceptance | pki workflow', function (hooks) {
|
|||||||
await runCommands([`delete sys/mounts/${this.mountPath}`]);
|
await runCommands([`delete sys/mounts/${this.mountPath}`]);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('empty state messages are correct when PKI not configured', async function (assert) {
|
module('not configured', function (hooks) {
|
||||||
assert.expect(21);
|
hooks.beforeEach(async function () {
|
||||||
const assertEmptyState = (assert, resource) => {
|
await authPage.login();
|
||||||
assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/${resource}`);
|
const pki_admin_policy = adminPolicy(this.mountPath, 'roles');
|
||||||
assert
|
this.pkiAdminToken = await tokenWithPolicy(`pki-admin-${this.mountPath}`, pki_admin_policy);
|
||||||
.dom(SELECTORS.emptyStateTitle)
|
await logout.visit();
|
||||||
.hasText(
|
clearRecords(this.store);
|
||||||
'PKI not configured',
|
});
|
||||||
`${resource} index renders correct empty state title when PKI not configured`
|
|
||||||
);
|
|
||||||
assert.dom(SELECTORS.emptyStateLink).hasText('Configure PKI');
|
|
||||||
assert
|
|
||||||
.dom(SELECTORS.emptyStateMessage)
|
|
||||||
.hasText(
|
|
||||||
`This PKI mount hasn't yet been configured with a certificate issuer.`,
|
|
||||||
`${resource} index empty state message correct when PKI not configured`
|
|
||||||
);
|
|
||||||
};
|
|
||||||
await authPage.login(this.pkiAdminToken);
|
|
||||||
await visit(`/vault/secrets/${this.mountPath}/pki/overview`);
|
|
||||||
assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/overview`);
|
|
||||||
|
|
||||||
await click(SELECTORS.rolesTab);
|
test('empty state messages are correct when PKI not configured', async function (assert) {
|
||||||
assertEmptyState(assert, 'roles');
|
assert.expect(21);
|
||||||
|
const assertEmptyState = (assert, resource) => {
|
||||||
|
assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/${resource}`);
|
||||||
|
assert
|
||||||
|
.dom(SELECTORS.emptyStateTitle)
|
||||||
|
.hasText(
|
||||||
|
'PKI not configured',
|
||||||
|
`${resource} index renders correct empty state title when PKI not configured`
|
||||||
|
);
|
||||||
|
assert.dom(SELECTORS.emptyStateLink).hasText('Configure PKI');
|
||||||
|
assert
|
||||||
|
.dom(SELECTORS.emptyStateMessage)
|
||||||
|
.hasText(
|
||||||
|
`This PKI mount hasn't yet been configured with a certificate issuer.`,
|
||||||
|
`${resource} index empty state message correct when PKI not configured`
|
||||||
|
);
|
||||||
|
};
|
||||||
|
await authPage.login(this.pkiAdminToken);
|
||||||
|
await visit(`/vault/secrets/${this.mountPath}/pki/overview`);
|
||||||
|
assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/overview`);
|
||||||
|
|
||||||
await click(SELECTORS.issuersTab);
|
await click(SELECTORS.rolesTab);
|
||||||
assertEmptyState(assert, 'issuers');
|
assertEmptyState(assert, 'roles');
|
||||||
|
|
||||||
await click(SELECTORS.certsTab);
|
await click(SELECTORS.issuersTab);
|
||||||
assertEmptyState(assert, 'certificates');
|
assertEmptyState(assert, 'issuers');
|
||||||
await click(SELECTORS.keysTab);
|
|
||||||
assertEmptyState(assert, 'keys');
|
await click(SELECTORS.certsTab);
|
||||||
await click(SELECTORS.tidyTab);
|
assertEmptyState(assert, 'certificates');
|
||||||
assertEmptyState(assert, 'tidy');
|
await click(SELECTORS.keysTab);
|
||||||
|
assertEmptyState(assert, 'keys');
|
||||||
|
await click(SELECTORS.tidyTab);
|
||||||
|
assertEmptyState(assert, 'tidy');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
module('roles', function (hooks) {
|
module('roles', function (hooks) {
|
||||||
@@ -91,10 +103,11 @@ module('Acceptance | pki workflow', function (hooks) {
|
|||||||
const pki_admin_policy = adminPolicy(this.mountPath, 'roles');
|
const pki_admin_policy = adminPolicy(this.mountPath, 'roles');
|
||||||
const pki_reader_policy = readerPolicy(this.mountPath, 'roles');
|
const pki_reader_policy = readerPolicy(this.mountPath, 'roles');
|
||||||
const pki_editor_policy = updatePolicy(this.mountPath, 'roles');
|
const pki_editor_policy = updatePolicy(this.mountPath, 'roles');
|
||||||
this.pkiRoleReader = await tokenWithPolicy('pki-reader', pki_reader_policy);
|
this.pkiRoleReader = await tokenWithPolicy(`pki-reader-${this.mountPath}`, pki_reader_policy);
|
||||||
this.pkiRoleEditor = await tokenWithPolicy('pki-editor', pki_editor_policy);
|
this.pkiRoleEditor = await tokenWithPolicy(`pki-editor-${this.mountPath}`, pki_editor_policy);
|
||||||
this.pkiAdminToken = await tokenWithPolicy('pki-admin', pki_admin_policy);
|
this.pkiAdminToken = await tokenWithPolicy(`pki-admin-${this.mountPath}`, pki_admin_policy);
|
||||||
await logout.visit();
|
await logout.visit();
|
||||||
|
clearRecords(this.store);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('shows correct items if user has all permissions', async function (assert) {
|
test('shows correct items if user has all permissions', async function (assert) {
|
||||||
@@ -222,10 +235,11 @@ module('Acceptance | pki workflow', function (hooks) {
|
|||||||
const pki_admin_policy = adminPolicy(this.mountPath);
|
const pki_admin_policy = adminPolicy(this.mountPath);
|
||||||
const pki_reader_policy = readerPolicy(this.mountPath, 'keys', true);
|
const pki_reader_policy = readerPolicy(this.mountPath, 'keys', true);
|
||||||
const pki_editor_policy = updatePolicy(this.mountPath, 'keys');
|
const pki_editor_policy = updatePolicy(this.mountPath, 'keys');
|
||||||
this.pkiKeyReader = await tokenWithPolicy('pki-reader', pki_reader_policy);
|
this.pkiKeyReader = await tokenWithPolicy(`pki-reader-${this.mountPath}`, pki_reader_policy);
|
||||||
this.pkiKeyEditor = await tokenWithPolicy('pki-editor', pki_editor_policy);
|
this.pkiKeyEditor = await tokenWithPolicy(`pki-editor-${this.mountPath}`, pki_editor_policy);
|
||||||
this.pkiAdminToken = await tokenWithPolicy('pki-admin', pki_admin_policy);
|
this.pkiAdminToken = await tokenWithPolicy(`pki-admin-${this.mountPath}`, pki_admin_policy);
|
||||||
await logout.visit();
|
await logout.visit();
|
||||||
|
clearRecords(this.store);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('shows correct items if user has all permissions', async function (assert) {
|
test('shows correct items if user has all permissions', async function (assert) {
|
||||||
@@ -339,11 +353,14 @@ module('Acceptance | pki workflow', function (hooks) {
|
|||||||
module('issuers', function (hooks) {
|
module('issuers', function (hooks) {
|
||||||
hooks.beforeEach(async function () {
|
hooks.beforeEach(async function () {
|
||||||
await authPage.login();
|
await authPage.login();
|
||||||
|
const pki_admin_policy = adminPolicy(this.mountPath);
|
||||||
|
this.pkiAdminToken = await tokenWithPolicy(`pki-admin-${this.mountPath}`, pki_admin_policy);
|
||||||
// Configure engine with a default issuer
|
// Configure engine with a default issuer
|
||||||
await runCommands([
|
await runCommands([
|
||||||
`write ${this.mountPath}/root/generate/internal common_name="Hashicorp Test" name="Hashicorp Test"`,
|
`write ${this.mountPath}/root/generate/internal common_name="Hashicorp Test" name="Hashicorp Test"`,
|
||||||
]);
|
]);
|
||||||
await logout.visit();
|
await logout.visit();
|
||||||
|
clearRecords(this.store);
|
||||||
});
|
});
|
||||||
test('lists the correct issuer metadata info', async function (assert) {
|
test('lists the correct issuer metadata info', async function (assert) {
|
||||||
assert.expect(6);
|
assert.expect(6);
|
||||||
@@ -373,7 +390,10 @@ module('Acceptance | pki workflow', function (hooks) {
|
|||||||
capabilities = ["deny"]
|
capabilities = ["deny"]
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
this.token = await tokenWithPolicy('pki-issuer-denied-policy', pki_issuer_denied_policy);
|
this.token = await tokenWithPolicy(
|
||||||
|
`pki-issuer-denied-policy-${this.mountPath}`,
|
||||||
|
pki_issuer_denied_policy
|
||||||
|
);
|
||||||
await logout.visit();
|
await logout.visit();
|
||||||
await authPage.login(this.token);
|
await authPage.login(this.token);
|
||||||
await visit(`/vault/secrets/${this.mountPath}/pki/overview`);
|
await visit(`/vault/secrets/${this.mountPath}/pki/overview`);
|
||||||
@@ -487,7 +507,10 @@ module('Acceptance | pki workflow', function (hooks) {
|
|||||||
${adminPolicy(this.mountPath)}
|
${adminPolicy(this.mountPath)}
|
||||||
${readerPolicy(this.mountPath, 'config/cluster')}
|
${readerPolicy(this.mountPath, 'config/cluster')}
|
||||||
`;
|
`;
|
||||||
this.mixedConfigCapabilities = await tokenWithPolicy('pki-reader', mixed_config_policy);
|
this.mixedConfigCapabilities = await tokenWithPolicy(
|
||||||
|
`pki-reader-${this.mountPath}`,
|
||||||
|
mixed_config_policy
|
||||||
|
);
|
||||||
await logout.visit();
|
await logout.visit();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -10,12 +10,13 @@ import logout from 'vault/tests/pages/logout';
|
|||||||
import enablePage from 'vault/tests/pages/settings/mount-secret-backend';
|
import enablePage from 'vault/tests/pages/settings/mount-secret-backend';
|
||||||
import { click, currentURL, currentRouteName, visit } from '@ember/test-helpers';
|
import { click, currentURL, currentRouteName, visit } from '@ember/test-helpers';
|
||||||
import { SELECTORS } from 'vault/tests/helpers/pki/overview';
|
import { SELECTORS } from 'vault/tests/helpers/pki/overview';
|
||||||
import { tokenWithPolicy, runCommands } from 'vault/tests/helpers/pki/pki-run-commands';
|
import { tokenWithPolicy, runCommands, clearRecords } from 'vault/tests/helpers/pki/pki-run-commands';
|
||||||
|
|
||||||
module('Acceptance | pki overview', function (hooks) {
|
module('Acceptance | pki overview', function (hooks) {
|
||||||
setupApplicationTest(hooks);
|
setupApplicationTest(hooks);
|
||||||
|
|
||||||
hooks.beforeEach(async function () {
|
hooks.beforeEach(async function () {
|
||||||
|
this.store = this.owner.lookup('service:store');
|
||||||
await authPage.login();
|
await authPage.login();
|
||||||
// Setup PKI engine
|
// Setup PKI engine
|
||||||
const mountPath = `pki`;
|
const mountPath = `pki`;
|
||||||
@@ -42,6 +43,7 @@ module('Acceptance | pki overview', function (hooks) {
|
|||||||
this.pkiIssuersList = await tokenWithPolicy('pki-issuers-list', pki_issuers_list_policy);
|
this.pkiIssuersList = await tokenWithPolicy('pki-issuers-list', pki_issuers_list_policy);
|
||||||
this.pkiAdminToken = await tokenWithPolicy('pki-admin', pki_admin_policy);
|
this.pkiAdminToken = await tokenWithPolicy('pki-admin', pki_admin_policy);
|
||||||
await logout.visit();
|
await logout.visit();
|
||||||
|
clearRecords(this.store);
|
||||||
});
|
});
|
||||||
|
|
||||||
hooks.afterEach(async function () {
|
hooks.afterEach(async function () {
|
||||||
|
|||||||
@@ -45,6 +45,7 @@ module('Acceptance | policies (old)', function (hooks) {
|
|||||||
assert.dom('[data-test-policy-name]').hasText(policyLower, 'displays the policy name on the show page');
|
assert.dom('[data-test-policy-name]').hasText(policyLower, 'displays the policy name on the show page');
|
||||||
assert.dom('[data-test-flash-message].is-info').doesNotExist('no flash message is displayed on save');
|
assert.dom('[data-test-flash-message].is-info').doesNotExist('no flash message is displayed on save');
|
||||||
await click('[data-test-policy-list-link] a');
|
await click('[data-test-policy-list-link] a');
|
||||||
|
await fillIn('[data-test-component="navigate-input"]', policyLower);
|
||||||
assert
|
assert
|
||||||
.dom(`[data-test-policy-link="${policyLower}"]`)
|
.dom(`[data-test-policy-link="${policyLower}"]`)
|
||||||
.exists({ count: 1 }, 'new policy shown in the list');
|
.exists({ count: 1 }, 'new policy shown in the list');
|
||||||
@@ -63,6 +64,7 @@ module('Acceptance | policies (old)', function (hooks) {
|
|||||||
`/vault/policies/acl`,
|
`/vault/policies/acl`,
|
||||||
'navigates to policy list on successful deletion'
|
'navigates to policy list on successful deletion'
|
||||||
);
|
);
|
||||||
|
await fillIn('[data-test-component="navigate-input"]', policyLower);
|
||||||
assert
|
assert
|
||||||
.dom(`[data-test-policy-item="${policyLower}"]`)
|
.dom(`[data-test-policy-item="${policyLower}"]`)
|
||||||
.doesNotExist('deleted policy is not shown in the list');
|
.doesNotExist('deleted policy is not shown in the list');
|
||||||
|
|||||||
@@ -34,3 +34,21 @@ export const runCommands = async function (commands) {
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Clears pki-related data and capabilities so that admin
|
||||||
|
// capabilities from setup don't rollover
|
||||||
|
export function clearRecords(store) {
|
||||||
|
store.unloadAll('pki/action');
|
||||||
|
store.unloadAll('pki/issuer');
|
||||||
|
store.unloadAll('pki/key');
|
||||||
|
store.unloadAll('pki/role');
|
||||||
|
store.unloadAll('pki/sign-intermediate');
|
||||||
|
store.unloadAll('pki/tidy');
|
||||||
|
store.unloadAll('pki/config/urls');
|
||||||
|
store.unloadAll('pki/config/crl');
|
||||||
|
store.unloadAll('pki/config/cluster');
|
||||||
|
store.unloadAll('pki/config/acme');
|
||||||
|
store.unloadAll('pki/certificate/generate');
|
||||||
|
store.unloadAll('pki/certificate/sign');
|
||||||
|
store.unloadAll('capabilities');
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user