rack-attack 4.0.1 → 4.1.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of rack-attack might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b2ad64c34913ec247b9f1952ec77a38762742151
4
- data.tar.gz: f953e23413add27445c65ef5d058afc0c5dc2cb7
3
+ metadata.gz: 459c5b823f0b03b1d839e5577d1d57fc14332d2c
4
+ data.tar.gz: e8e15fe0e7619b07a9710160cd429dab4499f6c1
5
5
  SHA512:
6
- metadata.gz: e2c8ebf7e34dae93d31c300ca035723794f1f185fecaa008fdf1f305697c6d1f36614ae6e5c1135be3722cbfd68b7ea1ef809d6f045f7858e6674dca837cbcc0
7
- data.tar.gz: 6b8d3632cae6db709922e400e681b7e0742067baaf3596957af962ab13be55a5a445fee534b40279ae19ab3f50ae2cd8776d473359e06d8889c4b8b5e0b3dab0
6
+ metadata.gz: 67aad493c5a2b719de12f17a099e9e3ffabfe32fb33ba2d11b9c8149918a78e300fad9c56b786fcca2e328f898a022f0da158becf81304eba42928f1119a5f74
7
+ data.tar.gz: 4cc797bcb7a7e88fe7b9df2c016b6aeb766dc71007d8124b3d3cd4b1e7da4e6d0695de0465f21afc798aafc81f0b6ac3dbe5f8cdc4f05e856bca49a69e49ce70
data/README.md CHANGED
@@ -39,7 +39,7 @@ use Rack::Attack
39
39
  Add a `rack-attack.rb` file to `config/initalizers/`:
40
40
  ```ruby
41
41
  # In config/initializers/rack-attack.rb
42
- module Rack::Attack
42
+ class Rack::Attack
43
43
  # your custom configuration...
44
44
  end
45
45
  ```
@@ -188,11 +188,16 @@ end
188
188
  ### Tracks
189
189
 
190
190
  ```ruby
191
- # Track requests from a special user agent
191
+ # Track requests from a special user agent.
192
192
  Rack::Attack.track("special_agent") do |req|
193
193
  req.user_agent == "SpecialAgent"
194
194
  end
195
195
 
196
+ # Supports optional limit and period, triggers the notification only when the limit is reached.
197
+ Rack::Attack.track("special_agent", :limit 6, :period => 60.seconds) do |req|
198
+ req.user_agent == "SpecialAgent"
199
+ end
200
+
196
201
  # Track it using ActiveSupport::Notification
197
202
  ActiveSupport::Notifications.subscribe("rack.attack") do |name, start, finish, request_id, req|
198
203
  if req.env['rack.attack.matched'] == "special_agent" && req.env['rack.attack.match_type'] == :track
@@ -31,8 +31,8 @@ class Rack::Attack
31
31
  self.throttles[name] = Throttle.new(name, options, block)
32
32
  end
33
33
 
34
- def track(name, &block)
35
- self.tracks[name] = Track.new(name, block)
34
+ def track(name, options = {}, &block)
35
+ self.tracks[name] = Track.new(name, options, block)
36
36
  end
37
37
 
38
38
  def whitelists; @whitelists ||= {}; end
@@ -73,17 +73,17 @@ class Rack::Attack
73
73
  end
74
74
 
75
75
  def clear!
76
- @whitelists, @blacklists, @throttles = {}, {}, {}
76
+ @whitelists, @blacklists, @throttles, @tracks = {}, {}, {}, {}
77
77
  end
78
78
 
79
79
  end
80
80
 
81
81
  # Set defaults
82
82
  @notifier = ActiveSupport::Notifications if defined?(ActiveSupport::Notifications)
83
- @blacklisted_response = lambda {|env| [403, {}, ["Forbidden\n"]] }
83
+ @blacklisted_response = lambda {|env| [403, {'Content-Type' => 'text/plain'}, ["Forbidden\n"]] }
84
84
  @throttled_response = lambda {|env|
85
85
  retry_after = env['rack.attack.match_data'][:period] rescue nil
86
- [429, {'Retry-After' => retry_after.to_s}, ["Retry later\n"]]
86
+ [429, {'Content-Type' => 'text/plain', 'Retry-After' => retry_after.to_s}, ["Retry later\n"]]
87
87
  }
88
88
 
89
89
  def initialize(app)
@@ -2,9 +2,9 @@ module Rack
2
2
  class Attack
3
3
  class Check
4
4
  attr_reader :name, :block, :type
5
- def initialize(name, block)
5
+ def initialize(name, options = {}, block)
6
6
  @name, @block = name, block
7
- @type = nil
7
+ @type = options.fetch(:type, nil)
8
8
  end
9
9
 
10
10
  def [](req)
@@ -2,7 +2,7 @@ module Rack
2
2
  class Attack
3
3
  class Throttle
4
4
  MANDATORY_OPTIONS = [:limit, :period]
5
- attr_reader :name, :limit, :period, :block
5
+ attr_reader :name, :limit, :period, :block, :type
6
6
  def initialize(name, options, block)
7
7
  @name, @block = name, block
8
8
  MANDATORY_OPTIONS.each do |opt|
@@ -10,6 +10,7 @@ module Rack
10
10
  end
11
11
  @limit = options[:limit]
12
12
  @period = options[:period].to_i
13
+ @type = options.fetch(:type, :throttle)
13
14
  end
14
15
 
15
16
  def cache
@@ -34,7 +35,7 @@ module Rack
34
35
  if throttled
35
36
  req.env['rack.attack.matched'] = name
36
37
  req.env['rack.attack.match_discriminator'] = discriminator
37
- req.env['rack.attack.match_type'] = :throttle
38
+ req.env['rack.attack.match_type'] = type
38
39
  req.env['rack.attack.match_data'] = data
39
40
  Rack::Attack.instrument(req)
40
41
  end
@@ -1,10 +1,21 @@
1
1
  module Rack
2
2
  class Attack
3
- class Track < Check
4
- def initialize(name, block)
5
- super
6
- @type = :track
3
+ class Track
4
+ extend Forwardable
5
+
6
+ attr_reader :filter
7
+
8
+ def initialize(name, options = {}, block)
9
+ options[:type] = :track
10
+
11
+ if options[:limit] && options[:period]
12
+ @filter = Throttle.new(name, options, block)
13
+ else
14
+ @filter = Check.new(name, options, block)
15
+ end
7
16
  end
17
+
18
+ def_delegator :@filter, :[]
8
19
  end
9
20
  end
10
21
  end
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  class Attack
3
- VERSION = '4.0.1'
3
+ VERSION = '4.1.0'
4
4
  end
5
5
  end
@@ -41,4 +41,18 @@ describe 'Rack::Attack.track' do
41
41
  Counter.check.must_equal 2
42
42
  end
43
43
  end
44
+
45
+ describe "without limit and period options" do
46
+ it "should assign the track filter to a Check instance" do
47
+ tracker = Rack::Attack.track("homepage") { |req| req.path == "/"}
48
+ tracker.filter.class.must_equal Rack::Attack::Check
49
+ end
50
+ end
51
+
52
+ describe "with limit and period options" do
53
+ it "should assign the track filter to a Throttle instance" do
54
+ tracker = Rack::Attack.track("homepage", :limit => 10, :period => 10) { |req| req.path == "/"}
55
+ tracker.filter.class.must_equal Rack::Attack::Throttle
56
+ end
57
+ end
44
58
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-attack
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.1
4
+ version: 4.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Suggs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-14 00:00:00.000000000 Z
11
+ date: 2014-05-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack