package middleware import ( "context" "net/http" ) // SessionStore defines the interface for session validation type SessionStore interface { ValidateSession(r *http.Request) bool GetUserID(r *http.Request) (string, error) } // contextKey is a custom type for context keys to avoid collisions type contextKey string const userIDContextKey contextKey = "user_id" // GetUserIDContextKey returns the context key for user ID (for testing) func GetUserIDContextKey() contextKey { return userIDContextKey } // RequireAuth is a middleware that ensures the user is authenticated func RequireAuth(sessionStore SessionStore) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Validate session if !sessionStore.ValidateSession(r) { http.Redirect(w, r, "/login", http.StatusSeeOther) return } // Get user ID and add to context userID, err := sessionStore.GetUserID(r) if err != nil { http.Redirect(w, r, "/login", http.StatusSeeOther) return } // Add user ID to request context ctx := context.WithValue(r.Context(), userIDContextKey, userID) next.ServeHTTP(w, r.WithContext(ctx)) }) } } // GetUserIDFromContext retrieves the user ID from the request context func GetUserIDFromContext(ctx context.Context) (string, bool) { userID, ok := ctx.Value(userIDContextKey).(string) return userID, ok }