rack-attack 5.3.0 → 5.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c8f4c760b1ff68e6fbe79cf7576cbe2e0cc79ef5e2734ff55e63b46665ed6731
4
- data.tar.gz: 75d7dd7fc98035d3961952582373af467fcfd225dac11af8db4aaf1cbaaf44b8
3
+ metadata.gz: f06d0fae1f4dc5d960274ca06a4da7be66a1180a3df051595c98813296e80e46
4
+ data.tar.gz: 32fa128bb61140836c8fcce73d1cd972c3987405e581a43dea2334d6ba05cfa7
5
5
  SHA512:
6
- metadata.gz: 53ecb94578ea2497b660ca508b572b8a1f9a5a40e986b4bc6f834e05f90ea49eb4e721aefe4bd431b26754aeb33440fa4b43cc204705c035e61ada8e79d543dc
7
- data.tar.gz: 22dbd120cdc634115f7096d5e9e4a44cc4ec97ae5dd11fc746b0e21e6b2ad860bb8bbd62c0bf7b7ee0f63d5803c568579b5569d3f849159751b25c236ede1520
6
+ metadata.gz: 7d7be10e1ddb908f07fb10aec414f47fcb9d23289eacd98a1a91e1f87ffa0212d63f424fff44bcfa0b0154263518d807e535bcd8791200c8dc290ea31bd4395e
7
+ data.tar.gz: c99bfe7df1e11591e80526fd17b414494ddaa797906a4cced2beca884fe51db9fe9ce9d4dd99ee92ac98921a35f87361944ca4d8895b83a86ccc442b6d5cae31
data/Rakefile CHANGED
@@ -2,6 +2,9 @@ require "rubygems"
2
2
  require "bundler/setup"
3
3
  require 'bundler/gem_tasks'
4
4
  require 'rake/testtask'
5
+ require "rubocop/rake_task"
6
+
7
+ RuboCop::RakeTask.new
5
8
 
6
9
  namespace :test do
7
10
  Rake::TestTask.new(:units) do |t|
@@ -20,4 +23,4 @@ end
20
23
  desc 'Run tests'
21
24
  task :test => %w[test:units test:integration test:acceptance]
22
25
 
23
- task :default => :test
26
+ task :default => [:rubocop, :test]
@@ -38,15 +38,15 @@ class Rack::Attack
38
38
  self.blocklists[name] = Blocklist.new(name, block)
39
39
  end
40
40
 
41
- def blocklist_ip(ip)
41
+ def blocklist_ip(ip_address)
42
42
  @ip_blocklists ||= []
43
- ip_blocklist_proc = lambda { |request| IPAddr.new(ip).include?(IPAddr.new(request.ip)) }
43
+ ip_blocklist_proc = lambda { |request| IPAddr.new(ip_address).include?(IPAddr.new(request.ip)) }
44
44
  @ip_blocklists << Blocklist.new(nil, ip_blocklist_proc)
45
45
  end
46
46
 
47
- def safelist_ip(ip)
47
+ def safelist_ip(ip_address)
48
48
  @ip_safelists ||= []
49
- ip_safelist_proc = lambda { |request| IPAddr.new(ip).include?(IPAddr.new(request.ip)) }
49
+ ip_safelist_proc = lambda { |request| IPAddr.new(ip_address).include?(IPAddr.new(request.ip)) }
50
50
  @ip_safelists << Safelist.new(nil, ip_safelist_proc)
51
51
  end
52
52
 
@@ -8,21 +8,26 @@ module Rack
8
8
  defined?(::ActiveSupport::Cache::RedisCacheStore) && store.is_a?(::ActiveSupport::Cache::RedisCacheStore)
9
9
  end
10
10
 
11
- def increment(name, amount, options = {})
12
- # Redis doesn't check expiration on the INCRBY command. See https://redis.io/commands/expire
13
- count = redis.pipelined do
14
- redis.incrby(name, amount)
15
- redis.expire(name, options[:expires_in]) if options[:expires_in]
11
+ def increment(name, amount = 1, options = {})
12
+ # RedisCacheStore#increment ignores options[:expires_in].
13
+ #
14
+ # So in order to workaround this we use RedisCacheStore#write (which sets expiration) to initialize
15
+ # the counter. After that we continue using the original RedisCacheStore#increment.
16
+ if options[:expires_in] && !read(name)
17
+ write(name, amount, options)
18
+
19
+ 1
20
+ else
21
+ super
16
22
  end
17
- count.first
18
23
  end
19
24
 
