Class: ThrottleMachines::RackMiddleware::Configuration

Inherits:
Object
  • Object
show all
Defined in:
lib/throttle_machines/rack_middleware/configuration.rb

Constant Summary collapse

DEFAULT_BLOCKLISTED_RESPONDER =
->(_req) { [403, { 'content-type' => 'text/plain' }, ["Forbidden\n"]] }
DEFAULT_THROTTLED_RESPONDER =
lambda do |req|
  match_data = req.env['rack.attack.match_data']
  retry_after = match_data[:retry_after] || 60

  [429, { 'content-type' => 'text/plain', 'retry-after' => retry_after.to_s }, ["Retry later\n"]]
end

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeConfiguration

Returns a new instance of Configuration.



20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/throttle_machines/rack_middleware/configuration.rb', line 20

def initialize
  @throttles = {}
  @tracks = {}
  @safelists = {}
  @blocklists = {}
  @anonymous_safelists = []
  @anonymous_blocklists = []
  @fail2bans = {}
  @allow2bans = {}

  @throttled_responder = DEFAULT_THROTTLED_RESPONDER
  @blocklisted_responder = DEFAULT_BLOCKLISTED_RESPONDER
end

Instance Attribute Details

#blocklisted_responderObject

Returns the value of attribute blocklisted_responder.



18
19
20
# File 'lib/throttle_machines/rack_middleware/configuration.rb', line 18

def blocklisted_responder
  @blocklisted_responder
end

#blocklistsObject (readonly)

Returns the value of attribute blocklists.



17
18
19
# File 'lib/throttle_machines/rack_middleware/configuration.rb', line 17

def blocklists
  @blocklists
end

#safelistsObject (readonly)

Returns the value of attribute safelists.



17
18
19
# File 'lib/throttle_machines/rack_middleware/configuration.rb', line 17

def safelists
  @safelists
end

#throttled_responderObject

Returns the value of attribute throttled_responder.



18
19
20
# File 'lib/throttle_machines/rack_middleware/configuration.rb', line 18

def throttled_responder
  @throttled_responder
end

#throttlesObject (readonly)

Returns the value of attribute throttles.



17
18
19
# File 'lib/throttle_machines/rack_middleware/configuration.rb', line 17

def throttles
  @throttles
end

#tracksObject (readonly)

Returns the value of attribute tracks.



17
18
19
# File 'lib/throttle_machines/rack_middleware/configuration.rb', line 17

def tracks
  @tracks
end

Instance Method Details

#allow2ban(name, options = {}, &block) ⇒ Object



71
72
73
# File 'lib/throttle_machines/rack_middleware/configuration.rb', line 71

def allow2ban(name, options = {}, &block)
  @allow2bans[name] = Allow2Ban.new(name, options, &block)
end

#blocklist(name = nil, &block) ⇒ Object



51
52
53
54
55
56
57
# File 'lib/throttle_machines/rack_middleware/configuration.rb', line 51

def blocklist(name = nil, &block)
  if name
    @blocklists[name] = Blocklist.new(name, &block)
  else
    @anonymous_blocklists << Blocklist.new(nil, &block)
  end
end

#blocklist_ip(ip_address) ⇒ Object



63
64
65
# File 'lib/throttle_machines/rack_middleware/configuration.rb', line 63

def blocklist_ip(ip_address)
  @anonymous_blocklists << Blocklist.new(nil) { |req| req.ip == ip_address }
end

#blocklisted?(request) ⇒ Boolean

Returns:

  • (Boolean)


81
82
83
84
85
86
87
88
# File 'lib/throttle_machines/rack_middleware/configuration.rb', line 81

def blocklisted?(request)
  # Check explicit blocklists
  return true if @anonymous_blocklists.any? { |blocklist| blocklist.matched_by?(request) }
  return true if @blocklists.values.any? { |blocklist| blocklist.matched_by?(request) }

  # Check fail2bans
  @fail2bans.values.any? { |fail2ban| fail2ban.banned?(request) }
end

#fail2ban(name, options = {}, &block) ⇒ Object



67
68
69
# File 'lib/throttle_machines/rack_middleware/configuration.rb', line 67

def fail2ban(name, options = {}, &block)
  @fail2bans[name] = Fail2Ban.new(name, options, &block)
end

#safelist(name = nil, &block) ⇒ Object



43
44
45
46
47
48
49
# File 'lib/throttle_machines/rack_middleware/configuration.rb', line 43

def safelist(name = nil, &block)
  if name
    @safelists[name] = Safelist.new(name, &block)
  else
    @anonymous_safelists << Safelist.new(nil, &block)
  end
end

#safelist_ip(ip_address) ⇒ Object



59
60
61
# File 'lib/throttle_machines/rack_middleware/configuration.rb', line 59

def safelist_ip(ip_address)
  @anonymous_safelists << Safelist.new(nil) { |req| req.ip == ip_address }
end

#safelisted?(request) ⇒ Boolean

Check methods

Returns:

  • (Boolean)


76
77
78
79
# File 'lib/throttle_machines/rack_middleware/configuration.rb', line 76

def safelisted?(request)
  @anonymous_safelists.any? { |safelist| safelist.matched_by?(request) } ||
    @safelists.values.any? { |safelist| safelist.matched_by?(request) }
end

#throttle(name, options = {}, &block) ⇒ Object

DSL Methods



35
36
37
# File 'lib/throttle_machines/rack_middleware/configuration.rb', line 35

def throttle(name, options = {}, &block)
  @throttles[name] = Throttle.new(name, options, &block)
end

#throttled?(request) ⇒ Boolean

Returns:

  • (Boolean)


90
91
92
93
94
95
96
# File 'lib/throttle_machines/rack_middleware/configuration.rb', line 90

def throttled?(request)
  # Process allow2bans first (they can reset fail2ban counters)
  @allow2bans.each_value { |allow2ban| allow2ban.matched_by?(request) }

  # Check throttles
  @throttles.values.any? { |throttle| throttle.matched_by?(request) }
end

#track(name, options = {}, &block) ⇒ Object



39
40
41
# File 'lib/throttle_machines/rack_middleware/configuration.rb', line 39

def track(name, options = {}, &block)
  @tracks[name] = Track.new(name, options, &block)
end

#tracked?(request) ⇒ Boolean

Returns:

  • (Boolean)


98
99
100
# File 'lib/throttle_machines/rack_middleware/configuration.rb', line 98

def tracked?(request)
  @tracks.each_value { |track| track.matched_by?(request) }
end