module Airbrake::Filters::KeysFilter
This is a filter helper that endows a class ability to filter notices' payload based on the return value of the should_filter?
method that a class that includes this module must implement.
@see Notice
@see KeysAllowlist
@see KeysBlocklist
@api private
Constants
- FILTERABLE_CONTEXT_KEYS
@return [Array<Symbol>] parts of a Notice's context payload that can
be modified by blocklist/allowlist filters
- FILTERABLE_KEYS
@return [Array<Symbol>] parts of a Notice's payload that can be modified
by blocklist/allowlist filters
- FILTERED
@return [String] The label to replace real values of filtered payload
- VALID_PATTERN_CLASSES
@return [Array<String,Symbol,Regexp>] the array of classes instances of
which can compared with payload keys
Attributes
@return [Integer]
Public Class Methods
Creates a new KeysBlocklist
or KeysAllowlist
filter that uses the given patterns
for filtering a notice's payload.
@param [Array<String,Regexp,Symbol>] patterns
# File lib/airbrake-ruby/filters/keys_filter.rb, line 49 def initialize(patterns) @patterns = patterns @valid_patterns = false end
Public Instance Methods
@!macro call_filter
This is a mandatory method required by any filter integrated with FilterChain. @param [Notice] notice the notice to be filtered @return [void] @see FilterChain
# File lib/airbrake-ruby/filters/keys_filter.rb, line 61 def call(notice) unless @valid_patterns eval_proc_patterns! validate_patterns end FILTERABLE_KEYS.each do |key| notice[key] = filter_hash(notice[key]) end FILTERABLE_CONTEXT_KEYS.each { |key| filter_context_key(notice, key) } return unless notice[:context][:url] filter_url(notice) end
@raise [NotImplementedError] if called directly
# File lib/airbrake-ruby/filters/keys_filter.rb, line 79 def should_filter?(_key) raise NotImplementedError, 'method must be implemented in the included class' end
Private Instance Methods
# File lib/airbrake-ruby/filters/keys_filter.rb, line 125 def eval_proc_patterns! return unless @patterns.any? { |pattern| pattern.is_a?(Proc) } @patterns = @patterns.flat_map do |pattern| next(pattern) unless pattern.respond_to?(:call) pattern.call end end
# File lib/airbrake-ruby/filters/keys_filter.rb, line 148 def filter_context_key(notice, key) return unless notice[:context][key] return if notice[:context][key] == FILTERED unless should_filter?(key) return notice[:context][key] = filter_hash(notice[:context][key]) end notice[:context][key] = FILTERED end
# File lib/airbrake-ruby/filters/keys_filter.rb, line 85 def filter_hash(hash) # rubocop:disable Metrics/AbcSize return hash unless hash.is_a?(Hash) hash_copy = hash.dup hash.each_key do |key| if should_filter?(key.to_s) hash_copy[key] = FILTERED elsif hash_copy[key].is_a?(Hash) hash_copy[key] = filter_hash(hash_copy[key]) elsif hash[key].is_a?(Array) hash_copy[key].each_with_index do |h, i| hash_copy[key][i] = filter_hash(h) end end end hash_copy end
# File lib/airbrake-ruby/filters/keys_filter.rb, line 113 def filter_url(notice) begin url = URI(notice[:context][:url]) rescue URI::InvalidURIError return end return unless url.query notice[:context][:url] = filter_url_params(url) end
# File lib/airbrake-ruby/filters/keys_filter.rb, line 105 def filter_url_params(url) url.query = URI.decode_www_form(url.query).to_h.map do |key, val| should_filter?(key) ? "#{key}=[Filtered]" : "#{key}=#{val}" end.join('&') url.to_s end
# File lib/airbrake-ruby/filters/keys_filter.rb, line 135 def validate_patterns @valid_patterns = @patterns.all? do |pattern| VALID_PATTERN_CLASSES.any? { |c| pattern.is_a?(c) } end return if @valid_patterns logger.error( "#{LOG_LABEL} one of the patterns in #{self.class} is invalid. " \ "Known patterns: #{@patterns}", ) end