requests_counter 0.1.5
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.
- data/CHANGELOG.rdoc +4 -0
- data/Gemfile +2 -0
- data/MIT-LICENSE +20 -0
- data/Manifest +13 -0
- data/README.md +72 -0
- data/Rakefile +14 -0
- data/init.rb +1 -0
- data/lib/generators/my_requests_counter/install_generator.rb +21 -0
- data/lib/generators/my_requests_counter/templates/create_requests_counters_migration.rb +21 -0
- data/lib/generators/my_requests_counter/templates/requests_counter_init.rb +2 -0
- data/lib/requests_counter.rb +104 -0
- data/requests_counter.gemspec +37 -0
- data/spec/requests_counter_spec.rb +150 -0
- data/spec/spec_helper.rb +27 -0
- data.tar.gz.sig +0 -0
- metadata +121 -0
- metadata.gz.sig +4 -0
data/CHANGELOG.rdoc
ADDED
data/Gemfile
ADDED
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Maciej Mensfeld
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Manifest
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
CHANGELOG.rdoc
|
2
|
+
Gemfile
|
3
|
+
MIT-LICENSE
|
4
|
+
Manifest
|
5
|
+
README.md
|
6
|
+
Rakefile
|
7
|
+
init.rb
|
8
|
+
lib/generators/my_requests_counter/install_generator.rb
|
9
|
+
lib/generators/my_requests_counter/templates/create_requests_counters_migration.rb
|
10
|
+
lib/generators/my_requests_counter/templates/requests_counter_init.rb
|
11
|
+
lib/requests_counter.rb
|
12
|
+
spec/requests_counter_spec.rb
|
13
|
+
spec/spec_helper.rb
|
data/README.md
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
# Requests Counter
|
2
|
+
|
3
|
+
## Install
|
4
|
+
|
5
|
+
gem install requests_counter
|
6
|
+
|
7
|
+
and in your Gemfile:
|
8
|
+
|
9
|
+
gem 'requests_counter'
|
10
|
+
|
11
|
+
## About
|
12
|
+
|
13
|
+
Requests Counter allows you to count attemps to get resource. You can then decide if attemp should be stopped (banned).
|
14
|
+
|
15
|
+
When you want to limit attemps to something (for example to login form), you can count attemps and decide whether to show or not to show login form.
|
16
|
+
|
17
|
+
Works with Ruby 1.8.7, 1.8.7 EE, 1.9.2
|
18
|
+
|
19
|
+
## Requirements
|
20
|
+
|
21
|
+
ActiveRecord
|
22
|
+
|
23
|
+
## Simple example
|
24
|
+
|
25
|
+
# Example with IP
|
26
|
+
10.times { RequestsCounter.with_token('127.0.0.1').permitted? } ==> true
|
27
|
+
RequestsCounter.with_token('127.0.0.1').permit? ==> false
|
28
|
+
|
29
|
+
# You can also use
|
30
|
+
req = RequestsCounter.find_by_token('127.0.0.1')
|
31
|
+
reg.permit? ==> true
|
32
|
+
|
33
|
+
Wait 1 hour and then
|
34
|
+
|
35
|
+
RequestsCounter.with_token('127.0.0.1').permit? ==> true
|
36
|
+
|
37
|
+
Class methods:
|
38
|
+
|
39
|
+
* with_token(token, resource = nil, params ={}) - will give you back resource counter (if not found - will create one)
|
40
|
+
* permitted?(token, resource = nil, params ={}) - will tell you is token permitted to resource - without counting attempts
|
41
|
+
* permit?(token, resource = nil, params ={}) - same as above, but will count attempts
|
42
|
+
* remaining(token, resource = nil, params ={}) - how much attempts left
|
43
|
+
|
44
|
+
Instance methods:
|
45
|
+
|
46
|
+
* permitted? - will tell you is token permitted to resource - without counting attempts
|
47
|
+
* permit? - same as above, but will count attempts
|
48
|
+
* reset! - will reset counter
|
49
|
+
* remaining - how much attempts left
|
50
|
+
|
51
|
+
For more examples view rspec.
|
52
|
+
|
53
|
+
## Setup
|
54
|
+
|
55
|
+
rails generate my_requests_counter:install
|
56
|
+
|
57
|
+
## Tests
|
58
|
+
|
59
|
+
rspec requests_counter_spec.rb
|
60
|
+
|
61
|
+
## Note on Patches/Pull Requests
|
62
|
+
|
63
|
+
* Fork the project.
|
64
|
+
* Make your feature addition or bug fix.
|
65
|
+
* Add tests for it. This is important so I don't break it in a future version unintentionally.
|
66
|
+
* Commit, do not mess with Rakefile, version, or history.
|
67
|
+
(if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
68
|
+
* Send me a pull request. Bonus points for topic branches.
|
69
|
+
|
70
|
+
## Copyright
|
71
|
+
|
72
|
+
Copyright (c) 2011 Maciej Mensfeld. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'echoe'
|
4
|
+
|
5
|
+
Echoe.new('requests_counter', '0.1.5') do |p|
|
6
|
+
p.description = "Requests Counter allows you to count attemps to get resource. You can then decide if attemp should be stopped (banned)."
|
7
|
+
p.url = "https://github.com/mensfeld/Requests-Counter"
|
8
|
+
p.author = "Maciej Mensfeld"
|
9
|
+
p.email = "maciej@mensfeld.pl"
|
10
|
+
p.ignore_pattern = ["tmp/*", "script/*"]
|
11
|
+
p.development_dependencies = ["rspec >=2.0.0"]
|
12
|
+
p.dependencies = ["activerecord"]
|
13
|
+
end
|
14
|
+
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'requests_counter'
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module MyRequestsCounter
|
2
|
+
class InstallGenerator < Rails::Generators::Base
|
3
|
+
source_root File.expand_path("../templates", __FILE__)
|
4
|
+
|
5
|
+
def add_my_migration
|
6
|
+
timestamp = Time.now.strftime("%Y%m%d%H%M%S")
|
7
|
+
source = "create_requests_counters_migration.rb"
|
8
|
+
target = "db/migrate/#{timestamp}_create_requests_counters.rb"
|
9
|
+
copy_file source, target
|
10
|
+
end
|
11
|
+
|
12
|
+
def add_initializer
|
13
|
+
source = "requests_counter_init.rb"
|
14
|
+
target = "config/initializers/requests_counter.rb"
|
15
|
+
copy_file source, target
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class CreateRequestsCounters < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
|
4
|
+
create_table :requests_counters do |t|
|
5
|
+
t.string :token
|
6
|
+
t.string :resource
|
7
|
+
t.integer :attempts, :default => 0
|
8
|
+
t.integer :available_attempts, :default => 10
|
9
|
+
t.string :wait_time, :default => '1h'
|
10
|
+
t.datetime :last_logged
|
11
|
+
end
|
12
|
+
|
13
|
+
add_index :requests_counters, :resource
|
14
|
+
add_index :requests_counters, :token
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.down
|
19
|
+
drop_table :requests_counters
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
class RequestsCounter < ActiveRecord::Base
|
2
|
+
|
3
|
+
after_initialize :check_defaults
|
4
|
+
|
5
|
+
before_save :init_available_attempts
|
6
|
+
|
7
|
+
class << self
|
8
|
+
attr_accessor :available_attempts
|
9
|
+
attr_accessor :wait_time
|
10
|
+
end
|
11
|
+
|
12
|
+
class AvailableAttemptsNotInitialized < StandardError; end
|
13
|
+
class WaitTimeNotInitialized < StandardError; end
|
14
|
+
|
15
|
+
validates :token, :presence => true
|
16
|
+
|
17
|
+
# Searches for instance element with provided token and resource
|
18
|
+
# and if it does not find one - will create new and return it to us
|
19
|
+
def self.with_token(token, resource = nil, params = {})
|
20
|
+
unless el = self.where(:token => token, :resource => resource).first
|
21
|
+
el = self.create({
|
22
|
+
:token => token,
|
23
|
+
:resource => resource
|
24
|
+
}.merge(params))
|
25
|
+
end
|
26
|
+
el
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.permitted?(token, resource = nil, params = {})
|
30
|
+
self.with_token(token, resource, params).permitted?
|
31
|
+
end
|
32
|
+
|
33
|
+
def permitted?
|
34
|
+
if attempts < available_attempts
|
35
|
+
true
|
36
|
+
else
|
37
|
+
if time_permitted?
|
38
|
+
reset!
|
39
|
+
true
|
40
|
+
else
|
41
|
+
false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def self.permit?(token, resource = nil, params = {})
|
47
|
+
self.with_token(token, resource, params).permit?
|
48
|
+
end
|
49
|
+
|
50
|
+
def permit?
|
51
|
+
perm = permitted?
|
52
|
+
incr!
|
53
|
+
perm
|
54
|
+
end
|
55
|
+
|
56
|
+
def reset!
|
57
|
+
self.update_attributes(:attempts => 0)
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.remaining(token, resource = nil, params = {})
|
61
|
+
self.with_token(token, resource, params).remaining
|
62
|
+
end
|
63
|
+
|
64
|
+
def remaining
|
65
|
+
r = available_attempts - attempts
|
66
|
+
r = 0 if r < 0
|
67
|
+
r
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def init_available_attempts
|
73
|
+
if self.available_attempts.nil? || self.available_attempts < 1
|
74
|
+
self.available_attempts = self.class.available_attempts
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def time_permitted?
|
79
|
+
time = case self.wait_time
|
80
|
+
when /^(\d+)m$/ then Time.now - $1.to_i.minute
|
81
|
+
when /^(\d+)h$/ then Time.now - $1.to_i.hour
|
82
|
+
when /^(\d+)d$/ then Time.now - $1.to_i.day
|
83
|
+
else Time.now - 1.hour
|
84
|
+
end
|
85
|
+
self.last_logged < time
|
86
|
+
end
|
87
|
+
|
88
|
+
# Refreshes our internal timestamp
|
89
|
+
def refresh!
|
90
|
+
self.update_attributes(:last_logged => Time.now)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Increments our internatl attempts counter
|
94
|
+
def incr!
|
95
|
+
self.update_attributes(:attempts => self.attempts+1, :last_logged => Time.now)
|
96
|
+
end
|
97
|
+
|
98
|
+
# Default values should be initialized
|
99
|
+
def check_defaults
|
100
|
+
raise AvailableAttemptsNotInitialized unless self.class.available_attempts
|
101
|
+
raise WaitTimeNotInitialized unless self.class.wait_time
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{requests_counter}
|
5
|
+
s.version = "0.1.5"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["Maciej Mensfeld"]
|
9
|
+
s.cert_chain = ["/home/mencio/.cert_keys/gem-public_cert.pem"]
|
10
|
+
s.date = %q{2011-06-01}
|
11
|
+
s.description = %q{Requests Counter allows you to count attemps to get resource. You can then decide if attemp should be stopped (banned).}
|
12
|
+
s.email = %q{maciej@mensfeld.pl}
|
13
|
+
s.extra_rdoc_files = ["CHANGELOG.rdoc", "README.md", "lib/generators/my_requests_counter/install_generator.rb", "lib/generators/my_requests_counter/templates/create_requests_counters_migration.rb", "lib/generators/my_requests_counter/templates/requests_counter_init.rb", "lib/requests_counter.rb"]
|
14
|
+
s.files = ["CHANGELOG.rdoc", "Gemfile", "MIT-LICENSE", "Manifest", "README.md", "Rakefile", "init.rb", "lib/generators/my_requests_counter/install_generator.rb", "lib/generators/my_requests_counter/templates/create_requests_counters_migration.rb", "lib/generators/my_requests_counter/templates/requests_counter_init.rb", "lib/requests_counter.rb", "spec/requests_counter_spec.rb", "spec/spec_helper.rb", "requests_counter.gemspec"]
|
15
|
+
s.homepage = %q{https://github.com/mensfeld/Requests-Counter}
|
16
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Requests_counter", "--main", "README.md"]
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
s.rubyforge_project = %q{requests_counter}
|
19
|
+
s.rubygems_version = %q{1.5.2}
|
20
|
+
s.signing_key = %q{/home/mencio/.cert_keys/gem-private_key.pem}
|
21
|
+
s.summary = %q{Requests Counter allows you to count attemps to get resource. You can then decide if attemp should be stopped (banned).}
|
22
|
+
|
23
|
+
if s.respond_to? :specification_version then
|
24
|
+
s.specification_version = 3
|
25
|
+
|
26
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
27
|
+
s.add_runtime_dependency(%q<activerecord>, [">= 0"])
|
28
|
+
s.add_development_dependency(%q<rspec>, [">= 2.0.0"])
|
29
|
+
else
|
30
|
+
s.add_dependency(%q<activerecord>, [">= 0"])
|
31
|
+
s.add_dependency(%q<rspec>, [">= 2.0.0"])
|
32
|
+
end
|
33
|
+
else
|
34
|
+
s.add_dependency(%q<activerecord>, [">= 0"])
|
35
|
+
s.add_dependency(%q<rspec>, [">= 2.0.0"])
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,150 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
ROOT = File.expand_path(File.dirname(__FILE__))
|
4
|
+
|
5
|
+
|
6
|
+
RequestsCounter.wait_time = "10m"
|
7
|
+
RequestsCounter.available_attempts = 10
|
8
|
+
|
9
|
+
describe RequestsCounter do
|
10
|
+
subject { RequestsCounter }
|
11
|
+
after(:each){ RequestsCounter.destroy_all }
|
12
|
+
|
13
|
+
context "when we want to have subject instance" do
|
14
|
+
context "but we don't have any with corresponding ip" do
|
15
|
+
it "should create one and return it to use" do
|
16
|
+
subject.count.should == 0
|
17
|
+
subject.with_token('127.0.0.1').should_not == nil
|
18
|
+
subject.count.should == 1
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "and we have one already" do
|
23
|
+
it "should fetch it and return to us" do
|
24
|
+
subject.count.should == 0
|
25
|
+
subject.with_token('127.0.0.1')
|
26
|
+
subject.count.should == 1
|
27
|
+
subject.with_token('127.0.0.1')
|
28
|
+
subject.with_token('127.0.0.1')
|
29
|
+
subject.count.should == 1
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
context "with additional key" do
|
34
|
+
context "but we don't have any with corresponding ip" do
|
35
|
+
it "should create one and return it to use" do
|
36
|
+
subject.count.should == 0
|
37
|
+
subject.with_token('127.0.0.1', :test).should_not == nil
|
38
|
+
subject.count.should == 1
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "and we have one but with different key" do
|
43
|
+
it "should fetch a new one and return to us" do
|
44
|
+
subject.count.should == 0
|
45
|
+
subject.with_token('127.0.0.1')
|
46
|
+
subject.with_token('127.0.0.1', :test).should_not == nil
|
47
|
+
subject.count.should == 2
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "and we have one with good key" do
|
52
|
+
it "should return it to us" do
|
53
|
+
subject.count.should == 0
|
54
|
+
subject.with_token('127.0.0.1', :test).should_not == nil
|
55
|
+
subject.count.should == 1
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
|
61
|
+
context "and we want one with different available_attempts" do
|
62
|
+
it "should create it for us" do
|
63
|
+
el = subject.with_token('127.0.0.1', :resource, {:available_attempts => 12})
|
64
|
+
el.available_attempts.should == 12
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
context "and we want one with different wait_time" do
|
69
|
+
it "should create it for us" do
|
70
|
+
el = subject.with_token('127.0.0.1', :resource, {:wait_time => '4h'})
|
71
|
+
el.wait_time.should == '4h'
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
76
|
+
|
77
|
+
context "when we check if new ip is permitted" do
|
78
|
+
context "when we use class interface" do
|
79
|
+
it "should return true and should not count attempts" do
|
80
|
+
subject.permitted?('127.0.0.1').should == true
|
81
|
+
subject.permitted?('127.0.0.1', :resource).should == true
|
82
|
+
subject.with_token('127.0.0.1', :resource).attempts.should == 0
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context "when we use instance interface" do
|
87
|
+
it "should return true and should not count attempts" do
|
88
|
+
el = subject.with_token('127.0.0.1', :resource)
|
89
|
+
el.permitted?.should == true
|
90
|
+
el.reload
|
91
|
+
el.attempts.should == 0
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context "when we check if we can permit resource" do
|
97
|
+
context "when we use class interface" do
|
98
|
+
it "should return true and should count attempts" do
|
99
|
+
subject.permit?('127.0.0.1').should == true
|
100
|
+
subject.permit?('127.0.0.1', :resource).should == true
|
101
|
+
subject.with_token('127.0.0.1', :resource).attempts.should == 1
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context "when we use instance interface" do
|
106
|
+
it "should return true and should count attempts" do
|
107
|
+
el = subject.with_token('127.0.0.1', :resource)
|
108
|
+
el.permit?.should == true
|
109
|
+
el.permit?.should == true
|
110
|
+
el.reload
|
111
|
+
el.attempts.should == 2
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context "when we request smthng 2 many times" do
|
117
|
+
it "should ban us" do
|
118
|
+
10.times { subject.permit?('127.0.0.1').should == true }
|
119
|
+
subject.permit?('127.0.0.1').should == false
|
120
|
+
subject.with_token('127.0.0.1').permit?.should == false
|
121
|
+
end
|
122
|
+
|
123
|
+
context "but time has passed ..." do
|
124
|
+
it "should unban us" do
|
125
|
+
10.times { subject.permit?('127.0.0.1').should == true }
|
126
|
+
subject.permit?('127.0.0.1').should == false
|
127
|
+
subject.with_token('127.0.0.1').update_attributes(:last_logged => 2.hours.ago)
|
128
|
+
subject.permit?('127.0.0.1').should == true
|
129
|
+
subject.with_token('127.0.0.1').attempts.should == 1
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
context "when we make first request" do
|
136
|
+
it "should return us 9 remaining requests left" do
|
137
|
+
subject.permit?('127.0.0.1')
|
138
|
+
subject.with_token('127.0.0.1').remaining.should == 9
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
context "when we request something a lot of times" do
|
143
|
+
it "should not left us any remaining requests" do
|
144
|
+
20.times { subject.permit?('127.0.0.1') }
|
145
|
+
subject.with_token('127.0.0.1').remaining.should == 0
|
146
|
+
subject.remaining('127.0.0.1').should == 0
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
2
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
3
|
+
|
4
|
+
require 'rubygems'
|
5
|
+
require 'sqlite3'
|
6
|
+
require 'active_record'
|
7
|
+
require 'requests_counter'
|
8
|
+
|
9
|
+
ActiveRecord::Base.establish_connection(
|
10
|
+
:adapter => "sqlite3",
|
11
|
+
:database => ":memory:"
|
12
|
+
)
|
13
|
+
|
14
|
+
ActiveRecord::Schema.define do
|
15
|
+
ActiveRecord::Base.connection.create_table(:requests_counters) do |t|
|
16
|
+
t.column :token, :string
|
17
|
+
t.column :resource, :string
|
18
|
+
t.column :attempts, :integer, :default => 0
|
19
|
+
t.column :available_attempts, :integer, :default => 10
|
20
|
+
t.column :wait_time, :string, :default => '1h'
|
21
|
+
t.column :last_logged, :datetime
|
22
|
+
end
|
23
|
+
|
24
|
+
add_index :requests_counters, :resource
|
25
|
+
add_index :requests_counters, :token
|
26
|
+
end
|
27
|
+
|
data.tar.gz.sig
ADDED
Binary file
|
metadata
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: requests_counter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.5
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Maciej Mensfeld
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain:
|
12
|
+
- |
|
13
|
+
-----BEGIN CERTIFICATE-----
|
14
|
+
MIIDMjCCAhqgAwIBAgIBADANBgkqhkiG9w0BAQUFADA/MQ8wDQYDVQQDDAZtYWNp
|
15
|
+
ZWoxGDAWBgoJkiaJk/IsZAEZFghtZW5zZmVsZDESMBAGCgmSJomT8ixkARkWAnBs
|
16
|
+
MB4XDTExMDQwOTA5NDcyMloXDTEyMDQwODA5NDcyMlowPzEPMA0GA1UEAwwGbWFj
|
17
|
+
aWVqMRgwFgYKCZImiZPyLGQBGRYIbWVuc2ZlbGQxEjAQBgoJkiaJk/IsZAEZFgJw
|
18
|
+
bDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAL0+nG3V4/exIeiJ0IN+
|
19
|
+
wVfq8Utcu4Qpo+58EIVMIu3FiK+8w6MBvatZnUrRu12pqWLw9xrUkCiYeRErD+jF
|
20
|
+
AmdggIM/tu9CcjvURXH7VeTzOVA+pnV+eJWMD61o8HljFVcb/nyEYYVKErtr9/O4
|
21
|
+
QrIGv5lnszq1PMj2sBMy2gOP1YnzawncMLmkpp/T5SU4JZ5gAktGMRVz8RxmZzF5
|
22
|
+
6NVqFLbuqSRSU5U//WJvZVJt8dycCGgQzBM4Vi3nkOWyjIF0BANf1TqnlU2u6s8d
|
23
|
+
UK1AoDZfg5feef5e8eqoomHebX1opNGM/SOQhu3LRgax4rJfnl6VS3I2wighohsf
|
24
|
+
AgcCAwEAAaM5MDcwCQYDVR0TBAIwADAdBgNVHQ4EFgQUGlrWBqxVieAPk7NEzBDp
|
25
|
+
kM+iAMMwCwYDVR0PBAQDAgSwMA0GCSqGSIb3DQEBBQUAA4IBAQAJMoyBaJs8boiz
|
26
|
+
lFpbw6MWjk+7ZhqoHpFrWEV4nzb5GzyHZ7GU/pa1fSEQR0SCs+LnTLQbAYNQyUTT
|
27
|
+
O+UsTuA7xzI//v6cSodv3Q9NbfoDlou74xv1NXorWoosQFMpVWrXv+c/1RqU3cq4
|
28
|
+
WUr+rRiveEXG4tXOwkrpX8KH8xVp2vQZcGw3AXPqhzfqDGzpHd6ws3lk+8HoSrSo
|
29
|
+
2L68tDoxraF2Z2toAg9vfFw1+mOeDk1xVIPVcBy3tJxstHfHGHlQuMiRiDQX2b2D
|
30
|
+
YYU8UWVt2841IwB5Dgl4O+atXhe9ZTBO0W32pl4Bq5CP9lhQRT1KL7sxfznJlF7Y
|
31
|
+
BH3YFsdk
|
32
|
+
-----END CERTIFICATE-----
|
33
|
+
|
34
|
+
date: 2011-06-01 00:00:00 +02:00
|
35
|
+
default_executable:
|
36
|
+
dependencies:
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: activerecord
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ">="
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: "0"
|
46
|
+
type: :runtime
|
47
|
+
version_requirements: *id001
|
48
|
+
- !ruby/object:Gem::Dependency
|
49
|
+
name: rspec
|
50
|
+
prerelease: false
|
51
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
52
|
+
none: false
|
53
|
+
requirements:
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 2.0.0
|
57
|
+
type: :development
|
58
|
+
version_requirements: *id002
|
59
|
+
description: Requests Counter allows you to count attemps to get resource. You can then decide if attemp should be stopped (banned).
|
60
|
+
email: maciej@mensfeld.pl
|
61
|
+
executables: []
|
62
|
+
|
63
|
+
extensions: []
|
64
|
+
|
65
|
+
extra_rdoc_files:
|
66
|
+
- CHANGELOG.rdoc
|
67
|
+
- README.md
|
68
|
+
- lib/generators/my_requests_counter/install_generator.rb
|
69
|
+
- lib/generators/my_requests_counter/templates/create_requests_counters_migration.rb
|
70
|
+
- lib/generators/my_requests_counter/templates/requests_counter_init.rb
|
71
|
+
- lib/requests_counter.rb
|
72
|
+
files:
|
73
|
+
- CHANGELOG.rdoc
|
74
|
+
- Gemfile
|
75
|
+
- MIT-LICENSE
|
76
|
+
- Manifest
|
77
|
+
- README.md
|
78
|
+
- Rakefile
|
79
|
+
- init.rb
|
80
|
+
- lib/generators/my_requests_counter/install_generator.rb
|
81
|
+
- lib/generators/my_requests_counter/templates/create_requests_counters_migration.rb
|
82
|
+
- lib/generators/my_requests_counter/templates/requests_counter_init.rb
|
83
|
+
- lib/requests_counter.rb
|
84
|
+
- spec/requests_counter_spec.rb
|
85
|
+
- spec/spec_helper.rb
|
86
|
+
- requests_counter.gemspec
|
87
|
+
has_rdoc: true
|
88
|
+
homepage: https://github.com/mensfeld/Requests-Counter
|
89
|
+
licenses: []
|
90
|
+
|
91
|
+
post_install_message:
|
92
|
+
rdoc_options:
|
93
|
+
- --line-numbers
|
94
|
+
- --inline-source
|
95
|
+
- --title
|
96
|
+
- Requests_counter
|
97
|
+
- --main
|
98
|
+
- README.md
|
99
|
+
require_paths:
|
100
|
+
- lib
|
101
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
102
|
+
none: false
|
103
|
+
requirements:
|
104
|
+
- - ">="
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: "0"
|
107
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
108
|
+
none: false
|
109
|
+
requirements:
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: "1.2"
|
113
|
+
requirements: []
|
114
|
+
|
115
|
+
rubyforge_project: requests_counter
|
116
|
+
rubygems_version: 1.5.2
|
117
|
+
signing_key:
|
118
|
+
specification_version: 3
|
119
|
+
summary: Requests Counter allows you to count attemps to get resource. You can then decide if attemp should be stopped (banned).
|
120
|
+
test_files: []
|
121
|
+
|
metadata.gz.sig
ADDED