7cb2756b67
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)
39 lines
1.0 KiB
Go
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)
|
|
})
|
|
}
|
|
}
|