Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

Ticket #1897: filter_logged_params_v3.diff

File filter_logged_params_v3.diff, 5.3 kB (added by jeremye@bsa.ca.gov, 3 years ago)

Fix when no block is provided, add tests

  • actionpack/test/controller/filter_params_test.rb

    old new  
     1require File.dirname(__FILE__) + '/../abstract_unit' 
     2 
     3class TestController < ActionController::Base 
     4end 
     5 
     6class RequestTest < Test::Unit::TestCase 
     7  def setup 
     8    @controller = TestController.new 
     9  end 
     10   
     11  def test_filter_params 
     12    assert TestController.respond_to?(:filter_logged_params) 
     13    assert ! @controller.respond_to?(:filter_params) 
     14     
     15    TestController.filter_logged_params 
     16    assert @controller.respond_to?(:filter_params) 
     17     
     18    test_hashes = [[{},{},[]], 
     19    [{'foo'=>'bar'},{'foo'=>'bar'},[]], 
     20    [{'foo'=>'bar'},{'foo'=>'bar'},%w'food'], 
     21    [{'foo'=>'bar'},{'foo'=>'[FILTERED]'},%w'foo'], 
     22    [{'foo'=>'bar', 'bar'=>'foo'},{'foo'=>'[FILTERED]', 'bar'=>'foo'},%w'foo baz'], 
     23    [{'foo'=>'bar', 'baz'=>'foo'},{'foo'=>'[FILTERED]', 'baz'=>'[FILTERED]'},%w'foo baz'], 
     24    [{'bar'=>{'foo'=>'bar','bar'=>'foo'}},{'bar'=>{'foo'=>'[FILTERED]','bar'=>'foo'}},%w'fo'], 
     25    [{'foo'=>{'foo'=>'bar','bar'=>'foo'}},{'foo'=>'[FILTERED]'},%w'f banana']] 
     26     
     27    test_hashes.each do |before_filter, after_filter, filter_words| 
     28      TestController.filter_logged_params(*filter_words) 
     29      assert_equal after_filter, @controller.filter_params(before_filter) 
     30       
     31      filter_words.push('blah') 
     32      TestController.filter_logged_params(*filter_words) do |key, value| 
     33        value.reverse! if key =~ /bargain/ 
     34      end 
     35      before_filter['barg'] = {'bargain'=>'gain', 'blah'=>'bar', 'bar'=>{'bargain'=>{'blah'=>'foo'}}} 
     36      after_filter['barg'] = {'bargain'=>'niag', 'blah'=>'[FILTERED]', 'bar'=>{'bargain'=>{'blah'=>'[FILTERED]'}}} 
     37      assert_equal after_filter, @controller.filter_params(before_filter) 
     38    end 
     39  end 
     40end 
  • actionpack/lib/action_controller/benchmarking.rb

    old new  
    7070        log_message  = "Completed in #{sprintf("%.5f", runtime)} (#{(1 / runtime).floor} reqs/sec)" 
    7171        log_message << rendering_runtime(runtime) if @rendering_runtime 
    7272        log_message << active_record_runtime(runtime) if Object.const_defined?("ActiveRecord") && ActiveRecord::Base.connected? 
    73         log_message << " [#{complete_request_uri rescue "unknown"}]" 
     73        log_message << " [#{(self.respond_to?(:filter_params) ? complete_request_uri.gsub(/\?.*/,'?[FILTERED]') : complete_request_uri) rescue "unknown"}]" 
    7474        logger.info(log_message) 
    7575      end 
    7676    end 
  • actionpack/lib/action_controller/base.rb

    old new  
    346346        require 'action_controller/upload_progress' 
    347347        include ActionController::UploadProgress 
    348348      end 
     349       
     350      # Replace sensitive paramater data from the request log. 
     351      # Filters paramaters that have any of the arguments as a substring. 
     352      # Looks in all subhashes of the param hash for keys to filter. 
     353      # If a block is given, each key and value of the paramater hash and all 
     354      # subhashes is passed to it, the value or key 
     355      # can be replaced using String#replace or similar method. 
     356      # Examples: 
     357      #   filter_logged_params  
     358      #   => Does nothing, just slows the logging process down 
     359      # 
     360      #   filter_logged_params :password 
     361      #   => replaces the value to all keys matching /password/i with "[FILTERED]" 
     362      # 
     363      #   filter_logged_params :foo, "bar" 
     364      #   => replaces the value to all keys matching /foo|bar/i with "[FILTERED]" 
     365      # 
     366      #   filter_logged_params {|k,v| v.reverse! if k =~ /secret/i} 
     367      #   => reverses the value to all keys matching /secret/i 
     368      # 
     369      #   filter_logged_params(:foo, "bar") {|k,v| v.reverse! if k =~ /secret/i} 
     370      #   => reverses the value to all keys matching /secret/i, and  
     371      #      replaces the value to all keys matching /foo|bar/i with "[FILTERED]" 
     372      def filter_logged_params(*filter_words, &block) 
     373        param_filter = Regexp.new(filter_words.collect{|s|s.to_s}.join('|'),true) if filter_words.length > 0 
     374        define_method("filter_params") do |hash| 
     375          newhash = {} 
     376          hash.each do |key, value| 
     377            if key =~ param_filter 
     378              newhash[key] = '[FILTERED]' 
     379            elsif value.is_a?(Hash) 
     380              newhash[key] = filter_params(value)  
     381            elsif block_given? 
     382              key, value = key.dup, value.dup 
     383              yield key, value 
     384              newhash[key] = value 
     385            else newhash[key] = value 
     386            end 
     387          end 
     388          newhash 
     389        end 
     390      end 
    349391    end 
    350392 
    351393    public 
     
    815857 
    816858      def log_processing 
    817859        logger.info "\n\nProcessing #{controller_class_name}\##{action_name} (for #{request_origin})" 
    818         logger.info "  Parameters: #{@params.inspect}" 
     860        logger.info "  Parameters: #{self.respond_to?(:filter_params) ? filter_params(@params).inspect : @params.inspect}" 
    819861      end 
    820862     
    821863      def perform_action