protected_attributes 1.0.8 → 1.0.9
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 +4 -4
- data/README.md +15 -1
- data/lib/active_model/mass_assignment_security.rb +3 -3
- data/lib/active_model/mass_assignment_security/sanitizer.rb +1 -1
- data/lib/active_record/mass_assignment_security/associations.rb +16 -0
- data/lib/active_record/mass_assignment_security/persistence.rb +4 -2
- data/lib/active_record/mass_assignment_security/reflection.rb +11 -3
- data/lib/protected_attributes.rb +1 -1
- data/lib/protected_attributes/railtie.rb +0 -2
- data/lib/protected_attributes/version.rb +1 -1
- data/test/ar_helper.rb +1 -0
- data/test/attribute_sanitization_test.rb +113 -2
- data/test/mass_assignment_security_test.rb +0 -24
- data/test/models/pirate.rb +1 -1
- data/test/test_helper.rb +1 -0
- metadata +23 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 07a8c210afe27e08b760e2f61b86a60c6980ec1a
|
4
|
+
data.tar.gz: cb8ef9666fc6b0a73161f1d06a0cfd097edfc7cd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c6c29a159034c283fd0e77c2b5ddf1469655bce17916e801668d01e8e104c6e4142621c01c75966f0333413c0d7e7179b8c22aa4bf8a03966f0a71334850316b
|
7
|
+
data.tar.gz: d9e314e1e6b925ba6a34fb68b813999c1ffa00d29e4b32ca59eb8f523e35102d5c3098606410ae5cd702756737a1f0bacfa3d3e6b2d6ac01c1388c1bd42df771
|
data/README.md
CHANGED
@@ -1,11 +1,13 @@
|
|
1
1
|
# ProtectedAttributes
|
2
2
|
|
3
|
-
[](https://travis-ci.org/rails/protected_attributes)
|
4
4
|
|
5
5
|
Protect attributes from mass-assignment in ActiveRecord models.
|
6
6
|
|
7
7
|
This plugin adds `attr_accessible` and `attr_protected` in your models.
|
8
8
|
|
9
|
+
Note: This plugin will be officially supported until the release of Rails 5.0
|
10
|
+
|
9
11
|
## Installation
|
10
12
|
|
11
13
|
Add this line to your application's Gemfile:
|
@@ -105,6 +107,18 @@ class AccountsController < ApplicationController
|
|
105
107
|
end
|
106
108
|
end
|
107
109
|
```
|
110
|
+
|
111
|
+
### Errors
|
112
|
+
|
113
|
+
By default, errors will not be raised if the user passes attributes in the params hash which are not allowed to be updated.
|
114
|
+
If you want the functionality where exceptions (`ActiveModel::MassAssignmentSecurity::Error`) are raised. Add to your config
|
115
|
+
the strict flag:
|
116
|
+
|
117
|
+
```ruby
|
118
|
+
config.active_record.mass_assignment_sanitizer = :strict
|
119
|
+
```
|
120
|
+
|
121
|
+
|
108
122
|
## Contributing
|
109
123
|
|
110
124
|
1. Fork it
|
@@ -206,7 +206,7 @@ module ActiveModel
|
|
206
206
|
# end
|
207
207
|
#
|
208
208
|
# Customer.protected_attributes
|
209
|
-
# #
|
209
|
+
# # => #<ActiveModel::MassAssignmentSecurity::BlackList: {"logins_count"}>
|
210
210
|
#
|
211
211
|
# Customer.protected_attributes(:default)
|
212
212
|
# # => #<ActiveModel::MassAssignmentSecurity::BlackList: {"logins_count"}>
|
@@ -255,10 +255,10 @@ module ActiveModel
|
|
255
255
|
# end
|
256
256
|
#
|
257
257
|
# Customer.active_authorizers
|
258
|
-
# #
|
258
|
+
# # => {
|
259
259
|
# # :admin=> #<ActiveModel::MassAssignmentSecurity::WhiteList: {"name", "credit_rating"}>,
|
260
260
|
# # :default=>#<ActiveModel::MassAssignmentSecurity::WhiteList: {"name"}>
|
261
|
-
# #
|
261
|
+
# # }
|
262
262
|
def active_authorizers
|
263
263
|
self._active_authorizer ||= protected_attributes_configs
|
264
264
|
end
|
@@ -65,6 +65,22 @@ module ActiveRecord
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
68
|
+
module ThroughAssociation
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def build_record(attributes, options={})
|
73
|
+
inverse = source_reflection.inverse_of
|
74
|
+
target = through_association.target
|
75
|
+
|
76
|
+
if inverse && target && !target.is_a?(Array)
|
77
|
+
attributes[inverse.foreign_key] = target.id
|
78
|
+
end
|
79
|
+
|
80
|
+
super(attributes, options)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
68
84
|
class HasManyThroughAssociation
|
69
85
|
def build_record(attributes, options = {})
|
70
86
|
ensure_not_nested
|
@@ -57,7 +57,7 @@ module ActiveRecord
|
|
57
57
|
# If no +:as+ option is supplied then the +:default+ role will be used.
|
58
58
|
# If you want to bypass the forbidden attributes protection then you can do so using
|
59
59
|
# the +:without_protection+ option.
|
60
|
-
def
|
60
|
+
def update(attributes, options = {})
|
61
61
|
# The following transaction covers any possible database side-effects of the
|
62
62
|
# attributes assignment. For example, setting the IDs of a child collection.
|
63
63
|
with_transaction_returning_status do
|
@@ -65,10 +65,11 @@ module ActiveRecord
|
|
65
65
|
save
|
66
66
|
end
|
67
67
|
end
|
68
|
+
alias :update_attributes :update
|
68
69
|
|
69
70
|
# Updates its receiver just like +update_attributes+ but calls <tt>save!</tt> instead
|
70
71
|
# of +save+, so an exception is raised if the record is invalid.
|
71
|
-
def
|
72
|
+
def update!(attributes, options = {})
|
72
73
|
# The following transaction covers any possible database side-effects of the
|
73
74
|
# attributes assignment. For example, setting the IDs of a child collection.
|
74
75
|
with_transaction_returning_status do
|
@@ -76,6 +77,7 @@ module ActiveRecord
|
|
76
77
|
save!
|
77
78
|
end
|
78
79
|
end
|
80
|
+
alias :update_attributes! :update!
|
79
81
|
end
|
80
82
|
end
|
81
83
|
end
|
@@ -1,8 +1,16 @@
|
|
1
1
|
module ActiveRecord
|
2
2
|
module Reflection
|
3
|
-
|
4
|
-
|
5
|
-
|
3
|
+
if defined?(AbstractReflection)
|
4
|
+
class AbstractReflection
|
5
|
+
def build_association(*options, &block)
|
6
|
+
klass.new(*options, &block)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
else
|
10
|
+
class AssociationReflection
|
11
|
+
def build_association(*options, &block)
|
12
|
+
klass.new(*options, &block)
|
13
|
+
end
|
6
14
|
end
|
7
15
|
end
|
8
16
|
end
|
data/lib/protected_attributes.rb
CHANGED
data/test/ar_helper.rb
CHANGED
@@ -1,11 +1,18 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
require 'ar_helper'
|
3
3
|
require 'active_record/mass_assignment_security'
|
4
|
+
require 'models/battle'
|
4
5
|
require 'models/company'
|
5
|
-
require 'models/
|
6
|
+
require 'models/group'
|
6
7
|
require 'models/keyboard'
|
7
|
-
require 'models/
|
8
|
+
require 'models/membership'
|
8
9
|
require 'models/person'
|
10
|
+
require 'models/pirate'
|
11
|
+
require 'models/subscriber'
|
12
|
+
require 'models/task'
|
13
|
+
require 'models/team'
|
14
|
+
require 'models/vampire'
|
15
|
+
require 'models/wolf'
|
9
16
|
|
10
17
|
module MassAssignmentTestHelpers
|
11
18
|
def teardown
|
@@ -276,6 +283,86 @@ class AttributeSanitizationTest < ActiveSupport::TestCase
|
|
276
283
|
def test_new_with_unrelated_inheritance_column_class
|
277
284
|
assert_raise(ActiveRecord::SubclassNotFound) { Corporation.new(type: "Person") }
|
278
285
|
end
|
286
|
+
|
287
|
+
def test_update_attributes_as_admin
|
288
|
+
person = TightPerson.create({ "first_name" => 'Joshua' })
|
289
|
+
person.update_attributes({ "first_name" => 'Josh', "gender" => 'm', "comments" => 'from NZ' }, :as => :admin)
|
290
|
+
person.reload
|
291
|
+
|
292
|
+
assert_equal 'Josh', person.first_name
|
293
|
+
assert_equal 'm', person.gender
|
294
|
+
assert_equal 'from NZ', person.comments
|
295
|
+
end
|
296
|
+
|
297
|
+
def test_update_attributes_without_protection
|
298
|
+
person = TightPerson.create({ "first_name" => 'Joshua' })
|
299
|
+
person.update_attributes({ "first_name" => 'Josh', "gender" => 'm', "comments" => 'from NZ' }, :without_protection => true)
|
300
|
+
person.reload
|
301
|
+
|
302
|
+
assert_equal 'Josh', person.first_name
|
303
|
+
assert_equal 'm', person.gender
|
304
|
+
assert_equal 'from NZ', person.comments
|
305
|
+
end
|
306
|
+
|
307
|
+
def test_update_attributes_with_bang_as_admin
|
308
|
+
person = TightPerson.create({ "first_name" => 'Joshua' })
|
309
|
+
person.update_attributes!({ "first_name" => 'Josh', "gender" => 'm', "comments" => 'from NZ' }, :as => :admin)
|
310
|
+
person.reload
|
311
|
+
|
312
|
+
assert_equal 'Josh', person.first_name
|
313
|
+
assert_equal 'm', person.gender
|
314
|
+
assert_equal 'from NZ', person.comments
|
315
|
+
end
|
316
|
+
|
317
|
+
def test_update_attributes_with_bang_without_protection
|
318
|
+
person = TightPerson.create({ "first_name" => 'Joshua' })
|
319
|
+
person.update_attributes!({ "first_name" => 'Josh', "gender" => 'm', "comments" => 'from NZ' }, :without_protection => true)
|
320
|
+
person.reload
|
321
|
+
|
322
|
+
assert_equal 'Josh', person.first_name
|
323
|
+
assert_equal 'm', person.gender
|
324
|
+
assert_equal 'from NZ', person.comments
|
325
|
+
end
|
326
|
+
|
327
|
+
def test_update_as_admin
|
328
|
+
person = TightPerson.create({ "first_name" => 'Joshua' })
|
329
|
+
person.update({ "first_name" => 'Josh', "gender" => 'm', "comments" => 'from NZ' }, :as => :admin)
|
330
|
+
person.reload
|
331
|
+
|
332
|
+
assert_equal 'Josh', person.first_name
|
333
|
+
assert_equal 'm', person.gender
|
334
|
+
assert_equal 'from NZ', person.comments
|
335
|
+
end
|
336
|
+
|
337
|
+
def test_update_without_protection
|
338
|
+
person = TightPerson.create({ "first_name" => 'Joshua' })
|
339
|
+
person.update({ "first_name" => 'Josh', "gender" => 'm', "comments" => 'from NZ' }, :without_protection => true)
|
340
|
+
person.reload
|
341
|
+
|
342
|
+
assert_equal 'Josh', person.first_name
|
343
|
+
assert_equal 'm', person.gender
|
344
|
+
assert_equal 'from NZ', person.comments
|
345
|
+
end
|
346
|
+
|
347
|
+
def test_update_with_bang_as_admin
|
348
|
+
person = TightPerson.create({ "first_name" => 'Joshua' })
|
349
|
+
person.update!({ "first_name" => 'Josh', "gender" => 'm', "comments" => 'from NZ' }, :as => :admin)
|
350
|
+
person.reload
|
351
|
+
|
352
|
+
assert_equal 'Josh', person.first_name
|
353
|
+
assert_equal 'm', person.gender
|
354
|
+
assert_equal 'from NZ', person.comments
|
355
|
+
end
|
356
|
+
|
357
|
+
def test_update_with_bang_without_protection
|
358
|
+
person = TightPerson.create({ "first_name" => 'Joshua' })
|
359
|
+
person.update!({ "first_name" => 'Josh', "gender" => 'm', "comments" => 'from NZ' }, :without_protection => true)
|
360
|
+
person.reload
|
361
|
+
|
362
|
+
assert_equal 'Josh', person.first_name
|
363
|
+
assert_equal 'm', person.gender
|
364
|
+
assert_equal 'from NZ', person.comments
|
365
|
+
end
|
279
366
|
end
|
280
367
|
|
281
368
|
|
@@ -595,6 +682,12 @@ class MassAssignmentSecurityHasManyRelationsTest < ActiveSupport::TestCase
|
|
595
682
|
end
|
596
683
|
end
|
597
684
|
|
685
|
+
def test_has_many_through_build_with_attr_accessible_attributes
|
686
|
+
group = Group.create!
|
687
|
+
pirate = group.members.build(name: "Murphy")
|
688
|
+
assert_equal "Murphy", pirate.name
|
689
|
+
end
|
690
|
+
|
598
691
|
# new
|
599
692
|
|
600
693
|
def test_has_many_new_with_attr_protected_attributes
|
@@ -697,6 +790,24 @@ class MassAssignmentSecurityHasManyRelationsTest < ActiveSupport::TestCase
|
|
697
790
|
end
|
698
791
|
end
|
699
792
|
|
793
|
+
# concat
|
794
|
+
|
795
|
+
def test_concat_has_many_through_association_member
|
796
|
+
group = Group.create!
|
797
|
+
pirate = Pirate.create!
|
798
|
+
group.members << pirate
|
799
|
+
assert_equal pirate.memberships.first, group.memberships.first
|
800
|
+
end
|
801
|
+
|
802
|
+
def test_concat_has_many_through_polymorphic_association
|
803
|
+
team = Team.create!
|
804
|
+
vampire = Vampire.create!
|
805
|
+
wolf = Wolf.create!
|
806
|
+
|
807
|
+
team.vampire_battles << vampire
|
808
|
+
wolf.teams << team
|
809
|
+
assert_equal team.wolf_battles.first, wolf
|
810
|
+
end
|
700
811
|
end
|
701
812
|
|
702
813
|
|
@@ -1,13 +1,6 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
require 'active_model/mass_assignment_security'
|
3
3
|
require 'models/mass_assignment_specific'
|
4
|
-
require 'models/pirate'
|
5
|
-
require 'models/group'
|
6
|
-
require 'models/membership'
|
7
|
-
require 'models/battle'
|
8
|
-
require 'models/vampire'
|
9
|
-
require 'models/wolf'
|
10
|
-
require 'models/team'
|
11
4
|
|
12
5
|
class CustomSanitizer < ActiveModel::MassAssignmentSecurity::Sanitizer
|
13
6
|
|
@@ -122,21 +115,4 @@ class MassAssignmentSecurityTest < ActiveModel::TestCase
|
|
122
115
|
ensure
|
123
116
|
User.mass_assignment_sanitizer = old_sanitizer
|
124
117
|
end
|
125
|
-
|
126
|
-
def test_concat_has_many_through_association_member
|
127
|
-
group = Group.create!
|
128
|
-
pirate = Pirate.create!
|
129
|
-
group.members << pirate
|
130
|
-
assert_equal pirate.memberships.first, group.memberships.first
|
131
|
-
end
|
132
|
-
|
133
|
-
def test_concat_has_many_through_polymorphic_association
|
134
|
-
team = Team.create!
|
135
|
-
vampire = Vampire.create!
|
136
|
-
wolf = Wolf.create!
|
137
|
-
|
138
|
-
team.vampire_battles << vampire
|
139
|
-
wolf.teams << team
|
140
|
-
assert_equal team.wolf_battles.first, wolf
|
141
|
-
end
|
142
118
|
end
|
data/test/models/pirate.rb
CHANGED
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: protected_attributes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Heinemeier Hansson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-03-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|
@@ -70,6 +70,26 @@ dependencies:
|
|
70
70
|
- - "<"
|
71
71
|
- !ruby/object:Gem::Version
|
72
72
|
version: '5.0'
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: railties
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: 4.0.1
|
80
|
+
- - "<"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '5.0'
|
83
|
+
type: :development
|
84
|
+
prerelease: false
|
85
|
+
version_requirements: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 4.0.1
|
90
|
+
- - "<"
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '5.0'
|
73
93
|
- !ruby/object:Gem::Dependency
|
74
94
|
name: sqlite3
|
75
95
|
requirement: !ruby/object:Gem::Requirement
|
@@ -167,7 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
167
187
|
version: '0'
|
168
188
|
requirements: []
|
169
189
|
rubyforge_project:
|
170
|
-
rubygems_version: 2.
|
190
|
+
rubygems_version: 2.4.5
|
171
191
|
signing_key:
|
172
192
|
specification_version: 4
|
173
193
|
summary: Protect attributes from mass assignment in Active Record models
|