double_trouble 0.1.0 → 0.1.1
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/README.rdoc +48 -2
- data/lib/double_trouble/protection.rb +15 -20
- data/lib/double_trouble/version.rb +1 -1
- metadata +6 -6
data/README.rdoc
CHANGED
@@ -1,10 +1,56 @@
|
|
1
1
|
= Double Trouble
|
2
2
|
|
3
|
-
Adds nonces to your Rails' forms
|
3
|
+
Adds nonces to your Rails' forms, avoiding duplicates by sending the
|
4
|
+
same form again (when the user has ADHD, as well in the other
|
5
|
+
situations).
|
4
6
|
|
5
7
|
== Installation
|
6
8
|
|
7
|
-
gem install
|
9
|
+
gem install double_trouble
|
10
|
+
|
11
|
+
== Usage
|
12
|
+
|
13
|
+
class CommentsController < ApplicationController
|
14
|
+
protect_from_double_trouble :comment, :only => :create
|
15
|
+
|
16
|
+
def create
|
17
|
+
@comment = Comment.new(params[:comment])
|
18
|
+
if @comment.save
|
19
|
+
# ordinary stuff
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
Double trouble works quite similar to CSRF protection
|
25
|
+
(authenticity_token) - it adds form_nonce parameter to your
|
26
|
+
forms. After the protected model is successfully saved (when
|
27
|
+
new_record? returns false), it stores received form_nonce in the
|
28
|
+
Rails.cache by default (you can easily replace the default store by DB
|
29
|
+
backend for instance).
|
30
|
+
|
31
|
+
== Configuration
|
32
|
+
|
33
|
+
You can globally turn the protection off (test environment?):
|
34
|
+
|
35
|
+
ActionController::Base.allow_double_trouble_protection = false
|
36
|
+
|
37
|
+
Default nonce store can be changed:
|
38
|
+
|
39
|
+
ActionController::Base.double_trouble_nonce_store = FormNonce
|
40
|
+
|
41
|
+
FormNonce class must implement two class methods:
|
42
|
+
|
43
|
+
def self.valid?(nonce)
|
44
|
+
# checks if the nonce has not been used before
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.store!(nonce)
|
48
|
+
# stores the given nonce somewhere
|
49
|
+
end
|
50
|
+
|
51
|
+
The name of the form nonce param can be changed as well:
|
52
|
+
|
53
|
+
ActionController::Base.double_trouble_nonce_param = :double_trouble_nonce
|
8
54
|
|
9
55
|
== Copyright
|
10
56
|
|
@@ -3,52 +3,47 @@ module DoubleTrouble
|
|
3
3
|
def self.included(base)
|
4
4
|
base.class_eval do
|
5
5
|
class_inheritable_accessor :allow_double_trouble_protection
|
6
|
-
class_inheritable_accessor :double_trouble_resource_name
|
7
6
|
cattr_accessor :double_trouble_nonce_store
|
8
7
|
cattr_accessor :double_trouble_nonce_param
|
9
8
|
helper_method :protect_against_double_trouble?, :double_trouble_nonce_param, :double_trouble_form_nonce
|
10
9
|
|
11
10
|
self.allow_double_trouble_protection = true
|
11
|
+
|
12
12
|
extend(ClassMethods)
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
16
|
module ClassMethods
|
17
17
|
def protect_from_double_trouble(resource_name, options = {})
|
18
|
-
self.double_trouble_resource_name = resource_name
|
19
18
|
self.double_trouble_nonce_param ||= :form_nonce
|
20
19
|
self.double_trouble_nonce_store ||= CachedNonce
|
21
20
|
|
22
|
-
around_filter
|
23
|
-
|
24
|
-
|
21
|
+
around_filter(options.slice(:only, :except)) do |controller, action_block|
|
22
|
+
if controller.send(:protect_against_double_trouble?)
|
23
|
+
nonce = controller.params[double_trouble_nonce_param]
|
25
24
|
|
26
|
-
|
25
|
+
double_trouble_nonce_store.valid?(nonce) || raise(InvalidNonce)
|
27
26
|
|
28
|
-
|
29
|
-
if protect_against_double_trouble?
|
30
|
-
nonce = params[double_trouble_nonce_param]
|
31
|
-
store = double_trouble_nonce_store
|
27
|
+
action_block.call
|
32
28
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
29
|
+
controller.instance_variable_get("@#{resource_name}").tap do |resource|
|
30
|
+
resource.present? && !resource.new_record? && double_trouble_nonce_store.store!(nonce)
|
31
|
+
end
|
32
|
+
else
|
33
|
+
action_block.call
|
34
|
+
end
|
37
35
|
end
|
38
|
-
else
|
39
|
-
yield
|
40
36
|
end
|
41
37
|
end
|
42
38
|
|
39
|
+
protected
|
40
|
+
|
43
41
|
def double_trouble_form_nonce
|
44
42
|
ActiveSupport::SecureRandom.base64(32)
|
45
43
|
end
|
46
44
|
|
47
45
|
def protect_against_double_trouble?
|
48
|
-
allow_double_trouble_protection &&
|
49
|
-
double_trouble_resource_name &&
|
50
|
-
double_trouble_nonce_store &&
|
51
|
-
double_trouble_nonce_param
|
46
|
+
allow_double_trouble_protection && double_trouble_nonce_store && double_trouble_nonce_param
|
52
47
|
end
|
53
48
|
end
|
54
49
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: double_trouble
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 1
|
10
|
+
version: 0.1.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- "Jakub Ku\xC5\xBAma"
|
@@ -72,11 +72,11 @@ extensions: []
|
|
72
72
|
extra_rdoc_files: []
|
73
73
|
|
74
74
|
files:
|
75
|
-
- lib/double_trouble/errors.rb
|
76
|
-
- lib/double_trouble/cached_nonce.rb
|
77
75
|
- lib/double_trouble/form_tag_helper_hack.rb
|
78
|
-
- lib/double_trouble/version.rb
|
79
76
|
- lib/double_trouble/protection.rb
|
77
|
+
- lib/double_trouble/cached_nonce.rb
|
78
|
+
- lib/double_trouble/version.rb
|
79
|
+
- lib/double_trouble/errors.rb
|
80
80
|
- lib/double_trouble.rb
|
81
81
|
- LICENSE
|
82
82
|
- README.rdoc
|