mirror of
https://github.com/SecurityBrewery/catalyst.git
synced 2025-12-06 15:22:47 +01:00
80 lines
1.8 KiB
Go
80 lines
1.8 KiB
Go
package router
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
"net/http"
|
|
"slices"
|
|
"strings"
|
|
|
|
"github.com/SecurityBrewery/catalyst/app/database"
|
|
"github.com/SecurityBrewery/catalyst/app/database/sqlc"
|
|
)
|
|
|
|
func demoMode(queries *sqlc.Queries) func(http.Handler) http.Handler {
|
|
return func(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
if isCriticalPath(r) && isCriticalMethod(r) && isDemoMode(r.Context(), queries) {
|
|
http.Error(w, "Cannot modify reactions or files in demo mode", http.StatusForbidden)
|
|
|
|
return
|
|
}
|
|
|
|
next.ServeHTTP(w, r)
|
|
})
|
|
}
|
|
}
|
|
|
|
func isCriticalPath(r *http.Request) bool {
|
|
// Define critical paths that should not be accessed in demo mode
|
|
criticalPaths := []string{
|
|
"/api/files",
|
|
"/api/groups",
|
|
"/api/reactions",
|
|
"/api/settings",
|
|
"/api/users",
|
|
"/api/webhooks",
|
|
}
|
|
|
|
for _, path := range criticalPaths {
|
|
if strings.Contains(r.URL.Path, path) {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func isCriticalMethod(r *http.Request) bool {
|
|
return !slices.Contains([]string{http.MethodHead, http.MethodGet}, r.Method)
|
|
}
|
|
|
|
func isDemoMode(ctx context.Context, queries *sqlc.Queries) bool {
|
|
var demoMode bool
|
|
|
|
if err := database.Paginate(ctx, func(ctx context.Context, offset, limit int64) (nextPage bool, err error) {
|
|
slog.InfoContext(ctx, "Checking for demo mode", "offset", offset, "limit", limit)
|
|
|
|
features, err := queries.ListFeatures(ctx, sqlc.ListFeaturesParams{Offset: offset, Limit: limit})
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
for _, feature := range features {
|
|
if feature.Key == "demo" {
|
|
demoMode = true
|
|
|
|
return false, nil // Stop pagination if demo mode is found
|
|
}
|
|
}
|
|
|
|
return true, nil
|
|
}); err != nil {
|
|
slog.ErrorContext(ctx, "Failed to check demo mode", "error", err)
|
|
|
|
return false
|
|
}
|
|
|
|
return demoMode
|
|
}
|