mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-10-30 02:02:43 +00:00 
			
		
		
		
	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:
		
							
								
								
									
										3
									
								
								changelog/20907.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								changelog/20907.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | ```release-note:bug | ||||||
|  | ui: fixes key_bits and signature_bits reverting to default values when editing a pki role | ||||||
|  | ``` | ||||||
| @@ -184,7 +184,7 @@ export default class PkiRoleModel extends Model { | |||||||
|   }) |   }) | ||||||
|   keyBits; // no possibleValues because options are dependent on selected key type |   keyBits; // no possibleValues because options are dependent on selected key type | ||||||
|  |  | ||||||
|   @attr('number', { |   @attr('string', { | ||||||
|     label: 'Signature bits', |     label: 'Signature bits', | ||||||
|     subText: `Only applicable for key_type 'RSA'. Ignore for other key types.`, |     subText: `Only applicable for key_type 'RSA'. Ignore for other key types.`, | ||||||
|     defaultValue: '0', |     defaultValue: '0', | ||||||
|   | |||||||
| @@ -46,7 +46,7 @@ | |||||||
|               </option> |               </option> | ||||||
|             {{/if}} |             {{/if}} | ||||||
|             {{#each (path-or-array @attr.options.possibleValues @model) as |val|}} |             {{#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}} |                 {{or val.displayName val}} | ||||||
|               </option> |               </option> | ||||||
|             {{/each}} |             {{/each}} | ||||||
|   | |||||||
							
								
								
									
										22
									
								
								ui/lib/core/addon/helpers/loose-equal.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								ui/lib/core/addon/helpers/loose-equal.js
									
									
									
									
									
										Normal 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); | ||||||
							
								
								
									
										6
									
								
								ui/lib/core/app/helpers/loose-equal.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								ui/lib/core/app/helpers/loose-equal.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | |||||||
|  | /** | ||||||
|  |  * Copyright (c) HashiCorp, Inc. | ||||||
|  |  * SPDX-License-Identifier: MPL-2.0 | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | export { default } from 'core/helpers/loose-equal'; | ||||||
| @@ -24,7 +24,7 @@ | |||||||
|                   </option> |                   </option> | ||||||
|                 {{/if}} |                 {{/if}} | ||||||
|                 {{#each this.keyBitOptions as |val|}} |                 {{#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}} |                     {{val}} | ||||||
|                   </option> |                   </option> | ||||||
|                 {{/each}} |                 {{/each}} | ||||||
|   | |||||||
| @@ -48,7 +48,6 @@ const KEY_BITS_OPTIONS: BitOptions = { | |||||||
| export default class PkiKeyParameters extends Component<Args> { | export default class PkiKeyParameters extends Component<Args> { | ||||||
|   get keyBitOptions() { |   get keyBitOptions() { | ||||||
|     if (!this.args.model.keyType) return []; |     if (!this.args.model.keyType) return []; | ||||||
|  |  | ||||||
|     return KEY_BITS_OPTIONS[this.args.model.keyType]; |     return KEY_BITS_OPTIONS[this.args.model.keyType]; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -145,4 +145,70 @@ module('Integration | Component | pki-role-form', function (hooks) { | |||||||
|     await click(SELECTORS.roleCreateButton); |     await click(SELECTORS.roleCreateButton); | ||||||
|     assert.strictEqual(this.role.issuerRef, 'issuer-1', 'Issuer Ref correctly saved on create'); |     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'); | ||||||
|  |   }); | ||||||
| }); | }); | ||||||
|   | |||||||
							
								
								
									
										34
									
								
								ui/tests/integration/helpers/loose-equal-test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								ui/tests/integration/helpers/loose-equal-test.js
									
									
									
									
									
										Normal 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, ''])); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
							
								
								
									
										2
									
								
								ui/types/vault/models/pki/role.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								ui/types/vault/models/pki/role.d.ts
									
									
									
									
										vendored
									
									
								
							| @@ -1,5 +1,5 @@ | |||||||
| import Model from '@ember-data/model'; | import Model from '@ember-data/model'; | ||||||
| import { FModelValidations } from 'vault/app-types'; | import { ModelValidations } from 'vault/app-types'; | ||||||
|  |  | ||||||
| export default class PkiRoleModel extends Model { | export default class PkiRoleModel extends Model { | ||||||
|   get useOpenAPI(): boolean; |   get useOpenAPI(): boolean; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 claire bontempo
					claire bontempo