double_trouble 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Jakub Kuźma
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/README.rdoc ADDED
@@ -0,0 +1,11 @@
1
+ = Double Trouble
2
+
3
+ Adds nonces to your Rails' forms.
4
+
5
+ == Installation
6
+
7
+ gem install form_nonce
8
+
9
+ == Copyright
10
+
11
+ Copyright (c) 2010 Jakub Kuźma. See LICENSE[http://github.com/qoobaa/form_nonce/raw/master/LICENSE] for details.
@@ -0,0 +1,36 @@
1
+ module DoubleTrouble
2
+ class CachedNonce
3
+ cattr_accessor :expires_in
4
+ self.expires_in = 1.hour
5
+
6
+ attr_accessor :nonce
7
+
8
+ def self.valid?(nonce)
9
+ new(nonce).valid?
10
+ end
11
+
12
+ def self.store!(nonce)
13
+ new(nonce).save!
14
+ end
15
+
16
+ def initialize(nonce)
17
+ self.nonce = nonce
18
+ end
19
+
20
+ def save
21
+ valid? && ::Rails.cache.write(cache_key, true, :expires_in => self.class.expires_in)
22
+ end
23
+
24
+ def save!
25
+ save || raise(InvalidNonce)
26
+ end
27
+
28
+ def valid?
29
+ nonce.present? && !::Rails.cache.exist?(cache_key, :expires_in => self.class.expires_in)
30
+ end
31
+
32
+ def cache_key
33
+ "double_trouble_cached_nonce.#{nonce}"
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,3 @@
1
+ module DoubleTrouble
2
+ class InvalidNonce < StandardError; end
3
+ end
@@ -0,0 +1,20 @@
1
+ # HAX: monkey patching is required to make it work
2
+
3
+ module ActionView::Helpers::FormTagHelper
4
+ private
5
+
6
+ def form_tag_html_with_double_trouble(html_options)
7
+ extra_tags = double_trouble_extra_tags_for_form
8
+ (form_tag_html_without_double_trouble(html_options) + extra_tags).html_safe
9
+ end
10
+
11
+ alias_method_chain :form_tag_html, :double_trouble
12
+
13
+ def double_trouble_extra_tags_for_form
14
+ (protect_against_double_trouble?) ? content_tag(:div, double_trouble_nonce_tag, :style => "margin:0;padding:0;display:inline") : ""
15
+ end
16
+
17
+ def double_trouble_nonce_tag
18
+ tag(:input, :type => "hidden", :name => double_trouble_nonce_param.to_s, :value => double_trouble_form_nonce)
19
+ end
20
+ end
@@ -0,0 +1,54 @@
1
+ module DoubleTrouble
2
+ module Protection
3
+ def self.included(base)
4
+ base.class_eval do
5
+ class_inheritable_accessor :allow_double_trouble_protection
6
+ class_inheritable_accessor :double_trouble_resource_name
7
+ cattr_accessor :double_trouble_nonce_store
8
+ cattr_accessor :double_trouble_nonce_param
9
+ helper_method :protect_against_double_trouble?, :double_trouble_nonce_param, :double_trouble_form_nonce
10
+
11
+ self.allow_double_trouble_protection = true
12
+ extend(ClassMethods)
13
+ end
14
+ end
15
+
16
+ module ClassMethods
17
+ def protect_from_double_trouble(resource_name, options = {})
18
+ self.double_trouble_resource_name = resource_name
19
+ self.double_trouble_nonce_param ||= :form_nonce
20
+ self.double_trouble_nonce_store ||= CachedNonce
21
+
22
+ around_filter :double_trouble_protection, options.slice(:only, :except)
23
+ end
24
+ end
25
+
26
+ protected
27
+
28
+ def double_trouble_protection
29
+ if protect_against_double_trouble?
30
+ nonce = params[double_trouble_nonce_param]
31
+ store = double_trouble_nonce_store
32
+
33
+ store.valid?(nonce) || raise(InvalidNonce)
34
+ yield
35
+ instance_variable_get("@#{double_trouble_resource_name}").tap do |resource|
36
+ resource.present? && !resource.new_record? && store.store!(nonce)
37
+ end
38
+ else
39
+ yield
40
+ end
41
+ end
42
+
43
+ def double_trouble_form_nonce
44
+ ActiveSupport::SecureRandom.base64(32)
45
+ end
46
+
47
+ 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
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,3 @@
1
+ module DoubleTrouble
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,15 @@
1
+ require "active_support"
2
+ require "action_pack"
3
+ require "action_controller"
4
+ require "action_controller/base"
5
+ require "action_view"
6
+ require "action_view/helpers/form_tag_helper"
7
+ require "active_support/cache"
8
+
9
+ require "double_trouble/errors"
10
+ require "double_trouble/cached_nonce"
11
+ require "double_trouble/form_tag_helper_hack"
12
+ require "double_trouble/protection"
13
+ require "double_trouble/version"
14
+
15
+ ActionController::Base.send(:include, DoubleTrouble::Protection)
metadata ADDED
@@ -0,0 +1,120 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: double_trouble
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - "Jakub Ku\xC5\xBAma"
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-07-09 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: rails
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - "="
28
+ - !ruby/object:Gem::Version
29
+ hash: 19
30
+ segments:
31
+ - 2
32
+ - 3
33
+ - 8
34
+ version: 2.3.8
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: test-unit
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ hash: 3
46
+ segments:
47
+ - 2
48
+ - 0
49
+ version: "2.0"
50
+ type: :development
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
53
+ name: mocha
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ hash: 3
61
+ segments:
62
+ - 0
63
+ version: "0"
64
+ type: :development
65
+ version_requirements: *id003
66
+ description: Adds nonces to your Rails' forms
67
+ email: qoobaa@gmail.com
68
+ executables: []
69
+
70
+ extensions: []
71
+
72
+ extra_rdoc_files: []
73
+
74
+ files:
75
+ - lib/double_trouble/errors.rb
76
+ - lib/double_trouble/cached_nonce.rb
77
+ - lib/double_trouble/form_tag_helper_hack.rb
78
+ - lib/double_trouble/version.rb
79
+ - lib/double_trouble/protection.rb
80
+ - lib/double_trouble.rb
81
+ - LICENSE
82
+ - README.rdoc
83
+ has_rdoc: true
84
+ homepage: http://github.com/qoobaa/double_trouble
85
+ licenses: []
86
+
87
+ post_install_message:
88
+ rdoc_options: []
89
+
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ hash: 3
98
+ segments:
99
+ - 0
100
+ version: "0"
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ none: false
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ hash: 21
107
+ segments:
108
+ - 1
109
+ - 3
110
+ - 7
111
+ version: 1.3.7
112
+ requirements: []
113
+
114
+ rubyforge_project:
115
+ rubygems_version: 1.3.7
116
+ signing_key:
117
+ specification_version: 3
118
+ summary: Adds nonces to your Rails' forms
119
+ test_files: []
120
+