Skip to content

Commit

Permalink
Merge branch 'main' into multiple-instances
Browse files Browse the repository at this point in the history
  • Loading branch information
santib authored May 4, 2024
2 parents f23dd26 + b6ce502 commit 5998db8
Show file tree
Hide file tree
Showing 35 changed files with 279 additions and 253 deletions.
7 changes: 7 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
version: 2

updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
21 changes: 11 additions & 10 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@ jobs:
ports:
- 11211:11211
strategy:
fail-fast: false
matrix:
ruby:
- '3.3'
- '3.2'
- '3.1'
- '3.0'
Expand All @@ -26,7 +28,6 @@ jobs:
gemfile:
- rack_3
- rack_2
- rack_1
- rails_7_1
- rails_7_0
- rails_6_1
Expand All @@ -47,8 +48,14 @@ jobs:
- active_support_5_redis_cache_store_pooled
- redis_store
exclude:
- gemfile: rack_1
ruby: '3.2'
- gemfile: rails_5_2
ruby: '3.3'
- gemfile: active_support_5_redis_cache_store
ruby: '3.3'
- gemfile: active_support_5_redis_cache_store_pooled
ruby: '3.3'
- gemfile: dalli2
ruby: '3.3'
- gemfile: rails_5_2
ruby: '3.2'
- gemfile: active_support_5_redis_cache_store
Expand All @@ -57,8 +64,6 @@ jobs:
ruby: '3.2'
- gemfile: dalli2
ruby: '3.2'
- gemfile: rack_1
ruby: '3.1'
- gemfile: rails_5_2
ruby: '3.1'
- gemfile: active_support_5_redis_cache_store
Expand All @@ -67,8 +72,6 @@ jobs:
ruby: '3.1'
- gemfile: dalli2
ruby: '3.1'
- gemfile: rack_1
ruby: '3.0'
- gemfile: rails_5_2
ruby: '3.0'
- gemfile: active_support_5_redis_cache_store
Expand All @@ -77,8 +80,6 @@ jobs:
ruby: '3.0'
- gemfile: dalli2
ruby: '3.0'
- gemfile: rack_1
ruby: '2.7'
- gemfile: rails_7_0
ruby: '2.6'
- gemfile: rails_7_0
Expand Down Expand Up @@ -106,7 +107,7 @@ jobs:
env:
BUNDLE_GEMFILE: gemfiles/${{ matrix.gemfile }}.gemfile
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
Expand Down
13 changes: 0 additions & 13 deletions Appraisals
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,6 @@ appraise "rack_2" do
gem "rack", "~> 2.0"
end

appraise "rack_1" do
# Override activesupport and actionpack version constraints by making
# it more loose so it's compatible with rack 1.6.x
gem "actionpack", ">= 4.2"
gem "activesupport", ">= 4.2"

gem "rack", "~> 1.6"

# Override rack-test version constraint by making it more loose
# so it's compatible with actionpack 4.2.x
gem "rack-test", ">= 0.6"
end

appraise 'rails_7-1' do
gem 'railties', '~> 7.1.0'
end
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ Rack::Attack.track("special_agent", limit: 6, period: 60) do |req|
end

# Track it using ActiveSupport::Notification
ActiveSupport::Notifications.subscribe("track.rack_attack") do |name, start, finish, request_id, payload|
ActiveSupport::Notifications.subscribe("track.rack_attack") do |name, start, finish, instrumenter_id, payload|
req = payload[:request]
if req.env['rack.attack.matched'] == "special_agent"
Rails.logger.info "special_agent: #{req.path}"
Expand Down Expand Up @@ -383,7 +383,7 @@ To get notified about specific type of events, subscribe to the event name follo
E.g. for throttles use:

