UI: fixes pki role editing changing to default key parameter values (#20907)

* add integer-to-string helper

* rename and add test

* add role test

* finish tests

* pass options so values are only converted if the type matches

* okay lets hit it with the loose-equal instead

* add changelog
This commit is contained in:
claire bontempo
2023-05-31 15:44:22 -07:00
committed by GitHub
parent 0defa2a1e7
commit e32cf520f4
10 changed files with 135 additions and 5 deletions

3
changelog/20907.txt Normal file
View File

@@ -0,0 +1,3 @@
```release-note:bug
ui: fixes key_bits and signature_bits reverting to default values when editing a pki role
```

View File

@@ -184,7 +184,7 @@ export default class PkiRoleModel extends Model {
})
keyBits; // no possibleValues because options are dependent on selected key type
@attr('number', {
@attr('string', {
label: 'Signature bits',
subText: `Only applicable for key_type 'RSA'. Ignore for other key types.`,
defaultValue: '0',

View File

@@ -46,7 +46,7 @@
</option>
{{/if}}
{{#each (path-or-array @attr.options.possibleValues @model) as |val|}}
<option selected={{eq (get @model this.valuePath) (or val.value val)}} value={{or val.value val}}>
<option selected={{loose-equal (get @model this.valuePath) (or val.value val)}} value={{or val.value val}}>
{{or val.displayName val}}
</option>
{{/each}}

View File

@@ -0,0 +1,22 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/
import { helper } from '@ember/component/helper';
/*
* use sparingly *
ex: logic for an HTML element's selected boolean because <select> values are strings
strict equal (===) will fail if the API param is a number
<option selected={{loose-equal model.someAttr someOption)}} value={{someOption}}>
*/
export function looseEqual([a, b]) {
// loose equal 0 == '' returns true, we don't want that
if ((a === 0 && b === '') || (a === '' && b === 0)) {
return false;
}
return a == b;
}
export default helper(looseEqual);

View File

@@ -0,0 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/
export { default } from 'core/helpers/loose-equal';

View File

@@ -24,7 +24,7 @@
</option>
{{/if}}
{{#each this.keyBitOptions as |val|}}
<option selected={{eq (get @model "keyBits") val}} value={{val}}>
<option selected={{loose-equal (get @model "keyBits") val}} value={{val}}>
{{val}}
</option>
{{/each}}

View File

@@ -48,7 +48,6 @@ const KEY_BITS_OPTIONS: BitOptions = {
export default class PkiKeyParameters extends Component<Args> {
get keyBitOptions() {
if (!this.args.model.keyType) return [];
return KEY_BITS_OPTIONS[this.args.model.keyType];
}

View File

@@ -145,4 +145,70 @@ module('Integration | Component | pki-role-form', function (hooks) {
await click(SELECTORS.roleCreateButton);
assert.strictEqual(this.role.issuerRef, 'issuer-1', 'Issuer Ref correctly saved on create');
});
test('it should edit a role', async function (assert) {
assert.expect(8);
this.server.post(`/pki-test/roles/test-role`, (schema, req) => {
assert.ok(true, 'Request made to correct endpoint to update role');
const request = JSON.parse(req.requestBody);
assert.propEqual(
request,
{
allow_ip_sans: true,
issuer_ref: 'issuer-1',
key_bits: '224',
key_type: 'ec',
key_usage: ['DigitalSignature', 'KeyAgreement', 'KeyEncipherment'],
not_before_duration: '30s',
require_cn: true,
signature_bits: '384',
use_csr_common_name: true,
use_csr_sans: true,
},
'sends role params in correct type'
);
return {};
});
this.store.pushPayload('pki/role', {
modelName: 'pki/role',
name: 'test-role',
backend: 'pki-test',
id: 'role-id',
key_type: 'rsa',
key_bits: 3072, // string type in dropdown, API returns as numbers
signature_bits: 512, // string type in dropdown, API returns as numbers
});
this.role = this.store.peekRecord('pki/role', 'role-id');
await render(
hbs`
<PkiRoleForm
@role={{this.role}}
@issuers={{this.issuers}}
@onCancel={{this.onCancel}}
@onSave={{this.onSave}}
/>
`,
{ owner: this.engine }
);
await click(SELECTORS.issuerRefToggle);
await fillIn(SELECTORS.issuerRefSelect, 'issuer-1');
await click(SELECTORS.keyParams);
assert.dom(SELECTORS.keyType).hasValue('rsa');
assert.dom(SELECTORS.keyBits).hasValue('3072', 'dropdown has model value, not default value (2048)');
assert.dom(SELECTORS.signatureBits).hasValue('512', 'dropdown has model value, not default value (0)');
await fillIn(SELECTORS.keyType, 'ec');
await fillIn(SELECTORS.keyBits, '224');
assert.dom(SELECTORS.keyBits).hasValue('224', 'dropdown has selected value, not default value (256)');
await fillIn(SELECTORS.signatureBits, '384');
assert.dom(SELECTORS.signatureBits).hasValue('384', 'dropdown has selected value, not default value (0)');
await click(SELECTORS.roleCreateButton);
assert.strictEqual(this.role.issuerRef, 'issuer-1', 'Issuer Ref correctly saved on create');
});
});

View File

@@ -0,0 +1,34 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'vault/tests/helpers';
import { render } from '@ember/test-helpers';
import { hbs } from 'ember-cli-htmlbars';
import { looseEqual } from 'core/helpers/loose-equal';
module('Integration | Helper | loose-equal', function (hooks) {
setupRenderingTest(hooks);
test('it renders', async function (assert) {
this.inputValue = 1234;
await render(hbs`{{if (loose-equal "1234" 1234) "true" "false"}}`);
assert.dom(this.element).hasText('true');
this.inputValue = '4567';
await render(hbs`{{if (loose-equal "1234" "4567") "true" "false"}}`);
assert.dom(this.element).hasText('false');
});
test('it compares values as expected', async function (assert) {
assert.true(looseEqual([0, '0']));
assert.true(looseEqual([0, 0]));
assert.true(looseEqual(['0', '0']));
assert.true(looseEqual(['1234', 1234]));
assert.true(looseEqual(['1234', '1234']));
assert.true(looseEqual([1234, 1234]));
assert.true(looseEqual(['abc', 'abc']));
assert.true(looseEqual(['', '']));
// == normally returns true for this comparison, we intercept and return false
assert.false(looseEqual(['', 0]));
assert.false(looseEqual([0, '']));
});
});

View File

@@ -1,5 +1,5 @@
import Model from '@ember-data/model';
import { FModelValidations } from 'vault/app-types';
import { ModelValidations } from 'vault/app-types';
export default class PkiRoleModel extends Model {
get useOpenAPI(): boolean;