From 78bc155ac9ed37553e44ea865859d0ba02bfe008 Mon Sep 17 00:00:00 2001 From: Andrew Baber Date: Fri, 19 Nov 2021 12:30:18 -0500 Subject: [PATCH 1/7] docs: update link to rack spec in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a2658d2..6ed8d57 100644 --- a/README.md +++ b/README.md @@ -312,7 +312,7 @@ Note that `Rack::Attack.cache` is only used for throttling, allow2ban and fail2b ## Customizing responses -Customize the response of blocklisted and throttled requests using an object that adheres to the [Rack app interface](http://www.rubydoc.info/github/rack/rack/file/SPEC). +Customize the response of blocklisted and throttled requests using an object that adheres to the [Rack app interface](http://www.rubydoc.info/github/rack/rack/file/SPEC.rdoc). ```ruby Rack::Attack.blocklisted_callback = lambda do |request| From 7bcd3b1529ce7e828f9bf1ab13536125825dcee3 Mon Sep 17 00:00:00 2001 From: Gonzalo Date: Wed, 15 Dec 2021 11:59:10 -0300 Subject: [PATCH 2/7] ci: update rubies --- .github/workflows/build.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 2c33c80..00b806a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,9 +17,9 @@ jobs: strategy: matrix: ruby: - - 3.0.2 - - 2.7.4 - - 2.6.8 + - 3.0.3 + - 2.7.5 + - 2.6.9 - 2.5.8 gemfile: - rack_2 @@ -39,17 +39,17 @@ jobs: - active_support_redis_store exclude: - gemfile: rack_1 - ruby: 3.0.2 + ruby: 3.0.3 - gemfile: rails_5_2 - ruby: 3.0.2 + ruby: 3.0.3 - gemfile: rails_4_2 - ruby: 3.0.2 + ruby: 3.0.3 - gemfile: dalli2 - ruby: 3.0.2 + ruby: 3.0.3 - gemfile: rack_1 - ruby: 2.7.4 + ruby: 2.7.5 - gemfile: rails_4_2 - ruby: 2.7.4 + ruby: 2.7.5 env: BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile steps: From 4e90859a37c11f414e2e51cdc72bb8903e8dc27e Mon Sep 17 00:00:00 2001 From: Johnathan Lyman Date: Mon, 17 Jan 2022 12:25:43 -0800 Subject: [PATCH 3/7] Update README to mention .clear_configuration Adds a line to the Test case isolation section about `.clear_configuration`. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6ed8d57..5a0fa25 100644 --- a/README.md +++ b/README.md @@ -407,7 +407,7 @@ for more on how to do this. ### Test case isolation -`Rack::Attack.reset!` can be used in your test suite to clear any Rack::Attack state between different test cases. +`Rack::Attack.reset!` can be used in your test suite to clear any Rack::Attack state between different test cases. If you're testing blocklist and safelist configurations, consider using `Rack::Attack.clear_configuration` to unset the values for those lists between test cases. ## How it works From c95f9624aaa42b2d164867393297c88f73f58b93 Mon Sep 17 00:00:00 2001 From: Orhan Toy Date: Fri, 28 Jan 2022 19:04:52 +0100 Subject: [PATCH 4/7] Include LICENSE in gem build --- rack-attack.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rack-attack.gemspec b/rack-attack.gemspec index 75ca531..fd7cac2 100644 --- a/rack-attack.gemspec +++ b/rack-attack.gemspec @@ -14,7 +14,7 @@ Gem::Specification.new do |s| s.description = "A rack middleware for throttling and blocking abusive requests" s.email = "aaron@ktheory.com" - s.files = Dir.glob("{bin,lib}/**/*") + %w(Rakefile README.md) + s.files = Dir.glob("{bin,lib}/**/*") + %w(Rakefile README.md LICENSE) s.homepage = 'https://github.com/rack/rack-attack' s.rdoc_options = ["--charset=UTF-8"] s.require_paths = ["lib"] From 8bf9d4efad0fb9e6409f32119a4de66c1baa8f81 Mon Sep 17 00:00:00 2001 From: Gonzalo Date: Sat, 29 Jan 2022 15:06:13 -0300 Subject: [PATCH 5/7] refactor: attempt to make method name more self explanatory and clear --- README.md | 9 ++++---- lib/rack/attack.rb | 12 +++++----- lib/rack/attack/configuration.rb | 22 +++++++++---------- .../customizing_blocked_response_spec.rb | 4 ++-- .../customizing_throttled_response_spec.rb | 4 ++-- spec/rack_attack_spec.rb | 8 +++---- 6 files changed, 29 insertions(+), 30 deletions(-) diff --git a/README.md b/README.md index 5a0fa25..d6ae610 100644 --- a/README.md +++ b/README.md @@ -315,13 +315,13 @@ Note that `Rack::Attack.cache` is only used for throttling, allow2ban and fail2b Customize the response of blocklisted and throttled requests using an object that adheres to the [Rack app interface](http://www.rubydoc.info/github/rack/rack/file/SPEC.rdoc). ```ruby -Rack::Attack.blocklisted_callback = lambda do |request| +Rack::Attack.blocklisted_responder = lambda do |request| # Using 503 because it may make attacker think that they have successfully # DOSed the site. Rack::Attack returns 403 for blocklists by default [ 503, {}, ['Blocked']] end -Rack::Attack.throttled_callback = lambda do |request| +Rack::Attack.throttled_responder = lambda do |request| # NB: you have access to the name and other data about the matched throttle # request.env['rack.attack.matched'], # request.env['rack.attack.match_type'], @@ -427,10 +427,9 @@ def call(env) if safelisted?(req) @app.call(env) elsif blocklisted?(req) - self.class.blocklisted_callback.call(req) + self.class.blocklisted_responder.call(req) elsif throttled?(req) - self.class.throttled_response.call(env) - self.class.throttled_callback.call(req) + self.class.throttled_responder.call(req) else tracked?(req) @app.call(env) diff --git a/lib/rack/attack.rb b/lib/rack/attack.rb index bc9dbed..9b13416 100644 --- a/lib/rack/attack.rb +++ b/lib/rack/attack.rb @@ -66,10 +66,10 @@ module Rack :safelist_ip, :throttle, :track, - :throttled_callback, - :throttled_callback=, - :blocklisted_callback, - :blocklisted_callback=, + :throttled_responder, + :throttled_responder=, + :blocklisted_responder, + :blocklisted_responder=, :blocklisted_response, :blocklisted_response=, :throttled_response, @@ -113,14 +113,14 @@ module Rack if configuration.blocklisted_response configuration.blocklisted_response.call(env) else - configuration.blocklisted_callback.call(request) + configuration.blocklisted_responder.call(request) end elsif configuration.throttled?(request) # Deprecated: Keeping throttled_response for backwards compatibility if configuration.throttled_response configuration.throttled_response.call(env) else - configuration.throttled_callback.call(request) + configuration.throttled_responder.call(request) end else configuration.tracked?(request) diff --git a/lib/rack/attack/configuration.rb b/lib/rack/attack/configuration.rb index c609310..67bcc61 100644 --- a/lib/rack/attack/configuration.rb +++ b/lib/rack/attack/configuration.rb @@ -5,9 +5,9 @@ require "ipaddr" module Rack class Attack class Configuration - DEFAULT_BLOCKLISTED_CALLBACK = lambda { |_req| [403, { 'Content-Type' => 'text/plain' }, ["Forbidden\n"]] } + DEFAULT_BLOCKLISTED_RESPONDER = lambda { |_req| [403, { 'Content-Type' => 'text/plain' }, ["Forbidden\n"]] } - DEFAULT_THROTTLED_CALLBACK = lambda do |req| + DEFAULT_THROTTLED_RESPONDER = lambda do |req| if Rack::Attack.configuration.throttled_response_retry_after_header match_data = req.env['rack.attack.match_data'] now = match_data[:epoch_time] @@ -20,22 +20,22 @@ module Rack end attr_reader :safelists, :blocklists, :throttles, :anonymous_blocklists, :anonymous_safelists - attr_accessor :blocklisted_callback, :throttled_callback, :throttled_response_retry_after_header + attr_accessor :blocklisted_responder, :throttled_responder, :throttled_response_retry_after_header attr_reader :blocklisted_response, :throttled_response # Keeping these for backwards compatibility - def blocklisted_response=(callback) + def blocklisted_response=(responder) # TODO: uncomment in 7.0 # warn "[DEPRECATION] Rack::Attack.blocklisted_response is deprecated. "\ - # "Please use Rack::Attack.blocklisted_callback instead." - @blocklisted_response = callback + # "Please use Rack::Attack.blocklisted_responder instead." + @blocklisted_response = responder end - def throttled_response=(callback) + def throttled_response=(responder) # TODO: uncomment in 7.0 # warn "[DEPRECATION] Rack::Attack.throttled_response is deprecated. "\ - # "Please use Rack::Attack.throttled_callback instead" - @throttled_response = callback + # "Please use Rack::Attack.throttled_responder instead" + @throttled_response = responder end def initialize @@ -115,8 +115,8 @@ module Rack @anonymous_safelists = [] @throttled_response_retry_after_header = false - @blocklisted_callback = DEFAULT_BLOCKLISTED_CALLBACK - @throttled_callback = DEFAULT_THROTTLED_CALLBACK + @blocklisted_responder = DEFAULT_BLOCKLISTED_RESPONDER + @throttled_responder = DEFAULT_THROTTLED_RESPONDER # Deprecated: Keeping these for backwards compatibility @blocklisted_response = nil diff --git a/spec/acceptance/customizing_blocked_response_spec.rb b/spec/acceptance/customizing_blocked_response_spec.rb index 9a53862..86fcd02 100644 --- a/spec/acceptance/customizing_blocked_response_spec.rb +++ b/spec/acceptance/customizing_blocked_response_spec.rb @@ -14,7 +14,7 @@ describe "Customizing block responses" do assert_equal 403, last_response.status - Rack::Attack.blocklisted_callback = lambda do |_req| + Rack::Attack.blocklisted_responder = lambda do |_req| [503, {}, ["Blocked"]] end @@ -28,7 +28,7 @@ describe "Customizing block responses" do matched = nil match_type = nil - Rack::Attack.blocklisted_callback = lambda do |req| + Rack::Attack.blocklisted_responder = lambda do |req| matched = req.env['rack.attack.matched'] match_type = req.env['rack.attack.match_type'] diff --git a/spec/acceptance/customizing_throttled_response_spec.rb b/spec/acceptance/customizing_throttled_response_spec.rb index df875ec..39a3950 100644 --- a/spec/acceptance/customizing_throttled_response_spec.rb +++ b/spec/acceptance/customizing_throttled_response_spec.rb @@ -20,7 +20,7 @@ describe "Customizing throttled response" do assert_equal 429, last_response.status - Rack::Attack.throttled_callback = lambda do |_req| + Rack::Attack.throttled_responder = lambda do |_req| [503, {}, ["Throttled"]] end @@ -36,7 +36,7 @@ describe "Customizing throttled response" do match_data = nil match_discriminator = nil - Rack::Attack.throttled_callback = lambda do |req| + Rack::Attack.throttled_responder = lambda do |req| matched = req.env['rack.attack.matched'] match_type = req.env['rack.attack.match_type'] match_data = req.env['rack.attack.match_data'] diff --git a/spec/rack_attack_spec.rb b/spec/rack_attack_spec.rb index c55fa20..c835835 100644 --- a/spec/rack_attack_spec.rb +++ b/spec/rack_attack_spec.rb @@ -64,15 +64,15 @@ describe 'Rack::Attack' do end end - describe '#blocklisted_callback' do + describe '#blocklisted_responder' do it 'should exist' do - _(Rack::Attack.blocklisted_callback).must_respond_to :call + _(Rack::Attack.blocklisted_responder).must_respond_to :call end end - describe '#throttled_callback' do + describe '#throttled_responder' do it 'should exist' do - _(Rack::Attack.throttled_callback).must_respond_to :call + _(Rack::Attack.throttled_responder).must_respond_to :call end end end From aaeff6d0ae7d06a97c3f438321dea3edbca55acd Mon Sep 17 00:00:00 2001 From: Gonzalo Date: Sat, 29 Jan 2022 15:09:54 -0300 Subject: [PATCH 6/7] feat: deprecate throttled_response and blocklisted_response --- lib/rack/attack/configuration.rb | 10 ++++------ spec/acceptance/customizing_blocked_response_spec.rb | 6 ++++-- spec/acceptance/customizing_throttled_response_spec.rb | 6 ++++-- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/lib/rack/attack/configuration.rb b/lib/rack/attack/configuration.rb index 67bcc61..ba353ab 100644 --- a/lib/rack/attack/configuration.rb +++ b/lib/rack/attack/configuration.rb @@ -25,16 +25,14 @@ module Rack attr_reader :blocklisted_response, :throttled_response # Keeping these for backwards compatibility def blocklisted_response=(responder) - # TODO: uncomment in 7.0 - # warn "[DEPRECATION] Rack::Attack.blocklisted_response is deprecated. "\ - # "Please use Rack::Attack.blocklisted_responder instead." + warn "[DEPRECATION] Rack::Attack.blocklisted_response is deprecated. "\ + "Please use Rack::Attack.blocklisted_responder instead." @blocklisted_response = responder end def throttled_response=(responder) - # TODO: uncomment in 7.0 - # warn "[DEPRECATION] Rack::Attack.throttled_response is deprecated. "\ - # "Please use Rack::Attack.throttled_responder instead" + warn "[DEPRECATION] Rack::Attack.throttled_response is deprecated. "\ + "Please use Rack::Attack.throttled_responder instead" @throttled_response = responder end diff --git a/spec/acceptance/customizing_blocked_response_spec.rb b/spec/acceptance/customizing_blocked_response_spec.rb index 86fcd02..1ca127c 100644 --- a/spec/acceptance/customizing_blocked_response_spec.rb +++ b/spec/acceptance/customizing_blocked_response_spec.rb @@ -46,8 +46,10 @@ describe "Customizing block responses" do assert_equal 403, last_response.status - Rack::Attack.blocklisted_response = lambda do |_env| - [503, {}, ["Blocked"]] + silence_warnings do + Rack::Attack.blocklisted_response = lambda do |_env| + [503, {}, ["Blocked"]] + end end get "/", {}, "REMOTE_ADDR" => "1.2.3.4" diff --git a/spec/acceptance/customizing_throttled_response_spec.rb b/spec/acceptance/customizing_throttled_response_spec.rb index 39a3950..0990975 100644 --- a/spec/acceptance/customizing_throttled_response_spec.rb +++ b/spec/acceptance/customizing_throttled_response_spec.rb @@ -68,8 +68,10 @@ describe "Customizing throttled response" do assert_equal 429, last_response.status - Rack::Attack.throttled_response = lambda do |_req| - [503, {}, ["Throttled"]] + silence_warnings do + Rack::Attack.throttled_response = lambda do |_req| + [503, {}, ["Throttled"]] + end end get "/", {}, "REMOTE_ADDR" => "1.2.3.4" From 501ab01573e0aadfc0b2e66fcdfdabc0cea8ff17 Mon Sep 17 00:00:00 2001 From: Gonzalo Date: Sat, 29 Jan 2022 15:36:51 -0300 Subject: [PATCH 7/7] ci: run tests against ruby 3.1 --- .github/workflows/build.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 00b806a..22a09c4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,6 +17,7 @@ jobs: strategy: matrix: ruby: + - 3.1.0 - 3.0.3 - 2.7.5 - 2.6.9 @@ -38,6 +39,14 @@ jobs: - redis_store - active_support_redis_store exclude: + - gemfile: rack_1 + ruby: 3.1.0 + - gemfile: rails_5_2 + ruby: 3.1.0 + - gemfile: rails_4_2 + ruby: 3.1.0 + - gemfile: dalli2 + ruby: 3.1.0 - gemfile: rack_1 ruby: 3.0.3 - gemfile: rails_5_2