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.
- checksums.yaml +4 -4
- data/lib/credit_card_sanitizer.rb +36 -28
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a6d9bf9f31799627015af93b4bc5101cf28cfadc
|
4
|
+
data.tar.gz: 501db783e84aaf980694e9e27ff6bb0a3ecee9de
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
-
@
|
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
|
-
|
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
|
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 =
|
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?(
|
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
|
-
|
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 <
|
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
|
+
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-
|
13
|
+
date: 2016-01-15 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: appraisal
|