mirror of
https://github.com/samsonjs/rack-attack.git
synced 2026-03-25 09:25:49 +00:00
Merge pull request #262 from grzuy/legibility
Attempt to improve legibility
This commit is contained in:
commit
6f545e2665
7 changed files with 27 additions and 15 deletions
|
|
@ -1,4 +1,5 @@
|
|||
require_relative 'spec_helper'
|
||||
|
||||
describe 'Rack::Attack.Allow2Ban' do
|
||||
before do
|
||||
# Use a long findtime; failures due to cache key rotation less likely
|
||||
|
|
@ -7,6 +8,7 @@ describe 'Rack::Attack.Allow2Ban' do
|
|||
@bantime = 60
|
||||
Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new
|
||||
@f2b_options = {:bantime => @bantime, :findtime => @findtime, :maxretry => 2}
|
||||
|
||||
Rack::Attack.blocklist('pentest') do |req|
|
||||
Rack::Attack::Allow2Ban.filter(req.ip, @f2b_options){req.query_string =~ /OMGHAX/}
|
||||
end
|
||||
|
|
@ -23,6 +25,7 @@ describe 'Rack::Attack.Allow2Ban' do
|
|||
describe 'making qualifying request' do
|
||||
describe 'when not at maxretry' do
|
||||
before { get '/?foo=OMGHAX', {}, 'REMOTE_ADDR' => '1.2.3.4' }
|
||||
|
||||
it 'succeeds' do
|
||||
last_response.status.must_equal 200
|
||||
end
|
||||
|
|
@ -58,7 +61,6 @@ describe 'Rack::Attack.Allow2Ban' do
|
|||
key = "rack::attack:allow2ban:ban:1.2.3.4"
|
||||
@cache.store.read(key).must_equal 1
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -116,6 +118,5 @@ describe 'Rack::Attack.Allow2Ban' do
|
|||
@cache.store.read(key).must_equal 1
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
require_relative 'spec_helper'
|
||||
|
||||
describe 'Rack::Attack.Fail2Ban' do
|
||||
before do
|
||||
# Use a long findtime; failures due to cache key rotation less likely
|
||||
|
|
@ -7,6 +8,7 @@ describe 'Rack::Attack.Fail2Ban' do
|
|||
@bantime = 60
|
||||
Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new
|
||||
@f2b_options = {:bantime => @bantime, :findtime => @findtime, :maxretry => 2}
|
||||
|
||||
Rack::Attack.blocklist('pentest') do |req|
|
||||
Rack::Attack::Fail2Ban.filter(req.ip, @f2b_options){req.query_string =~ /OMGHAX/}
|
||||
end
|
||||
|
|
@ -23,6 +25,7 @@ describe 'Rack::Attack.Fail2Ban' do
|
|||
describe 'making failing request' do
|
||||
describe 'when not at maxretry' do
|
||||
before { get '/?foo=OMGHAX', {}, 'REMOTE_ADDR' => '1.2.3.4' }
|
||||
|
||||
it 'fails' do
|
||||
last_response.status.must_equal 403
|
||||
end
|
||||
|
|
@ -136,6 +139,5 @@ describe 'Rack::Attack.Fail2Ban' do
|
|||
@cache.store.read(key).must_equal 1
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ require 'dalli'
|
|||
require_relative '../spec_helper'
|
||||
|
||||
OfflineExamples = Minitest::SharedExamples.new do
|
||||
|
||||
it 'should write' do
|
||||
@cache.write('cache-test-key', 'foobar', 1)
|
||||
end
|
||||
|
|
@ -16,7 +15,6 @@ OfflineExamples = Minitest::SharedExamples.new do
|
|||
it 'should count' do
|
||||
@cache.send(:do_count, 'rack::attack::cache-test-key', 1)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe 'when Redis is offline' do
|
||||
|
|
@ -27,7 +25,6 @@ describe 'when Redis is offline' do
|
|||
# Use presumably unused port for Redis client
|
||||
@cache.store = ActiveSupport::Cache::RedisStore.new(:host => '127.0.0.1', :port => 3333)
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
describe 'when Memcached is offline' do
|
||||
|
|
@ -43,5 +40,4 @@ describe 'when Memcached is offline' do
|
|||
after {
|
||||
Dalli.logger.level = Logger::INFO
|
||||
}
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
require_relative '../spec_helper'
|
||||
|
||||
describe Rack::Attack::Cache do
|
||||
|
||||
# A convenience method for deleting a key from cache.
|
||||
# Slightly differnet than @cache.delete, which adds a prefix.
|
||||
def delete(key)
|
||||
|
|
@ -20,6 +19,7 @@ describe Rack::Attack::Cache do
|
|||
require 'active_support/cache/mem_cache_store'
|
||||
require 'active_support/cache/redis_store'
|
||||
require 'connection_pool'
|
||||
|
||||
cache_stores = [
|
||||
ActiveSupport::Cache::MemoryStore.new,
|
||||
ActiveSupport::Cache::DalliStore.new("127.0.0.1"),
|
||||
|
|
@ -32,8 +32,8 @@ describe Rack::Attack::Cache do
|
|||
|
||||
cache_stores.each do |store|
|
||||
store = Rack::Attack::StoreProxy.build(store)
|
||||
describe "with #{store.class}" do
|
||||
|
||||
describe "with #{store.class}" do
|
||||
before {
|
||||
@cache = Rack::Attack::Cache.new
|
||||
@key = "rack::attack:cache-test-key"
|
||||
|
|
@ -117,6 +117,5 @@ describe Rack::Attack::Cache do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -33,11 +33,13 @@ describe 'Rack::Attack' do
|
|||
|
||||
describe "a bad request" do
|
||||
before { get '/', {}, 'REMOTE_ADDR' => @bad_ip }
|
||||
|
||||
it "should return a blocklist response" do
|
||||
get '/', {}, 'REMOTE_ADDR' => @bad_ip
|
||||
last_response.status.must_equal 403
|
||||
last_response.body.must_equal "Forbidden\n"
|
||||
end
|
||||
|
||||
it "should tag the env" do
|
||||
last_request.env['rack.attack.matched'].must_equal "ip #{@bad_ip}"
|
||||
last_request.env['rack.attack.match_type'].must_equal :blocklist
|
||||
|
|
@ -52,7 +54,7 @@ describe 'Rack::Attack' do
|
|||
Rack::Attack.safelist("good ua") {|req| req.user_agent == @good_ua }
|
||||
end
|
||||
|
||||
it('has a safelist'){ Rack::Attack.safelists.key?("good ua") }
|
||||
it('has a safelist') { Rack::Attack.safelists.key?("good ua") }
|
||||
|
||||
it('has a whitelist with a deprication warning') {
|
||||
_, stderror = capture_io do
|
||||
|
|
@ -63,10 +65,12 @@ describe 'Rack::Attack' do
|
|||
|
||||
describe "with a request match both safelist & blocklist" do
|
||||
before { get '/', {}, 'REMOTE_ADDR' => @bad_ip, 'HTTP_USER_AGENT' => @good_ua }
|
||||
|
||||
it "should allow safelists before blocklists" do
|
||||
get '/', {}, 'REMOTE_ADDR' => @bad_ip, 'HTTP_USER_AGENT' => @good_ua
|
||||
last_response.status.must_equal 200
|
||||
end
|
||||
|
||||
it "should tag the env" do
|
||||
last_request.env['rack.attack.matched'].must_equal 'good ua'
|
||||
last_request.env['rack.attack.match_type'].must_equal :safelist
|
||||
|
|
@ -84,7 +88,6 @@ describe 'Rack::Attack' do
|
|||
Rack::Attack.blacklisted_response
|
||||
end
|
||||
assert_match "[DEPRECATION] 'Rack::Attack.blacklisted_response' is deprecated. Please use 'blocklisted_response' instead.", stderror
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -93,7 +96,5 @@ describe 'Rack::Attack' do
|
|||
Rack::Attack.throttled_response.must_respond_to :call
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
require_relative 'spec_helper'
|
||||
|
||||
describe 'Rack::Attack.throttle' do
|
||||
before do
|
||||
@period = 60 # Use a long period; failures due to cache key rotation less likely
|
||||
|
|
@ -6,11 +7,13 @@ describe 'Rack::Attack.throttle' do
|
|||
Rack::Attack.throttle('ip/sec', :limit => 1, :period => @period) { |req| req.ip }
|
||||
end
|
||||
|
||||
it('should have a throttle'){ Rack::Attack.throttles.key?('ip/sec') }
|
||||
it('should have a throttle') { Rack::Attack.throttles.key?('ip/sec') }
|
||||
|
||||
allow_ok_requests
|
||||
|
||||
describe 'a single request' do
|
||||
before { get '/', {}, 'REMOTE_ADDR' => '1.2.3.4' }
|
||||
|
||||
it 'should set the counter for one request' do
|
||||
key = "rack::attack:#{Time.now.to_i/@period}:ip/sec:1.2.3.4"
|
||||
Rack::Attack.cache.store.read(key).must_equal 1
|
||||
|
|
@ -21,19 +24,23 @@ describe 'Rack::Attack.throttle' do
|
|||
last_request.env['rack.attack.throttle_data']['ip/sec'].must_equal data
|
||||
end
|
||||
end
|
||||
|
||||
describe "with 2 requests" do
|
||||
before do
|
||||
2.times { get '/', {}, 'REMOTE_ADDR' => '1.2.3.4' }
|
||||
end
|
||||
|
||||
it 'should block the last request' do
|
||||
last_response.status.must_equal 429
|
||||
end
|
||||
|
||||
it 'should tag the env' do
|
||||
last_request.env['rack.attack.matched'].must_equal 'ip/sec'
|
||||
last_request.env['rack.attack.match_type'].must_equal :throttle
|
||||
last_request.env['rack.attack.match_data'].must_equal({:count => 2, :limit => 1, :period => @period})
|
||||
last_request.env['rack.attack.match_discriminator'].must_equal('1.2.3.4')
|
||||
end
|
||||
|
||||
it 'should set a Retry-After header' do
|
||||
last_response.headers['Retry-After'].must_equal @period.to_s
|
||||
end
|
||||
|
|
@ -51,6 +58,7 @@ describe 'Rack::Attack.throttle with limit as proc' do
|
|||
|
||||
describe 'a single request' do
|
||||
before { get '/', {}, 'REMOTE_ADDR' => '1.2.3.4' }
|
||||
|
||||
it 'should set the counter for one request' do
|
||||
key = "rack::attack:#{Time.now.to_i/@period}:ip/sec:1.2.3.4"
|
||||
Rack::Attack.cache.store.read(key).must_equal 1
|
||||
|
|
@ -74,6 +82,7 @@ describe 'Rack::Attack.throttle with period as proc' do
|
|||
|
||||
describe 'a single request' do
|
||||
before { get '/', {}, 'REMOTE_ADDR' => '1.2.3.4' }
|
||||
|
||||
it 'should set the counter for one request' do
|
||||
key = "rack::attack:#{Time.now.to_i/@period}:ip/sec:1.2.3.4"
|
||||
Rack::Attack.cache.store.read(key).must_equal 1
|
||||
|
|
@ -97,6 +106,7 @@ describe 'Rack::Attack.throttle with block retuning nil' do
|
|||
|
||||
describe 'a single request' do
|
||||
before { get '/', {}, 'REMOTE_ADDR' => '1.2.3.4' }
|
||||
|
||||
it 'should not set the counter' do
|
||||
key = "rack::attack:#{Time.now.to_i/@period}:ip/sec:1.2.3.4"
|
||||
assert_nil Rack::Attack.cache.store.read(key)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,9 @@ describe 'Rack::Attack.track' do
|
|||
before do
|
||||
Rack::Attack.track("everything"){ |req| true }
|
||||
end
|
||||
|
||||
allow_ok_requests
|
||||
|
||||
it "should tag the env" do
|
||||
get '/'
|
||||
last_request.env['rack.attack.matched'].must_equal 'everything'
|
||||
|
|
@ -34,6 +36,7 @@ describe 'Rack::Attack.track' do
|
|||
ActiveSupport::Notifications.subscribe("rack.attack") do |*args|
|
||||
Counter.incr
|
||||
end
|
||||
|
||||
get "/"
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue