Replace KV v2 List route with wildcard instead of dynamic segment (#23620)

* initial work on the LIST route.

* fix

* changelog

* add s

* add in prepending forward slash
This commit is contained in:
Angel Garbarino
2023-10-13 11:01:23 -06:00
committed by GitHub
parent b0ce08bb4b
commit 27170b662d
5 changed files with 38 additions and 34 deletions

3
changelog/23620.txt Normal file
View File

@@ -0,0 +1,3 @@
```release-note:bug
ui: Fixes issue where you could not share the list view URL from the KV v2 secrets engine.
```

View File

@@ -7,9 +7,10 @@ import buildRoutes from 'ember-engines/routes';
export default buildRoutes(function () {
// There are two list routes because Ember won't let a route param (e.g. *path_to_secret) be blank.
// :path_to_secret is used when we're listing a secret directory. Example { path: '/:beep%2Fboop%2F/directory' });
// *path_to_secret is used when we're listing a secret directory.
// Must use a wildcard for path-to-secret because the value can contain a forward slash if it's a secret directory. Ember's router decodes encoded forward slashes which leads to beep%2fboop becoming beep/boop and messing up routing after copying and pasting the URL.
this.route('list');
this.route('list-directory', { path: '/:path_to_secret/directory' });
this.route('list-directory', { path: '/list/*path_to_secret' });
this.route('create');
this.route('secret', { path: '/:name' }, function () {
this.route('paths');

View File

@@ -213,7 +213,7 @@ module('Acceptance | kv-v2 workflow | secret and version create', function (hook
});
test('creates a secret at a sub-directory (a)', async function (assert) {
const backend = this.backend;
await visit(`/vault/secrets/${backend}/kv/app%2F/directory`);
await visit(`/vault/secrets/${backend}/kv/list/app/`);
assert.dom(PAGE.list.item('first')).exists('Lists first sub-secret');
assert.dom(PAGE.list.item('new')).doesNotExist('Does not show new secret');
await click(PAGE.list.createSecret);
@@ -232,7 +232,7 @@ module('Acceptance | kv-v2 workflow | secret and version create', function (hook
'Redirects to detail after save'
);
await click(PAGE.breadcrumbAtIdx(2));
assert.strictEqual(currentURL(), `/vault/secrets/${backend}/kv/app%2F/directory`, 'sub-dir page');
assert.strictEqual(currentURL(), `/vault/secrets/${backend}/kv/list/app/`, 'sub-dir page');
assert.dom(PAGE.list.item('new')).exists('Lists new secret in sub-dir');
});
test('create new version of secret from older version (a)', async function (assert) {
@@ -390,7 +390,7 @@ module('Acceptance | kv-v2 workflow | secret and version create', function (hook
});
test('creates a secret at a sub-directory (dr)', async function (assert) {
const backend = this.backend;
await visit(`/vault/secrets/${backend}/kv/app%2F/directory`);
await visit(`/vault/secrets/${backend}/kv/list/app/`);
assert.dom(PAGE.list.item()).doesNotExist('Does not list any secrets');
await click(PAGE.list.createSecret);
assert.strictEqual(
@@ -535,7 +535,7 @@ module('Acceptance | kv-v2 workflow | secret and version create', function (hook
});
test('creates a secret at a sub-directory (dlr)', async function (assert) {
const backend = this.backend;
await visit(`/vault/secrets/${backend}/kv/app%2F/directory`);
await visit(`/vault/secrets/${backend}/kv/list/app/`);
assert.dom(PAGE.list.item()).doesNotExist('Does not list any secrets');
await click(PAGE.list.createSecret);
assert.strictEqual(
@@ -704,7 +704,7 @@ module('Acceptance | kv-v2 workflow | secret and version create', function (hook
});
test('creates a secret at a sub-directory (mm)', async function (assert) {
const backend = this.backend;
await visit(`/vault/secrets/${backend}/kv/app%2F/directory`);
await visit(`/vault/secrets/${backend}/kv/list/app/`);
assert.dom(PAGE.list.item('first')).exists('Lists first sub-secret');
assert.dom(PAGE.list.item('new')).doesNotExist('Does not show new secret');
await click(PAGE.list.createSecret);
@@ -941,7 +941,7 @@ module('Acceptance | kv-v2 workflow | secret and version create', function (hook
});
test('creates a secret at a sub-directory (sc)', async function (assert) {
const backend = this.backend;
await visit(`/vault/secrets/${backend}/kv/app%2F/directory`);
await visit(`/vault/secrets/${backend}/kv/list/app/`);
assert.dom(PAGE.list.item()).doesNotExist('Does not list any secrets');
await click(PAGE.list.createSecret);
assert.strictEqual(
@@ -959,7 +959,7 @@ module('Acceptance | kv-v2 workflow | secret and version create', function (hook
'Redirects to detail after save'
);
await click(PAGE.breadcrumbAtIdx(2));
assert.strictEqual(currentURL(), `/vault/secrets/${backend}/kv/app%2F/directory`, 'sub-dir page');
assert.strictEqual(currentURL(), `/vault/secrets/${backend}/kv/list/app/`, 'sub-dir page');
assert.dom(PAGE.list.item()).doesNotExist('Does not list any secrets');
});
test('create new version of secret from older version (sc)', async function (assert) {

View File

@@ -84,7 +84,7 @@ module('Acceptance | kv-v2 workflow | edge cases', function (hooks) {
// URL correct
assert.strictEqual(
currentURL(),
`/vault/secrets/${backend}/kv/${root}%2F/directory`,
`/vault/secrets/${backend}/kv/list/${root}/`,
'visits list-directory of root'
);
@@ -125,7 +125,7 @@ module('Acceptance | kv-v2 workflow | edge cases', function (hooks) {
await click(PAGE.breadcrumbAtIdx(previousCrumb));
assert.strictEqual(
currentURL(),
`/vault/secrets/${backend}/kv/${root}%2F${subdirectory}%2F/directory`,
`/vault/secrets/${backend}/kv/list/${root}/${subdirectory}/`,
'goes back to subdirectory list'
);
assert.dom(PAGE.list.filter).hasValue(`${root}/${subdirectory}/`);
@@ -136,7 +136,7 @@ module('Acceptance | kv-v2 workflow | edge cases', function (hooks) {
await click(PAGE.breadcrumbAtIdx(previousCrumb));
assert.strictEqual(
currentURL(),
`/vault/secrets/${backend}/kv/${root}%2F/directory`,
`/vault/secrets/${backend}/kv/list/${root}/`,
'goes back to root directory'
);
assert.dom(PAGE.list.item(`${subdirectory}/`)).exists('renders linked block for subdirectory');
@@ -253,7 +253,7 @@ module('Acceptance | kv-v2 workflow | edge cases', function (hooks) {
});
test('no ghost item after editing metadata', async function (assert) {
await visit(`/vault/secrets/${this.backend}/kv/edge/directory`);
await visit(`/vault/secrets/${this.backend}/kv/list/edge/`);
assert.dom(PAGE.list.item()).exists({ count: 2 }, 'two secrets are listed');
await click(PAGE.list.item('two'));
await click(PAGE.secretTab('Metadata'));

View File

@@ -165,14 +165,14 @@ module('Acceptance | kv-v2 workflow | navigation', function (hooks) {
// Navigate through list items
await click(PAGE.list.item('app/'));
assert.strictEqual(currentURL(), `/vault/secrets/${backend}/kv/app%2F/directory`);
assert.strictEqual(currentURL(), `/vault/secrets/${backend}/kv/list/app/`);
assertCorrectBreadcrumbs(assert, ['secret', backend, 'app']);
assert.dom(PAGE.title).hasText(`${backend} Version 2`);
assert.dom(PAGE.list.filter).hasValue('app/', 'List filter input is prefilled');
assert.dom(PAGE.list.item('nested/')).exists('Shows nested secret');
await click(PAGE.list.item('nested/'));
assert.strictEqual(currentURL(), `/vault/secrets/${backend}/kv/app%2Fnested%2F/directory`);
assert.strictEqual(currentURL(), `/vault/secrets/${backend}/kv/list/app/nested/`);
assertCorrectBreadcrumbs(assert, ['secret', backend, 'app', 'nested']);
assert.dom(PAGE.title).hasText(`${backend} Version 2`);
assert.dom(PAGE.list.filter).hasValue('app/nested/', 'List filter input is prefilled');
@@ -189,13 +189,13 @@ module('Acceptance | kv-v2 workflow | navigation', function (hooks) {
await click(PAGE.breadcrumbAtIdx(3));
assert.ok(
currentURL().startsWith(`/vault/secrets/${backend}/kv/app%2Fnested%2F/directory`),
currentURL().startsWith(`/vault/secrets/${backend}/kv/list/app/nested/`),
'links back to list directory'
);
await click(PAGE.breadcrumbAtIdx(2));
assert.ok(
currentURL().startsWith(`/vault/secrets/${backend}/kv/app%2F/directory`),
currentURL().startsWith(`/vault/secrets/${backend}/kv/list/app/`),
'links back to list directory'
);
@@ -416,13 +416,13 @@ module('Acceptance | kv-v2 workflow | navigation', function (hooks) {
await click(PAGE.breadcrumbAtIdx(3));
assert.ok(
currentURL().startsWith(`/vault/secrets/${backend}/kv/app%2Fnested%2F/directory`),
currentURL().startsWith(`/vault/secrets/${backend}/kv/list/app/nested/`),
'links back to list directory'
);
await click(PAGE.breadcrumbAtIdx(2));
assert.ok(
currentURL().startsWith(`/vault/secrets/${backend}/kv/app%2F/directory`),
currentURL().startsWith(`/vault/secrets/${backend}/kv/list/app/`),
'links back to list directory'
);
@@ -585,7 +585,7 @@ module('Acceptance | kv-v2 workflow | navigation', function (hooks) {
// Navigate through list items
await click(PAGE.list.item('app/'));
assert.strictEqual(currentURL(), `/vault/secrets/${backend}/kv/app%2F/directory`);
assert.strictEqual(currentURL(), `/vault/secrets/${backend}/kv/list/app/`);
assertCorrectBreadcrumbs(assert, ['secret', backend, 'app']);
assert.dom(PAGE.title).hasText(`${backend} Version 2`);
assert.dom(PAGE.list.filter).doesNotExist('List filter hidden since no nested list access');
@@ -606,13 +606,13 @@ module('Acceptance | kv-v2 workflow | navigation', function (hooks) {
await click(PAGE.breadcrumbAtIdx(3));
assert.ok(
currentURL().startsWith(`/vault/secrets/${backend}/kv/app%2Fnested%2F/directory`),
currentURL().startsWith(`/vault/secrets/${backend}/kv/list/app/nested/`),
'links back to list directory'
);
await click(PAGE.breadcrumbAtIdx(2));
assert.ok(
currentURL().startsWith(`/vault/secrets/${backend}/kv/app%2F/directory`),
currentURL().startsWith(`/vault/secrets/${backend}/kv/list/app/`),
'links back to list directory'
);
@@ -771,14 +771,14 @@ module('Acceptance | kv-v2 workflow | navigation', function (hooks) {
// Navigate through list items
await click(PAGE.list.item('app/'));
assert.strictEqual(currentURL(), `/vault/secrets/${backend}/kv/app%2F/directory`);
assert.strictEqual(currentURL(), `/vault/secrets/${backend}/kv/list/app/`);
assertCorrectBreadcrumbs(assert, ['secret', backend, 'app']);
assert.dom(PAGE.title).hasText(`${backend} Version 2`);
assert.dom(PAGE.list.filter).hasValue('app/', 'List filter input is prefilled');
assert.dom(PAGE.list.item('nested/')).exists('Shows nested secret');
await click(PAGE.list.item('nested/'));
assert.strictEqual(currentURL(), `/vault/secrets/${backend}/kv/app%2Fnested%2F/directory`);
assert.strictEqual(currentURL(), `/vault/secrets/${backend}/kv/list/app/nested/`);
assertCorrectBreadcrumbs(assert, ['secret', backend, 'app', 'nested']);
assert.dom(PAGE.title).hasText(`${backend} Version 2`);
assert.dom(PAGE.list.filter).hasValue('app/nested/', 'List filter input is prefilled');
@@ -797,13 +797,13 @@ module('Acceptance | kv-v2 workflow | navigation', function (hooks) {
await click(PAGE.breadcrumbAtIdx(3));
assert.ok(
currentURL().startsWith(`/vault/secrets/${backend}/kv/app%2Fnested%2F/directory`),
currentURL().startsWith(`/vault/secrets/${backend}/kv/list/app/nested/`),
'links back to list directory'
);
await click(PAGE.breadcrumbAtIdx(2));
assert.ok(
currentURL().startsWith(`/vault/secrets/${backend}/kv/app%2F/directory`),
currentURL().startsWith(`/vault/secrets/${backend}/kv/list/app/`),
'links back to list directory'
);
@@ -989,13 +989,13 @@ module('Acceptance | kv-v2 workflow | navigation', function (hooks) {
await click(PAGE.breadcrumbAtIdx(3));
assert.ok(
currentURL().startsWith(`/vault/secrets/${backend}/kv/app%2Fnested%2F/directory`),
currentURL().startsWith(`/vault/secrets/${backend}/kv/list/app/nested/`),
'links back to list directory'
);
await click(PAGE.breadcrumbAtIdx(2));
assert.ok(
currentURL().startsWith(`/vault/secrets/${backend}/kv/app%2F/directory`),
currentURL().startsWith(`/vault/secrets/${backend}/kv/list/app/`),
'links back to list directory'
);
@@ -1152,14 +1152,14 @@ path "${this.backend}/*" {
// Navigate through list items
await click(PAGE.list.item('app/'));
assert.strictEqual(currentURL(), `/vault/secrets/${backend}/kv/app%2F/directory`);
assert.strictEqual(currentURL(), `/vault/secrets/${backend}/kv/list/app/`);
assertCorrectBreadcrumbs(assert, ['secret', backend, 'app']);
assert.dom(PAGE.title).hasText(`${backend} Version 2`);
assert.dom(PAGE.list.filter).hasValue('app/', 'List filter input is prefilled');
assert.dom(PAGE.list.item('nested/')).exists('Shows nested secret');
await click(PAGE.list.item('nested/'));
assert.strictEqual(currentURL(), `/vault/secrets/${backend}/kv/app%2Fnested%2F/directory`);
assert.strictEqual(currentURL(), `/vault/secrets/${backend}/kv/list/app/nested/`);
assertCorrectBreadcrumbs(assert, ['secret', backend, 'app', 'nested']);
assert.dom(PAGE.title).hasText(`${backend} Version 2`);
assert.dom(PAGE.list.filter).hasValue('app/nested/', 'List filter input is prefilled');
@@ -1174,12 +1174,12 @@ path "${this.backend}/*" {
);
await grantAccess({
apiPath: `${backend}/data/app/nested/secret`,
originUrl: `/vault/secrets/${backend}/kv/app%2Fnested%2F/directory`,
originUrl: `/vault/secrets/${backend}/kv/list/app/nested/`,
userToken: this.userToken,
});
assert.strictEqual(
currentURL(),
`/vault/secrets/${backend}/kv/app%2Fnested%2F/directory`,
`/vault/secrets/${backend}/kv/list/app/nested/`,
'navigates to list url where secret is'
);
await click(PAGE.list.item('secret'));
@@ -1195,13 +1195,13 @@ path "${this.backend}/*" {
await click(PAGE.breadcrumbAtIdx(3));
assert.ok(
currentURL().startsWith(`/vault/secrets/${backend}/kv/app%2Fnested%2F/directory`),
currentURL().startsWith(`/vault/secrets/${backend}/kv/list/app/nested/`),
'links back to list directory'
);
await click(PAGE.breadcrumbAtIdx(2));
assert.ok(
currentURL().startsWith(`/vault/secrets/${backend}/kv/app%2F/directory`),
currentURL().startsWith(`/vault/secrets/${backend}/kv/list/app/`),
'links back to list directory'
);