rack-attack 5.4.0 → 6.2.0
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 +4 -4
- data/README.md +78 -27
- data/Rakefile +3 -1
- data/bin/setup +8 -0
- data/lib/rack/attack.rb +137 -148
- data/lib/rack/attack/allow2ban.rb +2 -0
- data/lib/rack/attack/blocklist.rb +3 -1
- data/lib/rack/attack/cache.rb +9 -4
- data/lib/rack/attack/check.rb +5 -2
- data/lib/rack/attack/fail2ban.rb +2 -0
- data/lib/rack/attack/path_normalizer.rb +22 -18
- data/lib/rack/attack/railtie.rb +21 -0
- data/lib/rack/attack/request.rb +2 -0
- data/lib/rack/attack/safelist.rb +3 -1
- data/lib/rack/attack/store_proxy.rb +12 -24
- data/lib/rack/attack/store_proxy/active_support_redis_store_proxy.rb +39 -0
- data/lib/rack/attack/store_proxy/dalli_proxy.rb +27 -13
- data/lib/rack/attack/store_proxy/mem_cache_store_proxy.rb +21 -0
- data/lib/rack/attack/store_proxy/redis_cache_store_proxy.rb +23 -9
- data/lib/rack/attack/store_proxy/redis_proxy.rb +16 -10
- data/lib/rack/attack/store_proxy/redis_store_proxy.rb +5 -5
- data/lib/rack/attack/throttle.rb +12 -8
- data/lib/rack/attack/track.rb +9 -6
- data/lib/rack/attack/version.rb +3 -1
- data/spec/acceptance/allow2ban_spec.rb +2 -0
- data/spec/acceptance/blocking_ip_spec.rb +4 -2
- data/spec/acceptance/blocking_spec.rb +45 -3
- data/spec/acceptance/blocking_subnet_spec.rb +4 -2
- data/spec/acceptance/cache_store_config_for_allow2ban_spec.rb +50 -39
- data/spec/acceptance/cache_store_config_for_fail2ban_spec.rb +38 -29
- data/spec/acceptance/cache_store_config_for_throttle_spec.rb +2 -0
- data/spec/acceptance/cache_store_config_with_rails_spec.rb +2 -0
- data/spec/acceptance/customizing_blocked_response_spec.rb +2 -0
- data/spec/acceptance/customizing_throttled_response_spec.rb +2 -0
- data/spec/acceptance/extending_request_object_spec.rb +2 -0
- data/spec/acceptance/fail2ban_spec.rb +2 -0
- data/spec/acceptance/rails_middleware_spec.rb +41 -0
- data/spec/acceptance/safelisting_ip_spec.rb +4 -2
- data/spec/acceptance/safelisting_spec.rb +57 -3
- data/spec/acceptance/safelisting_subnet_spec.rb +4 -2
- data/spec/acceptance/stores/active_support_dalli_store_spec.rb +3 -23
- data/spec/acceptance/stores/active_support_mem_cache_store_pooled_spec.rb +20 -0
- data/spec/acceptance/stores/active_support_mem_cache_store_spec.rb +4 -24
- data/spec/acceptance/stores/active_support_memory_store_spec.rb +3 -23
- data/spec/acceptance/stores/active_support_redis_cache_store_pooled_spec.rb +10 -24
- data/spec/acceptance/stores/active_support_redis_cache_store_spec.rb +9 -25
- data/spec/acceptance/stores/active_support_redis_store_spec.rb +4 -24
- data/spec/acceptance/stores/connection_pool_dalli_client_spec.rb +5 -23
- data/spec/acceptance/stores/dalli_client_spec.rb +3 -23
- data/spec/acceptance/stores/redis_spec.rb +1 -23
- data/spec/acceptance/stores/redis_store_spec.rb +3 -23
- data/spec/acceptance/throttling_spec.rb +7 -5
- data/spec/acceptance/track_spec.rb +5 -3
- data/spec/acceptance/track_throttle_spec.rb +5 -3
- data/spec/allow2ban_spec.rb +20 -15
- data/spec/fail2ban_spec.rb +20 -17
- data/spec/integration/offline_spec.rb +3 -1
- data/spec/rack_attack_dalli_proxy_spec.rb +2 -0
- data/spec/rack_attack_instrumentation_spec.rb +42 -0
- data/spec/rack_attack_path_normalizer_spec.rb +4 -2
- data/spec/rack_attack_request_spec.rb +2 -0
- data/spec/rack_attack_spec.rb +38 -34
- data/spec/rack_attack_throttle_spec.rb +50 -19
- data/spec/rack_attack_track_spec.rb +12 -7
- data/spec/spec_helper.rb +10 -8
- data/spec/support/cache_store_helper.rb +27 -1
- metadata +48 -28
- data/lib/rack/attack/store_proxy/mem_cache_proxy.rb +0 -50
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "../../spec_helper"
|
2
4
|
|
3
5
|
if defined?(::Dalli) && defined?(::ConnectionPool)
|
@@ -15,28 +17,8 @@ if defined?(::Dalli) && defined?(::ConnectionPool)
|
|
15
17
|
Rack::Attack.cache.store.with { |client| client.flush_all }
|
16
18
|
end
|
17
19
|
|
18
|
-
it_works_for_cache_backed_features
|
19
|
-
|
20
|
-
|
21
|
-
Rack::Attack.throttle("by ip", limit: 1, period: 1) do |request|
|
22
|
-
request.ip
|
23
|
-
end
|
24
|
-
|
25
|
-
key = nil
|
26
|
-
|
27
|
-
# Freeze time during these statement to be sure that the key used by rack attack is the same
|
28
|
-
# we pre-calculate in local variable `key`
|
29
|
-
Timecop.freeze do
|
30
|
-
key = "rack::attack:#{Time.now.to_i}:by ip:1.2.3.4"
|
31
|
-
|
32
|
-
get "/", {}, "REMOTE_ADDR" => "1.2.3.4"
|
33
|
-
end
|
34
|
-
|
35
|
-
assert(Rack::Attack.cache.store.with { |client| client.fetch(key) })
|
36
|
-
|
37
|
-
sleep 2.1
|
38
|
-
|
39
|
-
assert_nil(Rack::Attack.cache.store.with { |client| client.fetch(key) })
|
40
|
-
end
|
20
|
+
it_works_for_cache_backed_features(
|
21
|
+
fetch_from_store: ->(key) { Rack::Attack.cache.store.with { |client| client.fetch(key) } }
|
22
|
+
)
|
41
23
|
end
|
42
24
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "../../spec_helper"
|
2
4
|
|
3
5
|
if defined?(::Dalli)
|
@@ -14,28 +16,6 @@ if defined?(::Dalli)
|
|
14
16
|
Rack::Attack.cache.store.flush_all
|
15
17
|
end
|
16
18
|
|
17
|
-
it_works_for_cache_backed_features
|
18
|
-
|
19
|
-
it "doesn't leak keys" do
|
20
|
-
Rack::Attack.throttle("by ip", limit: 1, period: 1) do |request|
|
21
|
-
request.ip
|
22
|
-
end
|
23
|
-
|
24
|
-
key = nil
|
25
|
-
|
26
|
-
# Freeze time during these statement to be sure that the key used by rack attack is the same
|
27
|
-
# we pre-calculate in local variable `key`
|
28
|
-
Timecop.freeze do
|
29
|
-
key = "rack::attack:#{Time.now.to_i}:by ip:1.2.3.4"
|
30
|
-
|
31
|
-
get "/", {}, "REMOTE_ADDR" => "1.2.3.4"
|
32
|
-
end
|
33
|
-
|
34
|
-
assert Rack::Attack.cache.store.fetch(key)
|
35
|
-
|
36
|
-
sleep 2.1
|
37
|
-
|
38
|
-
assert_nil Rack::Attack.cache.store.fetch(key)
|
39
|
-
end
|
19
|
+
it_works_for_cache_backed_features(fetch_from_store: ->(key) { Rack::Attack.cache.store.fetch(key) })
|
40
20
|
end
|
41
21
|
end
|
@@ -15,28 +15,6 @@ if defined?(::Redis)
|
|
15
15
|
Rack::Attack.cache.store.flushdb
|
16
16
|
end
|
17
17
|
|
18
|
-
it_works_for_cache_backed_features
|
19
|
-
|
20
|
-
it "doesn't leak keys" do
|
21
|
-
Rack::Attack.throttle("by ip", limit: 1, period: 1) do |request|
|
22
|
-
request.ip
|
23
|
-
end
|
24
|
-
|
25
|
-
key = nil
|
26
|
-
|
27
|
-
# Freeze time during these statement to be sure that the key used by rack attack is the same
|
28
|
-
# we pre-calculate in local variable `key`
|
29
|
-
Timecop.freeze do
|
30
|
-
key = "rack::attack:#{Time.now.to_i}:by ip:1.2.3.4"
|
31
|
-
|
32
|
-
get "/", {}, "REMOTE_ADDR" => "1.2.3.4"
|
33
|
-
end
|
34
|
-
|
35
|
-
assert Rack::Attack.cache.store.get(key)
|
36
|
-
|
37
|
-
sleep 2.1
|
38
|
-
|
39
|
-
assert_nil Rack::Attack.cache.store.get(key)
|
40
|
-
end
|
18
|
+
it_works_for_cache_backed_features(fetch_from_store: ->(key) { Rack::Attack.cache.store.get(key) })
|
41
19
|
end
|
42
20
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "../../spec_helper"
|
2
4
|
require_relative "../../support/cache_store_helper"
|
3
5
|
|
@@ -13,28 +15,6 @@ if defined?(::Redis::Store)
|
|
13
15
|
Rack::Attack.cache.store.flushdb
|
14
16
|
end
|
15
17
|
|
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.read(key)
|
34
|
-
|
35
|
-
sleep 2.1
|
36
|
-
|
37
|
-
assert_nil Rack::Attack.cache.store.read(key)
|
38
|
-
end
|
18
|
+
it_works_for_cache_backed_features(fetch_from_store: ->(key) { Rack::Attack.cache.store.read(key) })
|
39
19
|
end
|
40
20
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "../spec_helper"
|
2
4
|
require "timecop"
|
3
5
|
|
@@ -123,11 +125,11 @@ describe "#throttle" do
|
|
123
125
|
notification_data = nil
|
124
126
|
notification_discriminator = nil
|
125
127
|
|
126
|
-
ActiveSupport::Notifications.subscribe("
|
127
|
-
notification_matched = request.env["rack.attack.matched"]
|
128
|
-
notification_type = request.env["rack.attack.match_type"]
|
129
|
-
notification_data = request.env['rack.attack.match_data']
|
130
|
-
notification_discriminator = request.env['rack.attack.match_discriminator']
|
128
|
+
ActiveSupport::Notifications.subscribe("throttle.rack_attack") do |_name, _start, _finish, _id, payload|
|
129
|
+
notification_matched = payload[:request].env["rack.attack.matched"]
|
130
|
+
notification_type = payload[:request].env["rack.attack.match_type"]
|
131
|
+
notification_data = payload[:request].env['rack.attack.match_data']
|
132
|
+
notification_discriminator = payload[:request].env['rack.attack.match_discriminator']
|
131
133
|
end
|
132
134
|
|
133
135
|
get "/", {}, "REMOTE_ADDR" => "5.6.7.8"
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "../spec_helper"
|
2
4
|
|
3
5
|
describe "#track" do
|
@@ -9,9 +11,9 @@ describe "#track" do
|
|
9
11
|
notification_matched = nil
|
10
12
|
notification_type = nil
|
11
13
|
|
12
|
-
ActiveSupport::Notifications.subscribe("
|
13
|
-
notification_matched = request.env["rack.attack.matched"]
|
14
|
-
notification_type = request.env["rack.attack.match_type"]
|
14
|
+
ActiveSupport::Notifications.subscribe("track.rack_attack") do |_name, _start, _finish, _id, payload|
|
15
|
+
notification_matched = payload[:request].env["rack.attack.matched"]
|
16
|
+
notification_type = payload[:request].env["rack.attack.match_type"]
|
15
17
|
end
|
16
18
|
|
17
19
|
get "/", {}, "REMOTE_ADDR" => "5.6.7.8"
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "../spec_helper"
|
2
4
|
require "timecop"
|
3
5
|
|
@@ -12,9 +14,9 @@ describe "#track with throttle-ish options" do
|
|
12
14
|
notification_matched = nil
|
13
15
|
notification_type = nil
|
14
16
|
|
15
|
-
ActiveSupport::Notifications.subscribe("
|
16
|
-
notification_matched = request.env["rack.attack.matched"]
|
17
|
-
notification_type = request.env["rack.attack.match_type"]
|
17
|
+
ActiveSupport::Notifications.subscribe("track.rack_attack") do |_name, _start, _finish, _id, payload|
|
18
|
+
notification_matched = payload[:request].env["rack.attack.matched"]
|
19
|
+
notification_type = payload[:request].env["rack.attack.match_type"]
|
18
20
|
end
|
19
21
|
|
20
22
|
get "/", {}, "REMOTE_ADDR" => "1.2.3.4"
|
data/spec/allow2ban_spec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'spec_helper'
|
2
4
|
|
3
5
|
describe 'Rack::Attack.Allow2Ban' do
|
@@ -7,7 +9,7 @@ describe 'Rack::Attack.Allow2Ban' do
|
|
7
9
|
@findtime = 60
|
8
10
|
@bantime = 60
|
9
11
|
Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new
|
10
|
-
@f2b_options = { :
|
12
|
+
@f2b_options = { bantime: @bantime, findtime: @findtime, maxretry: 2 }
|
11
13
|
|
12
14
|
Rack::Attack.blocklist('pentest') do |req|
|
13
15
|
Rack::Attack::Allow2Ban.filter(req.ip, @f2b_options) { req.query_string =~ /OMGHAX/ }
|
@@ -18,7 +20,8 @@ describe 'Rack::Attack.Allow2Ban' do
|
|
18
20
|
describe 'making ok request' do
|
19
21
|
it 'succeeds' do
|
20
22
|
get '/', {}, 'REMOTE_ADDR' => '1.2.3.4'
|
21
|
-
|
23
|
+
|
24
|
+
_(last_response.status).must_equal 200
|
22
25
|
end
|
23
26
|
end
|
24
27
|
|
@@ -27,17 +30,18 @@ describe 'Rack::Attack.Allow2Ban' do
|
|
27
30
|
before { get '/?foo=OMGHAX', {}, 'REMOTE_ADDR' => '1.2.3.4' }
|
28
31
|
|
29
32
|
it 'succeeds' do
|
30
|
-
last_response.status.must_equal 200
|
33
|
+
_(last_response.status).must_equal 200
|
31
34
|
end
|
32
35
|
|
33
36
|
it 'increases fail count' do
|
34
37
|
key = "rack::attack:#{Time.now.to_i / @findtime}:allow2ban:count:1.2.3.4"
|
35
|
-
|
38
|
+
|
39
|
+
_(@cache.store.read(key)).must_equal 1
|
36
40
|
end
|
37
41
|
|
38
42
|
it 'is not banned' do
|
39
43
|
key = "rack::attack:allow2ban:1.2.3.4"
|
40
|
-
@cache.store.read(key).must_be_nil
|
44
|
+
_(@cache.store.read(key)).must_be_nil
|
41
45
|
end
|
42
46
|
end
|
43
47
|
|
@@ -49,17 +53,17 @@ describe 'Rack::Attack.Allow2Ban' do
|
|
49
53
|
end
|
50
54
|
|
51
55
|
it 'succeeds' do
|
52
|
-
last_response.status.must_equal 200
|
56
|
+
_(last_response.status).must_equal 200
|
53
57
|
end
|
54
58
|
|
55
59
|
it 'increases fail count' do
|
56
60
|
key = "rack::attack:#{Time.now.to_i / @findtime}:allow2ban:count:1.2.3.4"
|
57
|
-
@cache.store.read(key).must_equal 2
|
61
|
+
_(@cache.store.read(key)).must_equal 2
|
58
62
|
end
|
59
63
|
|
60
64
|
it 'is banned' do
|
61
65
|
key = "rack::attack:allow2ban:ban:1.2.3.4"
|
62
|
-
@cache.store.read(key).must_equal 1
|
66
|
+
_(@cache.store.read(key)).must_equal 1
|
63
67
|
end
|
64
68
|
end
|
65
69
|
end
|
@@ -75,7 +79,8 @@ describe 'Rack::Attack.Allow2Ban' do
|
|
75
79
|
describe 'making request for other discriminator' do
|
76
80
|
it 'succeeds' do
|
77
81
|
get '/', {}, 'REMOTE_ADDR' => '2.2.3.4'
|
78
|
-
|
82
|
+
|
83
|
+
_(last_response.status).must_equal 200
|
79
84
|
end
|
80
85
|
end
|
81
86
|
|
@@ -85,17 +90,17 @@ describe 'Rack::Attack.Allow2Ban' do
|
|
85
90
|
end
|
86
91
|
|
87
92
|
it 'fails' do
|
88
|
-
last_response.status.must_equal 403
|
93
|
+
_(last_response.status).must_equal 403
|
89
94
|
end
|
90
95
|
|
91
96
|
it 'does not increase fail count' do
|
92
97
|
key = "rack::attack:#{Time.now.to_i / @findtime}:allow2ban:count:1.2.3.4"
|
93
|
-
@cache.store.read(key).must_equal 2
|
98
|
+
_(@cache.store.read(key)).must_equal 2
|
94
99
|
end
|
95
100
|
|
96
101
|
it 'is still banned' do
|
97
102
|
key = "rack::attack:allow2ban:ban:1.2.3.4"
|
98
|
-
@cache.store.read(key).must_equal 1
|
103
|
+
_(@cache.store.read(key)).must_equal 1
|
99
104
|
end
|
100
105
|
end
|
101
106
|
|
@@ -105,17 +110,17 @@ describe 'Rack::Attack.Allow2Ban' do
|
|
105
110
|
end
|
106
111
|
|
107
112
|
it 'fails' do
|
108
|
-
last_response.status.must_equal 403
|
113
|
+
_(last_response.status).must_equal 403
|
109
114
|
end
|
110
115
|
|
111
116
|
it 'does not increase fail count' do
|
112
117
|
key = "rack::attack:#{Time.now.to_i / @findtime}:allow2ban:count:1.2.3.4"
|
113
|
-
@cache.store.read(key).must_equal 2
|
118
|
+
_(@cache.store.read(key)).must_equal 2
|
114
119
|
end
|
115
120
|
|
116
121
|
it 'is still banned' do
|
117
122
|
key = "rack::attack:allow2ban:ban:1.2.3.4"
|
118
|
-
@cache.store.read(key).must_equal 1
|
123
|
+
_(@cache.store.read(key)).must_equal 1
|
119
124
|
end
|
120
125
|
end
|
121
126
|
end
|
data/spec/fail2ban_spec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative 'spec_helper'
|
2
4
|
|
3
5
|
describe 'Rack::Attack.Fail2Ban' do
|
@@ -7,7 +9,7 @@ describe 'Rack::Attack.Fail2Ban' do
|
|
7
9
|
@findtime = 60
|
8
10
|
@bantime = 60
|
9
11
|
Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new
|
10
|
-
@f2b_options = { :
|
12
|
+
@f2b_options = { bantime: @bantime, findtime: @findtime, maxretry: 2 }
|
11
13
|
|
12
14
|
Rack::Attack.blocklist('pentest') do |req|
|
13
15
|
Rack::Attack::Fail2Ban.filter(req.ip, @f2b_options) { req.query_string =~ /OMGHAX/ }
|
@@ -18,7 +20,7 @@ describe 'Rack::Attack.Fail2Ban' do
|
|
18
20
|
describe 'making ok request' do
|
19
21
|
it 'succeeds' do
|
20
22
|
get '/', {}, 'REMOTE_ADDR' => '1.2.3.4'
|
21
|
-
last_response.status.must_equal 200
|
23
|
+
_(last_response.status).must_equal 200
|
22
24
|
end
|
23
25
|
end
|
24
26
|
|
@@ -27,17 +29,17 @@ describe 'Rack::Attack.Fail2Ban' do
|
|
27
29
|
before { get '/?foo=OMGHAX', {}, 'REMOTE_ADDR' => '1.2.3.4' }
|
28
30
|
|
29
31
|
it 'fails' do
|
30
|
-
last_response.status.must_equal 403
|
32
|
+
_(last_response.status).must_equal 403
|
31
33
|
end
|
32
34
|
|
33
35
|
it 'increases fail count' do
|
34
36
|
key = "rack::attack:#{Time.now.to_i / @findtime}:fail2ban:count:1.2.3.4"
|
35
|
-
@cache.store.read(key).must_equal 1
|
37
|
+
_(@cache.store.read(key)).must_equal 1
|
36
38
|
end
|
37
39
|
|
38
40
|
it 'is not banned' do
|
39
41
|
key = "rack::attack:fail2ban:1.2.3.4"
|
40
|
-
@cache.store.read(key).must_be_nil
|
42
|
+
_(@cache.store.read(key)).must_be_nil
|
41
43
|
end
|
42
44
|
end
|
43
45
|
|
@@ -49,17 +51,17 @@ describe 'Rack::Attack.Fail2Ban' do
|
|
49
51
|
end
|
50
52
|
|
51
53
|
it 'fails' do
|
52
|
-
last_response.status.must_equal 403
|
54
|
+
_(last_response.status).must_equal 403
|
53
55
|
end
|
54
56
|
|
55
57
|
it 'increases fail count' do
|
56
58
|
key = "rack::attack:#{Time.now.to_i / @findtime}:fail2ban:count:1.2.3.4"
|
57
|
-
@cache.store.read(key).must_equal 2
|
59
|
+
_(@cache.store.read(key)).must_equal 2
|
58
60
|
end
|
59
61
|
|
60
62
|
it 'is banned' do
|
61
63
|
key = "rack::attack:fail2ban:ban:1.2.3.4"
|
62
|
-
@cache.store.read(key).must_equal 1
|
64
|
+
_(@cache.store.read(key)).must_equal 1
|
63
65
|
end
|
64
66
|
end
|
65
67
|
|
@@ -71,7 +73,7 @@ describe 'Rack::Attack.Fail2Ban' do
|
|
71
73
|
end
|
72
74
|
|
73
75
|
it 'succeeds' do
|
74
|
-
last_response.status.must_equal 200
|
76
|
+
_(last_response.status).must_equal 200
|
75
77
|
end
|
76
78
|
|
77
79
|
it 'resets fail count' do
|
@@ -80,7 +82,7 @@ describe 'Rack::Attack.Fail2Ban' do
|
|
80
82
|
end
|
81
83
|
|
82
84
|
it 'IP is not banned' do
|
83
|
-
Rack::Attack::Fail2Ban.banned?('1.2.3.4').must_equal false
|
85
|
+
_(Rack::Attack::Fail2Ban.banned?('1.2.3.4')).must_equal false
|
84
86
|
end
|
85
87
|
end
|
86
88
|
end
|
@@ -96,7 +98,8 @@ describe 'Rack::Attack.Fail2Ban' do
|
|
96
98
|
describe 'making request for other discriminator' do
|
97
99
|
it 'succeeds' do
|
98
100
|
get '/', {}, 'REMOTE_ADDR' => '2.2.3.4'
|
99
|
-
|
101
|
+
|
102
|
+
_(last_response.status).must_equal 200
|
100
103
|
end
|
101
104
|
end
|
102
105
|
|
@@ -106,17 +109,17 @@ describe 'Rack::Attack.Fail2Ban' do
|
|
106
109
|
end
|
107
110
|
|
108
111
|
it 'fails' do
|
109
|
-
last_response.status.must_equal 403
|
112
|
+
_(last_response.status).must_equal 403
|
110
113
|
end
|
111
114
|
|
112
115
|
it 'does not increase fail count' do
|
113
116
|
key = "rack::attack:#{Time.now.to_i / @findtime}:fail2ban:count:1.2.3.4"
|
114
|
-
@cache.store.read(key).must_equal 2
|
117
|
+
_(@cache.store.read(key)).must_equal 2
|
115
118
|
end
|
116
119
|
|
117
120
|
it 'is still banned' do
|
118
121
|
key = "rack::attack:fail2ban:ban:1.2.3.4"
|
119
|
-
@cache.store.read(key).must_equal 1
|
122
|
+
_(@cache.store.read(key)).must_equal 1
|
120
123
|
end
|
121
124
|
end
|
122
125
|
|
@@ -126,17 +129,17 @@ describe 'Rack::Attack.Fail2Ban' do
|
|
126
129
|
end
|
127
130
|
|
128
131
|
it 'fails' do
|
129
|
-
last_response.status.must_equal 403
|
132
|
+
_(last_response.status).must_equal 403
|
130
133
|
end
|
131
134
|
|
132
135
|
it 'does not increase fail count' do
|
133
136
|
key = "rack::attack:#{Time.now.to_i / @findtime}:fail2ban:count:1.2.3.4"
|
134
|
-
@cache.store.read(key).must_equal 2
|
137
|
+
_(@cache.store.read(key)).must_equal 2
|
135
138
|
end
|
136
139
|
|
137
140
|
it 'is still banned' do
|
138
141
|
key = "rack::attack:fail2ban:ban:1.2.3.4"
|
139
|
-
@cache.store.read(key).must_equal 1
|
142
|
+
_(@cache.store.read(key)).must_equal 1
|
140
143
|
end
|
141
144
|
end
|
142
145
|
end
|