monorepo/cloud/maplefile-backend/pkg/ratelimit/providers.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)
}