rate_limiter 0.0.6 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []