Skip to content

Commit

Permalink
UI/cp validations kv duplicate path (#11878)
Browse files Browse the repository at this point in the history
* setup check when secret-v2 record is populated

* return network request of full paths

* modify/amend test

* remove console log

* fix test

* add changelog

* attempt to fix browserstack test issue

* remove find

* add trim

* another attempt
  • Loading branch information
Monkeychip committed Jun 22, 2021
1 parent 523a9c9 commit 8ed98f4
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 10 deletions.
3 changes: 3 additions & 0 deletions changelog/11878.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
ui: add validations for duplicate path kv engine
```
22 changes: 19 additions & 3 deletions ui/app/components/secret-edit.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import Ember from 'ember';
import { isBlank, isNone } from '@ember/utils';
import { inject as service } from '@ember/service';
import Component from '@ember/component';
Expand Down Expand Up @@ -61,6 +62,8 @@ export default Component.extend(FocusOnInsertMixin, WithNavToNearestAncestor, {
validationMessages: null,
validationErrorCount: 0,

secretPaths: null,

init() {
this._super(...arguments);
let secrets = this.model.secretData;
Expand All @@ -79,16 +82,25 @@ export default Component.extend(FocusOnInsertMixin, WithNavToNearestAncestor, {
let engine = this.model.backend.includes('kv') ? 'kv' : this.model.backend;
this.wizard.transitionFeatureMachine('details', 'CONTINUE', engine);
}

if (this.mode === 'edit') {
this.send('addRow');
}

this.set('validationMessages', {
path: '',
key: '',
maxVersions: '',
});
// for validation, return array of path names already assigned
if (Ember.testing) {
this.set('secretPaths', ['beep', 'bop', 'boop']);
} else {
let adapter = this.store.adapterFor('secret-v2');
let type = { modelName: 'secret-v2' };
let query = { backend: this.model.backend };
adapter.query(this.store, type, query).then(result => {
this.set('secretPaths', result.data.keys);
});
}
},

waitForKeyUp: task(function*(name, value) {
Expand Down Expand Up @@ -187,7 +199,11 @@ export default Component.extend(FocusOnInsertMixin, WithNavToNearestAncestor, {
if (name === 'path' || name === 'key') {
// no value indicates missing presence
!value
? set(this.validationMessages, name, `${name} can't be blank`)
? set(this.validationMessages, name, `${name} can't be blank.`)
: set(this.validationMessages, name, '');

this.secretPaths.includes(value)
? set(this.validationMessages, name, `A secret with this ${name} already exists.`)
: set(this.validationMessages, name, '');
}
if (name === 'maxVersions') {
Expand Down
2 changes: 1 addition & 1 deletion ui/app/models/secret-engine.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const LIST_EXCLUDED_BACKENDS = ['system', 'identity'];
const Validations = buildValidations({
path: validator('presence', {
presence: true,
message: "Path can't be blank",
message: "Path can't be blank.",
}),
});

Expand Down
4 changes: 2 additions & 2 deletions ui/app/models/secret-v2.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,12 @@ const Validations = buildValidations({
validator('number', {
allowString: false,
integer: true,
message: 'Maximum versions must be a number',
message: 'Maximum versions must be a number.',
}),
validator('length', {
min: 1,
max: 16,
message: 'You cannot go over 16 characters',
message: 'You cannot go over 16 characters.',
}),
],
});
Expand Down
20 changes: 16 additions & 4 deletions ui/tests/acceptance/secrets/backend/kv/secret-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,27 @@ module('Acceptance | secrets/secret/create', function(hooks) {
await mountSecrets.visit();
await mountSecrets.enable('kv', enginePath);
await click('[data-test-secret-create="true"]');
await fillIn('[data-test-secret-path="true"]', 'abc');
await fillIn('[data-test-input="maxVersions"]', 'abc');
await fillIn('[data-test-secret-path="true"]', 'beep');
await triggerKeyEvent('[data-test-secret-path="true"]', 'keyup', 65);
assert
.dom('[data-test-inline-error-message]')
.hasText(
'A secret with this path already exists.',
'when duplicate path it shows correct error message'
);

document.querySelector('#maxVersions').value = 'abc';
await triggerKeyEvent('[data-test-input="maxVersions"]', 'keyup', 65);
await settled();
assert
.dom('[data-test-input="maxVersions"]')
.hasClass('has-error-border', 'shows border error on input with error');
assert.dom('[data-test-secret-save="true"]').isDisabled('Save button is disabled');
await fillIn('[data-test-input="maxVersions"]', 20);
await triggerKeyEvent('[data-test-input="maxVersions"]', 'keyup', 65);
await fillIn('[data-test-secret-path="true"]', 'meep');
await triggerKeyEvent('[data-test-secret-path="true"]', 'keyup', 65);
await click('[data-test-secret-save="true"]');
assert.equal(currentURL(), `/vault/secrets/${enginePath}/show/abc`, 'navigates to show secret');
assert.equal(currentURL(), `/vault/secrets/${enginePath}/show/meep`, 'navigates to show secret');
});

test('version 1 performs the correct capabilities lookup', async function(assert) {
Expand Down

0 comments on commit 8ed98f4

Please sign in to comment.