misc: allow using schwifty for IBAN validation (#41903) #959

Merged
fpeters merged 1 commits from wip/41903-iban-schwifty into main 2024-01-12 21:19:48 +01:00
3 changed files with 63 additions and 46 deletions

View File

@ -2,12 +2,14 @@ import copy
import datetime
import decimal
import os
from unittest import mock
import mechanize
import pytest
from pyquery import PyQuery
from quixote import cleanup, get_response
from quixote.http_request import parse_query
from schwifty import IBAN
from wcs.qommon import sessions
from wcs.qommon.form import (
@ -1284,57 +1286,60 @@ def test_wcsextrastringwidget_belgian_nrn_validation():
assert widget.has_error()
def test_wcsextrastringwidget_iban_validation():
@pytest.mark.parametrize('iban_class', [None, IBAN])
def test_wcsextrastringwidget_iban_validation(iban_class):
class FakeField:
pass
fakefield = FakeField()
fakefield.validation = {'type': 'iban'}
with mock.patch('wcs.qommon.misc.IBAN', iban_class):
fakefield = FakeField()
fakefield.validation = {'type': 'iban'}
# regular cases
for iban in [
'BE71 0961 2345 6769', # Belgium
'be71 0961 2345 6769', # Lowercase
' BE71 0961 2345 6769 ', # Extra padding
'FR76 3000 6000 0112 3456 7890 189', # France
'FR27 2004 1000 0101 2345 6Z02 068', # France (having letter)
'DE91 1000 0000 0123 4567 89', # Germany
'GR96 0810 0010 0000 0123 4567 890', # Greece
'RO09 BCYP 0000 0012 3456 7890', # Romania
'SA44 2000 0001 2345 6789 1234', # Saudi Arabia
'ES79 2100 0813 6101 2345 6789', # Spain
'CH56 0483 5012 3456 7800 9', # Switzerland
'GB98 MIDL 0700 9312 3456 78', # United Kingdom
]:
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': iban.replace(' ', '')})
assert not widget.has_error()
widget._parse(req)
assert widget.value == iban.upper().replace(' ', '').strip()
# regular cases
for iban in [
'BE71 0961 2345 6769', # Belgium
'be71 0961 2345 6769', # Lowercase
' BE71 0961 2345 6769 ', # Extra padding
'FR76 3000 6000 0112 3456 7890 189', # France
'FR27 2004 1000 0101 2345 6Z02 068', # France (having letter)
'DE91 1000 0000 0123 4567 89', # Germany
'GR96 0810 0010 0000 0123 4567 890', # Greece
'RO09 BCYP 0000 0012 3456 7890', # Romania
'SA44 2000 0001 2345 6789 1234', # Saudi Arabia
'ES79 2100 0813 6101 2345 6789', # Spain
'CH56 0483 5012 3456 7800 9', # Switzerland
'GB98 MIDL 0700 9312 3456 78', # United Kingdom
]:
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': iban.replace(' ', '')})
assert not widget.has_error()
widget._parse(req)
assert widget.value == iban.upper().replace(' ', '').strip()
# failing cases
for iban in [
'42',
'FR76 2004 1000 0101 2345 6Z02 068',
'FR76 2004 1000 0101 2345 6%02 068',
'FR76 hello 234 6789 1234 6789 123',
'FRxx 2004 1000 0101 2345 6Z02 068',
'FR76 3000 6000 011² 3456 7890 189', # ²
'XX12',
'XX12 0000 00',
'FR76',
'FR76 0000 0000 0000 0000 0000 000',
'FR76 1234 4567',
]:
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': iban.replace(' ', '')})
assert widget.has_error()
assert (
widget.error
== 'You should enter a valid IBAN code, it should have between 14 and 34 characters, for example FR7600001000010000000000101.'
)
# failing cases
for iban in [
'42',
'FR76 2004 1000 0101 2345 6Z02 068',
'FR76 2004 1000 0101 2345 6%02 068',
'FR76 hello 234 6789 1234 6789 123',
'FRxx 2004 1000 0101 2345 6Z02 068',
'FR76 3000 6000 011² 3456 7890 189', # ²
'XX12',
'XX12 0000 00',
'FR76',
'FR76 0000 0000 0000 0000 0000 000',
'FR76 1234 4567',
]:
widget = WcsExtraStringWidget('test', value='foo', required=False)
widget.field = fakefield
mock_form_submission(req, widget, {'test': iban.replace(' ', '')})
assert widget.has_error()
assert (
widget.error
== 'You should enter a valid IBAN code, it should have between 14 and 34 characters, '
'for example FR7600001000010000000000101.'
)
def test_wcsextrastringwidget_time():

View File

@ -32,6 +32,7 @@ deps =
pylint
pre-commit
pyzbar
schwifty
bleach<5
# others...
django32: django>=3.2,<3.3
@ -72,6 +73,7 @@ deps =
Quixote>=3.0,<3.2
pre-commit
pyzbar
schwifty
allowlist_externals =
./getlasso3.sh
commands =

View File

@ -61,6 +61,10 @@ try:
except subprocess.CalledProcessError:
HAS_PDFTOPPM = False
try:
from schwifty import IBAN
except ImportError:
IBAN = None
Review

C'est laissé optionnel par flemme de regarder pour le backport du paquet debian vers bullseye; une fois qu'on sera en bookworm on pourra regarder (a priori juste copier le paquet de trixie fera l'affaire).

C'est laissé optionnel par flemme de regarder pour le backport du paquet debian vers bullseye; une fois qu'on sera en bookworm on pourra regarder (a priori juste copier le paquet de trixie fera l'affaire).
EXIF_ORIENTATION = 0x0112
@ -1108,6 +1112,12 @@ def validate_iban(string_value):
'''https://fr.wikipedia.org/wiki/International_Bank_Account_Number'''
if not string_value:
return False
if IBAN:
try:
IBAN(string_value, validate_bban=True)
except ValueError:
return False
return True
string_value = string_value.upper().strip().replace(' ', '')
country_code = string_value[:2]
iban_key = string_value[2:4]