~bigbes/core-go

f500157cb271af570a653f45ac781d8fc2806944 — Drew DeVault 5 years ago 67ddd42
webhooks: refactor exec code into separate func
2 files changed, 49 insertions(+), 37 deletions(-)

M webhooks/context.go
M webhooks/queue.go
M webhooks/context.go => webhooks/context.go +47 -0
@@ 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, &params)
	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
}

M webhooks/queue.go => webhooks/queue.go +2 -37
@@ 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, &params)
	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).