lemonga.rb 1.0.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 (4) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +42 -0
  3. data/lib/lemonga.rb +54 -0
  4. metadata +78 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 76e8aedae525aac799317e5dd16148ecbf7eaf43
4
+ data.tar.gz: 8c29815459970f988d1bfd2ed9a8a718931526c6
5
+ SHA512:
6
+ metadata.gz: 25911ec6c95e8a9bcef24a9c1039b68cd163d14a0b45bef0b73c012411c57eadcb7d64e814444210ff5376a96d777fda62fb199df1db8ee87941b89bf3007178
7
+ data.tar.gz: ff8fd07450470cbba005f2313a67ed0536dab5958d9c7bf1d4006f8a7f3df4819a0169c073d0ed883a1e20dbbd1e0743cbde4705ffa81f761235e6a260980943
data/README.md ADDED
@@ -0,0 +1,42 @@
1
+ # lemonga.rb
2
+
3
+ Screaming-fast IP rate limiting. Call `duration.dungeon!` in your controller (or
4
+ anywhere, actually) to block the client's IP for the given amount of time.
5
+
6
+ ```rb
7
+ class CastleController < ApplicationController
8
+ def index
9
+ 1_000_000.years.dungeon!
10
+ end
11
+ end
12
+ ```
13
+
14
+ This will return a 406 and block the client from hitting any part of the app
15
+ until the time limit expires. If they make any more requests before the time is
16
+ up their sentence will start all over again.
17
+
18
+ If you want to use something other than IP address to identify the client, use
19
+ the `unacceptable!` hook.
20
+
21
+ ```rb
22
+ class CastleController < ApplicationController
23
+ unacceptable! { session[:user_id] }
24
+ end
25
+ ```
26
+
27
+
28
+ ## License
29
+
30
+ Copyright (C) 2014 James Coglan
31
+
32
+ This program is free software: you can redistribute it and/or modify it under
33
+ the terms of the GNU General Public License as published by the Free Software
34
+ Foundation, either version 3 of the License, or (at your option) any later
35
+ version.
36
+
37
+ This program is distributed in the hope that it will be useful, but WITHOUT ANY
38
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
39
+ PARTICULAR PURPOSE. See the GNU General Public License for more details.
40
+
41
+ You should have received a copy of the GNU General Public License along with
42
+ this program. If not, see http://www.gnu.org/licenses/.
data/lib/lemonga.rb ADDED
@@ -0,0 +1,54 @@
1
+ module Lemongrab
2
+ cattr_accessor :dungeon
3
+ self.dungeon = {}
4
+
5
+ module Dungeon
6
+ def dungeon!
7
+ raise Punishment, self
8
+ end
9
+ end
10
+
11
+ class Punishment < StandardError
12
+ include ActionView::Helpers::DateHelper
13
+
14
+ attr_reader :duration
15
+
16
+ def initialize(duration)
17
+ @duration = duration
18
+ end
19
+
20
+ def message
21
+ time_ago_in_words(@duration.from_now).upcase + " DUNGEON\n"
22
+ end
23
+ end
24
+
25
+ [Numeric, ActiveSupport::Duration].each do |klass|
26
+ klass.module_eval { include Dungeon }
27
+ end
28
+
29
+ ActionController::Base.module_eval do
30
+ def self.unacceptable!(&block)
31
+ define_method(:who_did_the_thing?, &block)
32
+ end
33
+
34
+ before_filter :clean_this_place_up
35
+
36
+ rescue_from Punishment do |error|
37
+ release_time = error.duration.from_now
38
+ Lemongrab.dungeon.store(who_did_the_thing?, [error.duration, release_time])
39
+ render(text: error.message, status: 406)
40
+ end
41
+
42
+ private
43
+
44
+ def who_did_the_thing?
45
+ request.remote_ip
46
+ end
47
+
48
+ def clean_this_place_up
49
+ duration, release_time = Lemongrab.dungeon.delete(who_did_the_thing?)
50
+ return true if release_time.nil? or Time.now >= release_time
51
+ duration.dungeon!
52
+ end
53
+ end
54
+ end
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lemonga.rb
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - James Coglan
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-10-10 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: actionpack
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description:
42
+ email: jcoglan@gmail.com
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files:
46
+ - README.md
47
+ files:
48
+ - README.md
49
+ - lib/lemonga.rb
50
+ homepage: http://github.com/jcoglan/lemonga.rb
51
+ licenses:
52
+ - GPL
53
+ metadata: {}
54
+ post_install_message:
55
+ rdoc_options:
56
+ - "--main"
57
+ - README.md
58
+ - "--markup"
59
+ - markdown
60
+ require_paths:
61
+ - lib
62
+ required_ruby_version: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ required_rubygems_version: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '0'
72
+ requirements: []
73
+ rubyforge_project:
74
+ rubygems_version: 2.2.2
75
+ signing_key:
76
+ specification_version: 4
77
+ summary: just a harmless prank... for laughs
78
+ test_files: []