all repos — weimar @ 4725091cf8486591001604eeabcb1c4632f7ab7f

Unnamed repository; edit this file 'description' to name the repository.

internal/server/middleware.go (view raw)

 1package server
 2
 3import (
 4	"context"
 5	"log/slog"
 6	"net/http"
 7	"strings"
 8
 9	"github.com/mjensen/weimar/internal/api"
10	"github.com/mjensen/weimar/internal/auth"
11)
12
13// requireAuth wraps a handler with session cookie authentication.
14// Unauthenticated requests receive a 401 JSON error.
15func (s *Server) requireAuth(next http.HandlerFunc) http.HandlerFunc {
16	return func(w http.ResponseWriter, r *http.Request) {
17		cookie, err := r.Cookie(auth.SessionCookieName)
18		if err != nil {
19			writeJSONError(w, http.StatusUnauthorized, "unauthorized")
20			return
21		}
22
23		user, err := s.auth.Authenticate(r.Context(), cookie.Value)
24		if err != nil {
25			slog.Debug("auth failed", "reason", err)
26			writeJSONError(w, http.StatusUnauthorized, "unauthorized")
27			return
28		}
29
30		ctx := context.WithValue(r.Context(), api.CtxKeyUser, user)
31		next(w, r.WithContext(ctx))
32	}
33}
34
35// writeJSONError writes a JSON error response.
36func writeJSONError(w http.ResponseWriter, status int, msg string) {
37	w.Header().Set("Content-Type", "application/json")
38	w.WriteHeader(status)
39	w.Write([]byte(`{"error":"` + strings.ReplaceAll(msg, `"`, `\"`) + `"}`))
40}