mirror of
				https://github.com/optim-enterprises-bv/vault.git
				synced 2025-10-31 18:48:08 +00:00 
			
		
		
		
	Add UI support name constraints (#29263)
* add open api params * support pki name constraints * fix conditional * revert helptextwsubtext * fix typo * add name constraints to sign intermediate form * add changelog * update test
This commit is contained in:
		| @@ -419,7 +419,7 @@ Ranges must be specified in the notation of IP address and prefix length, like " | |||||||
| 		Type:        framework.TypeCommaStringSlice, | 		Type:        framework.TypeCommaStringSlice, | ||||||
| 		Description: `Email addresses for which this certificate is allowed to sign or issue child certificates (see https://tools.ietf.org/html/rfc5280#section-4.2.1.10).`, | 		Description: `Email addresses for which this certificate is allowed to sign or issue child certificates (see https://tools.ietf.org/html/rfc5280#section-4.2.1.10).`, | ||||||
| 		DisplayAttrs: &framework.DisplayAttributes{ | 		DisplayAttrs: &framework.DisplayAttributes{ | ||||||
| 			Name: "Permitted email adresses", | 			Name: "Permitted email addresses", | ||||||
| 		}, | 		}, | ||||||
| 	} | 	} | ||||||
| 	fields["excluded_email_addresses"] = &framework.FieldSchema{ | 	fields["excluded_email_addresses"] = &framework.FieldSchema{ | ||||||
|   | |||||||
							
								
								
									
										3
									
								
								changelog/29263.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								changelog/29263.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | |||||||
|  | ```release-note:improvement | ||||||
|  | ui: Add support for the name constraints extension to be fully specified when creating root and intermediate CA certificates. | ||||||
|  | ``` | ||||||
| @@ -21,7 +21,6 @@ const validations = { | |||||||
|   'notBeforeDuration', |   'notBeforeDuration', | ||||||
|   'enforceLeafNotAfterBehavior', |   'enforceLeafNotAfterBehavior', | ||||||
|   'format', |   'format', | ||||||
|   'permittedDnsDomains', |  | ||||||
|   'maxPathLength', |   'maxPathLength', | ||||||
| ]) | ]) | ||||||
| export default class PkiSignIntermediateModel extends PkiCertificateBaseModel { | export default class PkiSignIntermediateModel extends PkiCertificateBaseModel { | ||||||
| @@ -58,19 +57,55 @@ export default class PkiSignIntermediateModel extends PkiCertificateBaseModel { | |||||||
|   }) |   }) | ||||||
|   enforceLeafNotAfterBehavior; |   enforceLeafNotAfterBehavior; | ||||||
|  |  | ||||||
|   @attr({ |  | ||||||
|     label: 'Permitted DNS domains', |  | ||||||
|     subText: |  | ||||||
|       'DNS domains for which certificates are allowed to be issued or signed by this CA certificate. Enter each value as a new input.', |  | ||||||
|   }) |  | ||||||
|   permittedDnsDomains; |  | ||||||
|  |  | ||||||
|   @attr({ |   @attr({ | ||||||
|     subText: 'Specifies the maximum path length to encode in the generated certificate. -1 means no limit', |     subText: 'Specifies the maximum path length to encode in the generated certificate. -1 means no limit', | ||||||
|     defaultValue: '-1', |     defaultValue: '-1', | ||||||
|   }) |   }) | ||||||
|   maxPathLength; |   maxPathLength; | ||||||
|  |  | ||||||
|  |   /* Name constraint overrides */ | ||||||
|  |   @attr({ | ||||||
|  |     subText: 'DNS domains for which certificates are allowed to be issued or signed by this CA certificate.', | ||||||
|  |   }) | ||||||
|  |   permittedDnsDomains; | ||||||
|  |  | ||||||
|  |   @attr({ | ||||||
|  |     subText: 'Domains for which this certificate is not allowed to sign or issue child certificates.', | ||||||
|  |   }) | ||||||
|  |   excludedDnsDomains; | ||||||
|  |  | ||||||
|  |   @attr({ | ||||||
|  |     subText: 'Email addresses for which this certificate is not allowed to sign or issue child certificates.', | ||||||
|  |   }) | ||||||
|  |   excludedEmailAddresses; | ||||||
|  |  | ||||||
|  |   @attr({ | ||||||
|  |     subText: | ||||||
|  |       'IP ranges for which this certificate is not allowed to sign or issue child certificates. Ranges must be specified in the notation of IP address and prefix length, such as "192.0.2.0/24" or "2001:db8::/32", as defined in RFC 4632 and RFC 4291.', | ||||||
|  |   }) | ||||||
|  |   excludedIpRanges; | ||||||
|  |  | ||||||
|  |   @attr({ | ||||||
|  |     subText: 'URI domains for which this certificate is not allowed to sign or issue child certificates.', | ||||||
|  |   }) | ||||||
|  |   excludedUriDomains; | ||||||
|  |  | ||||||
|  |   @attr({ | ||||||
|  |     subText: 'Email addresses for which this certificate is allowed to sign or issue child certificates.', | ||||||
|  |   }) | ||||||
|  |   permittedEmailAddresses; | ||||||
|  |  | ||||||
|  |   @attr({ | ||||||
|  |     subText: | ||||||
|  |       'IP ranges for which this certificate is allowed to sign or issue child certificates. Ranges must be specified in the notation of IP address and prefix length, such as "192.0.2.0/24" or "2001:db8::/32", as defined in RFC 4632 and RFC 4291.', | ||||||
|  |   }) | ||||||
|  |   permittedIpRanges; | ||||||
|  |  | ||||||
|  |   @attr({ | ||||||
|  |     subText: 'URI domains for which this certificate is allowed to sign or issue child certificates.', | ||||||
|  |   }) | ||||||
|  |   permittedUriDomains; | ||||||
|  |  | ||||||
|   /* Signing Options overrides */ |   /* Signing Options overrides */ | ||||||
|   @attr({ |   @attr({ | ||||||
|     label: 'Use PSS', |     label: 'Use PSS', | ||||||
|   | |||||||
| @@ -43,7 +43,6 @@ import { removeFromArray } from 'vault/helpers/remove-from-array'; | |||||||
|  * @param {Model} model - Ember Data model that `attr` is defined on |  * @param {Model} model - Ember Data model that `attr` is defined on | ||||||
|  * @param {boolean} [disabled=false] - whether the field is disabled |  * @param {boolean} [disabled=false] - whether the field is disabled | ||||||
|  * @param {boolean} [showHelpText=true] - whether to show the tooltip with help text from OpenAPI |  * @param {boolean} [showHelpText=true] - whether to show the tooltip with help text from OpenAPI | ||||||
|  * @param {string} [subText] - text to be displayed below the label |  | ||||||
|  * @param {string} [mode] - used when editType is 'kv' |  * @param {string} [mode] - used when editType is 'kv' | ||||||
|  * @param {object} [modelValidations] - Object of errors.  If attr.name is in object and has error message display in AlertInline. |  * @param {object} [modelValidations] - Object of errors.  If attr.name is in object and has error message display in AlertInline. | ||||||
|  * @param {function} [onChange] - called whenever a value on the model changes via the component |  * @param {function} [onChange] - called whenever a value on the model changes via the component | ||||||
| @@ -96,12 +95,11 @@ export default class FormFieldComponent extends Component { | |||||||
|   get disabled() { |   get disabled() { | ||||||
|     return this.args.disabled || false; |     return this.args.disabled || false; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   get showHelpText() { |   get showHelpText() { | ||||||
|     return this.args.showHelpText === false ? false : true; |     return this.args.showHelpText === false ? false : true; | ||||||
|   } |   } | ||||||
|   get subText() { |  | ||||||
|     return this.args.subText || ''; |  | ||||||
|   } |  | ||||||
|   // used in the label element next to the form element |   // used in the label element next to the form element | ||||||
|   get labelString() { |   get labelString() { | ||||||
|     const label = this.args.attr.options?.label || ''; |     const label = this.args.attr.options?.label || ''; | ||||||
|   | |||||||
| @@ -43,6 +43,13 @@ | |||||||
|             etc.) to be protected by a single certificate. |             etc.) to be protected by a single certificate. | ||||||
|           {{else if (eq group "Additional subject fields")}} |           {{else if (eq group "Additional subject fields")}} | ||||||
|             These fields provide more information about the client to which the certificate belongs. |             These fields provide more information about the client to which the certificate belongs. | ||||||
|  |           {{else if (eq group "Name constraints")}} | ||||||
|  |             These fields create the name constraints extension when generating CA certificates. Specifying any combination of | ||||||
|  |             these parameters will trigger the creation of the name constraints extension as per | ||||||
|  |             <Hds::Link::Inline | ||||||
|  |               @isHrefExternal={{true}} | ||||||
|  |               @href="https://datatracker.ietf.org/doc/html/rfc5280#section-4.2.1.10" | ||||||
|  |             >RFC 5280 section 4.2.1.10</Hds::Link::Inline>. | ||||||
|           {{/if}} |           {{/if}} | ||||||
|         </p> |         </p> | ||||||
|         {{#each fields as |fieldName|}} |         {{#each fields as |fieldName|}} | ||||||
|   | |||||||
| @@ -49,6 +49,16 @@ export default class PkiSignIntermediateFormComponent extends Component<Args> { | |||||||
|  |  | ||||||
|   get groups() { |   get groups() { | ||||||
|     return { |     return { | ||||||
|  |       'Name constraints': [ | ||||||
|  |         'permittedDnsDomains', | ||||||
|  |         'permittedEmailAddresses', | ||||||
|  |         'permittedIpRanges', | ||||||
|  |         'permittedUriDomains', | ||||||
|  |         'excludedDnsDomains', | ||||||
|  |         'excludedEmailAddresses', | ||||||
|  |         'excludedIpRanges', | ||||||
|  |         'excludedUriDomains', | ||||||
|  |       ], | ||||||
|       'Signing options': ['usePss', 'skid', 'signatureBits'], |       'Signing options': ['usePss', 'skid', 'signatureBits'], | ||||||
|       'Subject Alternative Name (SAN) Options': ['altNames', 'ipSans', 'uriSans', 'otherSans'], |       'Subject Alternative Name (SAN) Options': ['altNames', 'ipSans', 'uriSans', 'otherSans'], | ||||||
|       'Additional subject fields': [ |       'Additional subject fields': [ | ||||||
|   | |||||||
| @@ -14,9 +14,7 @@ import { setupMirage } from 'ember-cli-mirage/test-support'; | |||||||
| const selectors = { | const selectors = { | ||||||
|   form: '[data-test-sign-intermediate-form]', |   form: '[data-test-sign-intermediate-form]', | ||||||
|   csrInput: '[data-test-input="csr"]', |   csrInput: '[data-test-input="csr"]', | ||||||
|   toggleSigningOptions: '[data-test-toggle-group="Signing options"]', |   toggleGroup: (group) => `[data-test-toggle-group="${group}"]`, | ||||||
|   toggleSANOptions: '[data-test-toggle-group="Subject Alternative Name (SAN) Options"]', |  | ||||||
|   toggleAdditionalFields: '[data-test-toggle-group="Additional subject fields"]', |  | ||||||
|   fieldByName: (name) => `[data-test-field="${name}"]`, |   fieldByName: (name) => `[data-test-field="${name}"]`, | ||||||
|   saveButton: '[data-test-pki-sign-intermediate-save]', |   saveButton: '[data-test-pki-sign-intermediate-save]', | ||||||
|   cancelButton: '[data-test-pki-sign-intermediate-cancel]', |   cancelButton: '[data-test-pki-sign-intermediate-cancel]', | ||||||
| @@ -40,19 +38,24 @@ module('Integration | Component | pki-sign-intermediate-form', function (hooks) | |||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   test('renders correctly on load', async function (assert) { |   test('renders correctly on load', async function (assert) { | ||||||
|     assert.expect(9); |     assert.expect(10); | ||||||
|     await render(hbs`<PkiSignIntermediateForm @onCancel={{this.onCancel}} @model={{this.model}} />`, { |     await render(hbs`<PkiSignIntermediateForm @onCancel={{this.onCancel}} @model={{this.model}} />`, { | ||||||
|       owner: this.engine, |       owner: this.engine, | ||||||
|     }); |     }); | ||||||
|  |  | ||||||
|     assert.dom(selectors.form).exists('Form is rendered'); |     assert.dom(selectors.form).exists('Form is rendered'); | ||||||
|     assert.dom(selectors.resultsContainer).doesNotExist('Results display not rendered'); |     assert.dom(selectors.resultsContainer).doesNotExist('Results display not rendered'); | ||||||
|     assert.dom('[data-test-field]').exists({ count: 10 }, '10 default fields shown'); |     assert.dom('[data-test-field]').exists({ count: 9 }, '9 default fields shown'); | ||||||
|     assert.dom(selectors.toggleSigningOptions).exists(); |     [ | ||||||
|     assert.dom(selectors.toggleSANOptions).exists(); |       'Name constraints', | ||||||
|     assert.dom(selectors.toggleAdditionalFields).exists(); |       'Signing options', | ||||||
|  |       'Subject Alternative Name (SAN) Options', | ||||||
|  |       'Additional subject fields', | ||||||
|  |     ].forEach((group) => { | ||||||
|  |       assert.dom(selectors.toggleGroup(group)).exists(`${group} renders`); | ||||||
|  |     }); | ||||||
|  |  | ||||||
|     await click(selectors.toggleSigningOptions); |     await click(selectors.toggleGroup('Signing options')); | ||||||
|     ['usePss', 'skid', 'signatureBits'].forEach((name) => { |     ['usePss', 'skid', 'signatureBits'].forEach((name) => { | ||||||
|       assert.dom(selectors.fieldByName(name)).exists(); |       assert.dom(selectors.fieldByName(name)).exists(); | ||||||
|     }); |     }); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 claire bontempo
					claire bontempo