feat: add configurable test mode and rate limiting
- Add TestMode, RateLimitEnabled, RequestsPerMinute to Config - Add getEnvBool() and getEnvInt() helper functions - Update rate limiter to support enabled/disabled state - Pass test environment variables through docker-compose - Configure rate limiter dynamically in main.go This allows disabling rate limiting for integration testing while maintaining security in production environments.
This commit is contained in:
+6
-1
@@ -67,7 +67,12 @@ func main() {
|
||||
e.Use(ratelimit.RequestTracingMiddleware(cfg))
|
||||
|
||||
// Rate limiter for auth endpoints
|
||||
rateLimiter := ratelimit.NewRateLimiter(ratelimit.DefaultRateLimiterConfig())
|
||||
rateLimiterConfig := ratelimit.RateLimiterConfig{
|
||||
Enabled: cfg.RateLimitEnabled,
|
||||
RequestsPerMinute: cfg.RequestsPerMinute,
|
||||
CleanupInterval: 5 * time.Minute,
|
||||
}
|
||||
rateLimiter := ratelimit.NewRateLimiter(rateLimiterConfig)
|
||||
rateLimitMiddleware := ratelimit.RateLimiterMiddleware(rateLimiter)
|
||||
|
||||
// Auth routes (no auth required, but rate limited)
|
||||
|
||||
@@ -34,6 +34,9 @@ services:
|
||||
DATABASE_NAME: bookmann
|
||||
JWT_SECRET: ${JWT_SECRET}
|
||||
SERVER_PORT: 8765
|
||||
TEST_MODE: ${TEST_MODE:-false}
|
||||
RATE_LIMIT_ENABLED: ${RATE_LIMIT_ENABLED:-true}
|
||||
REQUESTS_PER_MINUTE: ${REQUESTS_PER_MINUTE:-10}
|
||||
ports:
|
||||
- "8765:8765"
|
||||
depends_on:
|
||||
|
||||
@@ -3,6 +3,7 @@ package config
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
@@ -14,6 +15,9 @@ type Config struct {
|
||||
DatabaseUser string
|
||||
DatabasePassword string
|
||||
DatabaseName string
|
||||
TestMode bool
|
||||
RateLimitEnabled bool
|
||||
RequestsPerMinute int
|
||||
}
|
||||
|
||||
func LoadConfig() *Config {
|
||||
@@ -26,6 +30,9 @@ func LoadConfig() *Config {
|
||||
DatabaseName: getEnv("DATABASE_NAME", "bookmann"),
|
||||
JWTSecret: getEnv("JWT_SECRET", "your-secret-key"),
|
||||
UploadPath: getEnv("UPLOAD_PATH", "./uploads"),
|
||||
TestMode: getEnvBool("TEST_MODE", false),
|
||||
RateLimitEnabled: getEnvBool("RATE_LIMIT_ENABLED", true),
|
||||
RequestsPerMinute: getEnvInt("REQUESTS_PER_MINUTE", 10),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,3 +47,23 @@ func getEnv(key, defaultValue string) string {
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
func getEnvBool(key string, defaultValue bool) bool {
|
||||
if value := os.Getenv(key); value != "" {
|
||||
boolVal, err := strconv.ParseBool(value)
|
||||
if err == nil {
|
||||
return boolVal
|
||||
}
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
func getEnvInt(key string, defaultValue int) int {
|
||||
if value := os.Getenv(key); value != "" {
|
||||
intVal, err := strconv.Atoi(value)
|
||||
if err == nil {
|
||||
return intVal
|
||||
}
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
// RateLimiterConfig defines rate limiting configuration
|
||||
type RateLimiterConfig struct {
|
||||
Enabled bool
|
||||
RequestsPerMinute int
|
||||
CleanupInterval time.Duration
|
||||
}
|
||||
@@ -17,6 +18,7 @@ type RateLimiterConfig struct {
|
||||
// DefaultRateLimiterConfig returns sensible defaults
|
||||
func DefaultRateLimiterConfig() RateLimiterConfig {
|
||||
return RateLimiterConfig{
|
||||
Enabled: true,
|
||||
RequestsPerMinute: 10,
|
||||
CleanupInterval: 5 * time.Minute,
|
||||
}
|
||||
@@ -98,6 +100,11 @@ func (rl *RateLimiter) Allow(ip string) bool {
|
||||
func RateLimiterMiddleware(rl *RateLimiter) echo.MiddlewareFunc {
|
||||
return func(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
// If rate limiting is disabled, skip checks
|
||||
if !rl.config.Enabled {
|
||||
return next(c)
|
||||
}
|
||||
|
||||
// Get client IP
|
||||
ip := c.RealIP()
|
||||
if ip == "" {
|
||||
|
||||
Reference in New Issue
Block a user