package auth import ( "crypto/subtle" "net/http" "strings" ) // BearerMiddleware authenticates requests via one of three paths (in order): // // 1. Bearer token is a valid JWT issued by the configured Dex OIDC server. // 2. Bearer token matches staticToken (constant-time compare). // 3. No Authorization header and defaultToken is set — allow through; the // Gitea client will use its service PAT for upstream calls. // // Any other case returns 401. func BearerMiddleware(jwtValidator *JWTValidator, staticToken, defaultToken string, next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { bearer, hasBearer := strings.CutPrefix(r.Header.Get("Authorization"), "Bearer ") hasBearer = hasBearer && bearer != "" if !hasBearer { if defaultToken != "" { next.ServeHTTP(w, r) return } http.Error(w, "unauthorized", http.StatusUnauthorized) return } if jwtValidator.Validate(r.Context(), bearer) { next.ServeHTTP(w, r) return } if staticToken != "" && subtle.ConstantTimeCompare([]byte(bearer), []byte(staticToken)) == 1 { next.ServeHTTP(w, r) return } http.Error(w, "unauthorized", http.StatusUnauthorized) }) }