rate_limiter_engine 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 25680fbf29d02bc0d1657d03a82074f66608db7115efa20387bb3d613a382d79
4
+ data.tar.gz: 39d2fe46ef92d55517bf070286157152888a2f3b654215f89a9d57fe0320b047
5
+ SHA512:
6
+ metadata.gz: 0ecd532d39f1d09de8db9f500a6b3e5ee03edfd7b801392cb996dce0f13e20085cfd9354b28f1454715ef5cf9563f66e27f2beffb3ddddc82e13e0d8a65c8bcd
7
+ data.tar.gz: 701c10ba0dee7ac5a9bdafaa7d79c2f013d59eab9035fadb92a73a9481c9d33394c45438e9b6bb0212d4e3685da94b22ca13cf8b2ae43e0cee3e2a42f203d2cd
@@ -0,0 +1,6 @@
1
+ require 'rate_limiter/configuration'
2
+ require 'rate_limiter/rate_limiter'
3
+ require 'rate_limiter/rate_limit'
4
+ require 'rate_limiter/engine'
5
+
6
+ module RateLimiter; end
@@ -0,0 +1,20 @@
1
+ module RateLimiter
2
+ class Configuration
3
+ attr_accessor :rate_default,
4
+ :period_default,
5
+ :force_rate_limit,
6
+ :force_period
7
+ end
8
+
9
+ class << self
10
+ def configure
11
+ yield(configuration)
12
+
13
+ configuration
14
+ end
15
+
16
+ def configuration
17
+ @configuration ||= Configuration.new
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,5 @@
1
+ module RateLimiter
2
+ class Engine < ::Rails::Engine
3
+ isolate_namespace RateLimiter
4
+ end
5
+ end
@@ -0,0 +1,45 @@
1
+ module RateLimiter
2
+ module RateLimit
3
+ extend ActiveSupport::Concern
4
+
5
+ @@rate = {}
6
+ @@rate_default = ::RateLimiter.configuration.rate_default || 100
7
+ @@period = {}
8
+ @@period_default = ::RateLimiter.configuration.period_default || 100
9
+
10
+ included do
11
+ before_action :rate_limiter
12
+
13
+ def self.rate(rate)
14
+ @@rate[controller_name] = rate
15
+ end
16
+
17
+ def self.period(period)
18
+ @@period[controller_name] = period
19
+ end
20
+ end
21
+
22
+ protected
23
+
24
+ def rate_limiter
25
+ rate_limiter_object.count
26
+ rate_limiter_object.increment
27
+
28
+ render_limit_exceeded if rate_limiter_object.blocked?
29
+ end
30
+
31
+ def render_limit_exceeded
32
+ render json: {
33
+ message: "Rate limit exceeded. Try again in #{rate_limiter_object.cooldown_period} seconds"
34
+ }, status: :too_many_requests
35
+ end
36
+
37
+ def client_key
38
+ "#{request.env['REMOTE_IP']}_counter"
39
+ end
40
+
41
+ def rate_limiter_object
42
+ RateLimiter.new(client_key)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,70 @@
1
+ module RateLimiter
2
+ class RateLimiter
3
+ def initialize(client_key)
4
+ @client_key = client_key
5
+ end
6
+
7
+ attr_reader :client_key
8
+
9
+ def blocked?
10
+ counter.present? && limit_exceeded
11
+ end
12
+
13
+ def count
14
+ return if counter
15
+
16
+ set_client_key
17
+ set_expire
18
+ end
19
+
20
+ def increment
21
+ $redis.incr(client_key)
22
+ end
23
+
24
+ def cooldown_period
25
+ $redis.ttl(client_key)
26
+ end
27
+
28
+ private
29
+
30
+ def counter
31
+ $redis.get(client_key)
32
+ end
33
+
34
+ def limit_exceeded
35
+ counter.to_i > rate_limit.to_i
36
+ end
37
+
38
+ def set_client_key
39
+ $redis.set(client_key, 0)
40
+ end
41
+
42
+ def set_expire
43
+ $redis.expire(client_key, period)
44
+ end
45
+
46
+ def rate_limit
47
+ force_rate_limit || rate_default
48
+ end
49
+
50
+ def period
51
+ force_period || period_default
52
+ end
53
+
54
+ def force_rate_limit
55
+ ::RateLimiter.configuration.force_rate_limit
56
+ end
57
+
58
+ def rate_default
59
+ ::RateLimiter.configuration.rate_default
60
+ end
61
+
62
+ def force_period
63
+ ::RateLimiter.configuration.force_period
64
+ end
65
+
66
+ def period_default
67
+ ::RateLimiter.configuration.period_default
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,3 @@
1
+ module RateLimiter
2
+ VERSION = "0.1.0"
3
+ end
metadata ADDED
@@ -0,0 +1,118 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rate_limiter_engine
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Vitor Oliveira
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-04-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 6.1.3
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 6.1.3
27
+ - !ruby/object:Gem::Dependency
28
+ name: redis
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '4.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '4.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: mock_redis
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pg
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec-rails
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: Rate Limiter for Rails APIs
84
+ email:
85
+ - vbrazo@gmail.com
86
+ executables: []
87
+ extensions: []
88
+ extra_rdoc_files: []
89
+ files:
90
+ - lib/rate_limiter.rb
91
+ - lib/rate_limiter/configuration.rb
92
+ - lib/rate_limiter/engine.rb
93
+ - lib/rate_limiter/rate_limit.rb
94
+ - lib/rate_limiter/rate_limiter.rb
95
+ - lib/rate_limiter/version.rb
96
+ homepage:
97
+ licenses: []
98
+ metadata: {}
99
+ post_install_message:
100
+ rdoc_options: []
101
+ require_paths:
102
+ - lib
103
+ required_ruby_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ">="
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ requirements: []
114
+ rubygems_version: 3.1.2
115
+ signing_key:
116
+ specification_version: 4
117
+ summary: Rate Limiter for Rails APIs
118
+ test_files: []