From 00481a9edc05fbe26519e037154f723f9fcd6d5d Mon Sep 17 00:00:00 2001 From: Michael Herold Date: Fri, 3 Feb 2017 15:36:11 -0600 Subject: [PATCH] Silence Hashie::Mash logger on Hashie 3.5.0+ We introduced a new logger for Mash due to the huge number of issues that we get where people try to set keys on their Mash. This change silences the info messages that get logged when a Mash has a conflict with a method name. I had to do this in a kind of hacky way. Since OmniAuth supports Hashie versions `>= 1.2, < 4`, I can't just hook into the method that we'll be adding in 3.5.2. As such, I apply an override for the logging method if the disable method isn't present. I'm also only overriding the method in versions that have the logging capability. --- lib/omniauth/auth_hash.rb | 6 +-- lib/omniauth/key_store.rb | 22 +++++++++ lib/omniauth/strategy.rb | 4 +- spec/omniauth/auth_hash_spec.rb | 20 +++++++++ spec/omniauth/key_store_spec.rb | 79 +++++++++++++++++++++++++++++++++ 5 files changed, 126 insertions(+), 5 deletions(-) create mode 100644 lib/omniauth/key_store.rb create mode 100644 spec/omniauth/key_store_spec.rb diff --git a/lib/omniauth/auth_hash.rb b/lib/omniauth/auth_hash.rb index e453043..164edce 100644 --- a/lib/omniauth/auth_hash.rb +++ b/lib/omniauth/auth_hash.rb @@ -1,11 +1,11 @@ -require 'hashie/mash' +require 'omniauth/key_store' module OmniAuth # The AuthHash is a normalized schema returned by all OmniAuth # strategies. It maps as much user information as the provider # is able to provide into the InfoHash (stored as the `'info'` # key). - class AuthHash < Hashie::Mash + class AuthHash < OmniAuth::KeyStore def self.subkey_class Hashie::Mash end @@ -26,7 +26,7 @@ module OmniAuth super end - class InfoHash < Hashie::Mash + class InfoHash < OmniAuth::KeyStore def self.subkey_class Hashie::Mash end diff --git a/lib/omniauth/key_store.rb b/lib/omniauth/key_store.rb new file mode 100644 index 0000000..c86338b --- /dev/null +++ b/lib/omniauth/key_store.rb @@ -0,0 +1,22 @@ +require 'hashie/mash' + +module OmniAuth + # Generic helper hash that allows method access on deeply nested keys. + class KeyStore < ::Hashie::Mash + # Disables warnings on Hashie 3.5.0+ for overwritten keys + def self.override_logging + require 'hashie/version' + return unless Gem::Version.new(Hashie::VERSION) >= Gem::Version.new('3.5.0') + + if respond_to?(:disable_warnings) + disable_warnings + else + define_method(:log_built_in_message) { |*| } + private :log_built_in_message + end + end + + # Disable on loading of the class + override_logging + end +end diff --git a/lib/omniauth/strategy.rb b/lib/omniauth/strategy.rb index 2d236f3..fe786c5 100644 --- a/lib/omniauth/strategy.rb +++ b/lib/omniauth/strategy.rb @@ -1,4 +1,4 @@ -require 'hashie/mash' +require 'omniauth/key_store' module OmniAuth class NoSessionError < StandardError; end @@ -480,7 +480,7 @@ module OmniAuth end end - class Options < Hashie::Mash; end + class Options < OmniAuth::KeyStore; end protected diff --git a/spec/omniauth/auth_hash_spec.rb b/spec/omniauth/auth_hash_spec.rb index e57d1ea..f8decf4 100644 --- a/spec/omniauth/auth_hash_spec.rb +++ b/spec/omniauth/auth_hash_spec.rb @@ -105,5 +105,25 @@ describe OmniAuth::AuthHash do expect(OmniAuth::AuthHash::InfoHash.new(:name => 'Awesome')).to be_valid end end + + require 'hashie/version' + if Gem::Version.new(Hashie::VERSION) >= Gem::Version.new('3.5.1') + context 'with Hashie 3.5.1+' do + around(:each) do |example| + original_logger = Hashie.logger + example.run + Hashie.logger = original_logger + end + + it 'does not log anything in Hashie 3.5.1+' do + logger = double('Logger') + expect(logger).not_to receive(:warn) + + Hashie.logger = logger + + subject.name = 'test' + end + end + end end end diff --git a/spec/omniauth/key_store_spec.rb b/spec/omniauth/key_store_spec.rb new file mode 100644 index 0000000..559cba6 --- /dev/null +++ b/spec/omniauth/key_store_spec.rb @@ -0,0 +1,79 @@ +require 'helper' + +RSpec.describe OmniAuth::KeyStore do + let(:logger) { double('Logger') } + + around(:each) do |example| + patched = monkey_patch_logger + example.run + remove_logger(patched) + end + + context 'on Hashie < 3.5.0' do + let(:version) { '3.4.0' } + + it 'does not log anything to the console' do + stub_const('Hashie::VERSION', version) + OmniAuth::KeyStore.override_logging + expect(logger).not_to receive(:info) + OmniAuth::KeyStore.new(:id => 1234) + end + end + + context 'on Hashie 3.5.0 and 3.5.1' do + let(:version) { '3.5.0' } + + it 'does not log anything to the console' do + stub_const('Hashie::VERSION', version) + OmniAuth::KeyStore.override_logging + expect(logger).not_to receive(:info) + OmniAuth::KeyStore.new(:id => 1234) + end + end + + context 'on Hashie 3.5.2+' do + let(:version) { '3.5.2' } + + around(:each) do |example| + patching = monkey_patch_unreleased_interface + example.run + remove_monkey_patch(patching) + end + + it 'does not log anything to the console' do + stub_const('Hashie::VERSION', version) + OmniAuth::KeyStore.override_logging + expect(logger).not_to receive(:info) + OmniAuth::KeyStore.new(:id => 1234) + end + end + + def monkey_patch_unreleased_interface + return false if OmniAuth::KeyStore.class.respond_to?(:disable_warnings, true) + + OmniAuth::KeyStore.define_singleton_method(:disable_warnings) {} + OmniAuth::KeyStore.define_singleton_method(:log_built_in_message) { |*| } + + true + end + + def monkey_patch_logger + return unless Hashie.respond_to?(:logger) + + original_logger = Hashie.logger + Hashie.logger = logger + original_logger + end + + def remove_logger(logger) + return unless logger + + Hashie.logger = logger + end + + def remove_monkey_patch(perform) + return unless perform + + OmniAuth::KeyStore.singleton_class.__send__(:remove_method, :disable_warnings) + end +end