From d99f7005bc48724d1da804a47a4099e7eedce252 Mon Sep 17 00:00:00 2001 From: Hank Donnay Date: Thu, 5 Jan 2023 15:27:17 -0600 Subject: [PATCH] webhook: add explicit signer argument Signed-off-by: Hank Donnay --- notifier/webhook/debug_server.go | 5 +++-- notifier/webhook/deliverer.go | 36 +++++++++++++++++------------- notifier/webhook/deliverer_test.go | 2 +- 3 files changed, 24 insertions(+), 19 deletions(-) diff --git a/notifier/webhook/debug_server.go b/notifier/webhook/debug_server.go index 097d2fc17c..6ef94bf7e2 100644 --- a/notifier/webhook/debug_server.go +++ b/notifier/webhook/debug_server.go @@ -1,3 +1,4 @@ +//go:build tools // +build tools package main @@ -131,7 +132,7 @@ func (h *Recv) ServeHTTP(w http.ResponseWriter, r *http.Request) { var resp response for next := new(uuid.UUID); next != nil; next = resp.Page.Next { - req, err := http.NewRequestWithContext(r.Context(), http.MethodGet, payload.Callback.String(), nil) + req, err := httputil.NewRequestWithContext(r.Context(), http.MethodGet, payload.Callback.String(), nil) if err != nil { http.Error(w, fmt.Sprintf("unable to create request: %v", err), http.StatusInternalServerError) log.Println("E", "unable to create request:", err.Error()) @@ -188,7 +189,7 @@ func (h *Recv) ServeHTTP(w http.ResponseWriter, r *http.Request) { log.Println(":", whid, n.ID, n.Manifest, n.Reason, n.Vulnerability.Name) } } - req, err := http.NewRequestWithContext(r.Context(), http.MethodDelete, payload.Callback.String(), nil) + req, err := httputil.NewRequestWithContext(r.Context(), http.MethodDelete, payload.Callback.String(), nil) if err != nil { log.Fatal(err) } diff --git a/notifier/webhook/deliverer.go b/notifier/webhook/deliverer.go index ff9ca6c601..ff756b9db4 100644 --- a/notifier/webhook/deliverer.go +++ b/notifier/webhook/deliverer.go @@ -13,6 +13,7 @@ import ( clairerror "github.com/quay/clair/v4/clair-error" "github.com/quay/clair/v4/internal/codec" + "github.com/quay/clair/v4/internal/httputil" "github.com/quay/clair/v4/notifier" ) @@ -24,12 +25,16 @@ type Deliverer struct { c *http.Client callback *url.URL target *url.URL + signer Signer headers http.Header - signed bool +} + +type Signer interface { + Sign(context.Context, *http.Request) error } // New returns a new webhook Deliverer -func New(conf *config.Webhook, client *http.Client) (*Deliverer, error) { +func New(conf *config.Webhook, client *http.Client, signer Signer) (*Deliverer, error) { switch { case conf == nil: return nil, errors.New("config not provided") @@ -52,7 +57,7 @@ func New(conf *config.Webhook, client *http.Client) (*Deliverer, error) { d.headers = make(map[string][]string) } d.headers.Set("content-type", "application/json") - d.signed = conf.Signed + d.signer = signer d.c = client return &d, nil @@ -81,20 +86,19 @@ func (d *Deliverer) Deliver(ctx context.Context, nID uuid.UUID) error { Callback: *callback, } - req := &http.Request{ - URL: d.target, - Header: d.headers.Clone(), - Body: codec.JSONReader(&wh), - Method: http.MethodPost, + req, err := httputil.NewRequestWithContext(ctx, http.MethodPost, d.target.String(), codec.JSONReader(&wh)) + if err != nil { + return err } - - // sign a jwt using key manager's private key - if d.signed { - signedOnce.Do(func() { - zlog.Warn(ctx).Msg(`"signed" configuration key no longer does anything`) - zlog.Warn(ctx).Msg(`specifying "signed" will be an error in the future`) - // Make good on this threat in... 4.4? - }) + for k, vs := range d.headers { + for _, v := range vs { + req.Header.Add(k, v) + } + } + if d.signer != nil { + if err := d.signer.Sign(ctx, req); err != nil { + return err + } } zlog.Info(ctx). diff --git a/notifier/webhook/deliverer_test.go b/notifier/webhook/deliverer_test.go index f5d437ccb8..8aa67c7f4f 100644 --- a/notifier/webhook/deliverer_test.go +++ b/notifier/webhook/deliverer_test.go @@ -54,7 +54,7 @@ func TestDeliverer(t *testing.T) { Target: server.URL, } - d, err := New(&conf, server.Client()) + d, err := New(&conf, server.Client(), nil) if err != nil { t.Fatalf("failed to create new webhook deliverer: %v", err) }