diff --git a/config/initializers/rack_attack.rb b/config/initializers/rack_attack.rb index ce88316761..8fe9ef61fc 100644 --- a/config/initializers/rack_attack.rb +++ b/config/initializers/rack_attack.rb @@ -6,8 +6,19 @@ def self.real_ip(req) req.get_header('HTTP_CF_CONNECTING_IP') || req.ip end + def self.authenticated?(req) + warden = req.env['warden'] + warden && warden.user.present? + end + # Throttle all graphql requests by IP address - throttle('api/graphql', limit: proc { CheckConfig.get('api_rate_limit', 100, :integer) }, period: 60.seconds) do |req| + throttle('api/graphql', limit: proc { |req| + if authenticated?(req) + CheckConfig.get('api_rate_limit_authenticated', 1000, :integer) + else + CheckConfig.get('api_rate_limit', 100, :integer) + end + }, period: 60.seconds) do |req| real_ip(req) if req.path == '/api/graphql' end diff --git a/test/lib/check_rack_attack_test.rb b/test/lib/check_rack_attack_test.rb index a467dcab4a..ac27b374db 100644 --- a/test/lib/check_rack_attack_test.rb +++ b/test/lib/check_rack_attack_test.rb @@ -58,4 +58,24 @@ class ThrottlingTest < ActionDispatch::IntegrationTest Rails.env = original_env end + + test "should apply higher rate limit for authenticated users" do + stub_configs({ 'api_rate_limit_authenticated' => 5 }) do + password = random_complex_password + user = create_user password: password + user_params = { api_user: { email: user.email, password: password } } + + + post api_user_session_path, params: user_params, as: :json + assert_response :success + + 5.times do + post api_graphql_path + assert_response :success + end + + post api_graphql_path + assert_response :too_many_requests + end + end end