From e6fa01c77ceb8a600521da8c32dd4e1075ae0527 Mon Sep 17 00:00:00 2001 From: Alessandro Berardi Date: Wed, 21 Dec 2016 11:29:02 +1030 Subject: [PATCH] WIP --- .../types/credit_card.rb | 25 +++------ .../types/credit_card_spec.rb | 53 ++----------------- 2 files changed, 11 insertions(+), 67 deletions(-) diff --git a/lib/sensitive_data_filter/types/credit_card.rb b/lib/sensitive_data_filter/types/credit_card.rb index c65fdcb..adc3136 100644 --- a/lib/sensitive_data_filter/types/credit_card.rb +++ b/lib/sensitive_data_filter/types/credit_card.rb @@ -4,21 +4,11 @@ module SensitiveDataFilter module Types module CreditCard - SEPARATORS = /[\s-]/ - SEPRS = SEPARATORS.source + '+' - CARD_16_DIGITS = /\d{4}#{SEPRS}\d{4}#{SEPRS}\d{4}#{SEPRS}\d{4}/ - CARD_13_DIGITS = /\d{3}#{SEPRS}\d{3}#{SEPRS}\d{3}#{SEPRS}\d#{SEPRS}\d{3}/ - CARD_14_DIGITS = /\d{4}#{SEPRS}\d{6}#{SEPRS}\d{4}/ - CARD_15_DIGITS = /\d{4}#{SEPRS}\d{6}#{SEPRS}\d{5}/ - CARD = / - #{CARD_16_DIGITS.source} - | #{CARD_13_DIGITS.source} - | #{CARD_14_DIGITS.source} - | #{CARD_15_DIGITS.source} - /x - CATCH_ALL_SEPRS = SEPARATORS.source + '*' - CATCH_ALL = /(?:\d#{CATCH_ALL_SEPRS}?){13,16}/ - FILTERED = '[FILTERED]' + SEPARATORS = /[\s-]/ + SEPRS = SEPARATORS.source + '*' + LENGTHS = (11..19) + CARD = Regexp.new(LENGTHS.map { |l| /(?=((?:\d#{SEPRS}){#{l-1}}\d))/.source }.join) + FILTERED = '[FILTERED]' module_function def valid?(number) return false unless number.is_a? String @@ -27,9 +17,8 @@ module CreditCard module_function def scan(value) return [] unless value.is_a? String - [CARD, CATCH_ALL] - .flat_map { |pattern| value.scan(pattern) }.uniq - .select { |card| valid?(card) } + puts "SCAN #{value.scan(CARD)}" + value.scan(CARD).flatten.select { |card| valid?(card) } end module_function def mask(value) diff --git a/spec/sensitive_data_filter/types/credit_card_spec.rb b/spec/sensitive_data_filter/types/credit_card_spec.rb index 917abab..0c869c4 100644 --- a/spec/sensitive_data_filter/types/credit_card_spec.rb +++ b/spec/sensitive_data_filter/types/credit_card_spec.rb @@ -68,7 +68,7 @@ def validations(cards) context 'a value that contains repeated valid credit card numbers' do let(:value) { 'cc1 4111 1111 1111 1111 cc2 4111 1111 1111 1111 123' } - specify { expect(scan).to eq ['4111 1111 1111 1111'] } + specify { expect(scan).to eq ['4111 1111 1111 1111', '4111 1111 1111 1111'] } end context 'a value that contains a valid credit card in a multi line string' do @@ -107,54 +107,9 @@ def validations(cards) specify { expect(mask).to eq value } end - context 'a value that is a luhn but not a credit card' do - let(:value) { '1234-5678-9012-3528' } - specify { expect(scan).to be_empty } - specify { expect(mask).to eq value } - end - end - - describe 'pattern matching' do - shared_examples_for 'a pattern matcher' do - context 'valid pattern' do - it 'should match' do - expect(subject.match(valid_match)[0]).to eq valid_match - end - end - - context 'invalid pattern' do - it 'should not match' do - expect(subject.match(invalid_match)).to be_nil - end - end - end - - context '13 digit card pattern' do - subject { SensitiveDataFilter::Types::CreditCard::CARD_13_DIGITS } - let(:valid_match) { '123-123-123-1-123' } - let(:invalid_match) { '1234-123-123-1-35' } - it_behaves_like 'a pattern matcher' - end - - context '14 digit card pattern' do - subject { SensitiveDataFilter::Types::CreditCard::CARD_14_DIGITS } - let(:valid_match) { '1234-123456-1234' } - let(:invalid_match) { '1234-12345-123' } - it_behaves_like 'a pattern matcher' - end - - context '15 digit card' do - subject { SensitiveDataFilter::Types::CreditCard::CARD_15_DIGITS } - let(:valid_match) { '1234-123456-12345' } - let(:invalid_match) { '123-1234567-12345' } - it_behaves_like 'a pattern matcher' - end - - context '16 digit card pattern' do - subject(:card_16_digits) { SensitiveDataFilter::Types::CreditCard::CARD_16_DIGITS } - let(:valid_match) { '1234-5678-9012-3528' } - let(:invalid_match) { '1234-15678-012-3528' } - it_behaves_like 'a pattern matcher' + context 'the scan' do + let(:value) { '1234111 1111 1111 1111234' } + specify { expect(scan).to eq ['4111 1111 1111 1111'] } end end end