rate_limiter 0.0.6 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +6 -0
  3. data/LICENSE.txt +20 -0
  4. data/README.md +18 -11
  5. data/lib/generators/rate_limiter/install_generator.rb +22 -0
  6. data/lib/generators/rate_limiter/templates/rate_limiter.rb +6 -0
  7. data/lib/rate_limiter.rb +51 -51
  8. data/lib/rate_limiter/config.rb +18 -3
  9. data/lib/rate_limiter/frameworks/rails.rb +3 -0
  10. data/lib/rate_limiter/frameworks/rails/controller.rb +69 -0
  11. data/lib/rate_limiter/model.rb +30 -48
  12. data/lib/rate_limiter/model_config.rb +34 -0
  13. data/lib/rate_limiter/request.rb +112 -0
  14. data/lib/rate_limiter/throttle.rb +79 -0
  15. data/lib/rate_limiter/validator.rb +29 -0
  16. data/lib/rate_limiter/version.rb +3 -1
  17. data/rate_limiter.gemspec +24 -18
  18. metadata +98 -183
  19. data/.gitignore +0 -11
  20. data/.rspec +0 -3
  21. data/.rvmrc +0 -80
  22. data/Gemfile +0 -3
  23. data/Gemfile.lock +0 -150
  24. data/Rakefile +0 -6
  25. data/lib/rate_limiter/controller.rb +0 -36
  26. data/spec/dummy/Rakefile +0 -7
  27. data/spec/dummy/app/assets/images/rails.png +0 -0
  28. data/spec/dummy/app/assets/javascripts/application.js +0 -15
  29. data/spec/dummy/app/assets/stylesheets/application.css +0 -13
  30. data/spec/dummy/app/controllers/application_controller.rb +0 -7
  31. data/spec/dummy/app/controllers/messages_controller.rb +0 -75
  32. data/spec/dummy/app/helpers/application_helper.rb +0 -2
  33. data/spec/dummy/app/mailers/.gitkeep +0 -0
  34. data/spec/dummy/app/models/message.rb +0 -5
  35. data/spec/dummy/app/views/layouts/application.html.erb +0 -15
  36. data/spec/dummy/app/views/messages/_form.html.erb +0 -22
  37. data/spec/dummy/app/views/messages/_message.html.erb +0 -8
  38. data/spec/dummy/app/views/messages/edit.html.erb +0 -3
  39. data/spec/dummy/app/views/messages/index.html.erb +0 -6
  40. data/spec/dummy/app/views/messages/new.html.erb +0 -3
  41. data/spec/dummy/app/views/messages/show.html.erb +0 -4
  42. data/spec/dummy/config.ru +0 -4
  43. data/spec/dummy/config/application.rb +0 -70
  44. data/spec/dummy/config/boot.rb +0 -11
  45. data/spec/dummy/config/database.yml +0 -25
  46. data/spec/dummy/config/environment.rb +0 -5
  47. data/spec/dummy/config/environments/development.rb +0 -37
  48. data/spec/dummy/config/environments/production.rb +0 -67
  49. data/spec/dummy/config/environments/test.rb +0 -37
  50. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
  51. data/spec/dummy/config/initializers/inflections.rb +0 -15
  52. data/spec/dummy/config/initializers/mime_types.rb +0 -5
  53. data/spec/dummy/config/initializers/secret_token.rb +0 -7
  54. data/spec/dummy/config/initializers/session_store.rb +0 -8
  55. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
  56. data/spec/dummy/config/locales/en.yml +0 -5
  57. data/spec/dummy/config/routes.rb +0 -5
  58. data/spec/dummy/db/migrate/20121213101512_create_messages.rb +0 -21
  59. data/spec/dummy/db/schema.rb +0 -33
  60. data/spec/dummy/db/seeds.rb +0 -7
  61. data/spec/dummy/lib/assets/.gitkeep +0 -0
  62. data/spec/dummy/lib/tasks/.gitkeep +0 -0
  63. data/spec/dummy/log/.gitkeep +0 -0
  64. data/spec/dummy/public/404.html +0 -26
  65. data/spec/dummy/public/422.html +0 -26
  66. data/spec/dummy/public/500.html +0 -25
  67. data/spec/dummy/public/favicon.ico +0 -0
  68. data/spec/dummy/script/rails +0 -6
  69. data/spec/rate_limiter/model_spec.rb +0 -20
  70. data/spec/rate_limiter_spec.rb +0 -10
  71. data/spec/spec_helper.rb +0 -30
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rate_limiter/validator'
4
+
5
+ module RateLimiter
6
+ # Sets up RateLimiter configuration for an ActiveRecord model.
7
+ class ModelConfig
8
+ def initialize(model_class)
9
+ @model_class = model_class
10
+ end
11
+
12
+ # Set up `@model_class` for RateLimiter. Includes callbacks, class
13
+ # attributes, instance methods, etc.
14
+ def setup(options = {})
15
+ @model_class.send(:include, Model::InstanceMethods)
16
+ setup_options(options)
17
+ setup_validations
18
+ end
19
+
20
+ private
21
+
22
+ def setup_options(options)
23
+ @model_class.class_attribute :rate_limiter_options
24
+ @model_class.rate_limiter_options = options.dup
25
+ end
26
+
27
+ def setup_validations
28
+ # TODO: Maybe make it so the context can be configured.
29
+ @model_class.validate(on: :create) do |record|
30
+ Validator.new(record).validate
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,112 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'request_store'
4
+
5
+ module RateLimiter
6
+ # Manages configuration and state for the current HTTP request such as
7
+ # `source`.
8
+ #
9
+ # It is recommended you don't use `RateLimiter::Request` directly. Instead
10
+ # use `RateLimiter.request`.
11
+ module Request
12
+ class InvalidOption < RuntimeError; end
13
+
14
+ class << self
15
+ # Turn off RateLimiter for the given model for this request.
16
+ def disable_model(model_class)
17
+ enabled_for_model(model_class, false)
18
+ end
19
+
20
+ # Turn on RateLimiter for the given model for this request.
21
+ def enable_model(model_class)
22
+ enabled_for_model(model_class, true)
23
+ end
24
+
25
+ # Returns `true` if RateLimiter is enabled for the current request,
26
+ # `false` otherwise.
27
+ def enabled?
28
+ !!store[:enabled]
29
+ end
30
+
31
+ # Sets whether RateLimiter is enabled or disabled for the current request.
32
+ def enabled=(value)
33
+ store[:enabled] = value
34
+ end
35
+
36
+ # Sets wheterh RateLimiter is enabled or disabled for this model for the
37
+ # current request.
38
+ def enabled_for_model(model, value)
39
+ store[:"enabled_for_#{model}"] = value
40
+ end
41
+
42
+ # Returns `true` if RateLimiter is enabled for this model for the current
43
+ # request, `false` otherwise.
44
+ def enabled_for_model?(model)
45
+ model.include?(Model::InstanceMethods) && !!store.fetch(:"enabled_for_#{model}", true)
46
+ end
47
+
48
+ def merge(options)
49
+ options.to_h.each do |k, v|
50
+ store[k] = v
51
+ end
52
+ end
53
+
54
+ def set(options)
55
+ store.clear
56
+ merge(options)
57
+ end
58
+
59
+ # Returns who is responsible for attempting to create a new record.
60
+ def source
61
+ who = store[:source]
62
+ who.respond_to?(:call) ? who.call : who
63
+ end
64
+
65
+ # Sets who is responsible for attempting to create a new record.
66
+ def source=(value)
67
+ store[:source] = value
68
+ end
69
+
70
+ # Returns a deep copy of the RequestStore.
71
+ def to_h
72
+ store.deep_dup
73
+ end
74
+
75
+ # Temporarily set options and execute a block.
76
+ def with(options)
77
+ return unless block_given?
78
+
79
+ before = to_h
80
+ validate_public_options(options)
81
+ merge(options)
82
+ yield
83
+ ensure
84
+ set(before)
85
+ end
86
+
87
+ private
88
+
89
+ # Internal store for the options for this request.
90
+ def store
91
+ RequestStore.store[:rate_limiter] ||= {
92
+ enabled: true
93
+ }
94
+ end
95
+
96
+ # Double checks that the options passed are known. Does not validate
97
+ # the values of the options.
98
+ def validate_public_options(options)
99
+ options.each do |k, _v|
100
+ case k
101
+ when /enabled_for_/,
102
+ :enabled,
103
+ :source
104
+ next
105
+ else
106
+ raise InvalidOption, "Invalid option: #{k}"
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RateLimiter
4
+ # Limits the rate at which new records of an ActiveRecord model can be saved.
5
+ # Checks to see if RateLimiter is enabled and, if all conditions are satisfied
6
+ # and if any other records have been created within the time interval for rate
7
+ # limiting.
8
+ class Throttle
9
+ DEFAULT_INTERVAL = 1.minute
10
+ DEFAULT_ON_FIELD = :ip_address
11
+ DEFAULT_TIMESTAMP_FIELD = :created_at
12
+
13
+ def initialize(record, options = {})
14
+ @record = record
15
+ @options = options
16
+ end
17
+
18
+ # Has the rate limit been exceeded?
19
+ def exceeded?
20
+ enabled? && rate_limit? && others_for_rate_limiting.present?
21
+ end
22
+
23
+ private
24
+
25
+ # Is RateLimiter enabled for this particular record?
26
+ def enabled?
27
+ RateLimiter.enabled? &&
28
+ RateLimiter.request.enabled? &&
29
+ RateLimiter.request.enabled_for_model?(@record.class)
30
+ end
31
+
32
+ # Proc that if present must return true for RateLimiter to be enabled for
33
+ # this particular record.
34
+ def if_condition
35
+ @options[:if_condition]
36
+ end
37
+
38
+ # The time interval (in seconds)
39
+ def interval
40
+ @options[:interval] || DEFAULT_INTERVAL
41
+ end
42
+
43
+ # Arel query for finding records within the interval.
44
+ def interval_query_params
45
+ @record.class.arel_table[timestamp_field].gteq(Time.current - interval)
46
+ end
47
+
48
+ # An Array of model attribute names to match against.
49
+ def on
50
+ Array(@options[:on] || DEFAULT_ON_FIELD)
51
+ end
52
+
53
+ # Arel query for finding records that match the on attributes.
54
+ def on_query_params
55
+ on.map { |attr| @record.class.arel_table[attr].eq(@record.send(attr)) }.inject(&:or)
56
+ end
57
+
58
+ # Other records that fall within the time interval.
59
+ def others_for_rate_limiting
60
+ @record.class.where(on_query_params).where(interval_query_params)
61
+ end
62
+
63
+ # Are all of the conditions for rate limiting met for this record?
64
+ def rate_limit?
65
+ (if_condition.blank? || if_condition.call(@record)) && !unless_condition.try(:call, @record)
66
+ end
67
+
68
+ # Timestamp field to test the interval against.
69
+ def timestamp_field
70
+ @options[:timestamp_field] || DEFAULT_TIMESTAMP_FIELD
71
+ end
72
+
73
+ # Proc that if present must return false for RateLimiter to be enabled for
74
+ # this particular record.
75
+ def unless_condition
76
+ @options[:unless_condition]
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RateLimiter
4
+ # Validates whether a model's rate limit has been exceeded.
5
+ class Validator
6
+ def initialize(record, options = {})
7
+ @record = record
8
+ @options = options
9
+ end
10
+
11
+ def validate
12
+ return unless @record.rate_limit_exceeded?
13
+
14
+ @record.errors.add(:base, I18n.t('rate_limiter.errors.rate_limit_exceeded', object_type: object_type, default: default_error_message))
15
+
16
+ false
17
+ end
18
+
19
+ private
20
+
21
+ def default_error_message
22
+ "You cannot create a new #{object_type} yet."
23
+ end
24
+
25
+ def object_type
26
+ @record.class.name
27
+ end
28
+ end
29
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module RateLimiter
2
- VERSION = '0.0.6'
4
+ VERSION = '0.1.0'
3
5
  end
