Class: CreditCardSanitizer
- Inherits:
-
Object
- Object
- CreditCardSanitizer
- Defined in:
- lib/credit_card_sanitizer.rb
Defined Under Namespace
Classes: Candidate
Constant Summary collapse
- CARD_COMPANIES =
{ 'visa' => /^4\d{12}(\d{3})?(\d{3})?$/, 'master' => /^(5[1-5]\d{4}|677189|222[1-9]\d{2}|22[3-9]\d{3}|2[3-6]\d{4}|27[01]\d{3}|2720\d{2})\d{10}$/, 'discover' => /^((6011|65\d{2}|64[4-9]\d)\d{12}|(62\d{14}))$/, 'american_express' => /^3[47]\d{13}$/, 'diners_club' => /^3(0[0-5]|[68]\d)\d{11}$/, 'jcb' => /^35(28|29|[3-8]\d)\d{12}$/, 'switch' => /^6759\d{12}(\d{2,3})?$/, 'solo' => /^6767\d{12}(\d{2,3})?$/, 'dankort' => /^5019\d{12}$/, 'maestro' => /^(5[06-8]|6\d)\d{10,17}$/, 'forbrugsforeningen' => /^600722\d{10}$/, 'laser' => /^(6304|6706|6709|6771(?!89))\d{8}(\d{4}|\d{6,7})?$/ }.freeze
- CARD_NUMBER_GROUPINGS =
{ 'visa' => [[4, 4, 4, 4]], 'master' => [[4, 4, 4, 4]], 'discover' => [[4, 4, 4, 4]], 'american_express' => [[4, 6, 5]], 'diners_club' => [[4, 6, 4]], 'jcb' => [[4, 4, 4, 4]], 'switch' => [[4, 4, 4, 4]], 'solo' => [[4, 4, 4, 4]], 'dankort' => [[4, 4, 4, 4]], 'maestro' => [[4], [5]], 'forbrugsforeningen' => [[4, 4, 4, 4]], 'laser' => [[4, 4, 4, 4]] }.freeze
- ACCEPTED_PREFIX =
/(?:cc|card|visa|amex)\z/i- ACCEPTED_POSTFIX =
/\Aex/i- ALPHANUMERIC =
/[[:alnum:]]/i- VALID_COMPANY_PREFIXES =
Regexp.union(*CARD_COMPANIES.values)
- EXPIRATION_DATE =
/\s(?:0?[1-9]|1[0-2])(?:\/|-)(?:\d{4}|\d{2})(?:\D|$)/- LINE_NOISE_CHAR =
/[^\w\n,()&.\/:;<>]/- LINE_NOISE =
/#{LINE_NOISE_CHAR}{,5}/- NONEMPTY_LINE_NOISE =
/#{LINE_NOISE_CHAR}{1,5}/- SCHEME_OR_PLUS =
/((?:+|\+)|(?:[a-zA-Z][\-+.a-zA-Z\d]{,9}):[^\s>]+)/- NUMBERS_WITH_LINE_NOISE =
/#{SCHEME_OR_PLUS}?\d(?:#{LINE_NOISE}\d){10,30}/- DEFAULT_OPTIONS =
{ replacement_token: '▇', expose_first: 6, expose_last: 4, use_groupings: false, exclude_tracking_numbers: false, parse_flanking: false }.freeze
Instance Attribute Summary collapse
-
#settings ⇒ Object
readonly
Returns the value of attribute settings.
Class Method Summary collapse
-
.parameter_filter(options = {}) ⇒ Object
A proc that can be used.
Instance Method Summary collapse
-
#initialize(options = {}) ⇒ CreditCardSanitizer
constructor
Create a new CreditCardSanitizer.
-
#sanitize!(text, options = {}) ⇒ Object
Finds credit card numbers and redacts digits from them.
Constructor Details
#initialize(options = {}) ⇒ CreditCardSanitizer
Create a new CreditCardSanitizer
Options
:replacement_character - the character that will replace digits for redaction. :expose_first - the number of leading digits that will not be redacted. :expose_last - the number of ending digits that will not be redacted. :use_groupings - require card number groupings to match to redact. :exclude_tracking_numbers - do not redact valid shipping company tracking numbers.
73 74 75 |
# File 'lib/credit_card_sanitizer.rb', line 73 def initialize( = {}) @settings = DEFAULT_OPTIONS.merge() end |
Instance Attribute Details
#settings ⇒ Object (readonly)
Returns the value of attribute settings.
59 60 61 |
# File 'lib/credit_card_sanitizer.rb', line 59 def settings @settings end |
Class Method Details
.parameter_filter(options = {}) ⇒ Object
A proc that can be used
text - the text containing potential credit card numbers
Examples
Rails.app.config.filter_parameters = [:password, CreditCardSanitizer.parameter_filter]
env = {
"action_dispatch.request.parameters" => {"credit_card_number" => "4111 1111 1111 1111", "password" => "123"},
"action_dispatch.parameter_filter" => Rails.app.config.filter_parameters
}
>> ActionDispatch::Request.new(env).filtered_parameters
=> {"credit_card_number" => "4111 11▇▇ ▇▇▇▇ 1111", "password" => "[FILTERED]"}
Returns a Proc that takes the key/value of the request parameter.
135 136 137 |
# File 'lib/credit_card_sanitizer.rb', line 135 def self.parameter_filter( = {}) proc { |_, value| new().sanitize!(value) if value.is_a?(String) } end |
Instance Method Details
#sanitize!(text, options = {}) ⇒ Object
Finds credit card numbers and redacts digits from them
text - the text containing potential credit card numbers
Examples
# If the text contains a credit card number:
sanitize!("4111 1111 1111 1111")
#=> "4111 11▇▇ ▇▇▇▇ 1111"
# If the text does not contain a credit card number:
sanitize!("I want all your credit card numbers!")
#=> nil
Returns a String of the redacted text if a credit card number was detected. Returns nil if no credit card numbers were detected.
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/credit_card_sanitizer.rb', line 93 def sanitize!(text, = {}) = @settings.merge() text.force_encoding(Encoding::UTF_8) text.scrub!('�') redacted = nil without_expiration(text) do text.gsub!(NUMBERS_WITH_LINE_NOISE) do |match| next match if $1 candidate = Candidate.new(match, match.tr('^0-9', ''), $`, $') if valid_context?(candidate, ) && valid_numbers?(candidate, ) redacted = true redact_numbers(candidate, ) else match end end end redacted && text end |