Skip to content

Commit 9d5b8da

Browse files
committed
Apply last_digits validation in a more isolated way
1 parent a7b7688 commit 9d5b8da

3 files changed

Lines changed: 71 additions & 110 deletions

File tree

minfraud/request.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,15 +69,15 @@ def _copy_and_clean(data: Any) -> Any:
6969
return data
7070

7171

72-
def clean_credit_card(transaction):
72+
def clean_credit_card(credit_card):
7373
"""Clean the credit_card input of a transaction request"""
74-
last4 = transaction["credit_card"].pop("last_4_digits", None)
74+
last4 = credit_card.pop("last_4_digits", None)
7575
if last4:
7676
warnings.warn(
7777
"last_4_digits has been deprecated in favor of last_digits",
7878
DeprecationWarning,
7979
)
80-
transaction["credit_card"]["last_digits"] = last4
80+
credit_card["last_digits"] = last4
8181

8282

8383
def maybe_hash_email(transaction):

minfraud/validation.py

Lines changed: 56 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -291,18 +291,14 @@ def _uri(s: str) -> str:
291291
return s
292292

293293

294-
def _validate_last_digits(req):
295-
cc = req.get("credit_card")
296-
if cc is None:
297-
return
298-
299-
iin = cc.get("issuer_id_number")
294+
def _validate_last_digits(cc):
295+
iin = cc.get("issuer_id_number", None)
300296
if iin is None:
301297
return
302298