```ruby
ActiveSupport::Notifications.subscribe("throttle.rack_attack") do |name, start, finish, request_id, payload|
ActiveSupport::Notifications.subscribe("throttle.rack_attack") do |name, start, finish, instrumenter_id, payload|
# request object available in payload[:request]

# Your code here
Expand All @@ -393,7 +393,7 @@ end
If you want to subscribe to every `rack_attack` event, use:

```ruby
ActiveSupport::Notifications.subscribe(/rack_attack/) do |name, start, finish, request_id, payload|
ActiveSupport::Notifications.subscribe(/rack_attack/) do |name, start, finish, instrumenter_id, payload|
# request object available in payload[:request]

# Your code here
Expand Down
15 changes: 0 additions & 15 deletions gemfiles/rack_1.gemfile

This file was deleted.

22 changes: 12 additions & 10 deletions lib/rack/attack/store_proxy/redis_cache_store_proxy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,19 @@ def self.handle?(store)
store.class.name == "ActiveSupport::Cache::RedisCacheStore"
end

def increment(name, amount = 1, **options)
# RedisCacheStore#increment ignores options[:expires_in].
#
# So in order to workaround this we use RedisCacheStore#write (which sets expiration) to initialize
# the counter. After that we continue using the original RedisCacheStore#increment.
if options[:expires_in] && !read(name)
write(name, amount, options)
if defined?(::ActiveSupport) && ::ActiveSupport::VERSION::MAJOR < 6
def increment(name, amount = 1, **options)
# RedisCacheStore#increment ignores options[:expires_in] in versions prior to 6.
#
# So in order to workaround this we use RedisCacheStore#write (which sets expiration) to initialize
# the counter. After that we continue using the original RedisCacheStore#increment.
if options[:expires_in] && !read(name)
write(name, amount, options)

amount
else
super
amount
else
super
end
end
end

Expand Down
15 changes: 7 additions & 8 deletions spec/acceptance/blocking_ip_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
require_relative "../spec_helper"

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

before do
Rack::Attack.blocklist_ip("1.2.3.4")
end
Expand All @@ -26,21 +28,18 @@
end

it "notifies when the request is blocked" do
notified = false
notification_type = nil

ActiveSupport::Notifications.subscribe("blocklist.rack_attack") do |_name, _start, _finish, _id, payload|
notified = true
notification_type = payload[:request].env["rack.attack.match_type"]
notifications.push(payload)
end

get "/", {}, "REMOTE_ADDR" => "5.6.7.8"

refute notified
assert notifications.empty?

get "/", {}, "REMOTE_ADDR" => "1.2.3.4"

assert notified
assert_equal :blocklist, notification_type
assert_equal 1, notifications.size
notification = notifications.pop
assert_equal :blocklist, notification[:request].env["rack.attack.match_type"]
end
end
34 changes: 16 additions & 18 deletions spec/acceptance/blocking_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
require_relative "../spec_helper"

describe "#blocklist" do
let(:notifications) { [] }

before do
Rack::Attack.blocklist do |request|
request.ip == "1.2.3.4"
Expand All @@ -22,27 +24,26 @@
end

it "notifies when the request is blocked" do
notification_matched = nil
notification_type = nil

ActiveSupport::Notifications.subscribe("rack.attack") do |_name, _start, _finish, _id, payload|
notification_matched = payload[:request].env["rack.attack.matched"]
notification_type = payload[:request].env["rack.attack.match_type"]
notifications.push(payload)
end

get "/", {}, "REMOTE_ADDR" => "5.6.7.8"

assert_nil notification_matched
assert_nil notification_type
assert notifications.empty?

get "/", {}, "REMOTE_ADDR" => "1.2.3.4"

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

describe "#blocklist with name" do
let(:notifications) { [] }

before do
Rack::Attack.blocklist("block 1.2.3.4") do |request|
request.ip == "1.2.3.4"
Expand All @@ -62,22 +63,19 @@
end

it "notifies when the request is blocked" do
notification_matched = nil
notification_type = nil

