Module: Legion::Extensions::Privatecore::Helpers::Redactor
- Defined in:
- lib/legion/extensions/privatecore/helpers/redactor.rb
Constant Summary collapse
- REDACTION_MARKER =
'[REDACTED]'
Class Method Summary collapse
- .build_replacement(detection, mode, type_counters, mapping) ⇒ Object
- .generate_luhn_number(length) ⇒ Object
- .generate_synthetic(type, original) ⇒ Object
- .mask_value(original) ⇒ Object
- .persist_mapping(mapping:, key:, ttl:) ⇒ Object
- .redact(text, detections:, mode:) ⇒ Object
- .restore(text:, mapping:) ⇒ Object
- .retrieve_mapping(key:) ⇒ Object
Class Method Details
.build_replacement(detection, mode, type_counters, mapping) ⇒ Object
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/legion/extensions/privatecore/helpers/redactor.rb', line 32 def build_replacement(detection, mode, type_counters, mapping) case mode when :placeholder type_counters[detection[:type]] += 1 tag = "[#{detection[:type].upcase}_#{type_counters[detection[:type]]}]" mapping[tag] = detection[:match] tag when :mask mask_value(detection[:match]) when :synthetic fake = generate_synthetic(detection[:type], detection[:match]) mapping[fake] = detection[:match] fake else REDACTION_MARKER end end |
.generate_luhn_number(length) ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/legion/extensions/privatecore/helpers/redactor.rb', line 77 def generate_luhn_number(length) digits = Array.new(length - 1) { rand(0..9) } sum = 0 digits.reverse.each_with_index do |d, i| v = i.even? ? d * 2 : d v -= 9 if v > 9 sum += v end check = (10 - (sum % 10)) % 10 (digits << check).join end |
.generate_synthetic(type, original) ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/legion/extensions/privatecore/helpers/redactor.rb', line 54 def generate_synthetic(type, original) case type when :ssn, :itin "#{rand(100..999)}-#{rand(10..99)}-#{rand(1000..9999)}" when :phone "#{rand(200..999)}-#{rand(200..999)}-#{rand(1000..9999)}" when :email "user#{rand(1000..9999)}@example.net" when :credit_card generate_luhn_number(16) when :ip "#{rand(1..254)}.#{rand(0..255)}.#{rand(0..255)}.#{rand(1..254)}" when :aadhaar "#{rand(2000..9999)} #{rand(1000..9999)} #{rand(1000..9999)}" when :passport "#{('A'..'Z').to_a.sample}#{rand(10_000_000..99_999_999)}" when :aws_key "AKIA#{Array.new(16) { (('0'..'9').to_a + ('A'..'Z').to_a).sample }.join}" else SecureRandom.hex([((original.length + 1) / 2), 1].max) end end |
.mask_value(original) ⇒ Object
50 51 52 |
# File 'lib/legion/extensions/privatecore/helpers/redactor.rb', line 50 def mask_value(original) original.gsub(/[A-Za-z]/, '*').gsub(/\d/, '*') end |
.persist_mapping(mapping:, key:, ttl:) ⇒ Object
97 98 99 100 101 |
# File 'lib/legion/extensions/privatecore/helpers/redactor.rb', line 97 def persist_mapping(mapping:, key:, ttl:) actual_key = key || SecureRandom.uuid Legion::Cache.set("privatecore:mapping:#{actual_key}", mapping, ttl: ttl) if defined?(Legion::Cache) # rubocop:disable Legion/HelperMigration/DirectCache actual_key end |
.redact(text, detections:, mode:) ⇒ Object
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/legion/extensions/privatecore/helpers/redactor.rb', line 14 def redact(text, detections:, mode:) return { cleaned: text, mapping: {}, detections: detections } unless text.is_a?(String) return { cleaned: text, mapping: {}, detections: detections } if detections.empty? mapping = {} type_counters = Hash.new(0) cleaned = text.dup sorted = detections.sort_by { |d| -d[:start] } sorted.each do |detection| replacement = build_replacement(detection, mode, type_counters, mapping) cleaned[detection[:start]...detection[:end]] = replacement end { cleaned: cleaned, mapping: mapping, detections: detections } end |
.restore(text:, mapping:) ⇒ Object
89 90 91 92 93 94 95 |
# File 'lib/legion/extensions/privatecore/helpers/redactor.rb', line 89 def restore(text:, mapping:) return text if mapping.nil? || mapping.empty? result = text.dup mapping.each { |placeholder, original| result.gsub!(placeholder, original) } result end |