Attempt to improve code legibility/clarity/semantics (#357)

* attempt to improve semantics for legibility

* Attempt to improve legibility by simplifying

* Make it more clear that we're calling procs/blocks here

* Enable rubocop Style/BlockDelimiters cop

* Prefer 'request' over 'req' abbreviation for legibility/clarity

* Instances of Track named 'track' not 'tracker'
This commit is contained in:
Gonzalo Rodriguez 2018-06-21 14:33:24 -03:00 committed by GitHub
parent d8b88cfb84
commit 08861f8d17
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 58 additions and 57 deletions

View file

@ -40,6 +40,9 @@ Security:
Lint: Lint:
Enabled: true Enabled: true
Style/BlockDelimiters:
Enabled: true
Style/BracesAroundHashParameters: Style/BracesAroundHashParameters:
Enabled: true Enabled: true

View file

@ -81,40 +81,40 @@ class Rack::Attack
blocklists blocklists
end end
def safelisted?(req) def safelisted?(request)
ip_safelists.any? { |safelist| safelist.match?(req) } || ip_safelists.any? { |safelist| safelist.matched_by?(request) } ||
safelists.any? { |_name, safelist| safelist.match?(req) } safelists.any? { |_name, safelist| safelist.matched_by?(request) }
end end
def whitelisted?(req) def whitelisted?(request)
warn "[DEPRECATION] 'Rack::Attack.whitelisted?' is deprecated. Please use 'safelisted?' instead." warn "[DEPRECATION] 'Rack::Attack.whitelisted?' is deprecated. Please use 'safelisted?' instead."
safelisted?(req) safelisted?(request)
end end
def blocklisted?(req) def blocklisted?(request)
ip_blocklists.any? { |blocklist| blocklist.match?(req) } || ip_blocklists.any? { |blocklist| blocklist.matched_by?(request) } ||
blocklists.any? { |_name, blocklist| blocklist.match?(req) } blocklists.any? { |_name, blocklist| blocklist.matched_by?(request) }
end end
def blacklisted?(req) def blacklisted?(request)
warn "[DEPRECATION] 'Rack::Attack.blacklisted?' is deprecated. Please use 'blocklisted?' instead." warn "[DEPRECATION] 'Rack::Attack.blacklisted?' is deprecated. Please use 'blocklisted?' instead."
blocklisted?(req) blocklisted?(request)
end end
def throttled?(req) def throttled?(request)
throttles.any? do |_name, throttle| throttles.any? do |_name, throttle|
throttle[req] throttle.matched_by?(request)
end end
end end
def tracked?(req) def tracked?(request)
tracks.each_value do |tracker| tracks.each_value do |track|
tracker[req] track.matched_by?(request)
end end
end end
def instrument(req) def instrument(request)
notifier.instrument('rack.attack', req) if notifier notifier.instrument('rack.attack', request) if notifier
end end
def cache def cache
@ -167,16 +167,16 @@ class Rack::Attack
def call(env) def call(env)
env['PATH_INFO'] = PathNormalizer.normalize_path(env['PATH_INFO']) env['PATH_INFO'] = PathNormalizer.normalize_path(env['PATH_INFO'])
req = Rack::Attack::Request.new(env) request = Rack::Attack::Request.new(env)
if safelisted?(req) if safelisted?(request)
@app.call(env) @app.call(env)
elsif blocklisted?(req) elsif blocklisted?(request)
self.class.blocklisted_response.call(env) self.class.blocklisted_response.call(env)
elsif throttled?(req) elsif throttled?(request)
self.class.throttled_response.call(env) self.class.throttled_response.call(env)
else else
tracked?(req) tracked?(request)
@app.call(env) @app.call(env)
end end
end end

View file

@ -7,17 +7,15 @@ module Rack
@type = options.fetch(:type, nil) @type = options.fetch(:type, nil)
end end
def [](req) def matched_by?(request)
block[req].tap { |match| block.call(request).tap do |match|
if match if match
req.env["rack.attack.matched"] = name request.env["rack.attack.matched"] = name
req.env["rack.attack.match_type"] = type request.env["rack.attack.match_type"] = type
Rack::Attack.instrument(req) Rack::Attack.instrument(request)
end end
} end
end end
alias_method :match?, :[]
end end
end end
end end

View file

@ -18,12 +18,12 @@ module Rack
Rack::Attack.cache Rack::Attack.cache
end end
def [](req) def matched_by?(request)
discriminator = block[req] discriminator = block.call(request)
return false unless discriminator return false unless discriminator
current_period = period.respond_to?(:call) ? period.call(req) : period current_period = period.respond_to?(:call) ? period.call(request) : period
current_limit = limit.respond_to?(:call) ? limit.call(req) : limit current_limit = limit.respond_to?(:call) ? limit.call(request) : limit
key = "#{name}:#{discriminator}" key = "#{name}:#{discriminator}"
count = cache.count(key, current_period) count = cache.count(key, current_period)
@ -32,15 +32,15 @@ module Rack
:period => current_period, :period => current_period,
:limit => current_limit :limit => current_limit
} }
(req.env['rack.attack.throttle_data'] ||= {})[name] = data (request.env['rack.attack.throttle_data'] ||= {})[name] = data
(count > current_limit).tap do |throttled| (count > current_limit).tap do |throttled|
if throttled if throttled
req.env['rack.attack.matched'] = name request.env['rack.attack.matched'] = name
req.env['rack.attack.match_discriminator'] = discriminator request.env['rack.attack.match_discriminator'] = discriminator
req.env['rack.attack.match_type'] = type request.env['rack.attack.match_type'] = type
req.env['rack.attack.match_data'] = data request.env['rack.attack.match_data'] = data
Rack::Attack.instrument(req) Rack::Attack.instrument(request)
end end
end end
end end

