Files
goaresv3/pkg/middleware/cors_dynamic.go
Beyhan Oğur b6e74bd024 first commit
2026-04-26 21:41:46 +03:00

69 lines
2.1 KiB
Go

package middleware
import (
"net/http"
"strings"
"github.com/gin-gonic/gin"
"goaresv3/app/settings/models"
"goaresv3/config"
)
// DynamicCORS applies CORS policy from DB-backed whitelist/blacklist tables.
func DynamicCORS() gin.HandlerFunc {
debug := envBool("CORS_DEBUG", false)
return func(c *gin.Context) {
// Defaults for downstream middlewares (e.g. rate limit)
c.Set("origin_whitelisted", false)
c.Set("origin_blacklisted", false)
origin := strings.TrimSpace(c.GetHeader("Origin"))
if origin == "" {
policyLogf(debug, "[cors] skip: no origin method=%s path=%s", c.Request.Method, c.Request.URL.Path)
c.Next()
return
}
if config.DB == nil {
c.AbortWithStatusJSON(http.StatusServiceUnavailable, gin.H{"error": "database is not connected"})
return
}
var blocked models.CorsBlacklist
if err := config.DB.
Where("origin = ? AND is_active = ?", origin, true).
First(&blocked).Error; err == nil {
c.Set("origin_blacklisted", true)
policyLogf(debug, "[cors] blocked origin=%s method=%s path=%s", origin, c.Request.Method, c.Request.URL.Path)
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"error": "origin is blocked"})
return
}
var whitelisted models.CorsWhitelist
if err := config.DB.
Where("origin = ? AND is_active = ?", origin, true).
First(&whitelisted).Error; err == nil {
c.Set("origin_whitelisted", true)
policyLogf(debug, "[cors] whitelisted origin=%s method=%s path=%s", origin, c.Request.Method, c.Request.URL.Path)
} else {
policyLogf(debug, "[cors] pass(non-listed) origin=%s method=%s path=%s", origin, c.Request.Method, c.Request.URL.Path)
}
c.Header("Access-Control-Allow-Origin", origin)
c.Header("Vary", "Origin")
c.Header("Access-Control-Allow-Methods", "GET, POST, PUT, PATCH, DELETE, OPTIONS")
c.Header("Access-Control-Allow-Headers", "Authorization, Content-Type, Accept")
c.Header("Access-Control-Allow-Credentials", "true")
if c.Request.Method == http.MethodOptions {
policyLogf(debug, "[cors] preflight origin=%s path=%s", origin, c.Request.URL.Path)
c.AbortWithStatus(http.StatusNoContent)
return
}
c.Next()
}
}