credit_card_sanitizer 0.2.10 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/credit_card_sanitizer.rb +75 -25
  3. metadata +2 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9dc65743cee097af71731792951b75869f841751
4
- data.tar.gz: 48b148cfc9d284e39b8aee68bb5e66806395983d
3
+ metadata.gz: d5ae372ef59ad6ef19b7378a2d4ed5f566dd4675
4
+ data.tar.gz: a5fc65e8197b308cf57f4c1e845338b7826c4680
5
5
  SHA512:
6
- metadata.gz: 2eeb65e7811c1e45ba55c173eb5eca6ffc92c9cd935048e063ab195f33be0e29315a75f103844978640be680153ccf340b7128d8d3ca57e3ff4f649a44832d79
7
- data.tar.gz: 7c2a97ff0c1bfe2a2cffe1a708461659e714491e68baa8920efc7f4a4392959f831823e49e46dcba2938b9803ac6ee8204a0d2e40b4aab2d51b36b22250d030d
6
+ metadata.gz: 3b48c055c87b0e35ad221edc2237ee93c854ff99bdd022993403040c291b81cf15c57c3c65dfcf4976dcf2684cec0ec1a13d03007b3a9c4a2462c7934c1d031a
7
+ data.tar.gz: 20fc3896f0d93523dc43d3cf966171f3959314631f43017579afbadba265a8c9b15a7ec29a858ea5af29423d61904b4a80cdc7465c596553ed13bc8241ed45ac
@@ -4,11 +4,7 @@ require 'luhn_checksum'
4
4
 
5
5
  class CreditCardSanitizer
6
6
 
