// Package middleware enthält HTTP-Middleware — das sind Funktionen die sich // "vor" den eigentlichen Handlern schalten und z.B. Authentifizierung prüfen. package middleware import ( "net/http" "strings" "wiki/handler" ) // RequireTeamOrAdminKey schützt /api/upload, /api/delete und /mcp. // // Der Bearer-Key wird gegen die TeamRegistry aufgelöst: ein Team-Key beschränkt // den Request auf das eigene Team, der globale Admin-Key (ADMIN_TOKEN) erlaubt // Zugriff auf jedes Team, muss dafür aber explizit sagen welches (siehe api.go: // Formfeld/Query-Param "team"; mcp.go: Header "X-Wiki-Team"). // // Das aufgelöste Team (oder der Admin-Status) landet im Request-Context — // siehe handler.WithTeam / handler.TeamFromContext. func RequireTeamOrAdminKey(next http.Handler, registry *handler.TeamRegistry) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { authHeader := r.Header.Get("Authorization") if !strings.HasPrefix(authHeader, "Bearer ") { http.Error(w, "Authorization header fehlt", http.StatusUnauthorized) return } key := strings.TrimPrefix(authHeader, "Bearer ") // Timing-sicherer Vergleich passiert bereits innerhalb von registry.Resolve // (subtle.ConstantTimeCompare, siehe registry.go) — verhindert dass ein // Angreifer anhand der Antwortzeit erraten kann wie viele Zeichen seines // Keys korrekt sind. team, isAdmin, ok := registry.Resolve(key) if !ok { http.Error(w, "Ungültiger Key", http.StatusUnauthorized) return } next.ServeHTTP(w, r.WithContext(handler.WithTeam(r.Context(), team, isAdmin))) }) }