package ratelimit import ( "github.com/redis/go-redis/v9" "go.uber.org/zap" "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config" ) // ProvideLoginRateLimiter creates a LoginRateLimiter for dependency injection // CWE-307: Implements rate limiting and account lockout protection against brute force attacks func ProvideLoginRateLimiter(redisClient redis.UniversalClient, cfg *config.Configuration, logger *zap.Logger) LoginRateLimiter { // Start with default config loginConfig := DefaultLoginRateLimiterConfig() // Override with configuration values if provided if cfg != nil { if cfg.LoginRateLimit.MaxAttemptsPerIP > 0 { loginConfig.MaxAttemptsPerIP = cfg.LoginRateLimit.MaxAttemptsPerIP } if cfg.LoginRateLimit.IPWindow > 0 { loginConfig.IPWindow = cfg.LoginRateLimit.IPWindow } if cfg.LoginRateLimit.MaxFailedAttemptsPerAccount > 0 { loginConfig.MaxFailedAttemptsPerAccount = cfg.LoginRateLimit.MaxFailedAttemptsPerAccount } if cfg.LoginRateLimit.AccountLockoutDuration > 0 { loginConfig.AccountLockoutDuration = cfg.LoginRateLimit.AccountLockoutDuration } } // Type assert to *redis.Client since LoginRateLimiter needs it client, ok := redisClient.(*redis.Client) if !ok { // If it's a cluster client or other type, log warning // This shouldn't happen in our standard setup logger.Warn("Redis client is not a standard client, login rate limiter may not work correctly") return NewLoginRateLimiter(nil, loginConfig, logger) } logger.Info("Login rate limiter initialized", zap.Int("max_attempts_per_ip", loginConfig.MaxAttemptsPerIP), zap.Duration("ip_window", loginConfig.IPWindow), zap.Int("max_failed_per_account", loginConfig.MaxFailedAttemptsPerAccount), zap.Duration("lockout_duration", loginConfig.AccountLockoutDuration)) return NewLoginRateLimiter(client, loginConfig, logger) } // ProvideAuthFailureRateLimiter creates an AuthFailureRateLimiter for dependency injection // CWE-307: Implements rate limiting for authorization failures to prevent privilege escalation attempts // OWASP A01:2021: Broken Access Control - Rate limiting authorization failures func ProvideAuthFailureRateLimiter(redisClient redis.UniversalClient, cfg *config.Configuration, logger *zap.Logger) AuthFailureRateLimiter { // Use default config with secure defaults for authorization failure protection authConfig := DefaultAuthFailureRateLimiterConfig() // Override defaults with configuration if provided // Allow configuration through environment variables for flexibility if cfg != nil { // These values could be configured via environment variables // For now, we use the secure defaults // TODO: Add auth failure rate limiting configuration to SecurityConfig } // Type assert to *redis.Client since AuthFailureRateLimiter needs it client, ok := redisClient.(*redis.Client) if !ok { // If it's a cluster client or other type, log warning logger.Warn("Redis client is not a standard client, auth failure rate limiter may not work correctly") return NewAuthFailureRateLimiter(nil, authConfig, logger) } logger.Info("Authorization failure rate limiter initialized", zap.Int("max_failures_per_user", authConfig.MaxFailuresPerUser), zap.Int("max_failures_per_resource", authConfig.MaxFailuresPerResource), zap.Duration("failure_window", authConfig.FailureWindow), zap.Duration("block_duration", authConfig.BlockDuration), zap.Int("alert_threshold", authConfig.AlertThreshold)) return NewAuthFailureRateLimiter(client, authConfig, logger) }