Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions Appraisals
Original file line number Diff line number Diff line change
Expand Up @@ -42,26 +42,41 @@ end

appraise "active_support_8-1_redis_cache_store" do
gem "activesupport", "~> 8.1.0"
# Direct version requirement on connection_pool
# can be removed once https://github.com/rails/rails#56291 is fixed and released
gem "connection_pool", "~> 2.5"
gem "redis", "~> 5.0"
end

appraise "active_support_8-0_redis_cache_store" do
gem "activesupport", "~> 8.0.0"
# Direct version requirement on connection_pool
# can be removed once https://github.com/rails/rails#56291 is fixed and released
gem "connection_pool", "~> 2.5"
gem "redis", "~> 5.0"
end

appraise "active_support_7-2_redis_cache_store" do
gem "activesupport", "~> 7.2.0"
# Direct version requirement on connection_pool
# can be removed once https://github.com/rails/rails#56291 is fixed and released
gem "connection_pool", "~> 2.5"
gem "redis", "~> 5.0"
end

appraise "active_support_7-1_redis_cache_store" do
gem "activesupport", "~> 7.1.0"
# Direct version requirement on connection_pool
# can be removed once https://github.com/rails/rails#56291 is fixed and released
gem "connection_pool", "~> 2.5"
gem "redis", "~> 5.0"
end

appraise "active_support_7-0_redis_cache_store" do
gem "activesupport", "~> 7.0.0"
# Direct version requirement on connection_pool
# can be removed once https://github.com/rails/rails#56291 is fixed and released
gem "connection_pool", "~> 2.5"
gem "redis", "~> 5.0"
end

Expand Down
1 change: 1 addition & 0 deletions gemfiles/active_support_7_0_redis_cache_store.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
source "https://rubygems.org"

gem "activesupport", "~> 7.0.0"
gem "connection_pool", "~> 2.5"
gem "redis", "~> 5.0"

group :maintenance, optional: true do
Expand Down
1 change: 1 addition & 0 deletions gemfiles/active_support_7_1_redis_cache_store.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
source "https://rubygems.org"

gem "activesupport", "~> 7.1.0"
gem "connection_pool", "~> 2.5"
gem "redis", "~> 5.0"

group :maintenance, optional: true do
Expand Down
1 change: 1 addition & 0 deletions gemfiles/active_support_7_2_redis_cache_store.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
source "https://rubygems.org"

gem "activesupport", "~> 7.2.0"
gem "connection_pool", "~> 2.5"
gem "redis", "~> 5.0"

group :maintenance, optional: true do
Expand Down
1 change: 1 addition & 0 deletions gemfiles/active_support_8_0_redis_cache_store.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
source "https://rubygems.org"

gem "activesupport", "~> 8.0.0"
gem "connection_pool", "~> 2.5"
gem "redis", "~> 5.0"

group :maintenance, optional: true do
Expand Down
1 change: 1 addition & 0 deletions gemfiles/active_support_8_1_redis_cache_store.gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
source "https://rubygems.org"

gem "activesupport", "~> 8.1.0"
gem "connection_pool", "~> 2.5"
gem "redis", "~> 5.0"

group :maintenance, optional: true do
Expand Down
5 changes: 0 additions & 5 deletions rack-attack.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,4 @@ Gem::Specification.new do |s|
if RUBY_ENGINE == "ruby"
s.add_development_dependency 'byebug', '~> 11.0'
end

s.add_development_dependency "activesupport"
# Fix activesupport Direct version requirement on connection_pool
# can be removed once https://github.com/rails/rails/issues/56291 is ixed and released
s.add_development_dependency "connection_pool", "~> 2.5"
end
94 changes: 48 additions & 46 deletions spec/acceptance/allow2ban_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,71 +3,73 @@
require_relative "../spec_helper"
require "timecop"

describe "allow2ban" do
before do
Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new

Rack::Attack.blocklist("allow2ban pentesters") do |request|
Rack::Attack::Allow2Ban.filter(request.ip, maxretry: 2, findtime: 30, bantime: 60) do
request.path.include?("scarce-resource")
if defined?(::ActiveSupport::Cache::MemoryStore)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these tests shouldn't be tied to active support

describe "allow2ban" do
before do
Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new

Rack::Attack.blocklist("allow2ban pentesters") do |request|
Rack::Attack::Allow2Ban.filter(request.ip, maxretry: 2, findtime: 30, bantime: 60) do
request.path.include?("scarce-resource")
end
end
end
end

it "returns OK for many requests that doesn't match the filter" do
get "/"
assert_equal 200, last_response.status

