protected_attributes_continued 1.2.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.
@@ -0,0 +1,83 @@
1
+ require 'active_support/concern'
2
+
3
+ module ActiveRecord
4
+ module MassAssignmentSecurity
5
+ # = Active Record Persistence
6
+ module Persistence
7
+ extend ActiveSupport::Concern
8
+
9
+ module ClassMethods
10
+ # Creates an object (or multiple objects) and saves it to the database, if validations pass.
11
+ # The resulting object is returned whether the object was saved successfully to the database or not.
12
+ #
13
+ # The +attributes+ parameter can be either a Hash or an Array of Hashes. These Hashes describe the
14
+ # attributes on the objects that are to be created.
15
+ #
16
+ # +create+ respects mass-assignment security and accepts either +:as+ or +:without_protection+ options
17
+ # in the +options+ parameter.
18
+ #
19
+ # ==== Examples
20
+ # # Create a single new object
21
+ # User.create(:first_name => 'Jamie')
22
+ #
23
+ # # Create a single new object using the :admin mass-assignment security role
24
+ # User.create({ :first_name => 'Jamie', :is_admin => true }, :as => :admin)
25
+ #
26
+ # # Create a single new object bypassing mass-assignment security
27
+ # User.create({ :first_name => 'Jamie', :is_admin => true }, :without_protection => true)
28
+ #
29
+ # # Create an Array of new objects
30
+ # User.create([{ :first_name => 'Jamie' }, { :first_name => 'Jeremy' }])
31
+ #
32
+ # # Create a single object and pass it into a block to set other attributes.
33
+ # User.create(:first_name => 'Jamie') do |u|
34
+ # u.is_admin = false
35
+ # end
36
+ #
37
+ # # Creating an Array of new objects using a block, where the block is executed for each object:
38
+ # User.create([{ :first_name => 'Jamie' }, { :first_name => 'Jeremy' }]) do |u|
39
+ # u.is_admin = false
40
+ # end
41
+ def create(attributes = nil, options = {}, &block)
42
+ if attributes.is_a?(Array)
43
+ attributes.collect { |attr| create(attr, options, &block) }
44
+ else
45
+ object = new(attributes, options, &block)
46
+ object.save
47
+ object
48
+ end
49
+ end
50
+ end
51
+
52
+ # Updates the attributes of the model from the passed-in hash and saves the
53
+ # record, all wrapped in a transaction. If the object is invalid, the saving
54
+ # will fail and false will be returned.
55
+ #
56
+ # When updating model attributes, mass-assignment security protection is respected.
57
+ # If no +:as+ option is supplied then the +:default+ role will be used.
58
+ # If you want to bypass the forbidden attributes protection then you can do so using
59
+ # the +:without_protection+ option.
60
+ def update(attributes, options = {})
61
+ # The following transaction covers any possible database side-effects of the
62
+ # attributes assignment. For example, setting the IDs of a child collection.
63
+ with_transaction_returning_status do
64
+ assign_attributes(attributes, options)
65
+ save
66
+ end
67
+ end
68
+ alias :update_attributes :update
69
+
70
+ # Updates its receiver just like +update_attributes+ but calls <tt>save!</tt> instead
71
+ # of +save+, so an exception is raised if the record is invalid.
72
+ def update!(attributes, options = {})
73
+ # The following transaction covers any possible database side-effects of the
74
+ # attributes assignment. For example, setting the IDs of a child collection.
75
+ with_transaction_returning_status do
76
+ assign_attributes(attributes, options)
77
+ save!
78
+ end
79
+ end
80
+ alias :update_attributes! :update!
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,21 @@
1
+ module ActiveRecord
2
+ module Reflection
3
+ if defined?(AbstractReflection)
4
+ class AbstractReflection
5
+ undef :build_association
6
+
7
+ def build_association(*options, &block)
8
+ klass.new(*options, &block)
9
+ end
10
+ end
11
+ else
12
+ class AssociationReflection
13
+ undef :build_association
14
+
15
+ def build_association(*options, &block)
16
+ klass.new(*options, &block)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,76 @@
1
+ module ActiveRecord
2
+ class Relation
3
+ undef :first_or_create
4
+ undef :first_or_create!
5
+ undef :first_or_initialize
6
+ undef :find_or_initialize_by
7
+ undef :find_or_create_by
8
+ undef :find_or_create_by!
9
+
10
+ # Tries to load the first record; if it fails, then <tt>create</tt> is called with the same arguments as this method.
11
+ #
12
+ # Expects arguments in the same format as +Base.create+.
13
+ #
14
+ # ==== Examples
15
+ # # Find the first user named Penélope or create a new one.
16
+ # User.where(:first_name => 'Penélope').first_or_create
17
+ # # => <User id: 1, first_name: 'Penélope', last_name: nil>
18
+ #
19
+ # # Find the first user named Penélope or create a new one.
20
+ # # We already have one so the existing record will be returned.
21
+ # User.where(:first_name => 'Penélope').first_or_create
22
+ # # => <User id: 1, first_name: 'Penélope', last_name: nil>
23
+ #
24
+ # # Find the first user named Scarlett or create a new one with a particular last name.
25
+ # User.where(:first_name => 'Scarlett').first_or_create(:last_name => 'Johansson')
26
+ # # => <User id: 2, first_name: 'Scarlett', last_name: 'Johansson'>
27
+ #
28
+ # # Find the first user named Scarlett or create a new one with a different last name.
29
+ # # We already have one so the existing record will be returned.
30
+ # User.where(:first_name => 'Scarlett').first_or_create do |user|
31
+ # user.last_name = "O'Hara"
32
+ # end
33
+ # # => <User id: 2, first_name: 'Scarlett', last_name: 'Johansson'>
34
+ def first_or_create(attributes = nil, options = {}, &block)
35
+ first || create(attributes, options, &block)
36
+ end
37
+
38
+ # Like <tt>first_or_create</tt> but calls <tt>create!</tt> so an exception is raised if the created record is invalid.
39
+ #
40
+ # Expects arguments in the same format as <tt>Base.create!</tt>.
41
+ def first_or_create!(attributes = nil, options = {}, &block)
42
+ first || create!(attributes, options, &block)
43
+ end
44
+
45
+ # Like <tt>first_or_create</tt> but calls <tt>new</tt> instead of <tt>create</tt>.
46
+ #
47
+ # Expects arguments in the same format as <tt>Base.new</tt>.
48
+ def first_or_initialize(attributes = nil, options = {}, &block)
49
+ first || new(attributes, options, &block)
50
+ end
51
+
52
+ def find_or_initialize_by(attributes, options = {}, &block)
53
+ find_by(attributes) || new(attributes, options, &block)
54
+ end
55
+
56
+ def find_or_create_by(attributes, options = {}, &block)
57
+ find_by(attributes) || create(attributes, options, &block)
58
+ end
59
+
60
+ def find_or_create_by!(attributes, options = {}, &block)
61
+ find_by(attributes) || create!(attributes, options, &block)
62
+ end
63
+ end
64
+
65
+ module QueryMethods
66
+ protected
67
+
68
+ def sanitize_forbidden_attributes(attributes) #:nodoc:
69
+ if !model._uses_mass_assignment_security
70
+ sanitize_for_mass_assignment(attributes)
71
+ else
72
+ attributes
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,24 @@
1
+ require 'active_support/concern'
2
+
3
+ module ActiveRecord
4
+ module MassAssignmentSecurity
5
+ module Validations
6
+ extend ActiveSupport::Concern
7
+
8
+ module ClassMethods
9
+ # Creates an object just like Base.create but calls <tt>save!</tt> instead of +save+
10
+ # so an exception is raised if the record is invalid.
11
+ def create!(attributes = nil, options = {}, &block)
12
+ if attributes.is_a?(Array)
13
+ attributes.collect { |attr| create!(attr, options, &block) }
14
+ else
15
+ object = new(attributes, options)
16
+ yield(object) if block_given?
17
+ object.save!
18
+ object
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,14 @@
1
+ require "active_model/mass_assignment_security"
2
+ require "protected_attributes/railtie" if defined? Rails::Railtie
3
+ require "protected_attributes/version"
4
+
5
+ ActiveSupport.on_load :active_record do
6
+ require "active_record/mass_assignment_security"
7
+ end
8
+
9
+ ActiveSupport.on_load :action_controller do
10
+ require "action_controller/accessible_params_wrapper"
11
+ end
12
+
13
+ module ProtectedAttributes
14
+ end
@@ -0,0 +1,9 @@
1
+ module ProtectedAttributes
2
+ class Railtie < ::Rails::Railtie
3
+ initializer "protected_attributes.active_record", :before => "active_record.set_configs" do |app|
4
+ if app.config.respond_to?(:active_record) && app.config.active_record.delete(:whitelist_attributes)
5
+ ActiveSupport::Deprecation.warn "config.active_record.whitelist_attributes is deprecated and have no effect. Remove its call from the configuration."
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module ProtectedAttributes
2
+ VERSION = "1.2.0"
3
+ end
metadata ADDED
@@ -0,0 +1,173 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: protected_attributes_continued
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.0
5
+ platform: ruby
6
+ authors:
7
+ - David Heinemeier Hansson
8
+ - Weston Ganger
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2016-08-20 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activemodel
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - ">="
19
+ - !ruby/object:Gem::Version
20
+ version: 4.0.1
21
+ - - "<"
22
+ - !ruby/object:Gem::Version
23
+ version: '6.0'
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ version: 4.0.1
31
+ - - "<"
32
+ - !ruby/object:Gem::Version
33
+ version: '6.0'
34
+ - !ruby/object:Gem::Dependency
35
+ name: activerecord
36
+ requirement: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 4.0.1
41
+ - - "<"
42
+ - !ruby/object:Gem::Version
43
+ version: '6.0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - ">="
49
+ - !ruby/object:Gem::Version
50
+ version: 4.0.1
51
+ - - "<"
52
+ - !ruby/object:Gem::Version
53
+ version: '6.0'
54
+ - !ruby/object:Gem::Dependency
55
+ name: actionpack
56
+ requirement: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ">="
59
+ - !ruby/object:Gem::Version
60
+ version: 4.0.1
61
+ - - "<"
62
+ - !ruby/object:Gem::Version
63
+ version: '6.0'
64
+ type: :development
65
+ prerelease: false
66
+ version_requirements: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: 4.0.1
71
+ - - "<"
72
+ - !ruby/object:Gem::Version
73
+ version: '6.0'
74
+ - !ruby/object:Gem::Dependency
75
+ name: railties
76
+ requirement: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: 4.0.1
81
+ - - "<"
82
+ - !ruby/object:Gem::Version
83
+ version: '6.0'
84
+ type: :development
85
+ prerelease: false
86
+ version_requirements: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: 4.0.1
91
+ - - "<"
92
+ - !ruby/object:Gem::Version
93
+ version: '6.0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: sqlite3
96
+ requirement: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ type: :development
102
+ prerelease: false
103
+ version_requirements: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ - !ruby/object:Gem::Dependency
109
+ name: mocha
110
+ requirement: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ type: :development
116
+ prerelease: false
117
+ version_requirements: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ description: Protect attributes from mass assignment
123
+ email:
124
+ - david@loudthinking.com
125
+ - westonganger@gmail.com
126
+ executables: []
127
+ extensions: []
128
+ extra_rdoc_files: []
129
+ files:
130
+ - LICENSE.txt
131
+ - README.md
132
+ - lib/action_controller/accessible_params_wrapper.rb
133
+ - lib/active_model/mass_assignment_security.rb
134
+ - lib/active_model/mass_assignment_security/permission_set.rb
135
+ - lib/active_model/mass_assignment_security/sanitizer.rb
136
+ - lib/active_record/mass_assignment_security.rb
137
+ - lib/active_record/mass_assignment_security/associations.rb
138
+ - lib/active_record/mass_assignment_security/attribute_assignment.rb
139
+ - lib/active_record/mass_assignment_security/core.rb
140
+ - lib/active_record/mass_assignment_security/inheritance.rb
141
+ - lib/active_record/mass_assignment_security/nested_attributes.rb
142
+ - lib/active_record/mass_assignment_security/persistence.rb
143
+ - lib/active_record/mass_assignment_security/reflection.rb
144
+ - lib/active_record/mass_assignment_security/relation.rb
145
+ - lib/active_record/mass_assignment_security/validations.rb
146
+ - lib/protected_attributes.rb
147
+ - lib/protected_attributes/railtie.rb
148
+ - lib/protected_attributes/version.rb
149
+ homepage: https://github.com/westonganger/protected_attributes_continued
150
+ licenses:
151
+ - MIT
152
+ metadata: {}
153
+ post_install_message:
154
+ rdoc_options: []
155
+ require_paths:
156
+ - lib
157
+ required_ruby_version: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - ">="
160
+ - !ruby/object:Gem::Version
161
+ version: '0'
162
+ required_rubygems_version: !ruby/object:Gem::Requirement
163
+ requirements:
164
+ - - ">="
165
+ - !ruby/object:Gem::Version
166
+ version: '0'
167
+ requirements: []
168
+ rubyforge_project:
169
+ rubygems_version: 2.5.1
170
+ signing_key:
171
+ specification_version: 4
172
+ summary: Protect attributes from mass assignment in Active Record models
173
+ test_files: []