From 44cf5e793e9c6be66d332dbc4e9301a155badef5 Mon Sep 17 00:00:00 2001 From: Drew DeVault Date: Wed, 27 Aug 2025 13:50:01 +0200 Subject: [PATCH] auth: remove legacy OAuth support --- auth/middleware.go | 103 --------------------------------------------- webhooks/config.go | 2 - 2 files changed, 105 deletions(-) diff --git a/auth/middleware.go b/auth/middleware.go index 23ed0de4b45e5e0efb716f91f29f683093127e2a..771756d91367478a3fd0c1824a5229759e403c30 100644 --- a/auth/middleware.go +++ b/auth/middleware.go @@ -33,7 +33,6 @@ type contextKey struct { } var ( - oauthBearerRegex = regexp.MustCompile(`^[0-9a-f]{32}$`) oauth2BearerRegex = regexp.MustCompile(`^[0-9a-zA-Z_+/]{33,}$`) ) @@ -45,7 +44,6 @@ const ( ) const ( - AUTH_OAUTH_LEGACY = "OAUTH_LEGACY" AUTH_OAUTH2 = "OAUTH2" AUTH_COOKIE = "COOKIE" AUTH_INTERNAL = "INTERNAL" @@ -87,13 +85,6 @@ func (authctx *AuthContext) Access(scope, kind string) error { switch authctx.AuthMethod { case AUTH_INTERNAL, AUTH_ANON_INTERNAL, AUTH_COOKIE: return nil - case AUTH_OAUTH_LEGACY: - if kind == RO { - // Only legacy tokens with "*" scopes ever get this far - return nil - } else { - return fmt.Errorf("Read/write access denied for legacy OAuth token") - } case AUTH_WEBHOOK: if kind != RO { return fmt.Errorf("Access to read/write resolver denied for webhook") @@ -566,94 +557,6 @@ func OAuth2(token string, hash [64]byte, w http.ResponseWriter, next.ServeHTTP(w, r) } -// TODO: Remove legacy OAuth support -func LegacyOAuth(bearer string, hash [64]byte, w http.ResponseWriter, - r *http.Request, next http.Handler) { - var ( - auth AuthContext - expires time.Time - scopes string - ) - if err := database.WithTx(r.Context(), &sql.TxOptions{ - Isolation: 0, - ReadOnly: true, - }, func(tx *sql.Tx) error { - var ( - err error - rows *sql.Rows - ) - query := database. - Select(r.Context(), []string{ - `ot.expires`, - `ot.scopes`, - `u.id`, `u.username`, - `u.created`, `u.updated`, - `u.email`, - `u.user_type`, - `u.url`, `u.location`, `u.bio`, - `u.suspension_notice`, - }). - From(`oauthtoken ot`). - Join(`"user" u ON u.id = ot.user_id`). - Where(`ot.token_hash = ?`, bearer) - if rows, err = query.RunWith(tx).Query(); err != nil { - panic(err) - } - defer rows.Close() - - if !rows.Next() { - if err := rows.Err(); err != nil { - panic(err) - } - authError(w, "Invalid or expired OAuth token", http.StatusForbidden) - return nil - } - if err := rows.Scan(&expires, &scopes, - &auth.UserID, &auth.Username, - &auth.Created, &auth.Updated, - &auth.Email, - &auth.UserType, - &auth.URL, - &auth.Location, - &auth.Bio, - &auth.SuspensionNotice); err != nil { - panic(err) - } - if rows.Next() { - if err := rows.Err(); err != nil { - panic(err) - } - panic(errors.New("Multiple matching OAuth tokens; invariant broken")) - } - return nil - }); err != nil { - panic(err) - } - - if time.Now().UTC().After(expires) { - authError(w, "Invalid or expired OAuth token", http.StatusForbidden) - return - } - - if auth.UserType == USER_TYPE_SUSPENDED { - authError(w, fmt.Sprintf( - "Account suspended with the following notice: %s\nContact support", - *auth.SuspensionNotice), http.StatusForbidden) - return - } - - if scopes != "*" { - authError(w, "Presently, OAuth authentication to the GraphQL API is only supported for OAuth tokens with all permissions, namely '*'.", http.StatusForbidden) - return - } - - auth.AuthMethod = AUTH_OAUTH_LEGACY - - ctx := context.WithValue(r.Context(), userCtxKey, &auth) - r = r.WithContext(ctx) - next.ServeHTTP(w, r) -} - // Returns an auth context configured for webhook delivery. This auth // configuration is not possible during a normal GraphQL query, and is only // used during webhook execution. @@ -718,12 +621,6 @@ func Middleware(conf ini.File, apiconf string) func(http.Handler) http.Handler { OAuth2(bearer, hash, w, r, next) return } - if oauthBearerRegex.Match(token) { - hash := sha512.Sum512(token) - bearer = hex.EncodeToString(hash[:]) - LegacyOAuth(bearer, hash, w, r, next) - return - } authError(w, "Invalid OAuth bearer token", http.StatusBadRequest) return case "internal": diff --git a/webhooks/config.go b/webhooks/config.go index af0f7d7334cd662e3de2f7ac2992ba9d38b586f9..883d4d34c95e87a23ab45bc2184c4dd0033177b6 100644 --- a/webhooks/config.go +++ b/webhooks/config.go @@ -32,8 +32,6 @@ type AuthConfig struct { func NewAuthConfig(ctx context.Context) (AuthConfig, error) { user := auth.ForContext(ctx) switch user.AuthMethod { - case auth.AUTH_OAUTH_LEGACY: - return AuthConfig{}, fmt.Errorf("Native webhooks are not supported with legacy OAuth") case auth.AUTH_OAUTH2: tokenHash := hex.EncodeToString(user.TokenHash[:]) grants := user.BearerToken.Grants