From d83af997da303dc7454cd897e9441fc3e4f1b717 Mon Sep 17 00:00:00 2001 From: Simon Ser Date: Wed, 16 Aug 2023 12:29:22 +0000 Subject: [PATCH] auth: make DecodeGrants return an error We'll use this function to validate grants passed in via builds.sr.ht manifests. --- auth/bearer.go | 8 ++++---- auth/middleware.go | 14 +++++++++++--- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/auth/bearer.go b/auth/bearer.go index 6755d9d209428e4e9ed9d12ea9e4d832009ca5e8..15105847d59a39b720eb1b0b067bb55fdf54950c 100644 --- a/auth/bearer.go +++ b/auth/bearer.go @@ -93,14 +93,14 @@ type Grants struct { encoded string } -func DecodeGrants(ctx context.Context, grants string) Grants { +func DecodeGrants(ctx context.Context, grants string) (Grants, error) { if grants == "" { // All permissions return Grants{ all: true, grants: nil, encoded: "", - } + }, nil } accessMap := make(map[string]string) for _, grant := range strings.Split(grants, " ") { @@ -111,7 +111,7 @@ func DecodeGrants(ctx context.Context, grants string) Grants { ) parts := strings.Split(grant, "/") if len(parts) != 2 { - panic(fmt.Errorf("OAuth grant '%s' without service/scope format", grant)) + return Grants{}, fmt.Errorf("OAuth grant '%s' without service/scope format", grant) } service = parts[0] parts = strings.Split(parts[1], ":") @@ -129,7 +129,7 @@ func DecodeGrants(ctx context.Context, grants string) Grants { all: false, grants: accessMap, encoded: grants, - } + }, nil } func (g *Grants) Has(grant string, mode string) bool { diff --git a/auth/middleware.go b/auth/middleware.go index 2771923843b0f35681b0e62bd4683f18abb95c80..033c4898d0f8444b099cdde02d3108dac8a6bcae 100644 --- a/auth/middleware.go +++ b/auth/middleware.go @@ -558,7 +558,10 @@ func OAuth2(token string, hash [64]byte, w http.ResponseWriter, auth.AuthMethod = AUTH_OAUTH2 auth.BearerToken = bt auth.TokenHash = hash - auth.Grants = DecodeGrants(r.Context(), bt.Grants) + auth.Grants, err = DecodeGrants(r.Context(), bt.Grants) + if err != nil { + panic(err) // unreachable + } ctx := context.WithValue(r.Context(), userCtxKey, &auth) r = r.WithContext(ctx) @@ -661,16 +664,21 @@ func LegacyOAuth(bearer string, hash [64]byte, w http.ResponseWriter, // should be the authentication context from the request which caused the // webhook to be fired. func WebhookAuth(ctx context.Context, auth *AuthContext, - tokenHash [64]byte, grants string, clientID *string, + tokenHash [64]byte, rawGrants string, clientID *string, expires time.Time) (context.Context, error) { if time.Now().UTC().After(expires) { return nil, fmt.Errorf("The authentication token used to create this webhook has expired") } + grants, err := DecodeGrants(ctx, rawGrants) + if err != nil { + return nil, err + } + whAuth := *auth whAuth.AuthMethod = AUTH_WEBHOOK whAuth.TokenHash = tokenHash - whAuth.Grants = DecodeGrants(ctx, grants) + whAuth.Grants = grants whAuth.Grants.ReadOnly = true whAuth.BearerToken = &BearerToken{} if clientID != nil {