From 2ba6c98e816dfb6d030ce450be2df983128aab31 Mon Sep 17 00:00:00 2001 From: Molly Struve Date: Thu, 30 Apr 2020 18:06:19 -0500 Subject: [PATCH] Limit 1 message every second for single user (#7631) * limit 1 message every second for single user * increase message limit to 2 in a second --- config/initializers/rack/attack.rb | 6 +++++ spec/initializers/rack/attack_spec.rb | 35 +++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) diff --git a/config/initializers/rack/attack.rb b/config/initializers/rack/attack.rb index a060268dd..e3769efc7 100644 --- a/config/initializers/rack/attack.rb +++ b/config/initializers/rack/attack.rb @@ -22,4 +22,10 @@ class Rack::Attack request.env["HTTP_FASTLY_CLIENT_IP"].to_s end end + + throttle("message_throttle", limit: 2, period: 1) do |request| + if request.path.starts_with?("/messages") && request.post? && request.env["HTTP_FASTLY_CLIENT_IP"].present? + request.env["HTTP_FASTLY_CLIENT_IP"].to_s + end + end end diff --git a/spec/initializers/rack/attack_spec.rb b/spec/initializers/rack/attack_spec.rb index c2f00b2f0..3d4c7b3f5 100644 --- a/spec/initializers/rack/attack_spec.rb +++ b/spec/initializers/rack/attack_spec.rb @@ -61,4 +61,39 @@ describe Rack::Attack, type: :request, throttle: true do end end end + + describe "message_throttle" do + let(:user) { create(:user) } + let(:chat_channel) { create(:chat_channel) } + let(:new_message) do + { + message_markdown: "hi", + user_id: user.id, + temp_id: "sd78jdssd", + chat_channel_id: chat_channel.id + } + end + + before do + allow(Pusher).to receive(:trigger).and_return(true) + sign_in user + end + + it "throttles creating messages" do + headers = { "HTTP_FASTLY_CLIENT_IP" => "5.6.7.8" } + dif_headers = { "HTTP_FASTLY_CLIENT_IP" => "1.1.1.1" } + + Timecop.freeze do + valid_responses = Array.new(2).map do + post messages_path, params: { message: new_message }, headers: headers + end + throttled_response = post messages_path, params: { message: new_message }, headers: headers + new_api_response = post messages_path, params: { message: new_message }, headers: dif_headers + + valid_responses.each { |r| expect(r).not_to eq(429) } + expect(throttled_response).to eq(429) + expect(new_api_response).not_to eq(429) + end + end + end end