20
25
  def read(name, options = {})
21
- super(name, options.merge!({ raw: true }))
26
+ super(name, options.merge!(raw: true))
22
27
  end
23
28
 
24
29
  def write(name, value, options = {})
25
- super(name, value, options.merge!({ raw: true }))
30
+ super(name, value, options.merge!(raw: true))
26
31
  end
27
32
  end
28
33
  end
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  class Attack
3
- VERSION = '5.3.0'
3
+ VERSION = '5.3.1'
4
4
  end
5
5
  end
@@ -0,0 +1,40 @@
1
+ require_relative "../../spec_helper"
2
+ require_relative "../../support/cache_store_helper"
3
+
4
+ require "timecop"
5
+
6
+ if ActiveSupport.version >= Gem::Version.new("5.2.0")
7
+ describe "RedisCacheStore (pooled) as a cache backend" do
8
+ before do
9
+ Rack::Attack.cache.store = ActiveSupport::Cache::RedisCacheStore.new(pool_size: 2)
10
+ end
11
+
12
+ after do
13
+ Rack::Attack.cache.store.clear
14
+ end
15
+
16
+ it_works_for_cache_backed_features
17
+
18
+ it "doesn't leak keys" do
19
+ Rack::Attack.throttle("by ip", limit: 1, period: 1) do |request|
20
+ request.ip
21
+ end
22
+
23
+ key = nil
24
+
25
+ # Freeze time during these statement to be sure that the key used by rack attack is the same
26
+ # we pre-calculate in local variable `key`
27
+ Timecop.freeze do
28
+ key = "rack::attack:#{Time.now.to_i}:by ip:1.2.3.4"
29
+
30
+ get "/", {}, "REMOTE_ADDR" => "1.2.3.4"
31
+ end
32
+
33
+ assert Rack::Attack.cache.store.fetch(key)
34
+
35
+ sleep 2.1
36
+
37
+ assert_nil Rack::Attack.cache.store.fetch(key)
38
+ end
39
+ end
40
+ end
@@ -37,7 +37,7 @@ describe 'Rack::Attack.throttle' do
37
37
  it 'should tag the env' do
38
38
  last_request.env['rack.attack.matched'].must_equal 'ip/sec'
39
39
  last_request.env['rack.attack.match_type'].must_equal :throttle
40
- last_request.env['rack.attack.match_data'].must_equal({ :count => 2, :limit => 1, :period => @period })
40
+ last_request.env['rack.attack.match_data'].must_equal(:count => 2, :limit => 1, :period => @period)
41
41
  last_request.env['rack.attack.match_discriminator'].must_equal('1.2.3.4')
42
42
  end
43
43
 
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: 5.3.0
4
+ version: 5.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Suggs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-19 00:00:00.000000000 Z
11
+ date: 2018-06-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -212,14 +212,14 @@ dependencies:
212
212
  requirements:
213
213
  - - '='
214
214
  - !ruby/object:Gem::Version
215
- version: 0.55.0
215
+ version: 0.57.2
216
216
  type: :development
217
217
  prerelease: false
218
218
  version_requirements: !ruby/object:Gem::Requirement
219
219
  requirements:
220
220
  - - '='
221
221
  - !ruby/object:Gem::Version
222
- version: 0.55.0
222
+ version: 0.57.2
223
223
  - !ruby/object:Gem::Dependency
224
224
  name: timecop
225
225
  requirement: !ruby/object:Gem::Requirement
@@ -303,6 +303,7 @@ files:
303
303
  - spec/acceptance/safelisting_spec.rb
304
304
  - spec/acceptance/safelisting_subnet_spec.rb
305
305
  - spec/acceptance/stores/mem_cache_store_spec.rb
306
+ - spec/acceptance/stores/redis_cache_store_pooled_spec.rb
306
307
  - spec/acceptance/stores/redis_cache_store_spec.rb
307
308
  - spec/acceptance/throttling_spec.rb
308
309
  - spec/acceptance/track_spec.rb
@@ -367,6 +368,7 @@ test_files:
367
368
  - spec/acceptance/fail2ban_spec.rb
368
369
  - spec/acceptance/stores/mem_cache_store_spec.rb
369
370
  - spec/acceptance/stores/redis_cache_store_spec.rb
371
+ - spec/acceptance/stores/redis_cache_store_pooled_spec.rb
370
372
  - spec/acceptance/customizing_blocked_response_spec.rb
371
373
  - spec/spec_helper.rb
372
374
  - spec/allow2ban_spec.rb