]> git.ipfire.org Git - thirdparty/python-fints.git/commitdiff
Deal with 3938 (locked PIN)
authorRaphael Michel <mail@raphaelmichel.de>
Fri, 25 Jan 2019 15:36:02 +0000 (16:36 +0100)
committerRaphael Michel <mail@raphaelmichel.de>
Fri, 25 Jan 2019 15:36:02 +0000 (16:36 +0100)
fints/client.py
fints/exceptions.py
tests/conftest.py
tests/test_client.py

index e8f09de021a4fc7c57aa27e54e291d2ed3f69b07..8bae84e04eaa7b847f080293fb28536db98d70a7 100644 (file)
@@ -1146,6 +1146,14 @@ class FinTS3PinTanClient(FinTS3Client):
                 self.pin.block()
             raise FinTSClientPINError("Error during dialog initialization, PIN wrong?")
 
+        if response.code == '3938':
+            # Account locked, e.g. after three wrong password attempts. Theoretically, the bank might allow us to
+            # send a HKPSA with a TAN to unlock, but since the library currently doesn't implement it and there's only
+            # one chance to get it right, let's rather error iout.
+            if self.pin:
+                self.pin.block()
+            raise FinTSClientTemporaryAuthError("Account is temporarily locked.")
+
     def get_tan_mechanisms(self):
         """
         Get the available TAN mechanisms.
index 08b0c6e98ce4fd9f16b5cc0e0a5ee426800c02d2..57ae05825c9aeb85ace4b9f4f9860ab23e2d8c60 100644 (file)
@@ -10,6 +10,10 @@ class FinTSClientPINError(FinTSClientError):
     pass
 
 
+class FinTSClientTemporaryAuthError(FinTSClientError):
+    pass
+
+
 class FinTSDialogError(FinTSError):
     pass
 
index 33e7c8fbe0f2dc3bbbd98ed955569ca76eb101f9..e3c958dc161d723c0a9eab2c97b5650e4266b167 100644 (file)
@@ -45,7 +45,7 @@ def fints_server():
                 if pinmatch.group(2):
                     tan = pinmatch.group(2).decode('us-ascii')
 
-            if pin != '1234':
+            if pin not in ('1234', '3938'):
                 return "HIRMG::2+9910::Pin ungültig'".encode('utf-8')
 
             result = []
@@ -65,8 +65,11 @@ def fints_server():
                     responses.append(b'3050::UPD nicht mehr aktuell, aktuelle Version enthalten.')
                     segments.append(b"HIUPA:57:4:4+test1+3+0'HIUPD:58:6:4+1::280:12345678+DE111234567800000001+test1++EUR+Fullname++Girokonto++HKSAK:1+HKISA:1+HKSSP:1+HKSAL:1+HKKAZ:1+HKEKA:1+HKCDB:1+HKPSP:1+HKCSL:1+HKCDL:1+HKPAE:1+HKPPD:1+HKCDN:1+HKCSB:1+HKCUB:1+HKQTG:1+HKSPA:1+HKDSB:1+HKCCM:1+HKCUM:1+HKCCS:1+HKCDE:1+HKCSE:1+HKDSW:1+HKPRO:1+HKSAL:1+HKKAZ:1+HKTUL:1+HKTUB:1+HKPRO:1+GKVPU:1+GKVPD:1'HIUPD:59:6:4+2::280:12345678+DE111234567800000002+test1++EUR+Fullname++Tagesgeld++HKSAK:1+HKISA:1+HKSSP:1+HKSAL:1+HKKAZ:1+HKEKA:1+HKPSP:1+HKCSL:1+HKPAE:1+HKCSB:1+HKCUB:1+HKQTG:1+HKSPA:1+HKCUM:1+HKCCS:1+HKCSE:1+HKPRO:1+HKSAL:1+HKKAZ:1+HKTUL:1+HKTUB:1+HKPRO:1+GKVPU:1+GKVPD:1'")
 
-                responses.append(b'3920::Zugelassene TAN-Verfahren fur den Benutzer:942')
-                responses.append(b'0901::*PIN gultig.')
+                if pin == '3938':
+                    responses.append(b'3938::Ihr Zugang ist vorl\u00e4ufig gesperrt - Bitte PIN-Sperre aufheben.')
+                else:
+                    responses.append(b'3920::Zugelassene TAN-Verfahren fur den Benutzer:942')
+                    responses.append(b'0901::*PIN gultig.')
                 responses.append(b'0020::*Dialoginitialisierung erfolgreich')
 
                 result.append(b"HIRMS::2:"+b"+".join(responses)+b"'")
index 61a34210d6625ea68965f3c08267432837a80808..703d9ff8d2daa867c9675d8b784f5f3a34b9f6ee 100644 (file)
@@ -1,5 +1,5 @@
 from fints.client import FinTS3PinTanClient, TransactionResponse, NeedTANResponse, ResponseStatus, NeedRetryResponse
-from fints.exceptions import FinTSClientPINError
+from fints.exceptions import FinTSClientPINError, FinTSClientTemporaryAuthError
 from decimal import Decimal
 import pytest
 
@@ -49,6 +49,27 @@ def test_pin_wrong(fints_server):
         str(client.pin)
 
 
+def test_pin_locked(fints_server):
+    client = FinTS3PinTanClient(
+        '12345678',
+        'test1',
+        '3938',
+        fints_server,
+    )
+    with pytest.raises(FinTSClientTemporaryAuthError):
+        with client:
+            pass
+
+    assert client.pin.blocked
+
+    with pytest.raises(Exception):
+        with client:
+            pass
+
+    with pytest.raises(Exception, match="Refusing"):
+        str(client.pin)
+
+
 def test_resume(fints_client, fints_server):
     with fints_client:
         system_id = fints_client.system_id