diff options
author | Josh Kalderimis <josh.kalderimis@gmail.com> | 2010-07-08 18:16:36 +0200 |
---|---|---|
committer | José Valim <jose.valim@gmail.com> | 2010-07-08 18:28:45 +0200 |
commit | 4b66aab00fa0ea6bcc6ec81df19e44de34fd7864 (patch) | |
tree | ff870b932c26869d6a27a6a058d37baa6c289e0a /activerecord/lib | |
parent | 7c86e8e21ba6a1f88226ddd0cf012a563f234d06 (diff) | |
download | rails-4b66aab00fa0ea6bcc6ec81df19e44de34fd7864.tar.gz rails-4b66aab00fa0ea6bcc6ec81df19e44de34fd7864.tar.bz2 rails-4b66aab00fa0ea6bcc6ec81df19e44de34fd7864.zip |
mass_assignment_security moved from AR to AMo, and minor test cleanup
Signed-off-by: José Valim <jose.valim@gmail.com>
Diffstat (limited to 'activerecord/lib')
5 files changed, 1 insertions, 214 deletions
diff --git a/activerecord/lib/active_record.rb b/activerecord/lib/active_record.rb index 9ab05a0548..e2f2508ae8 100644 --- a/activerecord/lib/active_record.rb +++ b/activerecord/lib/active_record.rb @@ -64,7 +64,6 @@ module ActiveRecord autoload :CounterCache autoload :DynamicFinderMatch autoload :DynamicScopeMatch - autoload :MassAssignmentSecurity autoload :Migration autoload :Migrator, 'active_record/migration' autoload :NamedScope diff --git a/activerecord/lib/active_record/base.rb b/activerecord/lib/active_record/base.rb index 56b4ba8260..f22a9de7b1 100644 --- a/activerecord/lib/active_record/base.rb +++ b/activerecord/lib/active_record/base.rb @@ -1797,7 +1797,7 @@ MSG include AttributeMethods::PrimaryKey include AttributeMethods::TimeZoneConversion include AttributeMethods::Dirty - include MassAssignmentSecurity + include ActiveModel::MassAssignmentSecurity include Callbacks, ActiveModel::Observing, Timestamp include Associations, AssociationPreload, NamedScope diff --git a/activerecord/lib/active_record/mass_assignment_security.rb b/activerecord/lib/active_record/mass_assignment_security.rb deleted file mode 100644 index 8f4d6e1c74..0000000000 --- a/activerecord/lib/active_record/mass_assignment_security.rb +++ /dev/null @@ -1,142 +0,0 @@ -require 'active_record/mass_assignment_security/permission_set' - -module ActiveRecord - # = Active Record Mass-Assignment Security - module MassAssignmentSecurity - extend ActiveSupport::Concern - - included do - class_attribute :_accessible_attributes - class_attribute :_protected_attributes - class_attribute :_active_authorizer - end - - # 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 ActiveRecord::MassAssignmentSecurity - # - # attr_accessible :first_name, :last_name - # - # def self.admin_accessible_attributes - # accessible_attributes + [ :plan_id ] - # end - # - # def update - # ... - # @account.update_attributes(account_params) - # ... - # end - # - # protected - # - # def account_params - # sanitize_for_mass_assignment(params[:account]) - # end - # - # def mass_assignment_authorizer - # admin ? admin_accessible_attributes : super - # end - # - # end - # - module ClassMethods - # Attributes named in this macro are protected from mass-assignment, - # such as <tt>new(attributes)</tt>, - # <tt>update_attributes(attributes)</tt>, or - # <tt>attributes=(attributes)</tt>. - # - # 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. - # - # class Customer < ActiveRecord::Base - # attr_protected :credit_rating - # end - # - # customer = Customer.new("name" => David, "credit_rating" => "Excellent") - # customer.credit_rating # => nil - # customer.attributes = { "description" => "Jolly fellow", "credit_rating" => "Superb" } - # customer.credit_rating # => nil - # - # customer.credit_rating = "Average" - # customer.credit_rating # => "Average" - # - # To start from an all-closed default and enable attributes as needed, - # have a look at +attr_accessible+. - # - # Note that using <tt>Hash#except</tt> or <tt>Hash#slice</tt> in place of +attr_protected+ - # to sanitize attributes won't provide sufficient protection. - def attr_protected(*names) - self._protected_attributes = self.protected_attributes + names - self._active_authorizer = self._protected_attributes - end - - # Specifies a white list of model attributes that can be set via - # mass-assignment, such as <tt>new(attributes)</tt>, - # <tt>update_attributes(attributes)</tt>, or - # <tt>attributes=(attributes)</tt> - # - # 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 < ActiveRecord::Base - # attr_accessible :name, :nickname - # end - # - # customer = Customer.new(:name => "David", :nickname => "Dave", :credit_rating => "Excellent") - # customer.credit_rating # => nil - # customer.attributes = { :name => "Jolly fellow", :credit_rating => "Superb" } - # customer.credit_rating # => nil - # - # customer.credit_rating = "Average" - # customer.credit_rating # => "Average" - # - # Note that using <tt>Hash#except</tt> or <tt>Hash#slice</tt> in place of +attr_accessible+ - # to sanitize attributes won't provide sufficient protection. - def attr_accessible(*names) - self._accessible_attributes = self.accessible_attributes + names - self._active_authorizer = self._accessible_attributes - end - - def protected_attributes - self._protected_attributes ||= BlackList.new(attributes_protected_by_default).tap { |w| w.logger = logger } - end - - def accessible_attributes - self._accessible_attributes ||= WhiteList.new.tap { |w| w.logger = logger } - end - - def active_authorizer - self._active_authorizer ||= protected_attributes - end - - def attributes_protected_by_default - [] - end - end - - protected - - def sanitize_for_mass_assignment(attributes) - mass_assignment_authorizer.sanitize(attributes) - end - - def mass_assignment_authorizer - self.class.active_authorizer - end - - end -end diff --git a/activerecord/lib/active_record/mass_assignment_security/permission_set.rb b/activerecord/lib/active_record/mass_assignment_security/permission_set.rb deleted file mode 100644 index 8446a4103b..0000000000 --- a/activerecord/lib/active_record/mass_assignment_security/permission_set.rb +++ /dev/null @@ -1,41 +0,0 @@ -require 'active_record/mass_assignment_security/sanitizer' - -module ActiveRecord - module MassAssignmentSecurity - - class PermissionSet < Set - attr_accessor :logger - - def +(values) - super(values.map(&:to_s)) - end - - def include?(key) - super(remove_multiparameter_id(key)) - end - - protected - - def remove_multiparameter_id(key) - key.gsub(/\(.+/, '') - end - end - - class WhiteList < PermissionSet - include Sanitizer - - def deny?(key) - !include?(key) - end - end - - class BlackList < PermissionSet - include Sanitizer - - def deny?(key) - include?(key) - end - end - - end -end
\ No newline at end of file diff --git a/activerecord/lib/active_record/mass_assignment_security/sanitizer.rb b/activerecord/lib/active_record/mass_assignment_security/sanitizer.rb deleted file mode 100644 index 11de35f9d6..0000000000 --- a/activerecord/lib/active_record/mass_assignment_security/sanitizer.rb +++ /dev/null @@ -1,29 +0,0 @@ -module ActiveRecord - module MassAssignmentSecurity - module Sanitizer - - # Returns all attributes not denied by the authorizer. - def sanitize(attributes) - sanitized_attributes = attributes.reject { |key, value| deny?(key) } - debug_protected_attribute_removal(attributes, sanitized_attributes) if debug? - sanitized_attributes - end - - protected - - def debug_protected_attribute_removal(attributes, sanitized_attributes) - removed_keys = attributes.keys - sanitized_attributes.keys - warn!(removed_keys) if removed_keys.any? - end - - def debug? - logger.present? - end - - def warn!(attrs) - logger.debug "WARNING: Can't mass-assign protected attributes: #{attrs.join(', ')}" - end - - end - end -end |