Skip to content

Commit d1cfed2

Browse files
authored
Backport UI: fix PKI issuer capabilities (#24686) (#24706)
1 parent a603971 commit d1cfed2

File tree

6 files changed

+99
-50
lines changed

6 files changed

+99
-50
lines changed

changelog/24686.txt

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
```release-note:bug
2+
ui: fix incorrectly calculated capabilities on PKI issuer endpoints
3+
```

ui/app/models/pki/issuer.js

+7-6
Original file line numberDiff line numberDiff line change
@@ -135,13 +135,14 @@ export default class PkiIssuerModel extends Model {
135135
@attr importedKeys;
136136
@attr mapping;
137137

138-
@lazyCapabilities(apiPath`${'backend'}/issuer/${'issuerId'}`) issuerPath;
139-
@lazyCapabilities(apiPath`${'backend'}/root/rotate/exported`) rotateExported;
140-
@lazyCapabilities(apiPath`${'backend'}/root/rotate/internal`) rotateInternal;
141-
@lazyCapabilities(apiPath`${'backend'}/root/rotate/existing`) rotateExisting;
138+
@lazyCapabilities(apiPath`${'backend'}/issuer/${'issuerId'}`, 'backend', 'issuerId') issuerPath;
139+
@lazyCapabilities(apiPath`${'backend'}/root/rotate/exported`, 'backend') rotateExported;
140+
@lazyCapabilities(apiPath`${'backend'}/root/rotate/internal`, 'backend') rotateInternal;
141+
@lazyCapabilities(apiPath`${'backend'}/root/rotate/existing`, 'backend') rotateExisting;
142142
@lazyCapabilities(apiPath`${'backend'}/root`, 'backend') deletePath;
143-
@lazyCapabilities(apiPath`${'backend'}/intermediate/cross-sign`) crossSignPath;
144-
@lazyCapabilities(apiPath`${'backend'}/issuer/${'issuerId'}/sign-intermediate`) signIntermediate;
143+
@lazyCapabilities(apiPath`${'backend'}/intermediate/cross-sign`, 'backend') crossSignPath;
144+
@lazyCapabilities(apiPath`${'backend'}/issuer/${'issuerId'}/sign-intermediate`, 'backend', 'issuerId')
145+
signIntermediate;
145146
get canRotateIssuer() {
146147
return (
147148
this.rotateExported.get('canUpdate') !== false ||

ui/tests/acceptance/pki/pki-engine-workflow-test.js

+66-43
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import enablePage from 'vault/tests/pages/settings/mount-secret-backend';
1313
import { click, currentURL, fillIn, find, isSettled, visit } from '@ember/test-helpers';
1414
import { SELECTORS } from 'vault/tests/helpers/pki/workflow';
1515
import { adminPolicy, readerPolicy, updatePolicy } from 'vault/tests/helpers/policy-generator/pki';
16-
import { tokenWithPolicy, runCommands } from 'vault/tests/helpers/pki/pki-run-commands';
16+
import { tokenWithPolicy, runCommands, clearRecords } from 'vault/tests/helpers/pki/pki-run-commands';
1717
import { unsupportedPem } from 'vault/tests/helpers/pki/values';
1818

1919
/**
@@ -25,12 +25,14 @@ module('Acceptance | pki workflow', function (hooks) {
2525
setupApplicationTest(hooks);
2626

2727
hooks.beforeEach(async function () {
28+
this.store = this.owner.lookup('service:store');
2829
await authPage.login();
2930
// Setup PKI engine
3031
const mountPath = `pki-workflow-${uuidv4()}`;
3132
await enablePage.enable('pki', mountPath);
3233
this.mountPath = mountPath;
3334
await logout.visit();
35+
clearRecords(this.store);
3436
});
3537

3638
hooks.afterEach(async function () {
@@ -40,40 +42,50 @@ module('Acceptance | pki workflow', function (hooks) {
4042
await runCommands([`delete sys/mounts/${this.mountPath}`]);
4143
});
4244

43-
test('empty state messages are correct when PKI not configured', async function (assert) {
44-
assert.expect(21);
45-
const assertEmptyState = (assert, resource) => {
46-
assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/${resource}`);
47-
assert
48-
.dom(SELECTORS.emptyStateTitle)
49-
.hasText(
50-
'PKI not configured',
51-
`${resource} index renders correct empty state title when PKI not configured`
52-
);
53-
assert.dom(SELECTORS.emptyStateLink).hasText('Configure PKI');
54-
assert
55-
.dom(SELECTORS.emptyStateMessage)
56-
.hasText(
57-
`This PKI mount hasn't yet been configured with a certificate issuer.`,
58-
`${resource} index empty state message correct when PKI not configured`
59-
);
60-
};
61-
await authPage.login(this.pkiAdminToken);
62-
await visit(`/vault/secrets/${this.mountPath}/pki/overview`);
63-
assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/overview`);
64-
65-
await click(SELECTORS.rolesTab);
66-
assertEmptyState(assert, 'roles');
67-
68-
await click(SELECTORS.issuersTab);
69-
assertEmptyState(assert, 'issuers');
70-
71-
await click(SELECTORS.certsTab);
72-
assertEmptyState(assert, 'certificates');
73-
await click(SELECTORS.keysTab);
74-
assertEmptyState(assert, 'keys');
75-
await click(SELECTORS.tidyTab);
76-
assertEmptyState(assert, 'tidy');
45+
module('not configured', function (hooks) {
46+
hooks.beforeEach(async function () {
47+
await authPage.login();
48+
const pki_admin_policy = adminPolicy(this.mountPath, 'roles');
49+
this.pkiAdminToken = await tokenWithPolicy(`pki-admin-${this.mountPath}`, pki_admin_policy);
50+
await logout.visit();
51+
clearRecords(this.store);
52+
});
53+
54+
test('empty state messages are correct when PKI not configured', async function (assert) {
55+
assert.expect(21);
56+
const assertEmptyState = (assert, resource) => {
57+
assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/${resource}`);
58+
assert
59+
.dom(SELECTORS.emptyStateTitle)
60+
.hasText(
61+
'PKI not configured',
62+
`${resource} index renders correct empty state title when PKI not configured`
63+
);
64+
assert.dom(SELECTORS.emptyStateLink).hasText('Configure PKI');
65+
assert
66+
.dom(SELECTORS.emptyStateMessage)
67+
.hasText(
68+
`This PKI mount hasn't yet been configured with a certificate issuer.`,
69+
`${resource} index empty state message correct when PKI not configured`
70+
);
71+
};
72+
await authPage.login(this.pkiAdminToken);
73+
await visit(`/vault/secrets/${this.mountPath}/pki/overview`);
74+
assert.strictEqual(currentURL(), `/vault/secrets/${this.mountPath}/pki/overview`);
75+
76+
await click(SELECTORS.rolesTab);
77+
assertEmptyState(assert, 'roles');
78+
79+
await click(SELECTORS.issuersTab);
80+
assertEmptyState(assert, 'issuers');
81+
82+
await click(SELECTORS.certsTab);
83+
assertEmptyState(assert, 'certificates');
84+
await click(SELECTORS.keysTab);
85+
assertEmptyState(assert, 'keys');
86+
await click(SELECTORS.tidyTab);
87+
assertEmptyState(assert, 'tidy');
88+
});
7789
});
7890

7991
module('roles', function (hooks) {
@@ -91,10 +103,11 @@ module('Acceptance | pki workflow', function (hooks) {
91103
const pki_admin_policy = adminPolicy(this.mountPath, 'roles');
92104
const pki_reader_policy = readerPolicy(this.mountPath, 'roles');
93105
const pki_editor_policy = updatePolicy(this.mountPath, 'roles');
94-
this.pkiRoleReader = await tokenWithPolicy('pki-reader', pki_reader_policy);
95-
this.pkiRoleEditor = await tokenWithPolicy('pki-editor', pki_editor_policy);
96-
this.pkiAdminToken = await tokenWithPolicy('pki-admin', pki_admin_policy);
106+
this.pkiRoleReader = await tokenWithPolicy(`pki-reader-${this.mountPath}`, pki_reader_policy);
107+
this.pkiRoleEditor = await tokenWithPolicy(`pki-editor-${this.mountPath}`, pki_editor_policy);
108+
this.pkiAdminToken = await tokenWithPolicy(`pki-admin-${this.mountPath}`, pki_admin_policy);
97109
await logout.visit();
110+
clearRecords(this.store);
98111
});
99112

100113
test('shows correct items if user has all permissions', async function (assert) {
@@ -222,10 +235,11 @@ module('Acceptance | pki workflow', function (hooks) {
222235
const pki_admin_policy = adminPolicy(this.mountPath);
223236
const pki_reader_policy = readerPolicy(this.mountPath, 'keys', true);
224237
const pki_editor_policy = updatePolicy(this.mountPath, 'keys');
225-
this.pkiKeyReader = await tokenWithPolicy('pki-reader', pki_reader_policy);
226-
this.pkiKeyEditor = await tokenWithPolicy('pki-editor', pki_editor_policy);
227-
this.pkiAdminToken = await tokenWithPolicy('pki-admin', pki_admin_policy);
238+
this.pkiKeyReader = await tokenWithPolicy(`pki-reader-${this.mountPath}`, pki_reader_policy);
239+
this.pkiKeyEditor = await tokenWithPolicy(`pki-editor-${this.mountPath}`, pki_editor_policy);
240+
this.pkiAdminToken = await tokenWithPolicy(`pki-admin-${this.mountPath}`, pki_admin_policy);
228241
await logout.visit();
242+
clearRecords(this.store);
229243
});
230244

231245
test('shows correct items if user has all permissions', async function (assert) {
@@ -339,11 +353,14 @@ module('Acceptance | pki workflow', function (hooks) {
339353
module('issuers', function (hooks) {
340354
hooks.beforeEach(async function () {
341355
await authPage.login();
356+
const pki_admin_policy = adminPolicy(this.mountPath);
357+
this.pkiAdminToken = await tokenWithPolicy(`pki-admin-${this.mountPath}`, pki_admin_policy);
342358
// Configure engine with a default issuer
343359
await runCommands([
344360
`write ${this.mountPath}/root/generate/internal common_name="Hashicorp Test" name="Hashicorp Test"`,
345361
]);
346362
await logout.visit();
363+
clearRecords(this.store);
347364
});
348365
test('lists the correct issuer metadata info', async function (assert) {
349366
assert.expect(6);
@@ -373,7 +390,10 @@ module('Acceptance | pki workflow', function (hooks) {
373390
capabilities = ["deny"]
374391
}
375392
`;
376-
this.token = await tokenWithPolicy('pki-issuer-denied-policy', pki_issuer_denied_policy);
393+
this.token = await tokenWithPolicy(
394+
`pki-issuer-denied-policy-${this.mountPath}`,
395+
pki_issuer_denied_policy
396+
);
377397
await logout.visit();
378398
await authPage.login(this.token);
379399
await visit(`/vault/secrets/${this.mountPath}/pki/overview`);
@@ -487,7 +507,10 @@ module('Acceptance | pki workflow', function (hooks) {
487507
${adminPolicy(this.mountPath)}
488508
${readerPolicy(this.mountPath, 'config/cluster')}
489509
`;
490-
this.mixedConfigCapabilities = await tokenWithPolicy('pki-reader', mixed_config_policy);
510+
this.mixedConfigCapabilities = await tokenWithPolicy(
511+
`pki-reader-${this.mountPath}`,
512+
mixed_config_policy
513+
);
491514
await logout.visit();
492515
});
493516

ui/tests/acceptance/pki/pki-overview-test.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@ import logout from 'vault/tests/pages/logout';
1010
import enablePage from 'vault/tests/pages/settings/mount-secret-backend';
1111
import { click, currentURL, currentRouteName, visit } from '@ember/test-helpers';
1212
import { SELECTORS } from 'vault/tests/helpers/pki/overview';
13-
import { tokenWithPolicy, runCommands } from 'vault/tests/helpers/pki/pki-run-commands';
13+
import { tokenWithPolicy, runCommands, clearRecords } from 'vault/tests/helpers/pki/pki-run-commands';
1414

1515
module('Acceptance | pki overview', function (hooks) {
1616
setupApplicationTest(hooks);
1717

1818
hooks.beforeEach(async function () {
19+
this.store = this.owner.lookup('service:store');
1920
await authPage.login();
2021
// Setup PKI engine
2122
const mountPath = `pki`;
@@ -42,6 +43,7 @@ module('Acceptance | pki overview', function (hooks) {
4243
this.pkiIssuersList = await tokenWithPolicy('pki-issuers-list', pki_issuers_list_policy);
4344
this.pkiAdminToken = await tokenWithPolicy('pki-admin', pki_admin_policy);
4445
await logout.visit();
46+
clearRecords(this.store);
4547
});
4648

4749
hooks.afterEach(async function () {

ui/tests/acceptance/policies-acl-old-test.js

+2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ module('Acceptance | policies (old)', function (hooks) {
4545
assert.dom('[data-test-policy-name]').hasText(policyLower, 'displays the policy name on the show page');
4646
assert.dom('[data-test-flash-message].is-info').doesNotExist('no flash message is displayed on save');
4747
await click('[data-test-policy-list-link]');
48+
await fillIn('[data-test-component="navigate-input"]', policyLower);
4849

4950
assert
5051
.dom(`[data-test-policy-link="${policyLower}"]`)
@@ -64,6 +65,7 @@ module('Acceptance | policies (old)', function (hooks) {
6465
`/vault/policies/acl`,
6566
'navigates to policy list on successful deletion'
6667
);
68+
await fillIn('[data-test-component="navigate-input"]', policyLower);
6769
assert
6870
.dom(`[data-test-policy-item="${policyLower}"]`)
6971
.doesNotExist('deleted policy is not shown in the list');

ui/tests/helpers/pki/pki-run-commands.js

+18
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,21 @@ export const runCommands = async function (commands) {
3434
throw error;
3535
}
3636
};
37+
38+
// Clears pki-related data and capabilities so that admin
39+
// capabilities from setup don't rollover
40+
export function clearRecords(store) {
41+
store.unloadAll('pki/action');
42+
store.unloadAll('pki/issuer');
43+
store.unloadAll('pki/key');
44+
store.unloadAll('pki/role');
45+
store.unloadAll('pki/sign-intermediate');
46+
store.unloadAll('pki/tidy');
47+
store.unloadAll('pki/config/urls');
48+
store.unloadAll('pki/config/crl');
49+
store.unloadAll('pki/config/cluster');
50+
store.unloadAll('pki/config/acme');
51+
store.unloadAll('pki/certificate/generate');
52+
store.unloadAll('pki/certificate/sign');
53+
store.unloadAll('capabilities');
54+
}

0 commit comments

Comments
 (0)