Created
April 27, 2019 13:35
-
-
Save ndbroadbent/0f9e01af5f03be81580e7792e85ffbb7 to your computer and use it in GitHub Desktop.
Monkey Patch for ActionDispatch::Http::ParameterFilter::CompiledFilter to support more complex filtering rules
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# lib/action_dispatch_parameter_filter.rb | |
require 'action_dispatch/http/parameter_filter' | |
if Rails.version != '5.2.2.1' | |
raise "You've updated the Rails version. " \ | |
"Please check #{__FILE__} and ensure that everything still works." | |
end | |
module ActionDispatch | |
module Http | |
class ParameterFilter | |
class CustomFilter | |
def filter(_params) | |
raise 'Not implemented!' | |
end | |
end | |
class CompiledFilter # :nodoc: | |
def self.compile(filters) | |
return ->(params) { params.dup } if filters.empty? | |
strings = [] | |
regexps = [] | |
blocks = [] | |
custom_filters = [] | |
filters.each do |item| | |
case item | |
when Proc | |
blocks << item | |
when CustomFilter | |
custom_filters << item | |
when Regexp | |
regexps << item | |
else | |
strings << Regexp.escape(item.to_s) | |
end | |
end | |
deep_regexps, regexps = regexps.partition { |r| r.to_s.include?('\\.') } | |
deep_strings, strings = strings.partition { |s| s.include?('\\.') } | |
regexps << Regexp.new(strings.join('|'), true) unless strings.empty? | |
deep_regexps << Regexp.new(deep_strings.join('|'), true) unless deep_strings.empty? | |
new regexps, deep_regexps, blocks, custom_filters | |
end | |
# attr_reader :regexps, :deep_regexps, :blocks, :custom_filters | |
attr_reader :custom_filters | |
def initialize(regexps, deep_regexps, blocks, custom_filters) | |
@regexps = regexps | |
@deep_regexps = deep_regexps.any? ? deep_regexps : nil | |
@blocks = blocks | |
@custom_filters = custom_filters | |
end | |
def call(original_params, parents = []) | |
custom_filtered_params = original_params | |
if custom_filters.any? | |
custom_filters.each do |filter| | |
custom_filtered_params = filter.filter(custom_filtered_params) | |
end | |
end | |
filtered_params = original_params.class.new | |
custom_filtered_params.each do |key, value| | |
parents.push(key) if deep_regexps | |
if regexps.any? { |r| key =~ r } | |
value = FILTERED | |
elsif deep_regexps && | |
(joined = parents.join('.')) && | |
deep_regexps.any? { |r| joined =~ r } | |
value = FILTERED | |
elsif value.is_a?(Hash) | |
value = call(value, parents) | |
elsif value.is_a?(Array) | |
value = value.map { |v| v.is_a?(Hash) ? call(v, parents) : v } | |
elsif blocks.any? | |
key = key.dup if key.duplicable? | |
value = value.dup if value.duplicable? | |
blocks.each { |b| b.call(key, value) } | |
end | |
parents.pop if deep_regexps | |
filtered_params[key] = value | |
end | |
filtered_params | |
end | |
end | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# lib/my_app/custom_parameter_filter.rb | |
module MyApp | |
class CustomParameterFilter < ActionDispatch::Http::ParameterFilter::CustomFilter | |
def filter(params) | |
case [params[:controller], params[:action]] | |
when ['api/v1/my_controller', 'create'] | |
cloned_params = params.dup | |
cloned_params[:data] = ActionDispatch::Http::ParameterFilter::FILTERED | |
return cloned_params | |
end | |
params | |
end | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# config/initializers/filter_parameter_logging.rb | |
# Be sure to restart your server when you modify this file. | |
# Configure sensitive parameters which will be filtered from the log file. | |
Rails.application.config.filter_parameters += %i[ | |
password | |
password_confirmation | |
] | |
Rails.application.config.filter_parameters << MyApp::CustomParameterFilter.new |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment