package middleware import ( "context" "log/slog" "net/http" "gitea.leeworks.dev/0xwheatyz/gitea-mobile/internal/auth" ) // contextKey is a private type for context keys in this package. type contextKey string const ( // TokenContextKey is the context key for the Gitea API token. TokenContextKey contextKey = "gitea_token" ) // TokenFromContext extracts the Gitea API token from the request context. func TokenFromContext(ctx context.Context) string { token, _ := ctx.Value(TokenContextKey).(string) return token } // Auth returns middleware that checks for a valid token cookie. // Unauthenticated requests are redirected to the settings page. // The /health, /settings, and /static/ paths are exempt from auth. func Auth(sessionSecret string) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { // Skip auth for exempt paths. path := r.URL.Path if path == "/health" || path == "/settings" || hasPrefix(path, "/static/") { next.ServeHTTP(w, r) return } token, err := auth.GetToken(r, sessionSecret) if err != nil || token == "" { slog.Debug("unauthenticated request, redirecting to settings", "path", path, "error", err) http.Redirect(w, r, "/settings", http.StatusSeeOther) return } // Inject token into request context. ctx := context.WithValue(r.Context(), TokenContextKey, token) next.ServeHTTP(w, r.WithContext(ctx)) }) } } func hasPrefix(s, prefix string) bool { return len(s) >= len(prefix) && s[:len(prefix)] == prefix }