Browse Source

Throttle admin password reset

pull/429/head
Kat 3 years ago
parent
commit
4ec622ef21
  1. 6
      config/initializers/rack_attack.rb
  2. 47
      spec/requests/rack_attack_spec.rb

6
config/initializers/rack_attack.rb

@ -14,6 +14,12 @@ Rack::Attack.throttle("password reset requests", limit: 5, period: 60.seconds) d
end end
end end
Rack::Attack.throttle("admin password reset requests", limit: 5, period: 60.seconds) do |request|
if request.params["admin_user"].present? && request.path == "/admin/password" && request.post?
request.params["admin_user"]["email"].to_s.downcase.gsub(/\s+/, "")
end
end
Rack::Attack.throttled_responder = lambda do |_env| Rack::Attack.throttled_responder = lambda do |_env|
headers = { headers = {
"Location" => "/429", "Location" => "/429",

47
spec/requests/rack_attack_spec.rb

@ -12,8 +12,11 @@ describe "Rack::Attack" do
let(:devise_notify_mailer) { DeviseNotifyMailer.new } let(:devise_notify_mailer) { DeviseNotifyMailer.new }
let(:params) { { user: { email: } } } let(:params) { { user: { email: } } }
let(:admin_params) { { admin_user: { email: admin_email } } }
let(:user) { FactoryBot.create(:user) } let(:user) { FactoryBot.create(:user) }
let(:admin_user) { FactoryBot.create(:admin_user) }
let(:email) { user.email } let(:email) { user.email }
let(:admin_email) { admin_user.email }
before do before do
Rack::Attack.enabled = true Rack::Attack.enabled = true
@ -29,7 +32,7 @@ describe "Rack::Attack" do
context "when a password reset is requested" do context "when a password reset is requested" do
context "when the number of requests is under the throttle limit" do context "when the number of requests is under the throttle limit" do
it "does not throttle" do it "does not throttle for a regular user" do
under_limit.times do under_limit.times do
post "/account/password", params: params post "/account/password", params: params
follow_redirect! follow_redirect!
@ -37,13 +40,42 @@ describe "Rack::Attack" do
last_response = response last_response = response
expect(last_response.status).to eq(200) expect(last_response.status).to eq(200)
end end
it "does not throttle for an admin user" do
under_limit.times do
post "/admin/password", params: admin_params
follow_redirect!
end
last_response = response
expect(last_response.status).to eq(200)
end
end end
context "when the number of requests is at the throttle limit" do context "when the number of requests is at the throttle limit" do
it "does not throttle" do it "does not throttle for a regular user" do
limit.times do
post "/account/password", params: params
follow_redirect!
end
last_response = response
expect(last_response.status).to eq(200)
end
it "does not throttle for an admin user" do
limit.times do
post "/admin/password", params: admin_params
follow_redirect!
end
last_response = response
expect(last_response.status).to eq(200)
end
it "does not throttle if both endpoints are hit" do
limit.times do limit.times do
post "/account/password", params: params post "/account/password", params: params
follow_redirect! follow_redirect!
post "/admin/password", params: admin_params
follow_redirect!
end end
last_response = response last_response = response
expect(last_response.status).to eq(200) expect(last_response.status).to eq(200)
@ -51,7 +83,7 @@ describe "Rack::Attack" do
end end
context "when the number of requests is over the throttle limit" do context "when the number of requests is over the throttle limit" do
it "throttles" do it "throttles for a regular user" do
over_limit.times do over_limit.times do
post "/account/password", params: params post "/account/password", params: params
follow_redirect! follow_redirect!
@ -59,6 +91,15 @@ describe "Rack::Attack" do
last_response = response last_response = response
expect(last_response.status).to eq(429) expect(last_response.status).to eq(429)
end end
it "throttles for an admin user" do
over_limit.times do
post "/admin/password", params: admin_params
follow_redirect!
end
last_response = response
expect(last_response.status).to eq(429)
end
end end
end end
end end

Loading…
Cancel
Save