package config import ( "fmt" "strings" "github.com/higress-group/wasm-go/pkg/wrapper" "github.com/tidwall/gjson" ) type ReplayProtectionConfig struct { ForceNonce bool // Whether to enforce nonce verification NonceTTL int // Expiration time of the nonce (in seconds) Redis RedisConfig NonceMinLen int // Minimum length of the nonce NonceMaxLen int // Maximum length of the nonce NonceHeader string // Name of the nonce header ValidateBase64 bool // Whether to validate base64 encoding format RejectCode uint32 // Response code RejectMsg string // Response body } type RedisConfig struct { Client wrapper.RedisClient KeyPrefix string } func ParseConfig(json gjson.Result, config *ReplayProtectionConfig) error { // Parse Redis configuration redisConfig := json.Get("redis") if !redisConfig.Exists() { return fmt.Errorf("missing redis config") } serviceName := redisConfig.Get("service_name").String() if serviceName == "" { return fmt.Errorf("redis service name is required") } servicePort := redisConfig.Get("service_port").Int() if servicePort == 0 { if strings.HasSuffix(serviceName, ".static") { servicePort = 80 // default logic port for static service } else { servicePort = 6379 } } username := redisConfig.Get("username").String() password := redisConfig.Get("password").String() timeout := redisConfig.Get("timeout").Int() if timeout == 0 { timeout = 1000 } // Initialize Redis client config.Redis.Client = wrapper.NewRedisClusterClient(wrapper.FQDNCluster{ FQDN: serviceName, Port: servicePort, }) database := int(redisConfig.Get("database").Int()) if err := config.Redis.Client.Init(username, password, timeout, wrapper.WithDataBase(database)); err != nil { return err } keyPrefix := redisConfig.Get("key_prefix").String() if keyPrefix == "" { keyPrefix = "replay-protection" } config.Redis.KeyPrefix = keyPrefix config.NonceHeader = json.Get("nonce_header").String() if config.NonceHeader == "" { config.NonceHeader = "X-Higress-Nonce" } config.ValidateBase64 = json.Get("validate_base64").Bool() config.RejectCode = uint32(json.Get("reject_code").Int()) if config.RejectCode == 0 { config.RejectCode = 429 } config.RejectMsg = json.Get("reject_msg").String() if config.RejectMsg == "" { config.RejectMsg = "Replay Attack Detected" } config.ForceNonce = json.Get("force_nonce").Bool() config.NonceTTL = int(json.Get("nonce_ttl").Int()) if config.NonceTTL == 0 { config.NonceTTL = 900 } config.NonceMinLen = int(json.Get("nonce_min_length").Int()) if config.NonceMinLen == 0 { config.NonceMinLen = 8 } config.NonceMaxLen = int(json.Get("nonce_max_length").Int()) if config.NonceMaxLen == 0 { config.NonceMaxLen = 128 } return nil }