Files
apocapoc-api/internal/infrastructure/http/rate_limit_middleware.go
T
david 7cb2756b67
CI/CD Pipeline / Test (push) Has been cancelled
CI/CD Pipeline / Lint (push) Has been cancelled
CI/CD Pipeline / Build and Push Docker Image (push) Has been cancelled
Implement Sprint 2 security enhancements
Add user-based rate limiting middleware (100 req/min) for authenticated endpoints using httprate library. Implement common password validation blocking 50+ weak passwords. Improve test coverage from 38.3% to 44.6% with comprehensive refresh token tests.

Security improvements:
- Rate limiting by user ID for /habits and /stats endpoints
- X-RateLimit-Limit header in responses
- Common password blacklist in password validation
- Refresh token test suite with 5 scenarios (valid, invalid, expired, revoked, empty)
2025-11-27 10:33:01 +01:00

39 lines
1.0 KiB
Go

package http
import (
"net/http"
"strconv"
"time"
"apocapoc-api/internal/infrastructure/auth"
"github.com/go-chi/httprate"
)
func RateLimitByUser(jwtService *auth.JWTService, requestsPerMinute int, duration time.Duration) func(http.Handler) http.Handler {
limiter := httprate.NewRateLimiter(
requestsPerMinute,
duration,
httprate.WithKeyFuncs(func(r *http.Request) (string, error) {
userID, ok := GetUserIDFromContext(r.Context())
if !ok {
return r.RemoteAddr, nil
}
return "user:" + userID, nil
}),
httprate.WithLimitHandler(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusTooManyRequests)
w.Write([]byte(`{"error":"Rate limit exceeded. Please try again later."}`))
}),
)
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("X-RateLimit-Limit", strconv.Itoa(requestsPerMinute))
limiter.Handler(next).ServeHTTP(w, r)
})
}
}