Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ui/ttl form field model #8891

Merged
merged 16 commits into from
May 8, 2020
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions ui/app/components/role-ssh-edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,12 @@ export default RoleEdit.extend({
this._super(...arguments);
this.set('backendType', 'ssh');
},

actions: {
updateTtl(path, val) {
const model = this.get('model');
let valueToSet = val.enabled === true ? `${val.seconds}s` : undefined;
model.set(path, valueToSet);
},
},
});
6 changes: 6 additions & 0 deletions ui/app/controllers/vault/cluster/secrets/backend/sign.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ export default Controller.extend({
}
},

updateTtl(path, val) {
const model = this.get('model');
let valueToSet = val.enabled === true ? `${val.seconds}s` : undefined;
set(model, path, valueToSet);
},

newModel() {
const model = this.get('model');
const roleModel = model.get('role');
Expand Down
6 changes: 6 additions & 0 deletions ui/app/styles/components/ttl-picker2.scss
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,9 @@ input.has-error:hover {
.ttl-value-error {
margin-top: 0.3em;
}

.description {
display: flex;
justify-content: flex-start;
align-content: center;
}
16 changes: 8 additions & 8 deletions ui/app/templates/partials/form-field-from-model.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,14 @@
</div>
</div>
{{else if (eq attr.options.editType "ttl")}}
{{ttl-picker
initialValue=(or (get model attr.name) attr.options.defaultValue)
labelText=(if
attr.options.label attr.options.label (humanize (dasherize attr.name))
)
setDefaultValue=false
onChange=(action (mut (get model attr.name)))
}}
<TtlPicker2
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💕angle bracket invocation

@initialValue={{or (get model attr.name) attr.options.defaultValue}}
@initialEnabled={{or (get model attr.name) false}}
@label={{or attr.options.label (humanize (dasherize attr.name))}}
@helperTextDisabled="If this is not set, the engine default will be used."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@helperTextEnabled="Disable lease after"
@onChange={{action "updateTtl" attr.name}}
/>
{{else if (or (eq attr.type "number") (eq attr.type "string"))}}
<div class="control">
{{input
Expand Down
2 changes: 1 addition & 1 deletion ui/lib/core/addon/components/form-field.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ export default Component.extend({

setAndBroadcastTtl(path, value) {
const alwaysSendValue = path === 'expiry' || path === 'safetyBuffer';
let valueToSet = value.enabled === true || alwaysSendValue ? `${value.seconds}s` : undefined;
let valueToSet = value.enabled === true || alwaysSendValue ? `${value.seconds}s` : 0;
this.send('setAndBroadcast', path, `${valueToSet}`);
},

Expand Down
13 changes: 12 additions & 1 deletion ui/lib/core/addon/components/ttl-picker2.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@
* @param label="Time to live (TTL)" {String} - Label is the main label that lives next to the toggle.
* @param helperTextDisabled="Allow tokens to be used indefinitely" {String} - This helper text is shown under the label when the toggle is switched off
* @param helperTextEnabled="Disable the use of the token after" {String} - This helper text is shown under the label when the toggle is switched on
* @param description="Longer description about this value, what it does, and why it is useful. Shows up in tooltip next to helpertext"
* @param time=30 {Number} - The time (in the default units) which will be adjustable by the user of the form
* @param unit="s" {String} - This is the unit key which will show by default on the form. Can be one of `s` (seconds), `m` (minutes), `h` (hours), `d` (days)
* @param recalculationTimeout=5000 {Number} - This is the time, in milliseconds, that `recalculateSeconds` will be be true after time is updated
* @param initialValue {String} - This is the value set initially (particularly from a string like '30h')
* @param initialValue=null {String} - This is the value set initially (particularly from a string like '30h')
* @param initialEnabled=null {Boolean} - Set this value if you want the toggle on when component is mounted
*/

import Ember from 'ember';
Expand Down Expand Up @@ -45,6 +47,7 @@ export default Component.extend({
label: 'Time to live (TTL)',
helperTextDisabled: 'Allow tokens to be used indefinitely',
helperTextEnabled: 'Disable the use of the token after',
description: '',
time: 30,
unit: 's',
recalculationTimeout: 5000,
Expand All @@ -53,12 +56,18 @@ export default Component.extend({
init() {
this._super(...arguments);
const value = this.initialValue;
const enable = this.initialEnabled;
// if initial value is unset use params passed in as defaults
if (!value && value !== 0) {
return;
}

let seconds = 30;
let setEnable = this.enableTTL;
if (!!enable || typeOf(enable) === 'boolean') {
// This allows non-boolean values passed in to be evaluated for truthiness
setEnable = !!enable;
}
if (typeOf(value) === 'number') {
seconds = value;
} else {
Expand All @@ -72,8 +81,10 @@ export default Component.extend({
this.setProperties({
time: seconds,
unit: 's',
enableTTL: setEnable,
});
},

unitOptions: computed(function() {
return [
{ label: 'seconds', value: 's' },
Expand Down
3 changes: 2 additions & 1 deletion ui/lib/core/addon/templates/components/form-field.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,9 @@
<TtlPicker2
@onChange={{action (action "setAndBroadcastTtl" valuePath)}}
@label={{labelString}}
@helperTextDisabled={{or attr.helpText "Vault will use the default lease duration"}}
@helperTextDisabled="Vault will use the default lease duration"
@helperTextEnabled="Lease will expire after"
@description={{attr.helpText}}
@initialValue={{or (get model valuePath) attr.options.setDefault}}
/>
{{else if (eq attr.options.editType "stringArray")}}
Expand Down
16 changes: 15 additions & 1 deletion ui/lib/core/addon/templates/components/ttl-picker2.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,21 @@
data-test-ttl-toggle
>
<span class="ttl-picker-label is-large">{{label}}</span><br/>
<span class="has-text-grey">{{helperText}}</span>
<div class="description has-text-grey">
<span>{{helperText}}</span>
{{#if description}}
<ToolTip @verticalPosition="below" as |T|>
<T.trigger data-test-tooltip-trigger tabindex=false>
<Icon @glyph="info-circle-outline" aria-label="description" />
</T.trigger>
<T.content @class="tool-tip">
<div class="box" data-test-hover-copy-tooltip-text>
{{description}}
</div>
</T.content>
</ToolTip>
{{/if}}
</div>
</Toggle>
{{#if enableTTL}}
<div class="ttl-show-picker" data-test-ttl-picker-group="{{label}}">
Expand Down
21 changes: 12 additions & 9 deletions ui/lib/core/stories/ttl-picker2.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,18 @@ TtlPicker2 components are used to enable and select time to live values. Use thi

**Params**

| Param | Type | Default | Description |
| -------------------- | --------------------- | -------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| onChange | <code>function</code> | | This function will be passed a TTL object, which includes enabled{bool}, seconds{number}, timeString{string}. |
| label | <code>String</code> | <code>&quot;Time to live (TTL)"</code> | Label is the main label that lives next to the toggle. |
| helperTextDisabled | <code>String</code> | <code>&quot;Allow tokens to be used indefinitely"</code> | This helper text is shown under the label when the toggle is switched off |
| helperTextEnabled | <code>String</code> | <code>&quot;Disable the use of the token after" </code> | This helper text is shown under the label when the toggle is switched on |
| time | <code>Number</code> | <code>30</code> | The time (in the default units) which will be adjustable by the user of the form |
| unit | <code>String</code> | <code>&quot;s&quot;</code> | This is the unit key which will show by default on the form. Can be one of `s` (seconds), `m` (minutes), `h` (hours), `d` (days) |
| recalculationTimeout | <code>Number</code> | <code>5000</code> | This is the time, in milliseconds, that `recalculateSeconds` will be be true after time is updated |
| Param | Type | Default | Description |
| -------------------- | --------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| onChange | <code>function</code> | | This function will be passed a TTL object, which includes enabled{bool}, seconds{number}, timeString{string}. |
| label | <code>String</code> | <code>&quot;Time to live (TTL)&quot;</code> | Label is the main label that lives next to the toggle. |
| helperTextDisabled | <code>String</code> | <code>&quot;Allow tokens to be used indefinitely&quot;</code> | This helper text is shown under the label when the toggle is switched off |
| helperTextEnabled | <code>String</code> | <code>&quot;Disable the use of the token after&quot;</code> | This helper text is shown under the label when the toggle is switched on |
| description | | <code></code> | Longer description about this value, what it does, and why it is useful. Shows up in tooltip next to helpertext |
| time | <code>Number</code> | <code>30</code> | The time (in the default units) which will be adjustable by the user of the form |
| unit | <code>String</code> | <code>&quot;s&quot;</code> | This is the unit key which will show by default on the form. Can be one of `s` (seconds), `m` (minutes), `h` (hours), `d` (days) |
| recalculationTimeout | <code>Number</code> | <code>5000</code> | This is the time, in milliseconds, that `recalculateSeconds` will be be true after time is updated |
| initialValue | <code>String</code> | <code></code> | This is the value set initially (particularly from a string like '30h') |
| initialEnabled | <code>Boolean</code> | <code></code> | Set this value if you want the toggle on when component is mounted |

**Example**

Expand Down
25 changes: 25 additions & 0 deletions ui/tests/acceptance/settings/mount-secret-backend-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,29 @@ module('Acceptance | settings/mount-secret-backend', function(hooks) {
assert.equal(configPage.defaultTTL, defaultTTLSeconds, 'shows the proper TTL');
assert.equal(configPage.maxTTL, maxTTLSeconds, 'shows the proper max TTL');
});

test('it sets the ttl when enabled then disabled', async function(assert) {
// always force the new mount to the top of the list
const path = `kv-${new Date().getTime()}`;
const maxTTLHours = 300;
const maxTTLSeconds = maxTTLHours * 60 * 60;

await page.visit();

assert.equal(currentRouteName(), 'vault.cluster.settings.mount-secret-backend');
await page.selectType('kv');
await page
.next()
.path(path)
.toggleOptions()
.enableDefaultTtl()
.enableDefaultTtl()
.enableMaxTtl()
.maxTTLUnit('h')
.maxTTLVal(maxTTLHours)
.submit();
await configPage.visit({ backend: path });
assert.equal(configPage.defaultTTL, 0, 'shows the proper TTL');
assert.equal(configPage.maxTTL, maxTTLSeconds, 'shows the proper max TTL');
});
});
33 changes: 33 additions & 0 deletions ui/tests/integration/components/ttl-picker2-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,37 @@ module('Integration | Component | ttl-picker2', function(hooks) {
assert.dom('[data-test-ttl-value]').hasValue('7200', 'time value is initialValue as seconds');
assert.dom('[data-test-select="ttl-unit"]').hasValue('s', 'unit is seconds');
});

test('it is enabled on init if initialEnabled is true', async function(assert) {
let changeSpy = sinon.spy();
this.set('onChange', changeSpy);
await render(hbs`
<TtlPicker2
@label="inittest"
@onChange={{onChange}}
@initialValue="100m"
@initialEnabled={{true}}
/>
`);
assert.dom('[data-test-ttl-value]').hasValue('6000', 'time value is initialValue as seconds');
assert.dom('[data-test-ttl-unit]').exists('Unit is shown on mount');
await click('[data-test-toggle-input="inittest"]');
assert.dom('[data-test-ttl-value]').doesNotExist('Value no longer shows after toggle');
assert.dom('[data-test-ttl-unit]').doesNotExist('Unit no longer shows after toggle');
});

test('it is enabled on init if initialEnabled evals to truthy', async function(assert) {
let changeSpy = sinon.spy();
this.set('onChange', changeSpy);
await render(hbs`
<TtlPicker2
@label="inittest"
@onChange={{onChange}}
@initialValue="100m"
@initialEnabled="true"
/>
`);
assert.dom('[data-test-ttl-value]').hasValue('6000', 'time value is initialValue as seconds');
assert.dom('[data-test-ttl-unit]').exists('Unit is shown on mount');
});
});