get "/"
assert_equal 200, last_response.status
end
it "returns OK for many requests that doesn't match the filter" do
get "/"
assert_equal 200, last_response.status

it "returns OK for first request that matches the filter" do
get "/scarce-resource"
assert_equal 200, last_response.status
end
get "/"
assert_equal 200, last_response.status
end

it "forbids all access after reaching maxretry limit" do
get "/scarce-resource"
assert_equal 200, last_response.status
it "returns OK for first request that matches the filter" do
get "/scarce-resource"
assert_equal 200, last_response.status
end

get "/scarce-resource"
assert_equal 200, last_response.status
it "forbids all access after reaching maxretry limit" do
get "/scarce-resource"
assert_equal 200, last_response.status

get "/scarce-resource"
assert_equal 403, last_response.status
get "/scarce-resource"
assert_equal 200, last_response.status

get "/"
assert_equal 403, last_response.status
end
get "/scarce-resource"
assert_equal 403, last_response.status

it "restores access after bantime elapsed" do
get "/scarce-resource"
assert_equal 200, last_response.status
get "/"
assert_equal 403, last_response.status
end

get "/scarce-resource"
assert_equal 200, last_response.status
it "restores access after bantime elapsed" do
get "/scarce-resource"
assert_equal 200, last_response.status

get "/"
assert_equal 403, last_response.status
get "/scarce-resource"
assert_equal 200, last_response.status

Timecop.travel(60) do
get "/"
assert_equal 403, last_response.status

assert_equal 200, last_response.status
end
end
Timecop.travel(60) do
get "/"

it "does not forbid all access if maxrety condition is met but not within the findtime timespan" do
get "/scarce-resource"
assert_equal 200, last_response.status
assert_equal 200, last_response.status
end
end

Timecop.travel(31) do
it "does not forbid all access if maxrety condition is met but not within the findtime timespan" do
get "/scarce-resource"
assert_equal 200, last_response.status

get "/"
assert_equal 200, last_response.status
Timecop.travel(31) do
get "/scarce-resource"
assert_equal 200, last_response.status

get "/"
assert_equal 200, last_response.status
end
end
end
end
56 changes: 29 additions & 27 deletions spec/acceptance/blocking_ip_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,46 @@

require_relative "../spec_helper"

describe "Blocking an IP" do
let(:notifications) { [] }
if defined?(::ActiveSupport::Notifications)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these tests shouldn't be tied to active support

describe "Blocking an IP" do
let(:notifications) { [] }

before do
Rack::Attack.blocklist_ip("1.2.3.4")
end
before do
Rack::Attack.blocklist_ip("1.2.3.4")
end

it "forbids request if IP matches" do
get "/", {}, "REMOTE_ADDR" => "1.2.3.4"
it "forbids request if IP matches" do
get "/", {}, "REMOTE_ADDR" => "1.2.3.4"

assert_equal 403, last_response.status
end

it "succeeds if IP doesn't match" do
get "/", {}, "REMOTE_ADDR" => "5.6.7.8"
assert_equal 403, last_response.status
end

assert_equal 200, last_response.status
end
it "succeeds if IP doesn't match" do
get "/", {}, "REMOTE_ADDR" => "5.6.7.8"

it "succeeds if IP is missing" do
get "/", {}, "REMOTE_ADDR" => ""
assert_equal 200, last_response.status
end

assert_equal 200, last_response.status
end
it "succeeds if IP is missing" do
get "/", {}, "REMOTE_ADDR" => ""

it "notifies when the request is blocked" do
ActiveSupport::Notifications.subscribe("blocklist.rack_attack") do |_name, _start, _finish, _id, payload|
notifications.push(payload)
assert_equal 200, last_response.status
end

get "/", {}, "REMOTE_ADDR" => "5.6.7.8"
it "notifies when the request is blocked" do
ActiveSupport::Notifications.subscribe("blocklist.rack_attack") do |_name, _start, _finish, _id, payload|
notifications.push(payload)
end

assert notifications.empty?
get "/", {}, "REMOTE_ADDR" => "5.6.7.8"

get "/", {}, "REMOTE_ADDR" => "1.2.3.4"
assert notifications.empty?

assert_equal 1, notifications.size
notification = notifications.pop
assert_equal :blocklist, notification[:request].env["rack.attack.match_type"]
get "/", {}, "REMOTE_ADDR" => "1.2.3.4"

assert_equal 1, notifications.size
notification = notifications.pop
assert_equal :blocklist, notification[:request].env["rack.attack.match_type"]
end
end
end
Loading