package handlers import ( "sneak.berlin/go/webhooker/internal/database" "sneak.berlin/go/webhooker/internal/signature" ) // signatureUnavailable is what an entrypoint's scheme renders as when // the stored value is not one this build supports. The stored string // is never echoed as a fallback: it is operator-supplied and the row // is already in a state the receiver refuses, so the UI says so // rather than inventing a description for it. const signatureUnavailable = "(unavailable)" // signatureNotVerified is the label for an entrypoint that performs // no inbound verification. const signatureNotVerified = "not verified" // signatureMisconfigured is the label for a row holding one half of // the scheme/secret pair. The receiver answers every request to such // an entrypoint 500, so calling it "not verified" would describe a // receiver that is refusing everything as one that is accepting // everything. The form cannot create the state; a hand-edited // database or a downgrade past a scheme can. const signatureMisconfigured = "misconfigured" // EntrypointView is the display-safe projection of an entrypoint for // the UI. It deliberately has no secret field, so no template — // present or future — can render the shared secret, in the same way // delivery.TargetView keeps a target's stored credential away from // one. type EntrypointView struct { ID string Path string Description string Active bool // Configured reports whether inbound requests to this entrypoint // are verified. Configured bool // Scheme is the stored scheme, carried so the form can preselect // it. It names an algorithm, not a secret. Scheme database.SignatureScheme // SchemeLabel and SchemeHeader describe the configured scheme for // display: the sender's name, and the header its signature // arrives in. SchemeLabel string SchemeHeader string } // NewEntrypointViews projects entrypoints for rendering, dropping the // shared secret on the way. func NewEntrypointViews( entrypoints []database.Entrypoint, ) []EntrypointView { views := make([]EntrypointView, 0, len(entrypoints)) for i := range entrypoints { e := &entrypoints[i] view := EntrypointView{ ID: e.ID, Path: e.Path, Description: e.Description, Active: e.Active, Configured: e.SignatureConfigured(), Scheme: e.SignatureScheme, SchemeLabel: signatureNotVerified, SchemeHeader: "", } switch { case view.Configured: view.SchemeLabel = signatureUnavailable info, ok := signature.Info(e.SignatureScheme) if ok { view.SchemeLabel = info.Label view.SchemeHeader = info.Header } case e.SignatureHalfConfigured(): view.SchemeLabel = signatureMisconfigured } views = append(views, view) } return views }