~sircmpwn/meta.sr.ht

7ace4c6d3b9c052e1030adc562f012f1a15192e5 — Drew DeVault 8 months ago 7613e05
API: Refactor webhook auth for internal use

See the related commit message in core-go for details.
M api/go.mod => api/go.mod +1 -1
@@ 3,7 3,7 @@ module git.sr.ht/~sircmpwn/meta.sr.ht/api
go 1.14

require (
	git.sr.ht/~sircmpwn/core-go v0.0.0-20210824124722-590c9c42037a // indirect
	git.sr.ht/~sircmpwn/core-go v0.0.0-20210824141646-99671f85b661 // indirect
	git.sr.ht/~sircmpwn/dowork v0.0.0-20210820133136-d3970e97def3 // indirect
	git.sr.ht/~sircmpwn/go-bare v0.0.0-20210227202403-5dae5c48f917 // indirect
	github.com/99designs/gqlgen v0.13.0

M api/go.sum => api/go.sum +2 -0
@@ 46,6 46,8 @@ git.sr.ht/~sircmpwn/core-go v0.0.0-20210824082404-4f926ddc9051 h1:5FA0kXpvxZSbqi
git.sr.ht/~sircmpwn/core-go v0.0.0-20210824082404-4f926ddc9051/go.mod h1:dOzMmMQFPH0ztBhLFNo/hFLHqck1tbhgL3aNi1XnOsI=
git.sr.ht/~sircmpwn/core-go v0.0.0-20210824124722-590c9c42037a h1:dhmRBQR1EE+SqoZFYnFbeWw4Otka5zWVYqbZ9SSfEEY=
git.sr.ht/~sircmpwn/core-go v0.0.0-20210824124722-590c9c42037a/go.mod h1:dOzMmMQFPH0ztBhLFNo/hFLHqck1tbhgL3aNi1XnOsI=
git.sr.ht/~sircmpwn/core-go v0.0.0-20210824141646-99671f85b661 h1:PpCR0gF2Tghq9zIGGQIQTvXTBRhxfcvKGmGgWHA5+gM=
git.sr.ht/~sircmpwn/core-go v0.0.0-20210824141646-99671f85b661/go.mod h1:dOzMmMQFPH0ztBhLFNo/hFLHqck1tbhgL3aNi1XnOsI=
git.sr.ht/~sircmpwn/dowork v0.0.0-20201013160733-35ca012e4dc8/go.mod h1:8neHEO3503w/rNtttnR0JFpQgM/GFhaafVwvkPsFIDw=
git.sr.ht/~sircmpwn/dowork v0.0.0-20201121170652-c2a771442daf h1:wRE9o+wlpTSuq/ucFJsfbglAobfGPIgFdaTtZXrk8P0=
git.sr.ht/~sircmpwn/dowork v0.0.0-20201121170652-c2a771442daf/go.mod h1:8neHEO3503w/rNtttnR0JFpQgM/GFhaafVwvkPsFIDw=

M api/graph/model/webhooks.go => api/graph/model/webhooks.go +13 -9
@@ 122,11 122,13 @@ type ProfileWebhookSubscription struct {
	Query  string         `json:"query"`
	URL    string         `json:"url"`

	ClientID  *string
	TokenHash string
	UserID    int
	Expires   time.Time
	Grants    string
	UserID     int
	AuthMethod string
	ClientID   *string
	TokenHash  *string
	Expires    *time.Time
	Grants     *string
	NodeID     *string

	alias  string
	fields *database.ModelFields


@@ 169,13 171,15 @@ func (sub *ProfileWebhookSubscription) Fields() *database.ModelFields {
			{ "url", "url", &sub.URL },

			// Always fetch:
			{ "client_id", "", &sub.ClientID },
			{ "expires", "", &sub.Expires },
			{ "grants", "", &sub.Grants },
			{ "id", "", &sub.ID },
			{ "query", "", &sub.Query },
			{ "token_hash", "", &sub.TokenHash },
			{ "user_id", "", &sub.UserID },
			{ "auth_method", "", &sub.AuthMethod },
			{ "token_hash", "", &sub.TokenHash },
			{ "client_id", "", &sub.ClientID },
			{ "grants", "", &sub.Grants },
			{ "expires", "", &sub.Expires },
			{ "node_id", "", &sub.NodeID },
		},
	}
	return sub.fields

M api/graph/schema.resolvers.go => api/graph/schema.resolvers.go +15 -9
@@ 530,14 530,18 @@ func (r *mutationResolver) CreateWebhook(ctx context.Context, config model.Profi
		row := tx.QueryRowContext(ctx, `
			INSERT INTO gql_profile_wh_sub (
				created, events, url, query,
				auth_method,
				token_hash, grants, client_id, expires,
				node_id,
				user_id
			) VALUES (
				NOW() at time zone 'utc',
				$1, $2, $3, $4, $5, $6, $7, $8
				$1, $2, $3, $4, $5, $6, $7, $8, $9, $10
			) RETURNING id, url, query, events, user_id;`,
			pq.Array(events), config.URL, config.Query,
			ac.TokenHash, ac.Grants, ac.ClientID, ac.Expires,
			ac.AuthMethod,
			ac.TokenHash, ac.Grants, ac.ClientID, ac.Expires, // OAUTH2
			ac.NodeID,                                        // INTERNAL
			auth.UserID)

		if err := row.Scan(&sub.ID, &sub.URL,


@@ 1000,13 1004,15 @@ func (r *profileWebhookSubscriptionResolver) Sample(ctx context.Context, obj *mo
		Name:        "profile",
		Event:       event.String(),
		Subscription: &corewebhooks.WebhookSubscription{
			ID:        obj.ID,
			URL:       obj.URL,
			Query:     obj.Query,
			TokenHash: obj.TokenHash,
			Grants:    obj.Grants,
			ClientID:  obj.ClientID,
			Expires:   obj.Expires,
			ID:         obj.ID,
			URL:        obj.URL,
			Query:      obj.Query,
			AuthMethod: obj.AuthMethod,
			TokenHash:  obj.TokenHash,
			Grants:     obj.Grants,
			ClientID:   obj.ClientID,
			Expires:    obj.Expires,
			NodeID:     obj.NodeID,
		},
	}


M metasrht/alembic/versions/3261793eae54_add_graphql_webhook_tables.py => metasrht/alembic/versions/3261793eae54_add_graphql_webhook_tables.py +15 -4
@@ 24,17 24,27 @@ def upgrade():
        'SSH_KEY_REMOVED'
    );

    CREATE TYPE auth_method AS ENUM (
        'OAUTH_LEGACY',
        'OAUTH2',
        'COOKIE',
        'INTERNAL',
        'WEBHOOK'
    );

    CREATE TABLE gql_profile_wh_sub (
        id serial PRIMARY KEY,
        created timestamp NOT NULL,
        events webhook_event[] NOT NULL CHECK (array_length(events, 1) > 0),
        events webhook_event[] NOT NULL check (array_length(events, 1) > 0),
        url varchar NOT NULL,
        query varchar NOT NULL,

        token_hash varchar(128) NOT NULL,
        grants varchar NOT NULL,
        auth_method auth_method NOT NULL check (auth_method in ('OAUTH2', 'INTERNAL')),
        token_hash varchar(128) check ((auth_method = 'OAUTH2') = (token_hash IS NOT NULL)),
        grants varchar,
        client_id uuid,
        expires timestamp,
        expires timestamp check ((auth_method = 'OAUTH2') = (expires IS NOT NULL)),
        node_id varchar check ((auth_method = 'INTERNAL') = (node_id IS NOT NULL)),

        user_id integer NOT NULL references "user"(id)
    );


@@ 60,5 70,6 @@ def downgrade():
    DROP TABLE gql_profile_wh_delivery;
    DROP INDEX gql_profile_wh_sub_token_hash_idx;
    DROP TABLE gql_profile_wh_sub;
    DROP TYPE auth_method;
    DROP TYPE webhook_event;
    """)