From 9945cd097a46771aedfcb9abc110419198452022 Mon Sep 17 00:00:00 2001 From: bogdanvlviv Date: Mon, 10 Sep 2018 12:39:07 +0300 Subject: Clarify docs of `config.filter_parameters` and `#filter_attributes` Add mention that `config.filter_parameters` also filters out sensitive values of database columns when call `#inspect` since #33756. --- activerecord/lib/active_record/core.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index 82cf7563a2..4f10cddc87 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -126,7 +126,7 @@ module ActiveRecord class_attribute :default_connection_handler, instance_writer: false ## - # Specifies columns which don't want to be exposed while calling #inspect + # Specifies columns which shouldn't be exposed while calling #inspect. class_attribute :filter_attributes, instance_writer: false, default: [] def self.connection_handler -- cgit v1.2.3 From d40e33fcc5899a91ceab10f8bd86a1455846917a Mon Sep 17 00:00:00 2001 From: bogdanvlviv Date: Mon, 10 Sep 2018 12:41:14 +0300 Subject: DRY `activerecord/lib/active_record/core.rb` and fix tests - Move ``` filter_attributes = self.filter_attributes.map(&:to_s).to_set filter_attributes.include?(attribute_name) && !read_attribute(attribute_name).nil? ``` to private method. - Fix tests in `activerecord/test/cases/filter_attributes_test.rb` - Ensure that `teardown` sets `ActiveRecord::Base.filter_attributes` to previous state. - Ensure that `Admin::Account.filter_attributes` is set to previous state in the "filter_attributes could be overwritten by models" test. Follow up #33756 --- activerecord/lib/active_record/core.rb | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index 4f10cddc87..d5d2c70a8a 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -493,13 +493,12 @@ module ActiveRecord # Returns the contents of the record as a nicely formatted string. def inspect - filter_attributes = self.filter_attributes.map(&:to_s).to_set # We check defined?(@attributes) not to issue warnings if the object is # allocated but not initialized. inspection = if defined?(@attributes) && @attributes self.class.attribute_names.collect do |name| if has_attribute?(name) - if filter_attributes.include?(name) && !read_attribute(name).nil? + if filter_attribute?(name) "#{name}: #{ActiveRecord::Core::FILTERED}" else "#{name}: #{attribute_for_inspect(name)}" @@ -517,21 +516,19 @@ module ActiveRecord # when pp is required. def pretty_print(pp) return super if custom_inspect_method_defined? - filter_attributes = self.filter_attributes.map(&:to_s).to_set pp.object_address_group(self) do if defined?(@attributes) && @attributes column_names = self.class.column_names.select { |name| has_attribute?(name) || new_record? } pp.seplist(column_names, proc { pp.text "," }) do |column_name| - column_value = read_attribute(column_name) pp.breakable " " pp.group(1) do pp.text column_name pp.text ":" pp.breakable - if filter_attributes.include?(column_name) && !column_value.nil? + if filter_attribute?(column_name) pp.text ActiveRecord::Core::FILTERED else - pp.pp column_value + pp.pp read_attribute(column_name) end end end @@ -583,5 +580,11 @@ module ActiveRecord def custom_inspect_method_defined? self.class.instance_method(:inspect).owner != ActiveRecord::Base.instance_method(:inspect).owner end + + def filter_attribute?(attribute_name) + filter_attributes = self.filter_attributes.map(&:to_s).to_set + + filter_attributes.include?(attribute_name) && !read_attribute(attribute_name).nil? + end end end -- cgit v1.2.3 From d1a14865e055091fc2a50ddfd7e9e206152b1095 Mon Sep 17 00:00:00 2001 From: bogdanvlviv Date: Mon, 10 Sep 2018 16:58:56 +0300 Subject: Build string set when `filter_attributes` is assigned It would allow `filter_attributes` to be reused across multiple calls to `#inspect` or `#pretty_print`. - Add `require "set"` - Remove `filter_attributes` instance reader. I think there is no need to keep it. --- activerecord/lib/active_record/core.rb | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index d5d2c70a8a..0002941ff6 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -3,6 +3,7 @@ require "active_support/core_ext/hash/indifferent_access" require "active_support/core_ext/string/filters" require "concurrent/map" +require "set" module ActiveRecord module Core @@ -125,9 +126,7 @@ module ActiveRecord class_attribute :default_connection_handler, instance_writer: false - ## - # Specifies columns which shouldn't be exposed while calling #inspect. - class_attribute :filter_attributes, instance_writer: false, default: [] + self.filter_attributes = [] def self.connection_handler ActiveRecord::RuntimeRegistry.connection_handler || default_connection_handler @@ -227,6 +226,20 @@ module ActiveRecord end end + # Returns columns which shouldn't be exposed while calling #inspect. + def filter_attributes + if defined?(@filter_attributes) + @filter_attributes + else + superclass.filter_attributes + end + end + + # Specifies columns which shouldn't be exposed while calling #inspect. + def filter_attributes=(attributes_names) + @filter_attributes = attributes_names.map(&:to_s).to_set + end + # Returns a string like 'Post(id:integer, title:string, body:text)' def inspect if self == Base @@ -582,9 +595,7 @@ module ActiveRecord end def filter_attribute?(attribute_name) - filter_attributes = self.filter_attributes.map(&:to_s).to_set - - filter_attributes.include?(attribute_name) && !read_attribute(attribute_name).nil? + self.class.filter_attributes.include?(attribute_name) && !read_attribute(attribute_name).nil? end end end -- cgit v1.2.3 From 59cae0755eea9aa7be4d746427b007f61f33c4ec Mon Sep 17 00:00:00 2001 From: bogdanvlviv Date: Mon, 10 Sep 2018 19:10:44 +0300 Subject: Add mention about `ActiveRecord::Base::filter_attributes` to the changelog entry Also remove `# :nodoc:` for `ActiveRecord::Core::ClassMethods` in order to show non-nodoc methods in that module on the api docs http://edgeapi.rubyonrails.org --- activerecord/lib/active_record/core.rb | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'activerecord/lib') diff --git a/activerecord/lib/active_record/core.rb b/activerecord/lib/active_record/core.rb index 0002941ff6..392602bc0f 100644 --- a/activerecord/lib/active_record/core.rb +++ b/activerecord/lib/active_record/core.rb @@ -139,7 +139,7 @@ module ActiveRecord self.default_connection_handler = ConnectionAdapters::ConnectionHandler.new end - module ClassMethods # :nodoc: + module ClassMethods def initialize_find_by_cache # :nodoc: @find_by_statement_cache = { true => Concurrent::Map.new, false => Concurrent::Map.new } end @@ -216,7 +216,7 @@ module ActiveRecord generated_association_methods end - def generated_association_methods + def generated_association_methods # :nodoc: @generated_association_methods ||= begin mod = const_set(:GeneratedAssociationMethods, Module.new) private_constant :GeneratedAssociationMethods @@ -226,7 +226,7 @@ module ActiveRecord end end - # Returns columns which shouldn't be exposed while calling #inspect. + # Returns columns which shouldn't be exposed while calling +#inspect+. def filter_attributes if defined?(@filter_attributes) @filter_attributes @@ -235,13 +235,13 @@ module ActiveRecord end end - # Specifies columns which shouldn't be exposed while calling #inspect. + # Specifies columns which shouldn't be exposed while calling +#inspect+. def filter_attributes=(attributes_names) @filter_attributes = attributes_names.map(&:to_s).to_set end # Returns a string like 'Post(id:integer, title:string, body:text)' - def inspect + def inspect # :nodoc: if self == Base super elsif abstract_class? @@ -257,7 +257,7 @@ module ActiveRecord end # Overwrite the default class equality method to provide support for decorated models. - def ===(object) + def ===(object) # :nodoc: object.is_a?(self) end -- cgit v1.2.3