protected_attributes_continued 1.2.4 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +23 -20
- data/lib/active_model/mass_assignment_security.rb +1 -5
- data/lib/active_record/mass_assignment_security.rb +0 -4
- data/lib/active_record/mass_assignment_security/core.rb +15 -0
- data/lib/active_record/mass_assignment_security/inheritance.rb +3 -1
- data/lib/active_record/mass_assignment_security/nested_attributes.rb +2 -6
- data/lib/active_record/mass_assignment_security/relation.rb +3 -3
- data/lib/protected_attributes.rb +0 -1
- data/lib/protected_attributes/version.rb +1 -1
- data/lib/protected_attributes_continued.rb +0 -18
- metadata +19 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2eb844e472b4ede262323c067507b498ad29bd27
|
4
|
+
data.tar.gz: a2c7241c8c82757901c5e065d39a0adbc8dfd5bb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7d9e0f27404e0f676ed38fc118da71dbc1e9dfa682bb632de1eadc33a96299277793b017467b0f3746ebdbf3bfe80aba726399124536b035b63e5f8827562e6b
|
7
|
+
data.tar.gz: 1ccfdcb731a28be930dee878c1d1d474ecb41a5f40636d96a899d6a8d26a09c8fde2ab403d98da73b1663f539df5ee2c1f48040be585932d474ce1d398c9e94b
|
data/README.md
CHANGED
@@ -2,24 +2,26 @@
|
|
2
2
|
|
3
3
|
[![Build Status](https://api.travis-ci.org/westonganger/protected_attributes_continued.svg?branch=master)](https://travis-ci.org/westonganger/protected_attributes_continued)
|
4
4
|
|
5
|
-
This is the community continued version of `protected_attributes`.
|
5
|
+
This is the community continued version of `protected_attributes`. It works with Rails 5 only and I recommend you only use it to support legacy portions of your application that you do not want to upgrade. Note that this feature was dropped by the Rails team and switched to strong_parameters because of security issues, just so you understand your risks. This is in use successfully in some of my Rails 5 apps in which security like this is a non-issue. For people who would like to continue using this feature in their Rails 5 apps lets continue the work here.
|
6
6
|
|
7
7
|
Protect attributes from mass-assignment in Active Record models.
|
8
8
|
|
9
9
|
This plugin adds the class methods `attr_accessible` and `attr_protected` to your models to be able to declare white or black lists of attributes.
|
10
10
|
|
11
11
|
|
12
|
-
|
13
|
-
|
14
12
|
## Installation
|
15
13
|
|
16
14
|
Add this line to your application's `Gemfile`:
|
17
15
|
|
18
|
-
|
16
|
+
```ruby
|
17
|
+
gem 'protected_attributes_continued'
|
18
|
+
```
|
19
19
|
|
20
20
|
And then execute:
|
21
21
|
|
22
|
-
|
22
|
+
```ruby
|
23
|
+
bundle install
|
24
|
+
```
|
23
25
|
|
24
26
|
## Usage
|
25
27
|
|
@@ -32,19 +34,19 @@ attr_protected :admin
|
|
32
34
|
`attr_protected` also optionally takes a role option using `:as` which allows you to define multiple mass-assignment groupings. If no role is defined then attributes will be added to the `:default` role.
|
33
35
|
|
34
36
|
```ruby
|
35
|
-
attr_protected :last_login, :
|
37
|
+
attr_protected :last_login, as: :admin
|
36
38
|
```
|
37
39
|
A much better way, because it follows the whitelist-principle, is the `attr_accessible` method. It is the exact opposite of `attr_protected`, because it takes a list of attributes that will be mass-assigned if present. Any other attributes will be ignored. This way you won’t forget to protect attributes when adding new ones in the course of development. Here is an example:
|
38
40
|
|
39
41
|
```ruby
|
40
42
|
attr_accessible :name
|
41
|
-
attr_accessible :name, :is_admin, :
|
43
|
+
attr_accessible :name, :is_admin, as: :admin
|
42
44
|
```
|
43
45
|
|
44
46
|
If you want to set a protected attribute, you will have to assign it individually:
|
45
47
|
|
46
48
|
```ruby
|
47
|
-
params[:user] # => {:
|
49
|
+
params[:user] # => {name: "owned", is_admin: true}
|
48
50
|
@user = User.new(params[:user])
|
49
51
|
@user.is_admin # => false, not mass-assigned
|
50
52
|
@user.is_admin = true
|
@@ -58,15 +60,15 @@ You can also bypass mass-assignment security by using the `:without_protection`
|
|
58
60
|
```ruby
|
59
61
|
@user = User.new
|
60
62
|
|
61
|
-
@user.assign_attributes(:
|
63
|
+
@user.assign_attributes(name: 'Josh', is_admin: true)
|
62
64
|
@user.name # => Josh
|
63
65
|
@user.is_admin # => false
|
64
66
|
|
65
|
-
@user.assign_attributes({ :
|
67
|
+
@user.assign_attributes({ name: 'Josh', is_admin: true }, as: :admin)
|
66
68
|
@user.name # => Josh
|
67
69
|
@user.is_admin # => true
|
68
70
|
|
69
|
-
@user.assign_attributes({ :
|
71
|
+
@user.assign_attributes({ name: 'Josh', is_admin: true }, without_protection: true)
|
70
72
|
@user.name # => Josh
|
71
73
|
@user.is_admin # => true
|
72
74
|
```
|
@@ -74,18 +76,18 @@ You can also bypass mass-assignment security by using the `:without_protection`
|
|
74
76
|
In a similar way, `new`, `create`, `create!`, `update_attributes` and `update_attributes!` methods all respect mass-assignment security and accept either `:as` or `:without_protection` options. For example:
|
75
77
|
|
76
78
|
```ruby
|
77
|
-
@user = User.new({ :
|
79
|
+
@user = User.new({ name: 'Sebastian', is_admin: true }, as: :admin)
|
78
80
|
@user.name # => Sebastian
|
79
81
|
@user.is_admin # => true
|
80
82
|
|
81
|
-
@user = User.create({ :
|
83
|
+
@user = User.create({ name: 'Sebastian', is_admin: true }, without_protection: true)
|
82
84
|
@user.name # => Sebastian
|
83
85
|
@user.is_admin # => true
|
84
86
|
```
|
85
87
|
|
86
88
|
By default the gem will use the strong parameters protection when assigning attribute, unless your model has `attr_accessible` or `attr_protected` calls.
|
87
89
|
|
88
|
-
|
90
|
+
## Errors
|
89
91
|
|
90
92
|
By default, attributes in the params hash which are not allowed to be updated are just ignored. If you prefer an exception to be raised configure:
|
91
93
|
|
@@ -95,10 +97,11 @@ config.active_record.mass_assignment_sanitizer = :strict
|
|
95
97
|
|
96
98
|
Any protected attributes violation raises `ActiveModel::MassAssignmentSecurity::Error` then.
|
97
99
|
|
98
|
-
## Contributing
|
99
100
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
101
|
+
# Credits
|
102
|
+
|
103
|
+
Created and Maintained by [Weston Ganger - @westonganger](https://github.com/westonganger)
|
104
|
+
|
105
|
+
Originally forked from the dead/unmaintained `protected_attributes` gem by the Rails team.
|
106
|
+
|
107
|
+
<a href='https://ko-fi.com/A5071NK' target='_blank'><img height='32' style='border:0px;height:32px;' src='https://az743702.vo.msecnd.net/cdn/kofi1.png?v=a' border='0' alt='Buy Me a Coffee' /></a>
|
@@ -323,11 +323,7 @@ module ActiveModel
|
|
323
323
|
# customer.assign_attributes(name: 'David')
|
324
324
|
# # => StandardError: StandardError
|
325
325
|
def mass_assignment_sanitizer=(value)
|
326
|
-
self._mass_assignment_sanitizer =
|
327
|
-
const_get(:"#{value.to_s.camelize}Sanitizer").new(self)
|
328
|
-
else
|
329
|
-
value
|
330
|
-
end
|
326
|
+
self._mass_assignment_sanitizer = value.is_a?(Symbol) ? const_get(:"#{value.to_s.camelize}Sanitizer").new(self) : value
|
331
327
|
end
|
332
328
|
|
333
329
|
private
|
@@ -1,9 +1,5 @@
|
|
1
1
|
require "active_record"
|
2
2
|
|
3
|
-
def active_record_40?
|
4
|
-
ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR == 0
|
5
|
-
end
|
6
|
-
|
7
3
|
require "active_record/mass_assignment_security/associations"
|
8
4
|
require "active_record/mass_assignment_security/attribute_assignment"
|
9
5
|
require "active_record/mass_assignment_security/core"
|
@@ -2,6 +2,20 @@ module ActiveRecord
|
|
2
2
|
module MassAssignmentSecurity
|
3
3
|
module Core
|
4
4
|
|
5
|
+
def initialize(attributes = nil, options = {})
|
6
|
+
self.class.define_attribute_methods
|
7
|
+
@attributes = self.class._default_attributes.deep_dup
|
8
|
+
|
9
|
+
init_internals
|
10
|
+
initialize_internals_callback
|
11
|
+
|
12
|
+
# +options+ argument is only needed to make protected_attributes gem easier to hook.
|
13
|
+
init_attributes(attributes, options) if attributes
|
14
|
+
|
15
|
+
yield self if block_given?
|
16
|
+
_run_initialize_callbacks
|
17
|
+
end
|
18
|
+
|
5
19
|
private
|
6
20
|
|
7
21
|
def init_attributes(attributes, options)
|
@@ -12,6 +26,7 @@ module ActiveRecord
|
|
12
26
|
super
|
13
27
|
@mass_assignment_options = nil
|
14
28
|
end
|
29
|
+
|
15
30
|
end
|
16
31
|
end
|
17
32
|
end
|
@@ -4,7 +4,9 @@ module ActiveRecord
|
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
6
|
module ClassMethods
|
7
|
-
|
7
|
+
|
8
|
+
private
|
9
|
+
|
8
10
|
# Detect the subclass from the inheritance column of attrs. If the inheritance column value
|
9
11
|
# is not self or a valid subclass, raises ActiveRecord::SubclassNotFound
|
10
12
|
# If this is a StrongParameters hash, and access to inheritance_column is not permitted,
|
@@ -15,11 +15,7 @@ module ActiveRecord
|
|
15
15
|
|
16
16
|
attr_names.each do |association_name|
|
17
17
|
if reflection = reflect_on_association(association_name)
|
18
|
-
|
19
|
-
reflection.options[:autosave] = true
|
20
|
-
else
|
21
|
-
reflection.autosave = true
|
22
|
-
end
|
18
|
+
reflection.autosave = true
|
23
19
|
add_autosave_association_callbacks(reflection)
|
24
20
|
|
25
21
|
nested_attributes_options = self.nested_attributes_options.dup
|
@@ -28,7 +24,7 @@ module ActiveRecord
|
|
28
24
|
|
29
25
|
type = (reflection.collection? ? :collection : :one_to_one)
|
30
26
|
|
31
|
-
generated_methods_module =
|
27
|
+
generated_methods_module = generated_association_methods
|
32
28
|
|
33
29
|
# def pirate_attributes=(attributes)
|
34
30
|
# assign_nested_attributes_for_one_to_one_association(:pirate, attributes, mass_assignment_options)
|
@@ -50,15 +50,15 @@ module ActiveRecord
|
|
50
50
|
end
|
51
51
|
|
52
52
|
def find_or_initialize_by(attributes, options = {}, &block)
|
53
|
-
find_by(attributes) || new(attributes, options, &block)
|
53
|
+
find_by(attributes.respond_to?(:to_unsafe_h) ? attributes.to_unsafe_h : attributes) || new(attributes, options, &block)
|
54
54
|
end
|
55
55
|
|
56
56
|
def find_or_create_by(attributes, options = {}, &block)
|
57
|
-
find_by(attributes) || create(attributes, options, &block)
|
57
|
+
find_by(attributes.respond_to?(:to_unsafe_h) ? attributes.to_unsafe_h : attributes) || create(attributes, options, &block)
|
58
58
|
end
|
59
59
|
|
60
60
|
def find_or_create_by!(attributes, options = {}, &block)
|
61
|
-
find_by(attributes) || create!(attributes, options, &block)
|
61
|
+
find_by(attributes.respond_to?(:to_unsafe_h) ? attributes.to_unsafe_h : attributes) || create!(attributes, options, &block)
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
data/lib/protected_attributes.rb
CHANGED
@@ -1,19 +1 @@
|
|
1
1
|
require "protected_attributes"
|
2
|
-
|
3
|
-
module ActiveRecord
|
4
|
-
module Core
|
5
|
-
def initialize(attributes = nil, options = {})
|
6
|
-
@attributes = self.class._default_attributes.dup
|
7
|
-
self.class.define_attribute_methods
|
8
|
-
|
9
|
-
init_internals
|
10
|
-
initialize_internals_callback
|
11
|
-
|
12
|
-
# +options+ argument is only needed to make protected_attributes gem easier to hook.
|
13
|
-
init_attributes(attributes, options) if attributes
|
14
|
-
|
15
|
-
yield self if block_given?
|
16
|
-
_run_initialize_callbacks
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
metadata
CHANGED
@@ -1,96 +1,71 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: protected_attributes_continued
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
|
-
- David Heinemeier Hansson
|
8
7
|
- Weston Ganger
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2017-05-05 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: activemodel
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
16
|
requirements:
|
18
|
-
- - "
|
19
|
-
- !ruby/object:Gem::Version
|
20
|
-
version: 4.0.1
|
21
|
-
- - "<"
|
17
|
+
- - "~>"
|
22
18
|
- !ruby/object:Gem::Version
|
23
|
-
version: '
|
19
|
+
version: '5.0'
|
24
20
|
type: :runtime
|
25
21
|
prerelease: false
|
26
22
|
version_requirements: !ruby/object:Gem::Requirement
|
27
23
|
requirements:
|
28
|
-
- - "
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
version: 4.0.1
|
31
|
-
- - "<"
|
24
|
+
- - "~>"
|
32
25
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
26
|
+
version: '5.0'
|
34
27
|
- !ruby/object:Gem::Dependency
|
35
28
|
name: activerecord
|
36
29
|
requirement: !ruby/object:Gem::Requirement
|
37
30
|
requirements:
|
38
|
-
- - "
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: 4.0.1
|
41
|
-
- - "<"
|
31
|
+
- - "~>"
|
42
32
|
- !ruby/object:Gem::Version
|
43
|
-
version: '
|
33
|
+
version: '5.0'
|
44
34
|
type: :development
|
45
35
|
prerelease: false
|
46
36
|
version_requirements: !ruby/object:Gem::Requirement
|
47
37
|
requirements:
|
48
|
-
- - "
|
49
|
-
- !ruby/object:Gem::Version
|
50
|
-
version: 4.0.1
|
51
|
-
- - "<"
|
38
|
+
- - "~>"
|
52
39
|
- !ruby/object:Gem::Version
|
53
|
-
version: '
|
40
|
+
version: '5.0'
|
54
41
|
- !ruby/object:Gem::Dependency
|
55
42
|
name: actionpack
|
56
43
|
requirement: !ruby/object:Gem::Requirement
|
57
44
|
requirements:
|
58
|
-
- - "
|
59
|
-
- !ruby/object:Gem::Version
|
60
|
-
version: 4.0.1
|
61
|
-
- - "<"
|
45
|
+
- - "~>"
|
62
46
|
- !ruby/object:Gem::Version
|
63
|
-
version: '
|
47
|
+
version: '5.0'
|
64
48
|
type: :development
|
65
49
|
prerelease: false
|
66
50
|
version_requirements: !ruby/object:Gem::Requirement
|
67
51
|
requirements:
|
68
|
-
- - "
|
69
|
-
- !ruby/object:Gem::Version
|
70
|
-
version: 4.0.1
|
71
|
-
- - "<"
|
52
|
+
- - "~>"
|
72
53
|
- !ruby/object:Gem::Version
|
73
|
-
version: '
|
54
|
+
version: '5.0'
|
74
55
|
- !ruby/object:Gem::Dependency
|
75
56
|
name: railties
|
76
57
|
requirement: !ruby/object:Gem::Requirement
|
77
58
|
requirements:
|
78
|
-
- - "
|
79
|
-
- !ruby/object:Gem::Version
|
80
|
-
version: 4.0.1
|
81
|
-
- - "<"
|
59
|
+
- - "~>"
|
82
60
|
- !ruby/object:Gem::Version
|
83
|
-
version: '
|
61
|
+
version: '5.0'
|
84
62
|
type: :development
|
85
63
|
prerelease: false
|
86
64
|
version_requirements: !ruby/object:Gem::Requirement
|
87
65
|
requirements:
|
88
|
-
- - "
|
89
|
-
- !ruby/object:Gem::Version
|
90
|
-
version: 4.0.1
|
91
|
-
- - "<"
|
66
|
+
- - "~>"
|
92
67
|
- !ruby/object:Gem::Version
|
93
|
-
version: '
|
68
|
+
version: '5.0'
|
94
69
|
- !ruby/object:Gem::Dependency
|
95
70
|
name: sqlite3
|
96
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -121,7 +96,6 @@ dependencies:
|
|
121
96
|
version: '0'
|
122
97
|
description: Protect attributes from mass assignment
|
123
98
|
email:
|
124
|
-
- david@loudthinking.com
|
125
99
|
- westonganger@gmail.com
|
126
100
|
executables: []
|
127
101
|
extensions: []
|
@@ -167,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
167
141
|
version: '0'
|
168
142
|
requirements: []
|
169
143
|
rubyforge_project:
|
170
|
-
rubygems_version: 2.
|
144
|
+
rubygems_version: 2.6.8
|
171
145
|
signing_key:
|
172
146
|
specification_version: 4
|
173
147
|
summary: Protect attributes from mass assignment in Active Record models
|