oxidecomputer / console

Oxide Web Console
https://console-preview.oxide.computer
Mozilla Public License 2.0
144 stars 11 forks source link

Validate both-or-neither on signing keypair on IdP create #1564

Open david-crespo opened 1 year ago

david-crespo commented 1 year ago

In the IdP create UI, we have two file fields for the signing keypair. In the API, these are optional as a pair. If (as concluded in https://github.com/oxidecomputer/omicron/issues/3155 after some confusion on my part) we do want to have first-class support for the no-keypair option, I think the UI should be more explicit about how you need either both or neither. Maybe something that collapses both together, or a radio, or something. Even if we don't do that, we should validate both-or-neither client-side with a helpful message.

david-crespo commented 3 weeks ago

Ok, this is pretty bad! If one is present and not the other, we don't get the expected API error you because we just leave the one that's present out of the request body.

https://github.com/oxidecomputer/console/blob/b01ca85dce52a73d759bff8ae6644b0a75b7b9b4/app/forms/idp/create.tsx#L77-L84

By tweaking the logic we can see that the mock API does validate the keypair object correctly if the client sends a partial one:

diff --git a/app/forms/idp/create.tsx b/app/forms/idp/create.tsx
index 1d97d53c..704de309 100644
--- a/app/forms/idp/create.tsx
+++ b/app/forms/idp/create.tsx
@@ -78,10 +78,14 @@ export function CreateIdpSideModalForm() {
       }) => {
         // if both signingKeypair files are present, base64 and add to post
         const keypair =
-          signingKeypair.publicCert && signingKeypair.privateKey
+          signingKeypair.publicCert || signingKeypair.privateKey
             ? {
-                publicCert: await readBlobAsBase64(signingKeypair.publicCert),
-                privateKey: await readBlobAsBase64(signingKeypair.privateKey),
+                publicCert: signingKeypair.publicCert
+                  ? await readBlobAsBase64(signingKeypair.publicCert)
+                  : undefined,
+                privateKey: signingKeypair.privateKey
+                  ? await readBlobAsBase64(signingKeypair.privateKey)
+                  : undefined,
               }
             : undefined

Image