Module: TranslationDiff::Redaction

Defined in:
lib/translation_diff/redaction.rb

Overview

Which configuration options must never be printed, decided by name rather than by a list someone maintains.

Constant Summary collapse

SENSITIVE =
/key|secret|token|password|auth|credential/
FILTERED =
"[FILTERED]".freeze

Class Method Summary collapse

Class Method Details

.declared_sensitive ⇒ Object

Unioned fresh on every call, never memoised -- a provider can register after the first inspect.



11
12
13
# File 'lib/translation_diff/redaction.rb', line 11

def self.declared_sensitive
  TranslationDiff::Providers.classes.flat_map(&:sensitive_options).map(&:to_sym)
end

.redact_userinfo(value) ⇒ Object

redis_url and a provider's *_api_base can carry a credential inline; the host stays, only the userinfo hides.



34
35
36
37
38
39
40
41
42
43
44
# File 'lib/translation_diff/redaction.rb', line 34

def self.redact_userinfo(value)
  return nil unless value.is_a?(String)

  userinfo = URI.parse(value).userinfo
  return nil unless userinfo

  user, separator, = userinfo.partition(":")
  value.sub(userinfo, separator.empty? ? FILTERED : "#{user}:#{FILTERED}")
rescue URI::Error
  nil
end

.render(config) ⇒ Object

Reads through the public accessor, or an option set only through its ENV-backed default goes unnoticed.



16
17
18
19
20
21
22
23
24
25
# File 'lib/translation_diff/redaction.rb', line 16

def self.render(config)
  declared = declared_sensitive

  TranslationDiff::Configuration.options.filter_map do |key|
    value = config.public_send(key)
    next if value.nil?

    "#{key}=#{rendered_value(key, value, declared)}"
  end
end

.rendered_value(key, value, declared) ⇒ Object



27
28
29
30
31
# File 'lib/translation_diff/redaction.rb', line 27

def self.rendered_value(key, value, declared)
  return FILTERED if sensitive?(key) || declared.include?(key)

  (redact_userinfo(value) || value).inspect
end

.sensitive?(name) ⇒ Boolean

Returns:

  • (Boolean)


8
# File 'lib/translation_diff/redaction.rb', line 8

def self.sensitive?(name) = name.to_s.match?(SENSITIVE)