|
15 | 15 | from typing import Optional |
16 | 16 |
|
17 | 17 | from email_validator import validate_email # type: ignore |
18 | | -from voluptuous import All, Any, In, Match, Range, Required, Schema |
| 18 | +from voluptuous import All, Any, In, Match, MultipleInvalid, Range, Required, Schema |
19 | 19 | from voluptuous.error import UrlInvalid |
20 | 20 |
|
21 | 21 | # Pylint doesn't like the private function type naming for the callable |
@@ -379,14 +379,48 @@ def _uuid(s: str) -> str: |
379 | 379 | raise ValueError |
380 | 380 |
|
381 | 381 |
|
382 | | -validate_report = Schema( |
| 382 | +NIL_UUID = str(uuid.UUID(int=0)) |
| 383 | + |
| 384 | + |
| 385 | +def _non_empty_uuid(s: str) -> str: |
| 386 | + if _uuid(s) == NIL_UUID: |
| 387 | + raise ValueError |
| 388 | + return s |
| 389 | + |
| 390 | + |
| 391 | +def _transaction_id(s: Optional[str]) -> str: |
| 392 | + if isinstance(s, str) and len(s) > 0: |
| 393 | + return s |
| 394 | + raise ValueError |
| 395 | + |
| 396 | + |
| 397 | +_validate_report_schema = Schema( |
383 | 398 | { |
384 | 399 | "chargeback_code": str, |
385 | | - Required("ip_address"): _ip_address, |
| 400 | + "ip_address": _ip_address, |
386 | 401 | "maxmind_id": _maxmind_id, |
387 | | - "minfraud_id": _uuid, |
| 402 | + "minfraud_id": _non_empty_uuid, |
388 | 403 | "notes": str, |
389 | 404 | Required("tag"): _tag, |
390 | | - "transaction_id": str, |
| 405 | + "transaction_id": _transaction_id, |
391 | 406 | }, |
392 | 407 | ) |
| 408 | + |
| 409 | + |
| 410 | +def _validate_at_least_one_identifier_field(report): |
| 411 | + optional_fields = ["ip_address", "maxmind_id", "minfraud_id", "transaction_id"] |
| 412 | + if not any(field in report for field in optional_fields): |
| 413 | + # We return MultipleInvalid instead of ValueError to be consistent with what |
| 414 | + # voluptuous returns. |
| 415 | + raise MultipleInvalid( |
| 416 | + "The report must contain at least one of the following fields: " |
| 417 | + "'ip_address', 'maxmind_id', 'minfraud_id', 'transaction_id'." |
| 418 | + ) |
| 419 | + return True |
| 420 | + |
| 421 | + |
| 422 | +def validate_report(report): |
| 423 | + """Validate minFraud Transaction Report fields.""" |
| 424 | + _validate_report_schema(report) |
| 425 | + _validate_at_least_one_identifier_field(report) |
| 426 | + return True |
0 commit comments