signed_form 0.2.0 → 0.5.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.
- checksums.yaml +5 -5
- data/.gitignore +1 -0
- data/.travis.yml +4 -0
- data/Changes.md +76 -8
- data/Gemfile +5 -11
- data/README.md +22 -2
- data/lib/signed_form.rb +0 -1
- data/lib/signed_form/action_controller/permit_signed_params.rb +5 -1
- data/lib/signed_form/form_builder.rb +43 -7
- data/lib/signed_form/hmac.rb +6 -0
- data/lib/signed_form/version.rb +1 -1
- data/signed_form.gemspec +3 -2
- data/spec/form_builder_spec.rb +104 -10
- data/spec/hmac_spec.rb +2 -2
- data/spec/permit_signed_params_spec.rb +7 -5
- data/spec/spec_helper.rb +1 -0
- metadata +37 -22
- data/lib/signed_form/engine.rb +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e8d65b2f35d3f09c9d3a8f19fa9f09fb5ba4861c97953b4d5fc47fd2e046f180
|
4
|
+
data.tar.gz: a5e96ac88b81ad28bf1a3f047181b4e9cf6ae35f75d8e9780f8f5adec42961c0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0f1f672f5aa3f8a269129b4d37fba225d75fd7bcc47a3bfbf63a45bd19417cdc7b0978419ca008a95f61b8b0cf3e6b69b5ada2c9098aeb5f2dc34a33b839daeb
|
7
|
+
data.tar.gz: e2242bf0dd88d0e8ebfd3a9bb74072b0412de296f4c12e617a335df64ed1b3f1984ad6f211cbdae038153374822165230aa73e162cdc51f1e727180cc3c61c78
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -4,11 +4,15 @@ language: ruby
|
|
4
4
|
rvm:
|
5
5
|
- 1.9.3
|
6
6
|
- 2.0.0
|
7
|
+
- 2.1.0
|
8
|
+
- 2.2.0
|
7
9
|
|
8
10
|
env:
|
9
11
|
- RAILS_VERSION=3-1-stable
|
10
12
|
- RAILS_VERSION=3-2-stable
|
11
13
|
- RAILS_VERSION=4-0-stable
|
14
|
+
- RAILS_VERSION=4-1-stable
|
15
|
+
- RAILS_VERSION=4-2-stable
|
12
16
|
- RAILS_VERSION=master
|
13
17
|
|
14
18
|
matrix:
|
data/Changes.md
CHANGED
@@ -1,25 +1,92 @@
|
|
1
|
+
## 0.5.0
|
2
|
+
This release is owed entirely to @eric1234 & @schuetzm, thank you both for your
|
3
|
+
efforts and patience.
|
4
|
+
|
5
|
+
In short, this release is intended to bring the project back to an active state,
|
6
|
+
any mistakes having been added in this version should be regarded as
|
7
|
+
intentional. Let's move forward.
|
8
|
+
|
9
|
+
Thank you as well to our gracious host @erichmenge for incepting this gem of a
|
10
|
+
gem.
|
11
|
+
|
12
|
+
* Merged #25 - Fix tests
|
13
|
+
Contributed by Marc Schütz <schuetzm@gmx.net>
|
14
|
+
|
15
|
+
* Merged #29 - Use `prepend_before_action` if available
|
16
|
+
Contributed by Marc Schütz <schuetzm@gmx.net>
|
17
|
+
|
18
|
+
* Merged #31 - Release attempt
|
19
|
+
Contributed by Eric Anderson <eric@pixelwareinc.com>
|
20
|
+
|
21
|
+
* Temporarily removed fields helper from being tested in 8517af8
|
22
|
+
Contributed by Eric Anderson <eric@pixelwareinc.com>
|
23
|
+
|
24
|
+
* Remove deprecation warnings & fixed bug revealed in 9985314
|
25
|
+
Contributed by Eric Anderson <eric@pixelwareinc.com>
|
26
|
+
|
27
|
+
* Enable signed_form to be tested against more versions of rails in b263e5b
|
28
|
+
Contributed by Eric Anderson <eric@pixelwareinc.com>
|
29
|
+
|
30
|
+
Released by Johnneylee Jack Rollins <Johnneylee.Rollins@gmail.com>
|
31
|
+
|
32
|
+
## 0.4.0
|
33
|
+
* Designate fields that submit multiple values correctly
|
34
|
+
Contributed by Marc Schütz <schuetzm@gmx.net>
|
35
|
+
|
36
|
+
* Allow to provide blocks to form helper methods
|
37
|
+
Previously, the block was swallowed rather than passed to the form helper
|
38
|
+
Christopher Schramm <cschramm@shakaweb.org>
|
39
|
+
|
40
|
+
## 0.3.0
|
41
|
+
|
42
|
+
* Disabled fields are no longer signed by default.
|
43
|
+
To include a disabled field, explicitly sign it with
|
44
|
+
`f.add_signed_fields field_name`
|
45
|
+
Contributed by James Moriarty <jamespaulmoriarty@gmail.com>
|
46
|
+
|
47
|
+
* Fix multiple fields_for calls
|
48
|
+
Prior to this fix, only the last of the calls would be passed.
|
49
|
+
Contributed by Marc Schütz <schuetzm@gmx.net>
|
50
|
+
|
51
|
+
* ActiveAdmin integration
|
52
|
+
CSchramm has created a plugin that integrates both activeadmin and
|
53
|
+
signed_form
|
54
|
+
Contributed by Christopher Schramm <cschramm@shakaweb.org>
|
55
|
+
|
56
|
+
* Tests pass under Rails 4.1
|
57
|
+
Contributed by Christopher Schramm <cschramm@shakaweb.org>
|
58
|
+
|
1
59
|
## 0.2.0
|
2
60
|
|
3
|
-
* Instead of using `signed_form_for` add an option for form signing to `form_for`
|
4
|
-
like SimpleForm doesn't require an
|
61
|
+
* Instead of using `signed_form_for` add an option for form signing to `form_for`
|
62
|
+
so that signing third party builders like SimpleForm doesn't require an
|
63
|
+
adapter.
|
64
|
+
|
5
65
|
* Move configuration options to main module name-space.
|
66
|
+
|
6
67
|
* Add default options hash to be passed to `form_for`.
|
68
|
+
|
7
69
|
* Add a digestor to verify that out dated forms aren't being submitted.
|
70
|
+
|
8
71
|
* Add a test helper to make testing controllers easy.
|
9
|
-
|
10
|
-
|
11
|
-
an exception
|
72
|
+
|
73
|
+
* Only permit parameters but don't require them.
|
74
|
+
Requiring them raises an exception if they're missing from the form
|
75
|
+
submission. But in cases where other parameters are sent as well and the form
|
76
|
+
object may be optional this would raise an exception that would be undesired.
|
77
|
+
|
12
78
|
* Allow all forms to be signed by default.
|
13
79
|
|
14
80
|
## 0.1.2
|
15
81
|
|
16
82
|
* Fix issues where request method was not being compared properly and request
|
17
|
-
url would not handle some potential cases leading to an erroneous rejection
|
18
|
-
the form. [Marc Schütz, #6]
|
83
|
+
url would not handle some potential cases leading to an erroneous rejection
|
84
|
+
of the form. [Marc Schütz, #6]
|
19
85
|
|
20
86
|
## 0.1.1
|
21
87
|
|
22
|
-
* Add some select and date/time field helpers that were not getting added to
|
88
|
+
* Add some select and date/time field helpers that were not getting added to
|
89
|
+
the signature [#5].
|
23
90
|
|
24
91
|
## 0.1.0
|
25
92
|
|
@@ -28,3 +95,4 @@
|
|
28
95
|
## 0.0.1
|
29
96
|
|
30
97
|
* Initial Release
|
98
|
+
|
data/Gemfile
CHANGED
@@ -7,16 +7,10 @@ rails_version = ENV['RAILS_VERSION'] || 'master'
|
|
7
7
|
|
8
8
|
case rails_version
|
9
9
|
when /master/
|
10
|
-
gem
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
gem "rails", github: "rails/rails", branch: "3-2-stable"
|
15
|
-
gem "strong_parameters"
|
16
|
-
when /3-1-stable/
|
17
|
-
gem "rails", github: "rails/rails", branch: "3-1-stable"
|
18
|
-
gem "strong_parameters"
|
10
|
+
gem 'rails', github: 'rails/rails'
|
11
|
+
gem 'arel', github: 'rails/arel'
|
12
|
+
when /-stable$/
|
13
|
+
gem 'rails', github: 'rails/rails', branch: rails_version
|
19
14
|
else
|
20
|
-
gem
|
21
|
-
gem "strong_parameters"
|
15
|
+
gem 'rails', ENV['RAILS_VERSION']
|
22
16
|
end
|
data/README.md
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
[](https://travis-ci.org/erichmenge/signed_form)
|
5
5
|
[](https://codeclimate.com/github/erichmenge/signed_form)
|
6
6
|
[](https://coveralls.io/r/erichmenge/signed_form)
|
7
|
+
[](https://inch-ci.org/github/erichmenge/signed_form)
|
7
8
|
|
8
9
|
SignedForm brings new convenience and security to your Rails 4 or Rails 3 application.
|
9
10
|
|
@@ -48,11 +49,26 @@ UsersController < ApplicationController
|
|
48
49
|
end
|
49
50
|
```
|
50
51
|
|
52
|
+
Disabled fields need to be explicitly signed:
|
53
|
+
|
54
|
+
```erb
|
55
|
+
<%= form_for @user, signed: true do |f| %>
|
56
|
+
<% f.add_signed_fields :name %>
|
57
|
+
|
58
|
+
<%= f.text_field :name, disabled: true %>
|
59
|
+
<%= f.submit %>
|
60
|
+
<% end %>
|
61
|
+
```
|
62
|
+
|
51
63
|
That's it. You're done. Need to add a field? Pop it in the form. You don't need to then update a list of attributes.
|
52
64
|
|
53
65
|
Of course, you're free to continue using the standard `form_for`. `SignedForm` is strictly opt-in. It won't change the
|
54
66
|
way you use standard forms.
|
55
67
|
|
68
|
+
## Is it any good?
|
69
|
+
|
70
|
+
Yes.
|
71
|
+
|
56
72
|
## More than just Convenience - Security
|
57
73
|
|
58
74
|
SignedForm protects you in 3 ways:
|
@@ -100,7 +116,7 @@ ApplicationController < ActionController::Base
|
|
100
116
|
end
|
101
117
|
```
|
102
118
|
|
103
|
-
|
119
|
+
On Rails versions older than 4.1, you'll also need to create an initializer:
|
104
120
|
|
105
121
|
```shell
|
106
122
|
$ echo "SignedForm.secret_key = '$(rake secret)'" > config/initializers/signed_form.rb
|
@@ -116,7 +132,7 @@ might look like this:
|
|
116
132
|
|
117
133
|
```erb
|
118
134
|
<%= simple_form_for @user, signed: true do |f| %>
|
119
|
-
f.input :name
|
135
|
+
<%= f.input :name %>
|
120
136
|
<% end %>
|
121
137
|
```
|
122
138
|
|
@@ -143,6 +159,10 @@ Then in your view:
|
|
143
159
|
<% end %>
|
144
160
|
```
|
145
161
|
|
162
|
+
## ActiveAdmin support
|
163
|
+
|
164
|
+
Gem [`signed_form-activeadmin`](https://github.com/cschramm/signed_form-activeadmin) integrates SignedForm with Active Admin.
|
165
|
+
|
146
166
|
## Form Digests
|
147
167
|
|
148
168
|
SignedForm will create a digest of all the views/partials involved with rendering your form. If the form is modifed old
|
data/lib/signed_form.rb
CHANGED
@@ -10,7 +10,6 @@ require "signed_form/digestor"
|
|
10
10
|
require "signed_form/action_view/form_helper"
|
11
11
|
require "signed_form/gate_keeper"
|
12
12
|
require "signed_form/action_controller/permit_signed_params"
|
13
|
-
require "signed_form/engine" if defined?(Rails)
|
14
13
|
|
15
14
|
module SignedForm
|
16
15
|
DEFAULT_OPTIONS = {
|
@@ -5,7 +5,11 @@ module SignedForm
|
|
5
5
|
# Include it in controllers that will be receiving signed forms.
|
6
6
|
module PermitSignedParams
|
7
7
|
def self.included(base)
|
8
|
-
base.
|
8
|
+
if base.respond_to? :prepend_before_action
|
9
|
+
base.prepend_before_action :permit_signed_form_data
|
10
|
+
else
|
11
|
+
base.prepend_before_filter :permit_signed_form_data
|
12
|
+
end
|
9
13
|
|
10
14
|
gem 'strong_parameters' unless defined?(::ActionController::Parameters)
|
11
15
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module SignedForm
|
2
2
|
module FormBuilder
|
3
|
-
FIELDS_TO_SIGN = [:select, :collection_select
|
4
|
-
:
|
3
|
+
FIELDS_TO_SIGN = [{:select => :multiple_select?}, {:collection_select => :multiple_select?},
|
4
|
+
{:grouped_collection_select => :multiple_select?},
|
5
|
+
:time_zone_select, :collection_radio_buttons, {:collection_check_boxes => []},
|
5
6
|
:date_select, :datetime_select, :time_select,
|
6
7
|
:text_field, :password_field, :hidden_field,
|
7
8
|
:file_field, :text_area, :check_box,
|
@@ -11,13 +12,22 @@ module SignedForm
|
|
11
12
|
:month_field, :week_field, :url_field,
|
12
13
|
:email_field, :number_field, :range_field]
|
13
14
|
|
14
|
-
FIELDS_TO_SIGN.delete_if { |e| !::ActionView::Helpers::FormBuilder.instance_methods.include?(e) }
|
15
|
+
FIELDS_TO_SIGN.delete_if { |e| !::ActionView::Helpers::FormBuilder.instance_methods.include?(e.is_a?(Symbol) ? e : e.keys.first) }
|
15
16
|
FIELDS_TO_SIGN.freeze
|
16
17
|
|
17
|
-
FIELDS_TO_SIGN.each do |
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
FIELDS_TO_SIGN.each do |kind|
|
19
|
+
kind, v = kind.is_a?(Symbol) ? [kind, nil] : kind.first
|
20
|
+
define_method(kind) do |field, *args, &block|
|
21
|
+
options = args.last.is_a?(Hash) ? args.last : {}
|
22
|
+
value = v.is_a?(Symbol) ? send(v, field, *args) : v
|
23
|
+
unless options[:disabled]
|
24
|
+
if value
|
25
|
+
add_signed_fields field => value
|
26
|
+
else
|
27
|
+
add_signed_fields field
|
28
|
+
end
|
29
|
+
end
|
30
|
+
super(field, *args, &block)
|
21
31
|
end
|
22
32
|
end
|
23
33
|
|
@@ -40,6 +50,7 @@ module SignedForm
|
|
40
50
|
|
41
51
|
def form_signature_tag
|
42
52
|
@signed_attributes.each { |k,v| v.uniq! if v.is_a?(Array) }
|
53
|
+
recursive_merge_identical_hashes! @signed_attributes
|
43
54
|
encoded_data = Base64.strict_encode64 Marshal.dump(@signed_attributes)
|
44
55
|
|
45
56
|
hmac = SignedForm::HMAC.new(secret_key: SignedForm.secret_key)
|
@@ -95,5 +106,30 @@ module SignedForm
|
|
95
106
|
@signed_attributes[:_options_][:digest_expiration] = Time.now + options[:digest_grace_period] if options[:digest_grace_period]
|
96
107
|
end
|
97
108
|
end
|
109
|
+
|
110
|
+
def recursive_merge_identical_hashes! hash
|
111
|
+
hash.each do |k,v|
|
112
|
+
hashes = []
|
113
|
+
hash[k] = v.reject do |attr|
|
114
|
+
attr.is_a?(Hash) && hashes << attr
|
115
|
+
end
|
116
|
+
unless hashes.empty?
|
117
|
+
sub_attrs = Hash.new {|hash,key| hash[key] = []}
|
118
|
+
hashes.each do |h|
|
119
|
+
h.each do |subk,subv|
|
120
|
+
sub_attrs[subk] += subv
|
121
|
+
end
|
122
|
+
end
|
123
|
+
recursive_merge_identical_hashes! sub_attrs
|
124
|
+
sub_attrs.default = nil
|
125
|
+
hash[k] << sub_attrs
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
def multiple_select? field, *args
|
131
|
+
options = args.last.is_a?(::Hash) ? args.last : {}
|
132
|
+
options[:multiple] ? [] : nil
|
133
|
+
end
|
98
134
|
end
|
99
135
|
end
|
data/lib/signed_form/hmac.rb
CHANGED
@@ -7,6 +7,12 @@ module SignedForm
|
|
7
7
|
def initialize(options = {})
|
8
8
|
self.secret_key = options[:secret_key]
|
9
9
|
|
10
|
+
if secret_key.nil? || secret_key.empty?
|
11
|
+
if defined?(::Rails) and ::Rails.application.respond_to?(:secrets)
|
12
|
+
self.secret_key = ::Rails.application.secrets.secret_key_base
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
10
16
|
if secret_key.nil? || secret_key.empty?
|
11
17
|
raise Errors::NoSecretKey, "Please consult the README for instructions on creating a secret key"
|
12
18
|
end
|
data/lib/signed_form/version.rb
CHANGED
data/signed_form.gemspec
CHANGED
@@ -6,8 +6,8 @@ require 'signed_form/version'
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "signed_form"
|
8
8
|
spec.version = SignedForm::VERSION
|
9
|
-
spec.authors = ["Erich Menge"]
|
10
|
-
spec.email = ["erichmenge@gmail.com"]
|
9
|
+
spec.authors = ["Erich Menge", "Johnneylee Jack Rollins"]
|
10
|
+
spec.email = ["erichmenge@gmail.com", "Johnneylee.Rollins@gmail.com"]
|
11
11
|
spec.description = %q{Rails signed form security}
|
12
12
|
spec.summary = %q{Rails signed form security}
|
13
13
|
spec.homepage = "https://github.com/erichmenge/signed_form"
|
@@ -23,6 +23,7 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_development_dependency "rspec", "~> 2.13"
|
24
24
|
spec.add_development_dependency "activemodel", ">= 3.1"
|
25
25
|
spec.add_development_dependency "coveralls"
|
26
|
+
spec.add_development_dependency "byebug"
|
26
27
|
|
27
28
|
spec.add_dependency "actionpack", ">= 3.1"
|
28
29
|
|
data/spec/form_builder_spec.rb
CHANGED
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
class User
|
4
4
|
extend ActiveModel::Naming
|
5
5
|
|
6
|
-
attr_accessor :name, :widgets_attributes
|
6
|
+
attr_accessor :name, :options, :widgets_attributes
|
7
7
|
|
8
8
|
def to_key
|
9
9
|
[1]
|
@@ -22,6 +22,7 @@ end
|
|
22
22
|
|
23
23
|
class ControllerRenderer < AbstractController::Base
|
24
24
|
include AbstractController::Rendering
|
25
|
+
include ActionView::Rendering if defined? ActionView::Rendering
|
25
26
|
self.view_paths = [ActionView::FileSystemResolver.new(File.join(File.dirname(__FILE__), 'fixtures', 'views'))]
|
26
27
|
|
27
28
|
view_context_class.class_eval do
|
@@ -130,9 +131,35 @@ describe SignedForm::FormBuilder do
|
|
130
131
|
end
|
131
132
|
end
|
132
133
|
|
134
|
+
describe "form collection inputs" do
|
135
|
+
after do
|
136
|
+
@data['user'].size.should == 1
|
137
|
+
@data['user'].should include({:options=>[]})
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should add to the allowed attributes when collection_check_boxes is used", action_pack: /4\.\d+/ do
|
141
|
+
content = form_for(User.new, signed: true) do |f|
|
142
|
+
f.collection_check_boxes :options, ['a', 'b'], :to_s, :to_s
|
143
|
+
end
|
144
|
+
|
145
|
+
@data = get_data_from_form(content)
|
146
|
+
end
|
147
|
+
|
148
|
+
it 'should pass a given block to the input helper method' do
|
149
|
+
content = form_for(User.new, signed: true) do |f|
|
150
|
+
f.collection_check_boxes :options, ['a'], :to_s, :to_s, {}, {} do |b|
|
151
|
+
'teststring'
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
content.should include 'teststring'
|
156
|
+
@data = get_data_from_form(content)
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
133
160
|
describe "form inputs" do
|
134
161
|
fields = ActionView::Helpers::FormBuilder.instance_methods - Object.instance_methods
|
135
|
-
fields -= [:button, :multipart=, :submit,
|
162
|
+
fields -= [:button, :multipart=, :submit, :fields,
|
136
163
|
:field_helpers, :label, :multipart,
|
137
164
|
:emitted_hidden_id?, :to_model, :field_helpers?,
|
138
165
|
:field_helpers=, :fields_for, :object_name=,
|
@@ -159,14 +186,6 @@ describe SignedForm::FormBuilder do
|
|
159
186
|
end
|
160
187
|
end
|
161
188
|
|
162
|
-
it "should add to the allowed attributes when collection_check_boxes is used", action_pack: /4\.\d+/ do
|
163
|
-
content = form_for(User.new, signed: true) do |f|
|
164
|
-
f.collection_check_boxes :name, ['a', 'b'], :to_s, :to_s
|
165
|
-
end
|
166
|
-
|
167
|
-
@data = get_data_from_form(content)
|
168
|
-
end
|
169
|
-
|
170
189
|
it "should add to the allowed attributes when grouped_collection_select is used" do
|
171
190
|
continent = Struct.new('Continent', :continent_name, :countries)
|
172
191
|
country = Struct.new('Country', :country_id, :country_name)
|
@@ -244,6 +263,65 @@ describe SignedForm::FormBuilder do
|
|
244
263
|
end
|
245
264
|
end
|
246
265
|
|
266
|
+
describe "disabled form inputs" do
|
267
|
+
it "should be explicitly signed" do
|
268
|
+
content = form_for(User.new, signed: true) do |f|
|
269
|
+
f.text_field :name, disabled: true
|
270
|
+
end
|
271
|
+
|
272
|
+
data = get_data_from_form(content)
|
273
|
+
data["user"].should be_empty
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
describe "form inputs that submit multiple values" do
|
278
|
+
after do
|
279
|
+
@data['user'].size.should == 1
|
280
|
+
@data['user'].should_not include(:name)
|
281
|
+
@data['user'].should include({:name => []})
|
282
|
+
end
|
283
|
+
|
284
|
+
it "should add a hash with an empty array when collection_check_boxes is used", action_pack: /4\.\d+/ do
|
285
|
+
content = form_for(User.new, signed: true) do |f|
|
286
|
+
f.collection_check_boxes :name, ['a', 'b'], :to_s, :to_s
|
287
|
+
end
|
288
|
+
|
289
|
+
@data = get_data_from_form(content)
|
290
|
+
end
|
291
|
+
|
292
|
+
it "should add a hash with an empty array when collection_select(..., multiple: true) is used" do
|
293
|
+
content = form_for(User.new, signed: true) do |f|
|
294
|
+
f.collection_select :name, %w(a b), :to_s, :to_s, multiple: true
|
295
|
+
end
|
296
|
+
|
297
|
+
@data = get_data_from_form(content)
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
describe "form inputs that don't submit multiple values" do
|
302
|
+
after do
|
303
|
+
@data['user'].size.should == 1
|
304
|
+
@data['user'].should include(:name)
|
305
|
+
@data['user'].should_not include({:name => []})
|
306
|
+
end
|
307
|
+
|
308
|
+
it "shouldn't add a hash with an empty array when collection_radio_buttons is used", action_pack: /4\.\d+/ do
|
309
|
+
content = form_for(User.new, signed: true) do |f|
|
310
|
+
f.collection_radio_buttons :name, ['a', 'b'], :to_s, :to_s
|
311
|
+
end
|
312
|
+
|
313
|
+
@data = get_data_from_form(content)
|
314
|
+
end
|
315
|
+
|
316
|
+
it "shouldn't add a hash with an empty array when collection_select(..., multiple: false) is used" do
|
317
|
+
content = form_for(User.new, signed: true) do |f|
|
318
|
+
f.collection_select :name, %w(a b), :to_s, :to_s, multiple: false
|
319
|
+
end
|
320
|
+
|
321
|
+
@data = get_data_from_form(content)
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
247
325
|
describe "add_signed_fields" do
|
248
326
|
it "should add fields to the marshaled data" do
|
249
327
|
content = form_for(User.new, signed: true) do |f|
|
@@ -309,6 +387,22 @@ describe SignedForm::FormBuilder do
|
|
309
387
|
data = get_data_from_form(content)
|
310
388
|
data[:author].size.should == 1
|
311
389
|
end
|
390
|
+
|
391
|
+
specify "multiple fields_for should create one hash only" do
|
392
|
+
content = form_for(:author, url: '/', signed: true) do |f|
|
393
|
+
f.fields_for :books do |ff|
|
394
|
+
ff.text_field :name
|
395
|
+
end
|
396
|
+
f.fields_for :books do |ff|
|
397
|
+
ff.text_field :price
|
398
|
+
end
|
399
|
+
f.fields_for :pets do |ff|
|
400
|
+
ff.text_field :name
|
401
|
+
end
|
402
|
+
end
|
403
|
+
data = get_data_from_form(content)
|
404
|
+
data[:author].size.should == 1
|
405
|
+
end
|
312
406
|
end
|
313
407
|
|
314
408
|
describe "form digests" do
|
data/spec/hmac_spec.rb
CHANGED
@@ -18,7 +18,7 @@ describe SignedForm::HMAC do
|
|
18
18
|
let(:hmac) { SignedForm::HMAC.new(secret_key: "superdupersecret") }
|
19
19
|
let(:signature) { hmac.create "My super secret" }
|
20
20
|
|
21
|
-
specify { hmac.verify(signature, "My super secret").should
|
22
|
-
specify { hmac.verify(signature, "My bad secret").should_not
|
21
|
+
specify { hmac.verify(signature, "My super secret").should be_truthy }
|
22
|
+
specify { hmac.verify(signature, "My bad secret").should_not be_truthy }
|
23
23
|
end
|
24
24
|
end
|
@@ -23,11 +23,13 @@ describe SignedForm::ActionController::PermitSignedParams do
|
|
23
23
|
"#{encoded_data}--#{signature}"
|
24
24
|
end
|
25
25
|
|
26
|
+
Object.send(:remove_const, :Rails) if defined?(Rails)
|
27
|
+
|
26
28
|
before do
|
27
29
|
SignedForm.secret_key = "abc123"
|
28
30
|
|
29
|
-
Controller.any_instance.stub(request: double('request', method: 'POST', request_method: 'POST', fullpath: '/users', url: '/users'))
|
30
|
-
Controller.any_instance.stub(params:
|
31
|
+
Controller.any_instance.stub(request: double('request', method: 'POST', request_method: 'POST', fullpath: '/users', url: '/users', variant: nil))
|
32
|
+
Controller.any_instance.stub(params: ActionController::Parameters.new("user" => { name: "Erich Menge", occupation: 'developer' }))
|
31
33
|
|
32
34
|
params.stub(:[]).and_call_original
|
33
35
|
params.stub(:[]).with('user').and_return(params)
|
@@ -69,7 +71,7 @@ describe SignedForm::ActionController::PermitSignedParams do
|
|
69
71
|
|
70
72
|
it "should not reject if inside grace period" do
|
71
73
|
params['form_signature'] = marshal_and_sign("user" => [:name], :_options_ => { digest: digestor, digest_expiration: Time.now + 20 })
|
72
|
-
expect { controller.permit_signed_form_data }.not_to raise_error
|
74
|
+
expect { controller.permit_signed_form_data }.not_to raise_error
|
73
75
|
end
|
74
76
|
|
75
77
|
it "should reject if outside the grace period" do
|
@@ -86,12 +88,12 @@ describe SignedForm::ActionController::PermitSignedParams do
|
|
86
88
|
context "when the digest is good" do
|
87
89
|
it "should not reject if outside grace period" do
|
88
90
|
params['form_signature'] = marshal_and_sign("user" => [:name], :_options_ => { digest: digestor, digest_expiration: Time.now - 20 })
|
89
|
-
expect { controller.permit_signed_form_data }.not_to raise_error
|
91
|
+
expect { controller.permit_signed_form_data }.not_to raise_error
|
90
92
|
end
|
91
93
|
|
92
94
|
it "should not reject if no grace period" do
|
93
95
|
params['form_signature'] = marshal_and_sign("user" => [:name], :_options_ => { digest: digestor })
|
94
|
-
expect { controller.permit_signed_form_data }.not_to raise_error
|
96
|
+
expect { controller.permit_signed_form_data }.not_to raise_error
|
95
97
|
end
|
96
98
|
end
|
97
99
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,110 +1,126 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: signed_form
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Erich Menge
|
8
|
+
- Johnneylee Jack Rollins
|
8
9
|
autorequire:
|
9
10
|
bindir: bin
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2018-02-27 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: bundler
|
15
16
|
requirement: !ruby/object:Gem::Requirement
|
16
17
|
requirements:
|
17
|
-
- - ~>
|
18
|
+
- - "~>"
|
18
19
|
- !ruby/object:Gem::Version
|
19
20
|
version: '1.3'
|
20
21
|
type: :development
|
21
22
|
prerelease: false
|
22
23
|
version_requirements: !ruby/object:Gem::Requirement
|
23
24
|
requirements:
|
24
|
-
- - ~>
|
25
|
+
- - "~>"
|
25
26
|
- !ruby/object:Gem::Version
|
26
27
|
version: '1.3'
|
27
28
|
- !ruby/object:Gem::Dependency
|
28
29
|
name: rake
|
29
30
|
requirement: !ruby/object:Gem::Requirement
|
30
31
|
requirements:
|
31
|
-
- -
|
32
|
+
- - ">="
|
32
33
|
- !ruby/object:Gem::Version
|
33
34
|
version: '0'
|
34
35
|
type: :development
|
35
36
|
prerelease: false
|
36
37
|
version_requirements: !ruby/object:Gem::Requirement
|
37
38
|
requirements:
|
38
|
-
- -
|
39
|
+
- - ">="
|
39
40
|
- !ruby/object:Gem::Version
|
40
41
|
version: '0'
|
41
42
|
- !ruby/object:Gem::Dependency
|
42
43
|
name: rspec
|
43
44
|
requirement: !ruby/object:Gem::Requirement
|
44
45
|
requirements:
|
45
|
-
- - ~>
|
46
|
+
- - "~>"
|
46
47
|
- !ruby/object:Gem::Version
|
47
48
|
version: '2.13'
|
48
49
|
type: :development
|
49
50
|
prerelease: false
|
50
51
|
version_requirements: !ruby/object:Gem::Requirement
|
51
52
|
requirements:
|
52
|
-
- - ~>
|
53
|
+
- - "~>"
|
53
54
|
- !ruby/object:Gem::Version
|
54
55
|
version: '2.13'
|
55
56
|
- !ruby/object:Gem::Dependency
|
56
57
|
name: activemodel
|
57
58
|
requirement: !ruby/object:Gem::Requirement
|
58
59
|
requirements:
|
59
|
-
- -
|
60
|
+
- - ">="
|
60
61
|
- !ruby/object:Gem::Version
|
61
62
|
version: '3.1'
|
62
63
|
type: :development
|
63
64
|
prerelease: false
|
64
65
|
version_requirements: !ruby/object:Gem::Requirement
|
65
66
|
requirements:
|
66
|
-
- -
|
67
|
+
- - ">="
|
67
68
|
- !ruby/object:Gem::Version
|
68
69
|
version: '3.1'
|
69
70
|
- !ruby/object:Gem::Dependency
|
70
71
|
name: coveralls
|
71
72
|
requirement: !ruby/object:Gem::Requirement
|
72
73
|
requirements:
|
73
|
-
- -
|
74
|
+
- - ">="
|
74
75
|
- !ruby/object:Gem::Version
|
75
76
|
version: '0'
|
76
77
|
type: :development
|
77
78
|
prerelease: false
|
78
79
|
version_requirements: !ruby/object:Gem::Requirement
|
79
80
|
requirements:
|
80
|
-
- -
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: byebug
|
86
|
+
requirement: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: '0'
|
91
|
+
type: :development
|
92
|
+
prerelease: false
|
93
|
+
version_requirements: !ruby/object:Gem::Requirement
|
94
|
+
requirements:
|
95
|
+
- - ">="
|
81
96
|
- !ruby/object:Gem::Version
|
82
97
|
version: '0'
|
83
98
|
- !ruby/object:Gem::Dependency
|
84
99
|
name: actionpack
|
85
100
|
requirement: !ruby/object:Gem::Requirement
|
86
101
|
requirements:
|
87
|
-
- -
|
102
|
+
- - ">="
|
88
103
|
- !ruby/object:Gem::Version
|
89
104
|
version: '3.1'
|
90
105
|
type: :runtime
|
91
106
|
prerelease: false
|
92
107
|
version_requirements: !ruby/object:Gem::Requirement
|
93
108
|
requirements:
|
94
|
-
- -
|
109
|
+
- - ">="
|
95
110
|
- !ruby/object:Gem::Version
|
96
111
|
version: '3.1'
|
97
112
|
description: Rails signed form security
|
98
113
|
email:
|
99
114
|
- erichmenge@gmail.com
|
115
|
+
- Johnneylee.Rollins@gmail.com
|
100
116
|
executables: []
|
101
117
|
extensions: []
|
102
118
|
extra_rdoc_files: []
|
103
119
|
files:
|
104
|
-
- .gitignore
|
105
|
-
- .rspec
|
106
|
-
- .travis.yml
|
107
|
-
- .yardopts
|
120
|
+
- ".gitignore"
|
121
|
+
- ".rspec"
|
122
|
+
- ".travis.yml"
|
123
|
+
- ".yardopts"
|
108
124
|
- Changes.md
|
109
125
|
- Gemfile
|
110
126
|
- LICENSE.txt
|
@@ -118,7 +134,6 @@ files:
|
|
118
134
|
- lib/signed_form/digest_stores/memory_store.rb
|
119
135
|
- lib/signed_form/digest_stores/null_store.rb
|
120
136
|
- lib/signed_form/digestor.rb
|
121
|
-
- lib/signed_form/engine.rb
|
122
137
|
- lib/signed_form/errors.rb
|
123
138
|
- lib/signed_form/form_builder.rb
|
124
139
|
- lib/signed_form/gate_keeper.rb
|
@@ -143,17 +158,17 @@ require_paths:
|
|
143
158
|
- lib
|
144
159
|
required_ruby_version: !ruby/object:Gem::Requirement
|
145
160
|
requirements:
|
146
|
-
- -
|
161
|
+
- - ">="
|
147
162
|
- !ruby/object:Gem::Version
|
148
163
|
version: '1.9'
|
149
164
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
150
165
|
requirements:
|
151
|
-
- -
|
166
|
+
- - ">="
|
152
167
|
- !ruby/object:Gem::Version
|
153
168
|
version: '0'
|
154
169
|
requirements: []
|
155
170
|
rubyforge_project:
|
156
|
-
rubygems_version: 2.
|
171
|
+
rubygems_version: 2.7.3
|
157
172
|
signing_key:
|
158
173
|
specification_version: 4
|
159
174
|
summary: Rails signed form security
|