Bug: Fix issue with double encoding on space in secret history route (#10596)

* setup for concept it works, but probably not the best solution

* add comment and remove console and test var

* use normalize path higher up to fix issu

* add test for bug that fixing

* forgot a couple of changes

* changelog
This commit is contained in:
Angel Garbarino 2021-01-04 09:32:52 -07:00 committed by GitHub
parent 05f1a429a8
commit feca115ef4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 42 additions and 4 deletions

4
changelog/10596.txt Normal file
View File

@ -0,0 +1,4 @@
```release-note:bug
ui: Fix bug that double encodes secret route when there are spaces in the path and makes you unable to view the version history.
```

View File

@ -1,6 +1,7 @@
import Route from '@ember/routing/route'; import Route from '@ember/routing/route';
import utils from 'vault/lib/key-utils'; import utils from 'vault/lib/key-utils';
import UnloadModelRoute from 'vault/mixins/unload-model-route'; import UnloadModelRoute from 'vault/mixins/unload-model-route';
import { normalizePath } from 'vault/utils/path-encoding-helpers';
export default Route.extend(UnloadModelRoute, { export default Route.extend(UnloadModelRoute, {
templateName: 'vault/cluster/secrets/backend/versions', templateName: 'vault/cluster/secrets/backend/versions',
@ -22,6 +23,7 @@ export default Route.extend(UnloadModelRoute, {
model(params) { model(params) {
let { secret } = params; let { secret } = params;
const { backend } = this.paramsFor('vault.cluster.secrets.backend'); const { backend } = this.paramsFor('vault.cluster.secrets.backend');
return this.store.queryRecord('secret-v2', { id: secret, backend }); let id = normalizePath(secret);
return this.store.queryRecord('secret-v2', { id, backend });
}, },
}); });

View File

@ -45,7 +45,7 @@
as |D| as |D|
> >
<D.trigger <D.trigger
data-test-popup-menu-trigger="true" data-test-popup-menu-trigger="history"
@class={{concat "popup-menu-trigger toolbar-link" (if D.isOpen " is-active")}} @class={{concat "popup-menu-trigger toolbar-link" (if D.isOpen " is-active")}}
@tagName="button" @tagName="button"
> >
@ -56,6 +56,7 @@
<ul class="menu-list"> <ul class="menu-list">
<li class="action"> <li class="action">
<SecretLink <SecretLink
@data-test-version-history
@mode="versions" @mode="versions"
@secret={{this.model.id}} @secret={{this.model.id}}
@class="has-text-black has-text-weight-semibold has-bottom-shadow" @class="has-text-black has-text-weight-semibold has-bottom-shadow"

View File

@ -8,6 +8,8 @@
data-test-transit-link=data-test-transit-link data-test-transit-link=data-test-transit-link
data-test-transit-key-actions-link=data-test-transit-key-actions-link data-test-transit-key-actions-link=data-test-transit-key-actions-link
data-test-transit-action-link=data-test-transit-action-link data-test-transit-action-link=data-test-transit-action-link
data-test-version-history=data-test-version-history
data-test-version=data-test-version
invokeAction=(action onLinkClick) invokeAction=(action onLinkClick)
}} }}
{{yield}} {{yield}}

View File

@ -43,6 +43,7 @@
<SecretVersionMenu @version={{list.item}} @useDefaultTrigger={{true}}> <SecretVersionMenu @version={{list.item}} @useDefaultTrigger={{true}}>
<li class="action"> <li class="action">
<SecretLink <SecretLink
@data-test-version
@mode="show" @mode="show"
@secret={{model.id}} @secret={{model.id}}
@class="has-text-black has-text-weight-semibold" @class="has-text-black has-text-weight-semibold"

View File

@ -1,4 +1,4 @@
import { visit, settled, currentURL, currentRouteName } from '@ember/test-helpers'; import { click, visit, settled, currentURL, currentRouteName } from '@ember/test-helpers';
import { create } from 'ember-cli-page-object'; import { create } from 'ember-cli-page-object';
import { module, test } from 'qunit'; import { module, test } from 'qunit';
import { setupApplicationTest } from 'ember-qunit'; import { setupApplicationTest } from 'ember-qunit';
@ -20,7 +20,7 @@ let writeSecret = async function(backend, path, key, val) {
return editPage.createSecret(path, key, val); return editPage.createSecret(path, key, val);
}; };
module('Acceptance | secrets/secret/create meep', function(hooks) { module('Acceptance | secrets/secret/create', function(hooks) {
setupApplicationTest(hooks); setupApplicationTest(hooks);
hooks.beforeEach(async function() { hooks.beforeEach(async function() {
@ -288,6 +288,34 @@ module('Acceptance | secrets/secret/create meep', function(hooks) {
} }
}); });
test('create secret with space shows version data', async function(assert) {
let enginePath = `kv-${new Date().getTime()}`;
let secretPath = 'space space';
// mount version 2
await mountSecrets.visit();
await mountSecrets.selectType('kv');
await mountSecrets
.next()
.path(enginePath)
.submit();
await settled();
await listPage.create();
await editPage.createSecret(secretPath, 'foo', 'bar');
await settled();
await click('[data-test-popup-menu-trigger="history"]');
await settled();
await click('[data-test-version-history]');
await settled();
assert.dom('[data-test-list-item-content]').exists('renders the version and not an error state');
// click on version
await click('[data-test-popup-menu-trigger="true"]');
await click('[data-test-version]');
await settled();
// perform encode function that should be done by the encodePath
let encodedSecretPath = secretPath.replace(/ /g, '%20');
assert.equal(currentURL(), `/vault/secrets/${enginePath}/show/${encodedSecretPath}?version=1`);
});
// the web cli does not handle a quote as part of a path, so we test it here via the UI // the web cli does not handle a quote as part of a path, so we test it here via the UI
test('creating a secret with a single or double quote works properly', async function(assert) { test('creating a secret with a single or double quote works properly', async function(assert) {
await consoleComponent.runCommands('write sys/mounts/kv type=kv'); await consoleComponent.runCommands('write sys/mounts/kv type=kv');