Module: ActiveModel::MassAssignmentSecurity::ClassMethods
- Defined in:
- activemodel/lib/active_model/mass_assignment_security.rb
Overview
Mass assignment security provides an interface for protecting attributes from end-user assignment. For more complex permissions, mass assignment security may be handled outside the model by extending a non-ActiveRecord class, such as a controller, with this behavior.
For example, a logged in user may need to assign additional attributes depending on their role:
class AccountsController < ApplicationController
include ActiveModel::MassAssignmentSecurity
attr_accessible :first_name, :last_name
attr_accessible :first_name, :last_name, :plan_id, :as => :admin
def update
...
@account.update_attributes(account_params)
...
end
protected
def account_params
role = admin ? :admin : :default
sanitize_for_mass_assignment(params[:account], role)
end
end
Configuration options
-
mass_assignment_sanitizer
- Defines sanitize method. Possible values are:-
:logger
(default) - writes filtered attributes to logger -
:strict
- raiseActiveModel::MassAssignmentSecurity::Error
on any protected attribute update
-
You can specify your own sanitizer object eg. MySanitizer.new. See ActiveModel::MassAssignmentSecurity::LoggerSanitizer
for example implementation.
Instance Method Summary collapse
- #accessible_attributes(role = :default) ⇒ Object
- #active_authorizers ⇒ Object (also: #active_authorizer)
-
#attr_accessible(*args) ⇒ Object
Specifies a white list of model attributes that can be set via mass-assignment.
-
#attr_protected(*args) ⇒ Object
Attributes named in this macro are protected from mass-assignment whenever attributes are sanitized before assignment.
- #attributes_protected_by_default ⇒ Object
- #mass_assignment_sanitizer=(value) ⇒ Object
- #protected_attributes(role = :default) ⇒ Object
Instance Method Details
#accessible_attributes(role = :default) ⇒ Object
191 192 193 |
# File 'activemodel/lib/active_model/mass_assignment_security.rb', line 191 def accessible_attributes(role = :default) accessible_attributes_configs[role] end |
#active_authorizers ⇒ Object Also known as:
195 196 197 |
# File 'activemodel/lib/active_model/mass_assignment_security.rb', line 195 def self. ||= protected_attributes_configs end |
#attr_accessible(*args) ⇒ Object
Specifies a white list of model attributes that can be set via mass-assignment.
Like attr_protected
, a role for the attributes is optional, if no role is provided then :default is used. A role can be defined by using the :as option.
This is the opposite of the attr_protected
macro: Mass-assignment will only set attributes in this list, to assign to the rest of attributes you can use direct writer methods. This is meant to protect sensitive attributes from being overwritten by malicious users tampering with URLs or forms. If you’d rather start from an all-open default and restrict attributes as needed, have a look at attr_protected
.
class Customer
include ActiveModel::MassAssignmentSecurity
attr_accessor :name, :credit_rating
attr_accessible :name
attr_accessible :name, :credit_rating, :as => :admin
def assign_attributes(values, = {})
sanitize_for_mass_assignment(values, [:as]).each do |k, v|
send("#{k}=", v)
end
end
end
When using the :default role:
customer = Customer.new
customer.assign_attributes({ "name" => "David", "credit_rating" => "Excellent", :last_login => 1.day.ago }, :as => :default)
customer.name # => "David"
customer. # => nil
customer. = "Average"
customer. # => "Average"
And using the :admin role:
customer = Customer.new
customer.assign_attributes({ "name" => "David", "credit_rating" => "Excellent", :last_login => 1.day.ago }, :as => :admin)
customer.name # => "David"
customer. # => "Excellent"
Note that using Hash#except
or Hash#slice
in place of attr_accessible
to sanitize attributes provides basically the same functionality, but it makes a bit tricky to deal with nested attributes.
174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'activemodel/lib/active_model/mass_assignment_security.rb', line 174 def attr_accessible(*args) = args. role = [:as] || :default self._accessible_attributes = accessible_attributes_configs.dup Array.wrap(role).each do |name| self._accessible_attributes[name] = self.accessible_attributes(name) + args end self. = self._accessible_attributes end |
#attr_protected(*args) ⇒ Object
Attributes named in this macro are protected from mass-assignment whenever attributes are sanitized before assignment. A role for the attributes is optional, if no role is provided then :default is used. A role can be defined by using the :as option.
Mass-assignment to these attributes will simply be ignored, to assign to them you can use direct writer methods. This is meant to protect sensitive attributes from being overwritten by malicious users tampering with URLs or forms. Example:
class Customer
include ActiveModel::MassAssignmentSecurity
attr_accessor :name, :credit_rating
attr_protected :credit_rating, :last_login
attr_protected :last_login, :as => :admin
def assign_attributes(values, = {})
sanitize_for_mass_assignment(values, [:as]).each do |k, v|
send("#{k}=", v)
end
end
end
When using the :default role:
customer = Customer.new
customer.assign_attributes({ "name" => "David", "credit_rating" => "Excellent", :last_login => 1.day.ago }, :as => :default)
customer.name # => "David"
customer. # => nil
customer.last_login # => nil
customer. = "Average"
customer. # => "Average"
And using the :admin role:
customer = Customer.new
customer.assign_attributes({ "name" => "David", "credit_rating" => "Excellent", :last_login => 1.day.ago }, :as => :admin)
customer.name # => "David"
customer. # => "Excellent"
customer.last_login # => nil
To start from an all-closed default and enable attributes as needed, have a look at attr_accessible
.
Note that using Hash#except
or Hash#slice
in place of attr_protected
to sanitize attributes provides basically the same functionality, but it makes a bit tricky to deal with nested attributes.
111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'activemodel/lib/active_model/mass_assignment_security.rb', line 111 def attr_protected(*args) = args. role = [:as] || :default self._protected_attributes = protected_attributes_configs.dup Array.wrap(role).each do |name| self._protected_attributes[name] = self.protected_attributes(name) + args end self. = self._protected_attributes end |
#attributes_protected_by_default ⇒ Object
200 201 202 |
# File 'activemodel/lib/active_model/mass_assignment_security.rb', line 200 def attributes_protected_by_default [] end |
#mass_assignment_sanitizer=(value) ⇒ Object
204 205 206 207 208 209 210 |
# File 'activemodel/lib/active_model/mass_assignment_security.rb', line 204 def mass_assignment_sanitizer=(value) self._mass_assignment_sanitizer = if value.is_a?(Symbol) const_get(:"#{value.to_s.camelize}Sanitizer").new(self) else value end end |
#protected_attributes(role = :default) ⇒ Object
187 188 189 |
# File 'activemodel/lib/active_model/mass_assignment_security.rb', line 187 def protected_attributes(role = :default) protected_attributes_configs[role] end |