data/rate_limiter.gemspec CHANGED
@@ -1,32 +1,38 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.unshift File.expand_path('lib', __dir__)
4
+
3
5
  require 'rate_limiter/version'
4
6
 
5
7
  Gem::Specification.new do |s|
6
8
  s.name = 'rate_limiter'
7
9
  s.version = RateLimiter::VERSION
8
- s.authors = ['Sean Eshbaugh']
9
- s.email = ['seaneshbaugh@gmail.com']
10
+ s.platform = Gem::Platform::RUBY
11
+ s.license = 'MIT'
12
+ s.author = 'Sean Eshbaugh'
13
+ s.email = 'seaneshbaugh@gmail.com'
10
14
  s.homepage = 'https://github.com/seaneshbaugh/rate_limiter'
11
15
  s.summary = 'Adds creation rate limiting to ActiveRecord models.'
12
16
  s.description = 'Adds creation rate limiting to ActiveRecord models.'
13
17
 
14
- s.rubyforge_project = 'rate_limiter'
18
+ s.required_ruby_version = '>= 2.5.0'
19
+ s.required_rubygems_version = '>= 1.8.11'
15
20
 
16
- s.files = `git ls-files`.split("\n")
17
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.files = Dir['lib/**/*', 'CHANGELOG.md', 'LICENSE.txt', 'README.md', 'rate_limiter.gemspec']
22
+ s.executables = []
19
23
  s.require_paths = ['lib']
