mirror of
https://github.com/samsonjs/rack-attack.git
synced 2026-04-27 15:07:41 +00:00
* Initial Rubocop configuration * Fix Rubocop layout offenses for lib * Fix some spec offenses * Fix leftover layout offenses
This commit is contained in:
parent
f995958f18
commit
11e9557ccb
23 changed files with 63 additions and 69 deletions
5
.rubocop.yml
Normal file
5
.rubocop.yml
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
AllCops:
|
||||||
|
DisabledByDefault: true
|
||||||
|
|
||||||
|
Layout:
|
||||||
|
Enabled: true
|
||||||
|
|
@ -7,4 +7,3 @@ guard :minitest do
|
||||||
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
||||||
watch(%r{^spec/spec_helper\.rb$}) { 'spec' }
|
watch(%r{^spec/spec_helper\.rb$}) { 'spec' }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@ class Rack::Attack
|
||||||
autoload :Allow2Ban, 'rack/attack/allow2ban'
|
autoload :Allow2Ban, 'rack/attack/allow2ban'
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
|
|
||||||
attr_accessor :notifier, :blocklisted_response, :throttled_response
|
attr_accessor :notifier, :blocklisted_response, :throttled_response
|
||||||
|
|
||||||
def safelist(name, &block)
|
def safelist(name, &block)
|
||||||
|
|
@ -64,8 +63,11 @@ class Rack::Attack
|
||||||
end
|
end
|
||||||
|
|
||||||
def safelists; @safelists ||= {}; end
|
def safelists; @safelists ||= {}; end
|
||||||
|
|
||||||
def blocklists; @blocklists ||= {}; end
|
def blocklists; @blocklists ||= {}; end
|
||||||
|
|
||||||
def throttles; @throttles ||= {}; end
|
def throttles; @throttles ||= {}; end
|
||||||
|
|
||||||
def tracks; @tracks ||= {}; end
|
def tracks; @tracks ||= {}; end
|
||||||
|
|
||||||
def whitelists
|
def whitelists
|
||||||
|
|
@ -126,7 +128,7 @@ class Rack::Attack
|
||||||
|
|
||||||
def blacklisted_response=(res)
|
def blacklisted_response=(res)
|
||||||
warn "[DEPRECATION] 'Rack::Attack.blacklisted_response=' is deprecated. Please use 'blocklisted_response=' instead."
|
warn "[DEPRECATION] 'Rack::Attack.blacklisted_response=' is deprecated. Please use 'blocklisted_response=' instead."
|
||||||
self.blocklisted_response=(res)
|
self.blocklisted_response = res
|
||||||
end
|
end
|
||||||
|
|
||||||
def blacklisted_response
|
def blacklisted_response
|
||||||
|
|
@ -147,10 +149,10 @@ class Rack::Attack
|
||||||
|
|
||||||
# Set defaults
|
# Set defaults
|
||||||
@notifier = ActiveSupport::Notifications if defined?(ActiveSupport::Notifications)
|
@notifier = ActiveSupport::Notifications if defined?(ActiveSupport::Notifications)
|
||||||
@blocklisted_response = lambda {|env| [403, {'Content-Type' => 'text/plain'}, ["Forbidden\n"]] }
|
@blocklisted_response = lambda { |env| [403, { 'Content-Type' => 'text/plain' }, ["Forbidden\n"]] }
|
||||||
@throttled_response = lambda {|env|
|
@throttled_response = lambda { |env|
|
||||||
retry_after = (env['rack.attack.match_data'] || {})[:period]
|
retry_after = (env['rack.attack.match_data'] || {})[:period]
|
||||||
[429, {'Content-Type' => 'text/plain', 'Retry-After' => retry_after.to_s}, ["Retry later\n"]]
|
[429, { 'Content-Type' => 'text/plain', 'Retry-After' => retry_after.to_s }, ["Retry later\n"]]
|
||||||
}
|
}
|
||||||
|
|
||||||
def initialize(app)
|
def initialize(app)
|
||||||
|
|
@ -174,8 +176,5 @@ class Rack::Attack
|
||||||
end
|
end
|
||||||
|
|
||||||
extend Forwardable
|
extend Forwardable
|
||||||
def_delegators self, :safelisted?,
|
def_delegators self, :safelisted?, :blocklisted?, :throttled?, :tracked?
|
||||||
:blocklisted?,
|
|
||||||
:throttled?,
|
|
||||||
:tracked?
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ module Rack
|
||||||
class Allow2Ban < Fail2Ban
|
class Allow2Ban < Fail2Ban
|
||||||
class << self
|
class << self
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def key_prefix
|
def key_prefix
|
||||||
'allow2ban'
|
'allow2ban'
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ module Rack
|
||||||
super
|
super
|
||||||
@type = :blocklist
|
@type = :blocklist
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
module Rack
|
module Rack
|
||||||
class Attack
|
class Attack
|
||||||
class Cache
|
class Cache
|
||||||
|
|
||||||
attr_accessor :prefix
|
attr_accessor :prefix
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ module Rack
|
||||||
end
|
end
|
||||||
|
|
||||||
def [](req)
|
def [](req)
|
||||||
block[req].tap {|match|
|
block[req].tap { |match|
|
||||||
if match
|
if match
|
||||||
req.env["rack.attack.matched"] = name
|
req.env["rack.attack.matched"] = name
|
||||||
req.env["rack.attack.match_type"] = type
|
req.env["rack.attack.match_type"] = type
|
||||||
|
|
@ -21,4 +21,3 @@ module Rack
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ module Rack
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def key_prefix
|
def key_prefix
|
||||||
'fail2ban'
|
'fail2ban'
|
||||||
end
|
end
|
||||||
|
|
@ -40,8 +41,8 @@ module Rack
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def ban!(discriminator, bantime)
|
def ban!(discriminator, bantime)
|
||||||
cache.write("#{key_prefix}:ban:#{discriminator}", 1, bantime)
|
cache.write("#{key_prefix}:ban:#{discriminator}", 1, bantime)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,4 @@
|
||||||
class Rack::Attack
|
class Rack::Attack
|
||||||
|
|
||||||
# When using Rack::Attack with a Rails app, developers expect the request path
|
# When using Rack::Attack with a Rails app, developers expect the request path
|
||||||
# to be normalized. In particular, trailing slashes are stripped.
|
# to be normalized. In particular, trailing slashes are stripped.
|
||||||
# (See https://git.io/v0rrR for implementation.)
|
# (See https://git.io/v0rrR for implementation.)
|
||||||
|
|
@ -20,5 +19,4 @@ class Rack::Attack
|
||||||
else
|
else
|
||||||
FallbackPathNormalizer
|
FallbackPathNormalizer
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ module Rack
|
||||||
super
|
super
|
||||||
@type = :safelist
|
@type = :safelist
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,8 @@ module Rack
|
||||||
klass ? klass.new(client) : client
|
klass ? klass.new(client) : client
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def self.unwrap_active_support_stores(store)
|
def self.unwrap_active_support_stores(store)
|
||||||
# ActiveSupport::Cache::RedisStore doesn't expose any way to set an expiry,
|
# ActiveSupport::Cache::RedisStore doesn't expose any way to set an expiry,
|
||||||
# so use the raw Redis::Store instead.
|
# so use the raw Redis::Store instead.
|
||||||
|
|
|
||||||
|
|
@ -28,14 +28,14 @@ module Rack
|
||||||
rescue Dalli::DalliError
|
rescue Dalli::DalliError
|
||||||
end
|
end
|
||||||
|
|
||||||
def write(key, value, options={})
|
def write(key, value, options = {})
|
||||||
with do |client|
|
with do |client|
|
||||||
client.set(key, value, options.fetch(:expires_in, 0), raw: true)
|
client.set(key, value, options.fetch(:expires_in, 0), raw: true)
|
||||||
end
|
end
|
||||||
rescue Dalli::DalliError
|
rescue Dalli::DalliError
|
||||||
end
|
end
|
||||||
|
|
||||||
def increment(key, amount, options={})
|
def increment(key, amount, options = {})
|
||||||
with do |client|
|
with do |client|
|
||||||
client.incr(key, amount, options.fetch(:expires_in, 0), amount)
|
client.incr(key, amount, options.fetch(:expires_in, 0), amount)
|
||||||
end
|
end
|
||||||
|
|
@ -58,7 +58,6 @@ module Rack
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -17,18 +17,18 @@ module Rack
|
||||||
rescue MemCache::MemCacheError
|
rescue MemCache::MemCacheError
|
||||||
end
|
end
|
||||||
|
|
||||||
def write(key, value, options={})
|
def write(key, value, options = {})
|
||||||
# Third argument: writing raw value
|
# Third argument: writing raw value
|
||||||
set(key, value, options.fetch(:expires_in, 0), true)
|
set(key, value, options.fetch(:expires_in, 0), true)
|
||||||
rescue MemCache::MemCacheError
|
rescue MemCache::MemCacheError
|
||||||
end
|
end
|
||||||
|
|
||||||
def increment(key, amount, options={})
|
def increment(key, amount, options = {})
|
||||||
incr(key, amount)
|
incr(key, amount)
|
||||||
rescue MemCache::MemCacheError
|
rescue MemCache::MemCacheError
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete(key, options={})
|
def delete(key, options = {})
|
||||||
with do |client|
|
with do |client|
|
||||||
client.delete(key)
|
client.delete(key)
|
||||||
end
|
end
|
||||||
|
|
@ -44,7 +44,6 @@ module Rack
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@ module Rack
|
||||||
rescue Redis::BaseError
|
rescue Redis::BaseError
|
||||||
end
|
end
|
||||||
|
|
||||||
def write(key, value, options={})
|
def write(key, value, options = {})
|
||||||
if (expires_in = options[:expires_in])
|
if (expires_in = options[:expires_in])
|
||||||
setex(key, expires_in, value, raw: true)
|
setex(key, expires_in, value, raw: true)
|
||||||
else
|
else
|
||||||
|
|
@ -33,7 +33,7 @@ module Rack
|
||||||
rescue Redis::BaseError
|
rescue Redis::BaseError
|
||||||
end
|
end
|
||||||
|
|
||||||
def increment(key, amount, options={})
|
def increment(key, amount, options = {})
|
||||||
count = nil
|
count = nil
|
||||||
|
|
||||||
pipelined do
|
pipelined do
|
||||||
|
|
@ -45,7 +45,7 @@ module Rack
|
||||||
rescue Redis::BaseError
|
rescue Redis::BaseError
|
||||||
end
|
end
|
||||||
|
|
||||||
def delete(key, options={})
|
def delete(key, options = {})
|
||||||
del(key)
|
del(key)
|
||||||
rescue Redis::BaseError
|
rescue Redis::BaseError
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
# -*- encoding: utf-8 -*-
|
# -*- encoding: utf-8 -*-
|
||||||
|
|
||||||
lib = File.expand_path('../lib/', __FILE__)
|
lib = File.expand_path('../lib/', __FILE__)
|
||||||
$:.unshift lib unless $:.include?(lib)
|
$:.unshift lib unless $:.include?(lib)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -46,4 +46,3 @@ describe "Safelist an IP" do
|
||||||
assert_equal :safelist, notification_type
|
assert_equal :safelist, notification_type
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,10 @@ describe 'Rack::Attack.Allow2Ban' do
|
||||||
@findtime = 60
|
@findtime = 60
|
||||||
@bantime = 60
|
@bantime = 60
|
||||||
Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new
|
Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new
|
||||||
@f2b_options = {:bantime => @bantime, :findtime => @findtime, :maxretry => 2}
|
@f2b_options = { :bantime => @bantime, :findtime => @findtime, :maxretry => 2 }
|
||||||
|
|
||||||
Rack::Attack.blocklist('pentest') do |req|
|
Rack::Attack.blocklist('pentest') do |req|
|
||||||
Rack::Attack::Allow2Ban.filter(req.ip, @f2b_options){req.query_string =~ /OMGHAX/}
|
Rack::Attack::Allow2Ban.filter(req.ip, @f2b_options) { req.query_string =~ /OMGHAX/ }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -31,7 +31,7 @@ describe 'Rack::Attack.Allow2Ban' do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'increases fail count' do
|
it 'increases fail count' do
|
||||||
key = "rack::attack:#{Time.now.to_i/@findtime}:allow2ban:count:1.2.3.4"
|
key = "rack::attack:#{Time.now.to_i / @findtime}:allow2ban:count:1.2.3.4"
|
||||||
@cache.store.read(key).must_equal 1
|
@cache.store.read(key).must_equal 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -53,7 +53,7 @@ describe 'Rack::Attack.Allow2Ban' do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'increases fail count' do
|
it 'increases fail count' do
|
||||||
key = "rack::attack:#{Time.now.to_i/@findtime}:allow2ban:count:1.2.3.4"
|
key = "rack::attack:#{Time.now.to_i / @findtime}:allow2ban:count:1.2.3.4"
|
||||||
@cache.store.read(key).must_equal 2
|
@cache.store.read(key).must_equal 2
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -89,7 +89,7 @@ describe 'Rack::Attack.Allow2Ban' do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not increase fail count' do
|
it 'does not increase fail count' do
|
||||||
key = "rack::attack:#{Time.now.to_i/@findtime}:allow2ban:count:1.2.3.4"
|
key = "rack::attack:#{Time.now.to_i / @findtime}:allow2ban:count:1.2.3.4"
|
||||||
@cache.store.read(key).must_equal 2
|
@cache.store.read(key).must_equal 2
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -109,7 +109,7 @@ describe 'Rack::Attack.Allow2Ban' do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not increase fail count' do
|
it 'does not increase fail count' do
|
||||||
key = "rack::attack:#{Time.now.to_i/@findtime}:allow2ban:count:1.2.3.4"
|
key = "rack::attack:#{Time.now.to_i / @findtime}:allow2ban:count:1.2.3.4"
|
||||||
@cache.store.read(key).must_equal 2
|
@cache.store.read(key).must_equal 2
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,10 @@ describe 'Rack::Attack.Fail2Ban' do
|
||||||
@findtime = 60
|
@findtime = 60
|
||||||
@bantime = 60
|
@bantime = 60
|
||||||
Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new
|
Rack::Attack.cache.store = ActiveSupport::Cache::MemoryStore.new
|
||||||
@f2b_options = {:bantime => @bantime, :findtime => @findtime, :maxretry => 2}
|
@f2b_options = { :bantime => @bantime, :findtime => @findtime, :maxretry => 2 }
|
||||||
|
|
||||||
Rack::Attack.blocklist('pentest') do |req|
|
Rack::Attack.blocklist('pentest') do |req|
|
||||||
Rack::Attack::Fail2Ban.filter(req.ip, @f2b_options){req.query_string =~ /OMGHAX/}
|
Rack::Attack::Fail2Ban.filter(req.ip, @f2b_options) { req.query_string =~ /OMGHAX/ }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -31,7 +31,7 @@ describe 'Rack::Attack.Fail2Ban' do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'increases fail count' do
|
it 'increases fail count' do
|
||||||
key = "rack::attack:#{Time.now.to_i/@findtime}:fail2ban:count:1.2.3.4"
|
key = "rack::attack:#{Time.now.to_i / @findtime}:fail2ban:count:1.2.3.4"
|
||||||
@cache.store.read(key).must_equal 1
|
@cache.store.read(key).must_equal 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -53,7 +53,7 @@ describe 'Rack::Attack.Fail2Ban' do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'increases fail count' do
|
it 'increases fail count' do
|
||||||
key = "rack::attack:#{Time.now.to_i/@findtime}:fail2ban:count:1.2.3.4"
|
key = "rack::attack:#{Time.now.to_i / @findtime}:fail2ban:count:1.2.3.4"
|
||||||
@cache.store.read(key).must_equal 2
|
@cache.store.read(key).must_equal 2
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -75,7 +75,7 @@ describe 'Rack::Attack.Fail2Ban' do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'resets fail count' do
|
it 'resets fail count' do
|
||||||
key = "rack::attack:#{Time.now.to_i/@findtime}:fail2ban:count:1.2.3.4"
|
key = "rack::attack:#{Time.now.to_i / @findtime}:fail2ban:count:1.2.3.4"
|
||||||
assert_nil @cache.store.read(key)
|
assert_nil @cache.store.read(key)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -110,7 +110,7 @@ describe 'Rack::Attack.Fail2Ban' do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not increase fail count' do
|
it 'does not increase fail count' do
|
||||||
key = "rack::attack:#{Time.now.to_i/@findtime}:fail2ban:count:1.2.3.4"
|
key = "rack::attack:#{Time.now.to_i / @findtime}:fail2ban:count:1.2.3.4"
|
||||||
@cache.store.read(key).must_equal 2
|
@cache.store.read(key).must_equal 2
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -130,7 +130,7 @@ describe 'Rack::Attack.Fail2Ban' do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not increase fail count' do
|
it 'does not increase fail count' do
|
||||||
key = "rack::attack:#{Time.now.to_i/@findtime}:fail2ban:count:1.2.3.4"
|
key = "rack::attack:#{Time.now.to_i / @findtime}:fail2ban:count:1.2.3.4"
|
||||||
@cache.store.read(key).must_equal 2
|
@cache.store.read(key).must_equal 2
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,8 @@
|
||||||
require_relative 'spec_helper'
|
require_relative 'spec_helper'
|
||||||
|
|
||||||
describe Rack::Attack::StoreProxy::DalliProxy do
|
describe Rack::Attack::StoreProxy::DalliProxy do
|
||||||
|
|
||||||
it 'should stub Dalli::Client#with on older clients' do
|
it 'should stub Dalli::Client#with on older clients' do
|
||||||
proxy = Rack::Attack::StoreProxy::DalliProxy.new(Class.new)
|
proxy = Rack::Attack::StoreProxy::DalliProxy.new(Class.new)
|
||||||
proxy.with {} # will not raise an error
|
proxy.with {} # will not raise an error
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ describe 'Rack::Attack' do
|
||||||
|
|
||||||
describe 'normalizing paths' do
|
describe 'normalizing paths' do
|
||||||
before do
|
before do
|
||||||
Rack::Attack.blocklist("banned_path") {|req| req.path == '/foo' }
|
Rack::Attack.blocklist("banned_path") { |req| req.path == '/foo' }
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'blocks requests with trailing slash' do
|
it 'blocks requests with trailing slash' do
|
||||||
|
|
@ -17,7 +17,7 @@ describe 'Rack::Attack' do
|
||||||
describe 'blocklist' do
|
describe 'blocklist' do
|
||||||
before do
|
before do
|
||||||
@bad_ip = '1.2.3.4'
|
@bad_ip = '1.2.3.4'
|
||||||
Rack::Attack.blocklist("ip #{@bad_ip}") {|req| req.ip == @bad_ip }
|
Rack::Attack.blocklist("ip #{@bad_ip}") { |req| req.ip == @bad_ip }
|
||||||
end
|
end
|
||||||
|
|
||||||
it('has a blocklist') {
|
it('has a blocklist') {
|
||||||
|
|
@ -50,7 +50,7 @@ describe 'Rack::Attack' do
|
||||||
describe "and safelist" do
|
describe "and safelist" do
|
||||||
before do
|
before do
|
||||||
@good_ua = 'GoodUA'
|
@good_ua = 'GoodUA'
|
||||||
Rack::Attack.safelist("good ua") {|req| req.user_agent == @good_ua }
|
Rack::Attack.safelist("good ua") { |req| req.user_agent == @good_ua }
|
||||||
end
|
end
|
||||||
|
|
||||||
it('has a safelist') { Rack::Attack.safelists.key?("good ua") }
|
it('has a safelist') { Rack::Attack.safelists.key?("good ua") }
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ describe 'Rack::Attack.throttle' do
|
||||||
before { get '/', {}, 'REMOTE_ADDR' => '1.2.3.4' }
|
before { get '/', {}, 'REMOTE_ADDR' => '1.2.3.4' }
|
||||||
|
|
||||||
it 'should set the counter for one request' do
|
it 'should set the counter for one request' do
|
||||||
key = "rack::attack:#{Time.now.to_i/@period}:ip/sec:1.2.3.4"
|
key = "rack::attack:#{Time.now.to_i / @period}:ip/sec:1.2.3.4"
|
||||||
Rack::Attack.cache.store.read(key).must_equal 1
|
Rack::Attack.cache.store.read(key).must_equal 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -37,7 +37,7 @@ describe 'Rack::Attack.throttle' do
|
||||||
it 'should tag the env' do
|
it 'should tag the env' do
|
||||||
last_request.env['rack.attack.matched'].must_equal 'ip/sec'
|
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_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_data'].must_equal({ :count => 2, :limit => 1, :period => @period })
|
||||||
last_request.env['rack.attack.match_discriminator'].must_equal('1.2.3.4')
|
last_request.env['rack.attack.match_discriminator'].must_equal('1.2.3.4')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -60,7 +60,7 @@ describe 'Rack::Attack.throttle with limit as proc' do
|
||||||
before { get '/', {}, 'REMOTE_ADDR' => '1.2.3.4' }
|
before { get '/', {}, 'REMOTE_ADDR' => '1.2.3.4' }
|
||||||
|
|
||||||
it 'should set the counter for one request' do
|
it 'should set the counter for one request' do
|
||||||
key = "rack::attack:#{Time.now.to_i/@period}:ip/sec:1.2.3.4"
|
key = "rack::attack:#{Time.now.to_i / @period}:ip/sec:1.2.3.4"
|
||||||
Rack::Attack.cache.store.read(key).must_equal 1
|
Rack::Attack.cache.store.read(key).must_equal 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -84,7 +84,7 @@ describe 'Rack::Attack.throttle with period as proc' do
|
||||||
before { get '/', {}, 'REMOTE_ADDR' => '1.2.3.4' }
|
before { get '/', {}, 'REMOTE_ADDR' => '1.2.3.4' }
|
||||||
|
|
||||||
it 'should set the counter for one request' do
|
it 'should set the counter for one request' do
|
||||||
key = "rack::attack:#{Time.now.to_i/@period}:ip/sec:1.2.3.4"
|
key = "rack::attack:#{Time.now.to_i / @period}:ip/sec:1.2.3.4"
|
||||||
Rack::Attack.cache.store.read(key).must_equal 1
|
Rack::Attack.cache.store.read(key).must_equal 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -108,7 +108,7 @@ describe 'Rack::Attack.throttle with block retuning nil' do
|
||||||
before { get '/', {}, 'REMOTE_ADDR' => '1.2.3.4' }
|
before { get '/', {}, 'REMOTE_ADDR' => '1.2.3.4' }
|
||||||
|
|
||||||
it 'should not set the counter' do
|
it 'should not set the counter' do
|
||||||
key = "rack::attack:#{Time.now.to_i/@period}:ip/sec:1.2.3.4"
|
key = "rack::attack:#{Time.now.to_i / @period}:ip/sec:1.2.3.4"
|
||||||
assert_nil Rack::Attack.cache.store.read(key)
|
assert_nil Rack::Attack.cache.store.read(key)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ describe 'Rack::Attack.track' do
|
||||||
end
|
end
|
||||||
|
|
||||||
before do
|
before do
|
||||||
Rack::Attack.track("everything"){ |req| true }
|
Rack::Attack.track("everything") { |req| true }
|
||||||
end
|
end
|
||||||
|
|
||||||
it_allows_ok_requests
|
it_allows_ok_requests
|
||||||
|
|
@ -31,7 +31,7 @@ describe 'Rack::Attack.track' do
|
||||||
before do
|
before do
|
||||||
Counter.reset
|
Counter.reset
|
||||||
# A second track
|
# A second track
|
||||||
Rack::Attack.track("homepage"){ |req| req.path == "/"}
|
Rack::Attack.track("homepage") { |req| req.path == "/" }
|
||||||
|
|
||||||
ActiveSupport::Notifications.subscribe("rack.attack") do |*args|
|
ActiveSupport::Notifications.subscribe("rack.attack") do |*args|
|
||||||
Counter.incr
|
Counter.incr
|
||||||
|
|
@ -47,14 +47,14 @@ describe 'Rack::Attack.track' do
|
||||||
|
|
||||||
describe "without limit and period options" do
|
describe "without limit and period options" do
|
||||||
it "should assign the track filter to a Check instance" do
|
it "should assign the track filter to a Check instance" do
|
||||||
tracker = Rack::Attack.track("homepage") { |req| req.path == "/"}
|
tracker = Rack::Attack.track("homepage") { |req| req.path == "/" }
|
||||||
tracker.filter.class.must_equal Rack::Attack::Check
|
tracker.filter.class.must_equal Rack::Attack::Check
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "with limit and period options" do
|
describe "with limit and period options" do
|
||||||
it "should assign the track filter to a Throttle instance" do
|
it "should assign the track filter to a Throttle instance" do
|
||||||
tracker = Rack::Attack.track("homepage", :limit => 10, :period => 10) { |req| req.path == "/"}
|
tracker = Rack::Attack.track("homepage", :limit => 10, :period => 10) { |req| req.path == "/" }
|
||||||
tracker.filter.class.must_equal Rack::Attack::Throttle
|
tracker.filter.class.must_equal Rack::Attack::Throttle
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ require "rack/attack"
|
||||||
begin
|
begin
|
||||||
require 'pry'
|
require 'pry'
|
||||||
rescue LoadError
|
rescue LoadError
|
||||||
#nothing to do here
|
# nothing to do here
|
||||||
end
|
end
|
||||||
|
|
||||||
if RUBY_ENGINE == "ruby"
|
if RUBY_ENGINE == "ruby"
|
||||||
|
|
@ -20,7 +20,6 @@ if RUBY_ENGINE == "ruby"
|
||||||
end
|
end
|
||||||
|
|
||||||
class MiniTest::Spec
|
class MiniTest::Spec
|
||||||
|
|
||||||
include Rack::Test::Methods
|
include Rack::Test::Methods
|
||||||
|
|
||||||
before do
|
before do
|
||||||
|
|
@ -43,7 +42,7 @@ class MiniTest::Spec
|
||||||
use Rack::Attack
|
use Rack::Attack
|
||||||
use Rack::Lint
|
use Rack::Lint
|
||||||
|
|
||||||
run lambda {|env| [200, {}, ['Hello World']]}
|
run lambda { |env| [200, {}, ['Hello World']] }
|
||||||
}.to_app
|
}.to_app
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue