Make store proxies lookup dynamic

This commit is contained in:
fatkodima 2019-10-24 02:48:32 +03:00 committed by Gonzalo
parent df354cd141
commit e131750a6b
No known key found for this signature in database
GPG key ID: 319EB6E3DB0D60FA
10 changed files with 51 additions and 41 deletions

View file

@ -6,6 +6,12 @@ require 'rack/attack/cache'
require 'rack/attack/configuration'
require 'rack/attack/path_normalizer'
require 'rack/attack/request'
require 'rack/attack/store_proxy/dalli_proxy'
require 'rack/attack/store_proxy/mem_cache_store_proxy'
require 'rack/attack/store_proxy/redis_proxy'
require 'rack/attack/store_proxy/redis_store_proxy'
require 'rack/attack/store_proxy/redis_cache_store_proxy'
require 'rack/attack/store_proxy/active_support_redis_store_proxy'
require 'rack/attack/railtie' if defined?(::Rails)
@ -21,13 +27,6 @@ module Rack
autoload :Safelist, 'rack/attack/safelist'
autoload :Blocklist, 'rack/attack/blocklist'
autoload :Track, 'rack/attack/track'
autoload :StoreProxy, 'rack/attack/store_proxy'
autoload :DalliProxy, 'rack/attack/store_proxy/dalli_proxy'
autoload :MemCacheStoreProxy, 'rack/attack/store_proxy/mem_cache_store_proxy'
autoload :RedisProxy, 'rack/attack/store_proxy/redis_proxy'
autoload :RedisStoreProxy, 'rack/attack/store_proxy/redis_store_proxy'
autoload :RedisCacheStoreProxy, 'rack/attack/store_proxy/redis_cache_store_proxy'
autoload :ActiveSupportRedisStoreProxy, 'rack/attack/store_proxy/active_support_redis_store_proxy'
autoload :Fail2Ban, 'rack/attack/fail2ban'
autoload :Allow2Ban, 'rack/attack/allow2ban'

View file

@ -0,0 +1,27 @@
# frozen_string_literal: true
require 'delegate'
module Rack
class Attack
class BaseProxy < SimpleDelegator
class << self
def proxies
@@proxies ||= []
end
def inherited(klass)
proxies << klass
end
def lookup(store)
proxies.find { |proxy| proxy.handle?(store) }
end
def handle?(_store)
raise NotImplementedError
end
end
end
end
end

View file

@ -14,7 +14,12 @@ module Rack
attr_reader :store
def store=(store)
@store = StoreProxy.build(store)
@store =
if (proxy = BaseProxy.lookup(store))
proxy.new(store)
else
store
end
end
def count(unprefixed_key, period)

View file

@ -1,21 +0,0 @@
# frozen_string_literal: true
module Rack
class Attack
module StoreProxy
PROXIES = [
DalliProxy,
MemCacheStoreProxy,
RedisStoreProxy,
RedisProxy,
RedisCacheStoreProxy,
ActiveSupportRedisStoreProxy
].freeze
def self.build(store)
klass = PROXIES.find { |proxy| proxy.handle?(store) }
klass ? klass.new(store) : store
end
end
end
end

View file

@ -1,11 +1,11 @@
# frozen_string_literal: true
require 'delegate'
require 'rack/attack/base_proxy'
module Rack
class Attack
module StoreProxy
class ActiveSupportRedisStoreProxy < SimpleDelegator
class ActiveSupportRedisStoreProxy < BaseProxy
def self.handle?(store)
defined?(::Redis) &&
defined?(::ActiveSupport::Cache::RedisStore) &&

View file

@ -1,11 +1,11 @@
# frozen_string_literal: true
require 'delegate'
require 'rack/attack/base_proxy'
module Rack
class Attack
module StoreProxy
class DalliProxy < SimpleDelegator
class DalliProxy < BaseProxy
def self.handle?(store)
return false unless defined?(::Dalli)

View file

@ -1,11 +1,11 @@
# frozen_string_literal: true
require 'delegate'
require 'rack/attack/base_proxy'
module Rack
class Attack
module StoreProxy
class MemCacheStoreProxy < SimpleDelegator
class MemCacheStoreProxy < BaseProxy
def self.handle?(store)
defined?(::Dalli) &&
defined?(::ActiveSupport::Cache::MemCacheStore) &&

View file

@ -1,11 +1,11 @@
# frozen_string_literal: true
require 'delegate'
require 'rack/attack/base_proxy'
module Rack
class Attack
module StoreProxy
class RedisCacheStoreProxy < SimpleDelegator
class RedisCacheStoreProxy < BaseProxy
def self.handle?(store)
store.class.name == "ActiveSupport::Cache::RedisCacheStore"
end

View file

@ -1,11 +1,11 @@
# frozen_string_literal: true
require 'delegate'
require 'rack/attack/base_proxy'
module Rack
class Attack
module StoreProxy
class RedisProxy < SimpleDelegator
class RedisProxy < BaseProxy
def initialize(*args)
if Gem::Version.new(Redis::VERSION) < Gem::Version.new("3")
warn 'RackAttack requires Redis gem >= 3.0.0.'
@ -15,7 +15,7 @@ module Rack
end
def self.handle?(store)
defined?(::Redis) && store.is_a?(::Redis)
defined?(::Redis) && store.class == ::Redis
end
def read(key)

View file

@ -1,6 +1,6 @@
# frozen_string_literal: true
require 'delegate'
require 'rack/attack/store_proxy/redis_proxy'
module Rack
class Attack