20
24
 
21
- s.add_dependency 'railties', '>= 3.2'
22
- s.add_dependency 'activerecord', '>= 3.2'
25
+ s.add_dependency 'activerecord', '>= 5.0.0'
26
+ s.add_dependency 'railties', '>= 5.0.0'
27
+ s.add_dependency 'request_store', '~> 1.4'
23
28
 
24
- s.add_development_dependency 'capybara'
25
- s.add_development_dependency 'database_cleaner'
26
- s.add_development_dependency 'jquery-rails'
27
- s.add_development_dependency 'rake'
28
- s.add_development_dependency 'rails', '>= 3.2'
29
- s.add_development_dependency 'rspec-rails'
30
- s.add_development_dependency 'shoulda-matchers'
31
- s.add_development_dependency 'sqlite3'
29
+ s.add_development_dependency 'minitest-spec-rails', '6.0.2'
30
+ s.add_development_dependency 'pry', '0.12.2'
31
+ s.add_development_dependency 'puma', '4.3.1'
32
+ s.add_development_dependency 'rails', '6.0.2.1'
33
+ s.add_development_dependency 'rake', '13.0.1'
34
+ s.add_development_dependency 'rubocop', '0.79.0'
35
+ s.add_development_dependency 'simplecov', '0.18.1'
36
+ s.add_development_dependency 'sqlite3', '1.4.2'
37
+ s.add_development_dependency 'timecop', '0.9.1'
32
38
  end
