credit_card_sanitizer 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/credit_card_sanitizer.rb +36 -28
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 98bf84c263cd302f4adb4cad41dbde01d048d979
4
- data.tar.gz: 38ce9eb0baa8c4882bb100bbd5cd6ddfe402c99b
3
+ metadata.gz: a6d9bf9f31799627015af93b4bc5101cf28cfadc
4
+ data.tar.gz: 501db783e84aaf980694e9e27ff6bb0a3ecee9de
5
5
  SHA512:
6
- metadata.gz: 0eca7811cd6c6c822e1d6c3bf3ba7a00af4fd61f099da469b1b130344067885b4a27ec0c67116852113a289333a7827308882aead6a4dba4399d3e5e7b1acffa
7
- data.tar.gz: e214f6777c5f0fa56e3fcbd6af818a63964570d2f5c7c9dff6bdc729b9ecce77d24def686bbc6c6a2a6241741f733d4301d842cf79d63d741b9d583caf10e57c
6
+ metadata.gz: fdf41fa14b877ff36471d7ff50b792d8c77274376b627c674fd8d0f2d647dad3a1cb1b68ae0801aaf670d25ec1b644279917afea8a9e366fc0e3edb851da67cf
7
+ data.tar.gz: 93a23abba82b38fb63a8e55755c7c48fbf13f0101287a033d914b2aa57f08cf25f6db70064e01d202e4f7491240ceed95fbb54fb8465de21e780343444c179db
@@ -45,7 +45,16 @@ class CreditCardSanitizer
45
45
  SCHEME_OR_PLUS = /((?:+|\+)|(?:[a-zA-Z][\-+.a-zA-Z\d]{,9}):\S+)/
46
46
  NUMBERS_WITH_LINE_NOISE = /#{SCHEME_OR_PLUS}?\d(?:#{LINE_NOISE}\d){10,18}/
47
47
 
48
- attr_reader :replacement_token, :expose_first, :expose_last, :use_groupings
48
+ DEFAULT_OPTIONS = {
49
+ replacement_token: '▇',
50
+ expose_first: 6,
51
+ expose_last: 4,
52
+ use_groupings: false
53
+ }
54
+
55
+ attr_reader :settings
56
+
57
+ Candidate = Struct.new(:text, :numbers)
49
58
 
50
59
  # Create a new CreditCardSanitizer
51
60
  #
@@ -54,12 +63,10 @@ class CreditCardSanitizer
54
63
  # :replacement_character - the character that will replace digits for redaction.
55
64
  # :expose_first - the number of leading digits that will not be redacted.
56
65
  # :expose_last - the number of ending digits that will not be redacted.
66
+ # :use_groupings - require card number groupings to match to redact.
57
67
  #
58
68
  def initialize(options = {})
59
- @replacement_token = options.fetch(:replacement_token, '▇')
60
- @expose_first = options.fetch(:expose_first, 6)
61
- @expose_last = options.fetch(:expose_last, 4)
62
- @use_groupings = options.fetch(:use_groupings, false)
69
+ @settings = DEFAULT_OPTIONS.merge(options)
63
70
  end
64
71
 
65
72
  # Finds credit card numbers and redacts digits from them
@@ -78,7 +85,9 @@ class CreditCardSanitizer
78
85
  #
79
86
  # Returns a String of the redacted text if a credit card number was detected.
80
87
  # Returns nil if no credit card numbers were detected.
81
- def sanitize!(text)
88
+ def sanitize!(text, options = {})
89
+ options = @settings.merge(options)
90
+
82
91
  text.force_encoding(Encoding::UTF_8)
83
92
  text.scrub!('�')
84
93
 
@@ -88,15 +97,14 @@ class CreditCardSanitizer
88
97
  text.gsub!(NUMBERS_WITH_LINE_NOISE) do |match|
89
98
  next match if $1
90
99
 
91
- @match = match
92
- @numbers = match.tr('^0-9', '')
100
+ candidate = Candidate.new(match, match.tr('^0-9', ''))
93
101
 
94
- if valid_numbers?
102
+ if valid_numbers?(candidate, options)
95
103
  redacted = true
96
- redact_numbers!
104
+ redact_numbers(candidate, options)
105
+ else
106
+ match
97
107
  end
98
-
99
- @match
100
108
  end
101
109
  end
102
110
 
@@ -120,8 +128,8 @@ class CreditCardSanitizer
120
128
  # => {"credit_card_number" => "4111 11▇▇ ▇▇▇▇ 1111", "password" => "[FILTERED]"}
121
129
  #
122
130
  # Returns a Proc that takes the key/value of the request parameter.
123
- def self.parameter_filter
124
- Proc.new { |_, value| new.sanitize!(value) if value.is_a?(String) }
131
+ def self.parameter_filter(options = {})
132
+ Proc.new { |_, value| new(options).sanitize!(value) if value.is_a?(String) }
125
133
  end
126
134
 
127
135
  private
@@ -130,16 +138,16 @@ class CreditCardSanitizer
130
138
  !!(numbers =~ VALID_COMPANY_PREFIXES)
131
139
  end
132
140
 
133
- def find_company
141
+ def find_company(numbers)
134
142
  CARD_COMPANIES.each do |company, pattern|
135
- return company if @numbers =~ pattern
143
+ return company if numbers =~ pattern
136
144
  end
137
145
  end
138
146
 
139
- def valid_grouping?
140
- if use_groupings
141
- if company = find_company
142
- groupings = @match.split(NONEMPTY_LINE_NOISE).map(&:length)
147
+ def valid_grouping?(candidate, options)
148
+ if options[:use_groupings]
149
+ if company = find_company(candidate.numbers)
150
+ groupings = candidate.text.split(NONEMPTY_LINE_NOISE).map(&:length)
143
151
  return true if groupings.length == 1
144
152
  if company_groupings = CARD_NUMBER_GROUPINGS[company]
145
153
  company_groupings.each do |company_grouping|
@@ -153,22 +161,22 @@ class CreditCardSanitizer
153
161
  end
154
162
  end
155
163
 
156
- def valid_numbers?
157
- LuhnChecksum.valid?(@numbers) && valid_prefix?(@numbers) && valid_grouping?
164
+ def valid_numbers?(candidate, options)
165
+ LuhnChecksum.valid?(candidate.numbers) && valid_prefix?(candidate.numbers) && valid_grouping?(candidate, options)
158
166
  end
159
167
 
160
- def redact_numbers!
161
- @match.gsub!(/\d/).with_index do |number, digit_index|
162
- if within_redaction_range?(digit_index)
163
- replacement_token
168
+ def redact_numbers(candidate, options)
169
+ candidate.text.gsub(/\d/).with_index do |number, digit_index|
170
+ if within_redaction_range?(candidate, digit_index, options)
171
+ options[:replacement_token]
164
172
  else
165
173
  number
166
174
  end
167
175
  end
168
176
  end
169
177
 
170
- def within_redaction_range?(digit_index)
171
- digit_index >= expose_first && digit_index < @numbers.size - expose_last
178
+ def within_redaction_range?(candidate, digit_index, options)
179
+ digit_index >= options[:expose_first] && digit_index < candidate.numbers.size - options[:expose_last]
172
180
  end
173
181
 
174
182
  def without_expiration(text)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: credit_card_sanitizer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Chapweske
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-01-12 00:00:00.000000000 Z
13
+ date: 2016-01-15 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: appraisal