81 lines
3.5 KiB
Go
81 lines
3.5 KiB
Go
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)
|
|
}
|