Skip to content

Commit 95347e3

Browse files
authored
Merge pull request #431 from fatkodima/use-middleware
Auto plug middleware for simpler installation
2 parents e5ceab0 + f22b24c commit 95347e3

File tree

12 files changed

+111
-26
lines changed

12 files changed

+111
-26
lines changed

Appraisals

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,24 +17,20 @@ appraise "rack_1_6" do
1717
gem "rack-test", ">= 0.6"
1818
end
1919

20-
appraise 'rails_6_0' do
21-
gem 'actionpack', '~> 6.0.0'
22-
gem 'activesupport', '~> 6.0.0'
20+
appraise 'rails_6-0' do
21+
gem 'railties', '~> 6.0.0'
2322
end
2423

2524
appraise 'rails_5-2' do
26-
gem 'actionpack', '~> 5.2.0'
27-
gem 'activesupport', '~> 5.2.0'
25+
gem 'railties', '~> 5.2.0'
2826
end
2927

3028
appraise 'rails_5-1' do
31-
gem 'actionpack', '~> 5.1.0'
32-
gem 'activesupport', '~> 5.1.0'
29+
gem 'railties', '~> 5.1.0'
3330
end
3431

3532
appraise 'rails_4-2' do
36-
gem 'actionpack', '~> 4.2.0'
37-
gem 'activesupport', '~> 4.2.0'
33+
gem 'railties', '~> 4.2.0'
3834

3935
# Override rack-test version constraint by making it more loose
4036
# so it's compatible with actionpack 4.2.x

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,19 @@ Or install it yourself as:
6868

6969
Then tell your ruby web application to use rack-attack as a middleware.
7070

71-
a) For __rails__ applications:
72-
71+
a) For __rails__ applications with versions >= 5 it is used by default. For older rails versions you should enable it explicitly:
7372
```ruby
7473
# In config/application.rb
7574

7675
config.middleware.use Rack::Attack
7776
```
7877

78+
You can disable it permanently (like for specific environment) or temporarily (can be useful for specific test cases) by writing:
79+
80+
```ruby
81+
Rack::Attack.enabled = false
82+
```
83+
7984
b) For __rack__ applications:
8085

8186
```ruby

gemfiles/rails_4_2.gemfile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22

33
source "https://rubygems.org"
44

5-
gem "actionpack", "~> 4.2.0"
6-
gem "activesupport", "~> 4.2.0"
5+
gem "railties", "~> 4.2.0"
76
gem "rack-test", ">= 0.6"
87

98
gemspec path: "../"

gemfiles/rails_5_1.gemfile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
source "https://rubygems.org"
44

5-
gem "actionpack", "~> 5.1.0"
6-
gem "activesupport", "~> 5.1.0"
5+
gem "railties", "~> 5.1.0"
76

87
gemspec path: "../"

gemfiles/rails_5_2.gemfile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
source "https://rubygems.org"
44

5-
gem "actionpack", "~> 5.2.0"
6-
gem "activesupport", "~> 5.2.0"
5+
gem "railties", "~> 5.2.0"
76

87
gemspec path: "../"

gemfiles/rails_6_0.gemfile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
source "https://rubygems.org"
44

5-
gem "actionpack", "~> 6.0.0"
6-
gem "activesupport", "~> 6.0.0"
5+
gem "railties", "~> 6.0.0"
76

87
gemspec path: "../"

lib/rack/attack.rb

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
require 'rack/attack/request'
77
require "ipaddr"
88

9+
require 'rack/attack/railtie' if defined?(::Rails)
10+
911
module Rack
1012
class Attack
1113
class MisconfiguredStoreError < StandardError; end
@@ -28,7 +30,8 @@ class MissingStoreError < StandardError; end
2830
autoload :Allow2Ban, 'rack/attack/allow2ban'
2931

3032
class << self
31-
attr_accessor :notifier, :blocklisted_response, :throttled_response, :anonymous_blocklists, :anonymous_safelists
33+
attr_accessor :enabled, :notifier, :blocklisted_response, :throttled_response,
34+
:anonymous_blocklists, :anonymous_safelists
3235

3336
def safelist(name = nil, &block)
3437
safelist = Safelist.new(name, &block)
@@ -134,6 +137,7 @@ def clear!
134137
end
135138

136139
# Set defaults
140+
@enabled = true
137141
@anonymous_blocklists = []
138142
@anonymous_safelists = []
139143
@notifier = ActiveSupport::Notifications if defined?(ActiveSupport::Notifications)
@@ -148,6 +152,8 @@ def initialize(app)
148152
end
149153

150154
def call(env)
155+
return @app.call(env) unless self.class.enabled
156+
151157
env['PATH_INFO'] = PathNormalizer.normalize_path(env['PATH_INFO'])
152158
request = Rack::Attack::Request.new(env)
153159

lib/rack/attack/railtie.rb

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# frozen_string_literal: true
2+
3+
module Rack
4+
class Attack
5+
class Railtie < ::Rails::Railtie
6+
initializer 'rack.attack.middleware', after: :load_config_initializers, before: :build_middleware_stack do |app|
7+
if Gem::Version.new(::Rails::VERSION::STRING) >= Gem::Version.new("5")
8+
middlewares = app.config.middleware
9+
operations = middlewares.send(:operations) + middlewares.send(:delete_operations)
10+
11+
use_middleware = operations.none? do |operation|
12+
middleware = operation[1]
13+
middleware.include?(Rack::Attack)
14+
end
15+
16+
middlewares.use(Rack::Attack) if use_middleware
17+
end
18+
end
19+
end
20+
end
21+
end

rack-attack.gemspec

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,5 @@ Gem::Specification.new do |s|
4646
s.add_development_dependency 'byebug', '~> 11.0'
4747
end
4848

49-
# The following are potential runtime dependencies users may have,
50-
# which rack-attack uses only for testing compatibility in test suite.
51-
s.add_development_dependency 'actionpack', '~> 5.2'
52-
s.add_development_dependency 'activesupport', '~> 5.2'
49+
s.add_development_dependency 'railties', '>= 4.2'
5350
end
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# frozen_string_literal: true
2+
3+
require_relative "../spec_helper"
4+
5+
if defined?(Rails)
6+
describe "Middleware for Rails" do
7+
before do
8+
@app = Class.new(Rails::Application) do
9+
config.eager_load = false
10+
config.logger = Logger.new(nil) # avoid creating the log/ directory automatically
11+
config.cache_store = :null_store # avoid creating tmp/ directory for cache
12+
end
13+
end
14+
15+
if Gem::Version.new(Rails::VERSION::STRING) >= Gem::Version.new("5")
16+
it "is used by default" do
17+
@app.initialize!
18+
assert_equal 1, @app.middleware.count(Rack::Attack)
19+
end
20+
21+
it "is not added when it was added explicitly" do
22+
@app.config.middleware.use(Rack::Attack)
23+
@app.initialize!
24+
assert_equal 1, @app.middleware.count(Rack::Attack)
25+
end
26+
27+
it "is not added when it was explicitly deleted" do
28+
@app.config.middleware.delete(Rack::Attack)
29+
@app.initialize!
30+
refute @app.middleware.include?(Rack::Attack)
31+
end
32+
end
33+
34+
if Gem::Version.new(Rails::VERSION::STRING) < Gem::Version.new("5")
35+
it "is not used by default" do
36+
@app.initialize!
37+
assert_equal 0, @app.middleware.count(Rack::Attack)
38+
end
39+
end
40+
end
41+
end

0 commit comments

Comments
 (0)