refactor(backend): replace inline Bearer parsing with OptionalAuth middleware in services
Removes the inline Bearer token fallback in ServicesHandler — the OptionalAuth middleware (added to the public services route group in main.go) now handles auth context population. This eliminates duplicated token parsing logic and ensures consistent auth behavior across all routes. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
@@ -2,7 +2,6 @@ package services
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crussell/auth"
|
|
||||||
"crussell/clock"
|
"crussell/clock"
|
||||||
"crussell/db"
|
"crussell/db"
|
||||||
"github.com/jackc/pgx/v5"
|
"github.com/jackc/pgx/v5"
|
||||||
@@ -12,7 +11,6 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
@@ -258,26 +256,10 @@ func DeleteServiceHandler(w http.ResponseWriter, r *http.Request) {
|
|||||||
// ServicesHandler returns all services from the database
|
// ServicesHandler returns all services from the database
|
||||||
// For non-admin logged-in users, filters based on age and patch test eligibility
|
// For non-admin logged-in users, filters based on age and patch test eligibility
|
||||||
func ServicesHandler(w http.ResponseWriter, r *http.Request) {
|
func ServicesHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
// Check if user is authenticated - try context first, then optional token
|
// Check if user is authenticated — context is set by OptionalAuth middleware
|
||||||
userID, hasUser := r.Context().Value(mw.UserIDKey).(string)
|
userID, hasUser := r.Context().Value(mw.UserIDKey).(string)
|
||||||
role, _ := r.Context().Value(mw.UserRoleKey).(string)
|
role, _ := r.Context().Value(mw.UserRoleKey).(string)
|
||||||
|
|
||||||
// If no user in context, try to parse token from header
|
|
||||||
if !hasUser || userID == "" {
|
|
||||||
authHeader := r.Header.Get("Authorization")
|
|
||||||
if strings.HasPrefix(authHeader, "Bearer ") {
|
|
||||||
tokenString := strings.TrimPrefix(authHeader, "Bearer ")
|
|
||||||
var err error
|
|
||||||
userID, role, _, err = auth.VerifyToken(tokenString, r.Context())
|
|
||||||
if err != nil {
|
|
||||||
// Invalid token - treat as unauthenticated
|
|
||||||
userID = ""
|
|
||||||
role = ""
|
|
||||||
}
|
|
||||||
hasUser = userID != ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If not logged in or admin, return all services (current behavior)
|
// If not logged in or admin, return all services (current behavior)
|
||||||
if !hasUser || userID == "" || role == "admin" {
|
if !hasUser || userID == "" || role == "admin" {
|
||||||
query := `
|
query := `
|
||||||
|
|||||||
@@ -186,6 +186,7 @@ func main() {
|
|||||||
// Public read-only (but check auth context if present for eligibility)
|
// Public read-only (but check auth context if present for eligibility)
|
||||||
r.Group(func(r chi.Router) {
|
r.Group(func(r chi.Router) {
|
||||||
r.Use(mw.RateLimit(120, time.Minute))
|
r.Use(mw.RateLimit(120, time.Minute))
|
||||||
|
r.Use(mw.OptionalAuth)
|
||||||
r.Get("/services", services.ServicesHandler)
|
r.Get("/services", services.ServicesHandler)
|
||||||
r.Get("/services/eligible-for/{user_id}", services.ServicesEligibleForUserHandler)
|
r.Get("/services/eligible-for/{user_id}", services.ServicesEligibleForUserHandler)
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user