Merge pull request #438 from fatkodima/case-insensitive-discriminator

Make discriminators case-insensitive by default
This commit is contained in:
Gonzalo Rodriguez 2019-10-22 11:31:34 -03:00 committed by GitHub
commit c962dc1a41
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 3 deletions

View file

@ -31,7 +31,7 @@ module Rack
autoload :Allow2Ban, 'rack/attack/allow2ban'
class << self
attr_accessor :enabled, :notifier
attr_accessor :enabled, :notifier, :discriminator_normalizer
attr_reader :configuration
def instrument(request)
@ -79,6 +79,9 @@ module Rack
# Set defaults
@enabled = true
@notifier = ActiveSupport::Notifications if defined?(ActiveSupport::Notifications)
@discriminator_normalizer = lambda do |discriminator|
discriminator.to_s.strip.downcase
end
@configuration = Configuration.new
attr_reader :configuration

View file

@ -22,8 +22,7 @@ module Rack
end
def matched_by?(request)
discriminator = block.call(request)
discriminator = discriminator_for(request)
return false unless discriminator
current_period = period_for(request)
@ -49,6 +48,14 @@ module Rack
private
def discriminator_for(request)
discriminator = block.call(request)
if discriminator && Rack::Attack.discriminator_normalizer
discriminator = Rack::Attack.discriminator_normalizer.call(discriminator)
end
discriminator
end
def period_for(request)
period.respond_to?(:call) ? period.call(request) : period
end

View file

@ -144,3 +144,47 @@ describe 'Rack::Attack.throttle with block retuning nil' do
end
end
end
describe 'Rack::Attack.throttle with discriminator_normalizer' do
before do
@period = 60
@emails = [
"person@example.com",
"PERSON@example.com ",
" person@example.com\r\n ",
]
Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new
Rack::Attack.throttle('logins/email', limit: 4, period: @period) do |req|
if req.path == '/login' && req.post?
req.params['email']
end
end
end
it 'should not differentiate requests when discriminator_normalizer is enabled' do
post_logins
key = "rack::attack:#{Time.now.to_i / @period}:logins/email:person@example.com"
_(Rack::Attack.cache.store.read(key)).must_equal 3
end
it 'should differentiate requests when discriminator_normalizer is disabled' do
begin
prev = Rack::Attack.discriminator_normalizer
Rack::Attack.discriminator_normalizer = nil
post_logins
@emails.each do |email|
key = "rack::attack:#{Time.now.to_i / @period}:logins/email:#{email}"
_(Rack::Attack.cache.store.read(key)).must_equal 1
end
ensure
Rack::Attack.discriminator_normalizer = prev
end
end
def post_logins
@emails.each do |email|
post '/login', email: email
end
end
end