metadata CHANGED
@@ -1,311 +1,226 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rate_limiter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.6
5
- prerelease:
4
+ version: 0.1.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Sean Eshbaugh
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-02-26 00:00:00.000000000 Z
11
+ date: 2020-02-14 00:00:00.000000000 Z
13
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activerecord
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 5.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 5.0.0
14
27
  - !ruby/object:Gem::Dependency
15
28
  name: railties
16
29
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
30
  requirements:
19
- - - ! '>='
31
+ - - ">="
20
32
  - !ruby/object:Gem::Version
21
- version: '3.2'
33
+ version: 5.0.0
22
34
  type: :runtime
23
35
  prerelease: false
24
36
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
37
  requirements:
27
- - - ! '>='
38
+ - - ">="
28
39
  - !ruby/object:Gem::Version
29
- version: '3.2'
40
+ version: 5.0.0
30
41
  - !ruby/object:Gem::Dependency
31
- name: activerecord
42
+ name: request_store
32
43
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
44
  requirements:
35
- - - ! '>='
45
+ - - "~>"
36
46
  - !ruby/object:Gem::Version
37
- version: '3.2'
47
+ version: '1.4'
38
48
  type: :runtime
39
49
  prerelease: false
40
50
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
51
  requirements:
43
- - - ! '>='
52
+ - - "~>"
44
53
  - !ruby/object:Gem::Version
45
- version: '3.2'
54
+ version: '1.4'
46
55
  - !ruby/object:Gem::Dependency
47
- name: capybara
56
+ name: minitest-spec-rails
48
57
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
58
  requirements:
51
- - - ! '>='
59
+ - - '='
52
60
  - !ruby/object:Gem::Version
53
- version: '0'
61
+ version: 6.0.2
54
62
  type: :development