7
- LINE_NOISE = /[^\w_\n,()\/:]{0,8}/
8
- # 12-19 digits explanation: https://en.wikipedia.org/wiki/Primary_Account_Number#Issuer_identification_number_.28IIN.29
9
- NUMBERS_WITH_LINE_NOISE = /\d(?:#{LINE_NOISE}\d#{LINE_NOISE}){10,17}\d/
10
-
11
- # Taken from https://github.com/Shopify/active_merchant/blob/master/lib/active_merchant/billing/credit_card_methods.rb#L7-L20
7
+ # https://github.com/Shopify/active_merchant/blob/master/lib/active_merchant/billing/credit_card_methods.rb#L5-L18
12
8
  CARD_COMPANIES = {
13
9
  'visa' => /^4\d{12}(\d{3})?$/,
14
10
  'master' => /^(5[1-5]\d{4}|677189)\d{10}$/,
@@ -24,54 +20,108 @@ class CreditCardSanitizer
24
20
  'laser' => /^(6304|6706|6709|6771(?!89))\d{8}(\d{4}|\d{6,7})?$/
25
21
  }
26
22
  VALID_COMPANY_PREFIXES = Regexp.union(*CARD_COMPANIES.values)
27
-
28
- def self.parameter_filter
29
- Proc.new { |_, value| new.sanitize!(value) if value.is_a?(String) }
30
- end
31
-
32
- def initialize(replacement_token = 'X', replace_first = 6, replace_last = 4)
33
- @replacement_token, @replace_first, @replace_last = replacement_token, replace_first, replace_last
23
+ LINE_NOISE = /[^\w_\n,()\/:]{,5}/
24
+ SCHEME = /((?:[a-zA-Z][\-+.a-zA-Z\d]{,9}):\S+)/
25
+ NUMBERS_WITH_LINE_NOISE = /#{SCHEME}?\d(?:#{LINE_NOISE}\d#{LINE_NOISE}){10,17}\d/
26
+
27
+ attr_reader :replacement_token, :expose_first, :expose_last
28
+
29
+ # Create a new CreditCardSanitizer
30
+ #
31
+ # Options
32
+ #
33
+ # :replacement_character - the character that will replace digits for redaction.
34
+ # :expose_first - the number of leading digits that will not be redacted.
35
+ # :expose_last - the number of ending digits that will not be redacted.
36
+ #
37
+ def initialize(options = {})
38
+ @replacement_token = options.fetch(:replacement_token, '▇')
39
+ @expose_first = options.fetch(:expose_first, 6)
40
+ @expose_last = options.fetch(:expose_last, 4)
34
41
  end
35
42
 
43
+ # Finds credit card numbers and redacts digits from them
44
+ #
45
+ # text - the text containing potential credit card numbers
46
+ #
47
+ # Examples
48
+ #
49
+ # # If the text contains a credit card number:
50
+ # sanitize!("4111 1111 1111 1111")
51
+ # #=> "4111 11▇▇ ▇▇▇▇ 1111"
52
+ #
53
+ # # If the text does not contain a credit card number:
54
+ # sanitize!("I want all your credit card numbers!")
55
+ # #=> nil
56
+ #
57
+ # Returns a String of the redacted text if a credit card number was detected.
58
+ # Returns nil if no credit card numbers were detected.
36
59
  def sanitize!(text)
37
- replaced = nil
38
-
39
60
  to_utf8!(text)
40
61
 
62
+ redacted = nil
41
63
  text.gsub!(NUMBERS_WITH_LINE_NOISE) do |match|
42
- numbers = match.gsub(/\D/, '')
64
+ next if $1
65
+ @numbers = match.tr('^0-9', '')
43
66
 
44
- if LuhnChecksum.valid?(numbers) && valid_prefix?(numbers)
45
- replaced = true
46
- replace_numbers!(match, numbers.size - @replace_last)
67
+ if valid_numbers?
68
+ redacted = true
69
+ redact_numbers!(match)
47
70
  end
48
71
 
49
72
  match
50
73
  end
51
74
 
52
- replaced && text
75
+ redacted && text
53
76
  end
54
77
 
78
+ # A proc that can be used
79
+ #
80
+ # text - the text containing potential credit card numbers
81
+ #
82
+ # Examples
83
+ #
84
+ # Rails.app.config.filter_parameters = [:password, CreditCardSanitizer.parameter_filter]
85
+ #
86
+ # env = {
87
+ # "action_dispatch.request.parameters" => {"credit_card_number" => "123 4512 3451 2348", "password" => "123"},
88
+ # "action_dispatch.parameter_filter" => Rails.app.config.filter_parameters
89
+ # }
90
+ #
91
+ # >> ActionDispatch::Request.new(env).filtered_parameters
92
+ # => {"credit_card_number" => "123 451X XXXX 2348", "password" => "[FILTERED]"}
93
+ #
94
+ # Returns a Proc that takes the key/value of the request parameter.
95
+ def self.parameter_filter
96
+ Proc.new { |_, value| new.sanitize!(value) if value.is_a?(String) }
97
+ end
98
+
99
+ private
100
+
55
101
  def valid_prefix?(numbers)
56
102
  !!(numbers =~ VALID_COMPANY_PREFIXES)
57
103
  end
58
104
 
59
- private
105
+ def valid_numbers?
106
+ LuhnChecksum.valid?(@numbers) && valid_prefix?(@numbers)
107
+ end
60
108
 
61
- def replace_numbers!(text, replacement_limit)
62
- # Leave the first @replace_first and last @replace_last numbers visible
109
+ def redact_numbers!(text)
63
110
  digit_index = 0
64
111
 
65
112
  text.gsub!(/\d/) do |number|
66
- digit_index += 1
67
- if digit_index > @replace_first && digit_index <= replacement_limit
68
- @replacement_token
113
+ if within_redaction_range?(digit_index += 1)
114
+ replacement_token
69
115
  else
70
116
  number
71
117
  end
72
118
  end
73
119
  end
74
120
 
121
+ def within_redaction_range?(digit_index)
122
+ digit_index > expose_first && digit_index <= @numbers.size - expose_last
123
+ end
124
+
75
125
  if ''.respond_to?(:scrub)
76
126
  def to_utf8!(str)
77
127
  str.force_encoding(Encoding::UTF_8)
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.2.10
4
+ version: 0.3.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: 2014-10-13 00:00:00.000000000 Z
13
+ date: 2014-10-16 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: appraisal