package middleware import ( "net/http" "code.nochebuena.dev/go/rbac" "code.nochebuena.dev/go/todo-api/internal/repository" ) // Auth reads the X-User-ID request header, looks up the user in the database, // and stores an rbac.Identity in the context. // // Returns 401 if the header is absent or the user ID is not found — the two // cases are intentionally indistinguishable to callers. func Auth(userRepo repository.UserRepository) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { uid := r.Header.Get("X-User-ID") if uid == "" { http.Error(w, `{"code":"UNAUTHENTICATED","message":"missing X-User-ID header"}`, http.StatusUnauthorized) return } user, err := userRepo.FindByID(r.Context(), uid) if err != nil { http.Error(w, `{"code":"UNAUTHENTICATED","message":"user not found"}`, http.StatusUnauthorized) return } identity := rbac.NewIdentity(user.ID, user.Name, user.Email) ctx := rbac.SetInContext(r.Context(), identity) next.ServeHTTP(w, r.WithContext(ctx)) }) } }