From f500157cb271af570a653f45ac781d8fc2806944 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 18 Aug 2021 11:31:38 +0200 Subject: [PATCH] webhooks: refactor exec code into separate func --- webhooks/context.go | 47 +++++++++++++++++++++++++++++++++++++++++++++ webhooks/queue.go | 39 ++----------------------------------- 2 files changed, 49 insertions(+), 37 deletions(-) diff --git a/webhooks/context.go b/webhooks/context.go index e4ea66ce7f5aa17f37fa3d2478f6245dc3686bc0..638eaad763369e50bb0a3fe118f2fa5d756981cf 100644 --- a/webhooks/context.go +++ b/webhooks/context.go @@ -2,8 +2,12 @@ package webhooks import ( "context" + "encoding/hex" + "encoding/json" "errors" + "github.com/99designs/gqlgen/graphql" + "github.com/99designs/gqlgen/graphql/executor" "github.com/google/uuid" "git.sr.ht/~sircmpwn/core-go/auth" @@ -37,3 +41,46 @@ func Payload(ctx context.Context) (interface{}, error) { } return payload, nil } + +// Executes the GraphQL query prepared stored in the WebhookContext. Handles +// the configuration of a secondary authentication and GraphQL context. +func (webhook *WebhookContext) Exec(ctx context.Context, + schema graphql.ExecutableSchema) ([]byte, error) { + sub := webhook.Subscription + tslice, err := hex.DecodeString(sub.TokenHash) + if err != nil { + panic(err) + } + + var tokenHash [64]byte + copy(tokenHash[:], tslice) + ctx, err = auth.WebhookAuth(ctx, webhook.User, + tokenHash, sub.Grants, sub.ClientID, sub.Expires) + if err != nil { + // TODO: This codepath can occur when the token has expired, and we may + // want to communicate this to the user. + return nil, err + } + + exec := executor.New(schema) + params := graphql.RawParams{ + Query: sub.Query, + ReadTime: graphql.TraceTiming{ + Start: graphql.Now(), + End: graphql.Now(), + }, + } + ctx = graphql.StartOperationTrace(ctx) + rc, errors := exec.CreateOperationContext(ctx, ¶ms) + if errors != nil { + panic(errors) + } + ctx = graphql.WithOperationContext(ctx, rc) + var resp graphql.ResponseHandler + resp, ctx = exec.DispatchOperation(ctx, rc) + payload, err := json.Marshal(resp(ctx)) + if err != nil { + panic(err) + } + return payload, nil +} diff --git a/webhooks/queue.go b/webhooks/queue.go index b3652b8ceded141945fd585d14e498573da01923..6e6e86bc05db6333dea41e3b08b803d0fe38e304 100644 --- a/webhooks/queue.go +++ b/webhooks/queue.go @@ -4,8 +4,6 @@ import ( "bytes" "context" "database/sql" - "encoding/hex" - "encoding/json" "fmt" "io" "io/ioutil" @@ -16,7 +14,6 @@ import ( "git.sr.ht/~sircmpwn/dowork" "github.com/99designs/gqlgen/graphql" - "github.com/99designs/gqlgen/graphql/executor" "github.com/google/uuid" sq "github.com/Masterminds/squirrel" @@ -162,49 +159,17 @@ func (queue *WebhookQueue) queueStage2(ctx context.Context, headers.Set("X-Webhook-Event", webhook.Event) headers.Set("X-Webhook-Delivery", webhook.PayloadUUID.String()) - sub := webhook.Subscription - tslice, err := hex.DecodeString(sub.TokenHash) + payload, err := webhook.Exec(ctx, queue.Schema) if err != nil { - panic(err) - } - - var tokenHash [64]byte - copy(tokenHash[:], tslice) - ctx, err = auth.WebhookAuth(ctx, webhook.User, - tokenHash, sub.Grants, sub.ClientID, sub.Expires) - if err != nil { - // TODO: This codepath can occur when the token has expired, and we may - // want to communicate this to the user. return nil, err } - exec := executor.New(queue.Schema) - params := graphql.RawParams{ - Query: sub.Query, - ReadTime: graphql.TraceTiming{ - Start: graphql.Now(), - End: graphql.Now(), - }, - } - ctx = graphql.StartOperationTrace(ctx) - rc, errors := exec.CreateOperationContext(ctx, ¶ms) - if errors != nil { - panic(errors) - } - ctx = graphql.WithOperationContext(ctx, rc) - var resp graphql.ResponseHandler - resp, ctx = exec.DispatchOperation(ctx, rc) - payload, err := json.Marshal(resp(ctx)) - if err != nil { - panic(err) - } - var deliveryID int err = sq. Insert("gql_"+webhook.Name+"_wh_delivery"). Columns("uuid", "date", "event", "subscription_id", "request_body"). Values(webhook.PayloadUUID, sq.Expr("NOW() at time zone 'utc'"), - webhook.Event, sub.ID, string(payload)). + webhook.Event, webhook.Subscription.ID, string(payload)). Suffix(`RETURNING (id)`). PlaceholderFormat(sq.Dollar). RunWith(tx).