55
63
  prerelease: false
56
64
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
65
  requirements:
59
- - - ! '>='
66
+ - - '='
60
67
  - !ruby/object:Gem::Version
61
- version: '0'
68
+ version: 6.0.2
62
69
  - !ruby/object:Gem::Dependency
63
- name: database_cleaner
70
+ name: pry
64
71
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
72
  requirements:
67
- - - ! '>='
73
+ - - '='
68
74
  - !ruby/object:Gem::Version
69
- version: '0'
75
+ version: 0.12.2
70
76
  type: :development
71
77
  prerelease: false
72
78
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
79
  requirements:
75
- - - ! '>='
80
+ - - '='
76
81
  - !ruby/object:Gem::Version
77
- version: '0'
82
+ version: 0.12.2
78
83
  - !ruby/object:Gem::Dependency
79
- name: jquery-rails
84
+ name: puma
80
85
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
86
  requirements:
83
- - - ! '>='
87
+ - - '='
84
88
  - !ruby/object:Gem::Version
85
- version: '0'
89
+ version: 4.3.1
86
90
  type: :development
87
91
  prerelease: false
88
92
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
93
  requirements:
91
- - - ! '>='
94
+ - - '='
92
95
  - !ruby/object:Gem::Version
93
- version: '0'
96
+ version: 4.3.1
94
97
  - !ruby/object:Gem::Dependency
95
- name: rake
98
+ name: rails
96
99
  requirement: !ruby/object:Gem::Requirement
97
- none: false
98
100
  requirements:
99
- - - ! '>='
101
+ - - '='
100
102
  - !ruby/object:Gem::Version
101
- version: '0'
103
+ version: 6.0.2.1
102
104
  type: :development
103
105
  prerelease: false
104
106
  version_requirements: !ruby/object:Gem::Requirement
105
- none: false
106
107
  requirements:
107
- - - ! '>='
108
+ - - '='
108
109
  - !ruby/object:Gem::Version
109
- version: '0'
110
+ version: 6.0.2.1
110
111
  - !ruby/object:Gem::Dependency
111
- name: rails
112
+ name: rake
112
113
  requirement: !ruby/object:Gem::Requirement
113
- none: false
114
114
  requirements:
115
- - - ! '>='
115
+ - - '='
116
116
  - !ruby/object:Gem::Version
117
- version: '3.2'
117
+ version: 13.0.1
118
118
  type: :development
119
119
  prerelease: false
120
120
  version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
121
  requirements:
123
- - - ! '>='
122
+ - - '='
124
123
  - !ruby/object:Gem::Version
125
- version: '3.2'
124
+ version: 13.0.1
126
125
  - !ruby/object:Gem::Dependency
127
- name: rspec-rails
126
+ name: rubocop
128
127
  requirement: !ruby/object:Gem::Requirement
129
- none: false
130
128
  requirements:
131
- - - ! '>='
129
+ - - '='
132
130
  - !ruby/object:Gem::Version
133
- version: '0'
131
+ version: 0.79.0
134
132
  type: :development
135
133
  prerelease: false
136
134
  version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
135
  requirements:
139
- - - ! '>='
136
+ - - '='
140
137
  - !ruby/object:Gem::Version
141
- version: '0'
138
+ version: 0.79.0
142
139
  - !ruby/object:Gem::Dependency
143
- name: shoulda-matchers
140
+ name: simplecov
144
141
  requirement: !ruby/object:Gem::Requirement
145
- none: false
146
142
  requirements:
147
- - - ! '>='
143
+ - - '='
148
144
  - !ruby/object:Gem::Version
149
- version: '0'
145
+ version: 0.18.1
150
146
  type: :development
151
147
  prerelease: false
152
148
  version_requirements: !ruby/object:Gem::Requirement
153
- none: false
154
149
  requirements:
155
- - - ! '>='
150
+ - - '='
156
151
  - !ruby/object:Gem::Version
157
- version: '0'
152
+ version: 0.18.1
158
153
  - !ruby/object:Gem::Dependency
159
154
  name: sqlite3
160
155
  requirement: !ruby/object:Gem::Requirement
161
- none: false
162
156
  requirements:
163
- - - ! '>='
157
+ - - '='
158
+ - !ruby/object:Gem::Version
159
+ version: 1.4.2
160
+ type: :development
161
+ prerelease: false
162
+ version_requirements: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - '='
165
+ - !ruby/object:Gem::Version
166
+ version: 1.4.2
167
+ - !ruby/object:Gem::Dependency
168
+ name: timecop
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - '='
164
172
  - !ruby/object:Gem::Version
165
- version: '0'
173
+ version: 0.9.1
166
174
  type: :development
167
175
  prerelease: false
168
176
  version_requirements: !ruby/object:Gem::Requirement
169
- none: false
170
177
  requirements:
171
- - - ! '>='
178
+ - - '='
172
179
  - !ruby/object:Gem::Version
173
- version: '0'
180
+ version: 0.9.1
174
181
  description: Adds creation rate limiting to ActiveRecord models.
175
- email:
176
- - seaneshbaugh@gmail.com
182
+ email: seaneshbaugh@gmail.com
177
183
  executables: []
178
184
  extensions: []
179
185
  extra_rdoc_files: []
180
186
  files:
181
- - .gitignore
182
- - .rspec
183
- - .rvmrc
184
187
  - CHANGELOG.md
185
- - Gemfile
186
- - Gemfile.lock
188
+ - LICENSE.txt
187
189
  - README.md
188
- - Rakefile
190
+ - lib/generators/rate_limiter/install_generator.rb
191
+ - lib/generators/rate_limiter/templates/rate_limiter.rb
189
192
  - lib/rate_limiter.rb
190
193
  - lib/rate_limiter/config.rb
191
- - lib/rate_limiter/controller.rb
194
+ - lib/rate_limiter/frameworks/rails.rb
195
+ - lib/rate_limiter/frameworks/rails/controller.rb
192
196
  - lib/rate_limiter/model.rb
197
+ - lib/rate_limiter/model_config.rb
198
+ - lib/rate_limiter/request.rb
199
+ - lib/rate_limiter/throttle.rb
200
+ - lib/rate_limiter/validator.rb
193
201
  - lib/rate_limiter/version.rb
194
202
  - rate_limiter.gemspec
195
- - spec/dummy/Rakefile
196
- - spec/dummy/app/assets/images/rails.png
197
- - spec/dummy/app/assets/javascripts/application.js
198
- - spec/dummy/app/assets/stylesheets/application.css
199
- - spec/dummy/app/controllers/application_controller.rb
200
- - spec/dummy/app/controllers/messages_controller.rb
201
- - spec/dummy/app/helpers/application_helper.rb
202
- - spec/dummy/app/mailers/.gitkeep
203
- - spec/dummy/app/models/message.rb
204
- - spec/dummy/app/views/layouts/application.html.erb
205
- - spec/dummy/app/views/messages/_form.html.erb
206
- - spec/dummy/app/views/messages/_message.html.erb
207
- - spec/dummy/app/views/messages/edit.html.erb
208
- - spec/dummy/app/views/messages/index.html.erb
209
- - spec/dummy/app/views/messages/new.html.erb
210
- - spec/dummy/app/views/messages/show.html.erb
211
- - spec/dummy/config.ru
212
- - spec/dummy/config/application.rb
213
- - spec/dummy/config/boot.rb
214
- - spec/dummy/config/database.yml
215
- - spec/dummy/config/environment.rb
216
- - spec/dummy/config/environments/development.rb
217
- - spec/dummy/config/environments/production.rb
218
- - spec/dummy/config/environments/test.rb
219
- - spec/dummy/config/initializers/backtrace_silencers.rb
220
- - spec/dummy/config/initializers/inflections.rb
221
- - spec/dummy/config/initializers/mime_types.rb
222
- - spec/dummy/config/initializers/secret_token.rb
223
- - spec/dummy/config/initializers/session_store.rb
224
- - spec/dummy/config/initializers/wrap_parameters.rb
225
- - spec/dummy/config/locales/en.yml
226
- - spec/dummy/config/routes.rb
227
- - spec/dummy/db/migrate/20121213101512_create_messages.rb
228
- - spec/dummy/db/schema.rb
229
- - spec/dummy/db/seeds.rb
230
- - spec/dummy/lib/assets/.gitkeep
231
- - spec/dummy/lib/tasks/.gitkeep
232
- - spec/dummy/log/.gitkeep
233
- - spec/dummy/public/404.html
234
- - spec/dummy/public/422.html
235
- - spec/dummy/public/500.html
236
- - spec/dummy/public/favicon.ico
237
- - spec/dummy/script/rails
238
- - spec/rate_limiter/model_spec.rb
239
- - spec/rate_limiter_spec.rb
240
- - spec/spec_helper.rb
241
203
  homepage: https://github.com/seaneshbaugh/rate_limiter
