diff --git a/app/controllers/concerns/rate_limiter.rb b/app/controllers/concerns/rate_limiter.rb new file mode 100644 index 0000000..3eb9c40 --- /dev/null +++ b/app/controllers/concerns/rate_limiter.rb @@ -0,0 +1,45 @@ +module RateLimiter + extend ActiveSupport::Concern + + included do + before_action :check_rate_limit, only: [:create] + end + + private + + def check_rate_limit + identifier = request.ip + cache_key = "rate_limit:#{controller_name}:#{identifier}" + + # Get current attempt count + attempts = Rails.cache.read(cache_key) || 0 + + if attempts >= max_attempts + @rate_limited = true + render_rate_limit_error + return + end + + # Increment attempt count with expiry + Rails.cache.write(cache_key, attempts + 1, expires_in: lockout_period) + end + + def reset_rate_limit + identifier = request.ip + cache_key = "rate_limit:#{controller_name}:#{identifier}" + Rails.cache.delete(cache_key) + end + + def render_rate_limit_error + flash.now[:alert] = "Too many failed attempts. Please try again in #{lockout_period / 60} minutes." + render action_name == "create" ? :new : action_name, status: :too_many_requests + end + + def max_attempts + 5 + end + + def lockout_period + 15.minutes + end +end