ActiveSupport::Notifications.subscribe("blocklist.rack_attack") do |_name, _start, _finish, _id, payload|
notification_matched = payload[:request].env["rack.attack.matched"]
notification_type = payload[:request].env["rack.attack.match_type"]
notifications.push(payload)
end

get "/", {}, "REMOTE_ADDR" => "5.6.7.8"

assert_nil notification_matched
assert_nil notification_type
assert notifications.empty?

get "/", {}, "REMOTE_ADDR" => "1.2.3.4"

assert_equal "block 1.2.3.4", notification_matched
assert_equal :blocklist, notification_type
assert_equal 1, notifications.size
notification = notifications.pop
assert_equal "block 1.2.3.4", notification[:request].env["rack.attack.matched"]
assert_equal :blocklist, notification[:request].env["rack.attack.match_type"]
end
end
15 changes: 7 additions & 8 deletions spec/acceptance/blocking_subnet_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
require_relative "../spec_helper"

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

before do
Rack::Attack.blocklist_ip("1.2.3.4/31")
end
Expand All @@ -26,21 +28,18 @@
end

it "notifies when the request is blocked" do
notified = false
notification_type = nil

ActiveSupport::Notifications.subscribe("blocklist.rack_attack") do |_name, _start, _finish, _id, payload|
notified = true
notification_type = payload[:request].env["rack.attack.match_type"]
notifications.push(payload)
end

get "/", {}, "REMOTE_ADDR" => "5.6.7.8"

refute notified
assert notifications.empty?

get "/", {}, "REMOTE_ADDR" => "1.2.3.4"

assert notified
assert_equal :blocklist, notification_type
assert_equal 1, notifications.size
notification = notifications.pop
assert_equal :blocklist, notification[:request].env["rack.attack.match_type"]
end
end
8 changes: 5 additions & 3 deletions spec/acceptance/cache_store_config_for_allow2ban_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@
end
end

it "gives semantic error if no store was configured" do
assert_raises(Rack::Attack::MissingStoreError) do
get "/scarce-resource"
unless defined?(Rails)
it "gives semantic error if no store was configured" do
assert_raises(Rack::Attack::MissingStoreError) do
get "/scarce-resource"
end
end
end

Expand Down
8 changes: 5 additions & 3 deletions spec/acceptance/cache_store_config_for_fail2ban_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,11 @@
end
end

it "gives semantic error if no store was configured" do
assert_raises(Rack::Attack::MissingStoreError) do
get "/private-place"
unless defined?(Rails)
it "gives semantic error if no store was configured" do
assert_raises(Rack::Attack::MissingStoreError) do
get "/private-place"
end
end
end

Expand Down
8 changes: 5 additions & 3 deletions spec/acceptance/cache_store_config_for_throttle_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
end
end

it "gives semantic error if no store was configured" do
assert_raises(Rack::Attack::MissingStoreError) do
get "/", {}, "REMOTE_ADDR" => "1.2.3.4"
unless defined?(Rails)
it "gives semantic error if no store was configured" do
assert_raises(Rack::Attack::MissingStoreError) do
get "/", {}, "REMOTE_ADDR" => "1.2.3.4"
end
end
end

Expand Down
10 changes: 6 additions & 4 deletions spec/acceptance/cache_store_config_with_rails_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@
end
end

it "fails when Rails.cache is not set" do
Object.stub_const(:Rails, OpenStruct.new(cache: nil)) do
assert_raises(Rack::Attack::MissingStoreError) do
get "/", {}, "REMOTE_ADDR" => "1.2.3.4"
unless defined?(Rails)
it "fails when Rails.cache is not set" do
Object.stub_const(:Rails, OpenStruct.new(cache: nil)) do
assert_raises(Rack::Attack::MissingStoreError) do
get "/", {}, "REMOTE_ADDR" => "1.2.3.4"
end
end
end
end
Expand Down
Loading

0 comments on commit 5998db8

Please sign in to comment.