View file

@ -1,8 +1,6 @@
module Rack module Rack
class Attack class Attack
class Track class Track
extend Forwardable
attr_reader :filter attr_reader :filter
def initialize(name, options = {}, block) def initialize(name, options = {}, block)
@ -15,7 +13,9 @@ module Rack
end end
end end
def_delegator :@filter, :[] def matched_by?(request)
filter.matched_by?(request)
end
end end
end end
end end

View file

@ -20,24 +20,24 @@ end
describe 'when Redis is offline' do describe 'when Redis is offline' do
include OfflineExamples include OfflineExamples
before { before do
@cache = Rack::Attack::Cache.new @cache = Rack::Attack::Cache.new
# Use presumably unused port for Redis client # Use presumably unused port for Redis client
@cache.store = ActiveSupport::Cache::RedisStore.new(:host => '127.0.0.1', :port => 3333) @cache.store = ActiveSupport::Cache::RedisStore.new(:host => '127.0.0.1', :port => 3333)
} end
end end
describe 'when Memcached is offline' do describe 'when Memcached is offline' do
include OfflineExamples include OfflineExamples
before { before do
Dalli.logger.level = Logger::FATAL Dalli.logger.level = Logger::FATAL
@cache = Rack::Attack::Cache.new @cache = Rack::Attack::Cache.new
@cache.store = Dalli::Client.new('127.0.0.1:22122') @cache.store = Dalli::Client.new('127.0.0.1:22122')
} end
after { after do
Dalli.logger.level = Logger::INFO Dalli.logger.level = Logger::INFO
} end
end end

View file

@ -37,13 +37,13 @@ describe Rack::Attack::Cache do
store = Rack::Attack::StoreProxy.build(store) store = Rack::Attack::StoreProxy.build(store)
describe "with #{store.class}" do describe "with #{store.class}" do
before { before do
@cache = Rack::Attack::Cache.new @cache = Rack::Attack::Cache.new
@key = "rack::attack:cache-test-key" @key = "rack::attack:cache-test-key"
@expires_in = 1 @expires_in = 1
@cache.store = store @cache.store = store
delete(@key) delete(@key)
} end
after { delete(@key) } after { delete(@key) }

View file

@ -47,15 +47,15 @@ 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 == "/" } track = Rack::Attack.track("homepage") { |req| req.path == "/" }
tracker.filter.class.must_equal Rack::Attack::Check track.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 == "/" } track = Rack::Attack.track("homepage", :limit => 10, :period => 10) { |req| req.path == "/" }
tracker.filter.class.must_equal Rack::Attack::Throttle track.filter.class.must_equal Rack::Attack::Throttle
end end
end end
end end

View file

@ -36,14 +36,14 @@ class MiniTest::Spec
end end
def app def app
Rack::Builder.new { Rack::Builder.new do
# Use Rack::Lint to test that rack-attack is complying with the rack spec # Use Rack::Lint to test that rack-attack is complying with the rack spec
use Rack::Lint use Rack::Lint
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 end.to_app
end end
def self.it_allows_ok_requests def self.it_allows_ok_requests