242
- licenses: []
204
+ licenses:
205
+ - MIT
206
+ metadata: {}
243
207
  post_install_message:
244
208
  rdoc_options: []
245
209
  require_paths:
246
210
  - lib
247
211
  required_ruby_version: !ruby/object:Gem::Requirement
248
- none: false
249
212
  requirements:
250
- - - ! '>='
213
+ - - ">="
251
214
  - !ruby/object:Gem::Version
252
- version: '0'
215
+ version: 2.5.0
253
216
  required_rubygems_version: !ruby/object:Gem::Requirement
254
- none: false
255
217
  requirements:
256
- - - ! '>='
218
+ - - ">="
257
219
  - !ruby/object:Gem::Version
258
- version: '0'
220
+ version: 1.8.11
259
221
  requirements: []
260
- rubyforge_project: rate_limiter
261
- rubygems_version: 1.8.24
222
+ rubygems_version: 3.1.2
262
223
  signing_key:
263
- specification_version: 3
224
+ specification_version: 4
264
225
  summary: Adds creation rate limiting to ActiveRecord models.
265
- test_files:
266
- - spec/dummy/Rakefile
267
- - spec/dummy/app/assets/images/rails.png
268
- - spec/dummy/app/assets/javascripts/application.js
269
- - spec/dummy/app/assets/stylesheets/application.css
270
- - spec/dummy/app/controllers/application_controller.rb
271
- - spec/dummy/app/controllers/messages_controller.rb
272
- - spec/dummy/app/helpers/application_helper.rb
273
- - spec/dummy/app/mailers/.gitkeep
274
- - spec/dummy/app/models/message.rb
275
- - spec/dummy/app/views/layouts/application.html.erb
276
- - spec/dummy/app/views/messages/_form.html.erb
277
- - spec/dummy/app/views/messages/_message.html.erb
278
- - spec/dummy/app/views/messages/edit.html.erb
279
- - spec/dummy/app/views/messages/index.html.erb
280
- - spec/dummy/app/views/messages/new.html.erb
281
- - spec/dummy/app/views/messages/show.html.erb
282
- - spec/dummy/config.ru
283
- - spec/dummy/config/application.rb
284
- - spec/dummy/config/boot.rb
285
- - spec/dummy/config/database.yml
286
- - spec/dummy/config/environment.rb
287
- - spec/dummy/config/environments/development.rb
288
- - spec/dummy/config/environments/production.rb
289
- - spec/dummy/config/environments/test.rb
290
- - spec/dummy/config/initializers/backtrace_silencers.rb
291
- - spec/dummy/config/initializers/inflections.rb
292
- - spec/dummy/config/initializers/mime_types.rb
293
- - spec/dummy/config/initializers/secret_token.rb
294
- - spec/dummy/config/initializers/session_store.rb
295
- - spec/dummy/config/initializers/wrap_parameters.rb
296
- - spec/dummy/config/locales/en.yml
297
- - spec/dummy/config/routes.rb
298
- - spec/dummy/db/migrate/20121213101512_create_messages.rb
299
- - spec/dummy/db/schema.rb
300
- - spec/dummy/db/seeds.rb
301
- - spec/dummy/lib/assets/.gitkeep
302
- - spec/dummy/lib/tasks/.gitkeep
303
- - spec/dummy/log/.gitkeep
304
- - spec/dummy/public/404.html
305
- - spec/dummy/public/422.html
306
- - spec/dummy/public/500.html
307
- - spec/dummy/public/favicon.ico
308
- - spec/dummy/script/rails
309
- - spec/rate_limiter/model_spec.rb
310
- - spec/rate_limiter_spec.rb
311
- - spec/spec_helper.rb
226
+ test_files: []