303299
if iin and len(iin) == 8:
304-
last_digits = cc.get("last_digits")
305-
last_4_digits = cc.get("last_4_digits")
300+
last_digits = cc.get("last_digits", None)
301+
last_4_digits = cc.get("last_4_digits", None)
306302
if last_digits and len(last_digits) != 2:
307303
raise LengthInvalid(
308304
"last_digits must be two digits when the issuer_id_number is eight digits."
@@ -315,19 +311,19 @@ def _validate_last_digits(req):
315311

316312

317313
validate_transaction = Schema(
318-
All(
319-
{
320-
"account": {
321-
"user_id": str,
322-
"username_md5": _md5,
323-
},
324-
"billing": _address,
325-
"payment": {
326-
"processor": _payment_processor,
327-
"was_authorized": bool,
328-
"decline_code": str,
329-
},
330-
"credit_card": {
314+
{
315+
"account": {
316+
"user_id": str,
317+
"username_md5": _md5,
318+
},
319+
"billing": _address,
320+
"payment": {
321+
"processor": _payment_processor,
322+
"was_authorized": bool,
323+
"decline_code": str,
324+
},
325+
"credit_card": All(
326+
{
331327
"avs_result": _single_char,
332328
"bank_name": str,
333329
"bank_phone_country_code": _telephone_country_code,
@@ -339,46 +335,46 @@ def _validate_last_digits(req):
339335
"token": _credit_card_token,
340336
"was_3d_secure_successful": bool,
341337
},
342-
"custom_inputs": {_custom_input_key: _custom_input_value},
343-
"device": {
344-
"accept_language": str,
345-
"ip_address": _ip_address,
346-
"session_age": All(_any_number, Range(min=0)),
347-
"session_id": str,
348-
"user_agent": str,
349-
},
350-
"email": {
351-
"address": _email_or_md5,
352-
"domain": _hostname,
353-
},
354-
"event": {
355-
"shop_id": str,
356-
"time": _rfc3339_datetime,
357-
"type": _event_type,
358-
"transaction_id": str,
359-
},
360-
"order": {
361-
"affiliate_id": str,
362-
"amount": _price,
363-
"currency": _currency_code,
364-
"discount_code": str,
365-
"has_gift_message": bool,
366-
"is_gift": bool,
367-
"referrer_uri": _uri,
368-
"subaffiliate_id": str,
369-
},
370-
"shipping": _shipping_address,
371-
"shopping_cart": [
372-
{
373-
"category": str,
374-
"item_id": str,
375-
"price": _price,
376-
"quantity": All(int, Range(min=1)),
377-
},
378-
],
338+
_validate_last_digits,
339+
),
340+
"custom_inputs": {_custom_input_key: _custom_input_value},
341+
"device": {
342+
"accept_language": str,
343+
"ip_address": _ip_address,
344+
"session_age": All(_any_number, Range(min=0)),
345+
"session_id": str,
346+
"user_agent": str,
347+
},
348+
"email": {
349+
"address": _email_or_md5,
350+
"domain": _hostname,
379351
},
380-
_validate_last_digits,
381-
)
352+
"event": {
353+
"shop_id": str,
354+
"time": _rfc3339_datetime,
355+
"type": _event_type,
356+
"transaction_id": str,
357+
},
358+
"order": {
359+
"affiliate_id": str,
360+
"amount": _price,
361+
"currency": _currency_code,
362+
"discount_code": str,
363+
"has_gift_message": bool,
364+
"is_gift": bool,
365+
"referrer_uri": _uri,
366+
"subaffiliate_id": str,
367+
},
368+
"shipping": _shipping_address,
369+
"shopping_cart": [
370+
{
371+
"category": str,
372+
"item_id": str,
373+
"price": _price,
374+
"quantity": All(int, Range(min=1)),
375+
},
376+
],
377+
},
382378
)
383379

384380

tests/test_request.py

Lines changed: 12 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -152,69 +152,34 @@ def test_clean_credit_card(self):
152152
{
153153
"name": "deprecated last_4_digits is cleaned to last_digits",
154154
"input": {
155-
"credit_card": {
156-
"issuer_id_number": "123456",
157-
"last_4_digits": "1234",
158-
},
159-
"device": {"ip_address": "1.1.1.1"},
155+
"issuer_id_number": "123456",
156+
"last_4_digits": "1234",
160157
},
161158
"expected": {
162-
"credit_card": {
163-
"issuer_id_number": "123456",
164-
"last_digits": "1234",
165-
},
166-
"device": {"ip_address": "1.1.1.1"},
159+
"issuer_id_number": "123456",
160+
"last_digits": "1234",
167161
},
168162
},
169163
{
170164
"name": "6 digit iin, 4 digit last_digits",
171165
"input": {
172-
"credit_card": {
173-
"issuer_id_number": "123456",
174-
"last_digits": "1234",
175-
},
176-
"device": {"ip_address": "1.1.1.1"},
166+
"issuer_id_number": "123456",
167+
"last_digits": "1234",
177168
},
178169
"expected": {
179-
"credit_card": {
180-
"issuer_id_number": "123456",
181-
"last_digits": "1234",
182-
},
183-
"device": {"ip_address": "1.1.1.1"},
170+
"issuer_id_number": "123456",
171+
"last_digits": "1234",
184172
},
185173
},
186174
{
187175
"name": "8 digit iin, 2 digit last_digits",
188176
"input": {
189-
"credit_card": {
190-
"issuer_id_number": "12345678",
191-
"last_digits": "34",
192-
},
193-
"device": {"ip_address": "1.1.1.1"},
177+
"issuer_id_number": "12345678",
178+
"last_digits": "34",
194179
},
195180
"expected": {
196-
"credit_card": {
197-
"issuer_id_number": "12345678",
198-
"last_digits": "34",
199-
},
200-
"device": {"ip_address": "1.1.1.1"},
201-
},
202-
},
203-
{
204-
"name": "8 digit iin, 4 digit last_digits",
205-
"input": {
206-
"credit_card": {
207-
"issuer_id_number": "12345678",
208-
"last_digits": "1234",
209-
},
210-
"device": {"ip_address": "1.1.1.1"},
211-
},
212-
"expected": {
213-
"credit_card": {
214-
"issuer_id_number": "12345678",
215-
"last_digits": "1234",
216-
},
217-
"device": {"ip_address": "1.1.1.1"},
181+
"issuer_id_number": "12345678",
182+
"last_digits": "34",
218183
},
219184
},
220185
]

0 commit comments

Comments
 (0)