diff --git a/activerecord/lib/active_record/attribute_assignment.rb b/activerecord/lib/active_record/attribute_assignment.rb index abc2fa546a821cc79d1e6f147d31426a831e8071..269fc3e381db7bea54d27d23c1fadf1943c2adff 100644 --- a/activerecord/lib/active_record/attribute_assignment.rb +++ b/activerecord/lib/active_record/attribute_assignment.rb @@ -1,11 +1,24 @@ require 'active_support/concern' module ActiveRecord + ActiveSupport.on_load(:active_record_config) do + mattr_accessor :whitelist_attributes, instance_accessor: false + end + module AttributeAssignment extend ActiveSupport::Concern include ActiveModel::MassAssignmentSecurity + included do + attr_accessible(nil) if Model.whitelist_attributes + end + module ClassMethods + def inherited(child) # :nodoc: + child.attr_accessible(nil) if Model.whitelist_attributes + super + end + private # The primary key and inheritance column can never be set by mass-assignment for security reasons. diff --git a/activerecord/lib/active_record/railtie.rb b/activerecord/lib/active_record/railtie.rb index 6937960e93e27b83b5a868cd68bd715267a22750..bcafcbb76c830a1da3b1fe298a8de48159325f45 100644 --- a/activerecord/lib/active_record/railtie.rb +++ b/activerecord/lib/active_record/railtie.rb @@ -68,9 +68,6 @@ class Railtie < Rails::Railtie initializer "active_record.set_configs" do |app| ActiveSupport.on_load(:active_record) do - if app.config.active_record.delete(:whitelist_attributes) - attr_accessible(nil) - end app.config.active_record.each do |k,v| send "#{k}=", v end diff --git a/activerecord/test/cases/mass_assignment_security_test.rb b/activerecord/test/cases/mass_assignment_security_test.rb index 214546802adea5cdf4e887444139a5ba28441a32..c75a0be98e19b78b820838acb3cbaf0c756b9ecc 100644 --- a/activerecord/test/cases/mass_assignment_security_test.rb +++ b/activerecord/test/cases/mass_assignment_security_test.rb @@ -251,6 +251,33 @@ def test_protection_against_class_attribute_writers assert !Task.new.respond_to?("#{method}=") end end + + test "ActiveRecord::Model.whitelist_attributes works for models which include Model" do + begin + prev, ActiveRecord::Model.whitelist_attributes = ActiveRecord::Model.whitelist_attributes, true + + klass = Class.new { include ActiveRecord::Model } + assert_equal ActiveModel::MassAssignmentSecurity::WhiteList, klass.active_authorizers[:default].class + assert_equal [], klass.active_authorizers[:default].to_a + ensure + ActiveRecord::Model.whitelist_attributes = prev + end + end + + test "ActiveRecord::Model.whitelist_attributes works for models which inherit Base" do + begin + prev, ActiveRecord::Model.whitelist_attributes = ActiveRecord::Model.whitelist_attributes, true + + klass = Class.new(ActiveRecord::Base) + assert_equal ActiveModel::MassAssignmentSecurity::WhiteList, klass.active_authorizers[:default].class + assert_equal [], klass.active_authorizers[:default].to_a + + klass.attr_accessible 'foo' + assert_equal ['foo'], Class.new(klass).active_authorizers[:default].to_a + ensure + ActiveRecord::Model.whitelist_attributes = prev + end + end end diff --git a/railties/test/application/configuration_test.rb b/railties/test/application/configuration_test.rb index 7193dfdef57b1623f2524326c71f94b87e5eb047..c1a68c57863463a459b590ecb71742970f6d92b9 100644 --- a/railties/test/application/configuration_test.rb +++ b/railties/test/application/configuration_test.rb @@ -374,9 +374,10 @@ def index require "#{app_path}/config/environment" - assert_equal ActiveModel::MassAssignmentSecurity::WhiteList, - ActiveRecord::Base.active_authorizers[:default].class - assert_equal [], ActiveRecord::Base.active_authorizers[:default].to_a + klass = Class.new(ActiveRecord::Base) + + assert_equal ActiveModel::MassAssignmentSecurity::WhiteList, klass.active_authorizers[:default].class + assert_equal [], klass.active_authorizers[:default].to_a end test "registers interceptors with ActionMailer" do