]> git.ipfire.org Git - thirdparty/python-fints.git/commitdiff
Support more HKTAN segment versions
authorRaphael Michel <mail@raphaelmichel.de>
Wed, 25 Jul 2018 15:37:21 +0000 (17:37 +0200)
committerRaphael Michel <mail@raphaelmichel.de>
Wed, 25 Jul 2018 15:37:21 +0000 (17:37 +0200)
fints/client.py
fints/models.py
fints/segments/auth.py

index f87255e7273b5b21b44e0ee290b4fc4662051443..b4d370500d80bce359925fcd9ce27981fa363bbc 100644 (file)
@@ -10,7 +10,7 @@ from .connection import FinTSHTTPSConnection
 from .dialog import FinTSDialog
 from .message import FinTSMessage
 from .message import FinTSResponse
-from .models import SEPAAccount, TANMethod, TANChallenge6, TANChallenge5, TANChallenge3, TANChallenge4
+from .models import SEPAAccount, TANMethod, TANChallenge6, TANChallenge5, TANChallenge3, TANChallenge4, TANChallenge
 from .segments.accounts import HKSPA
 from .segments.auth import HKTAN, HKTAB
 from .segments.depot import HKWPD
@@ -31,7 +31,7 @@ class FinTS3Client:
     def _new_dialog(self):
         raise NotImplemented()
 
-    def _new_message(self, dialog: FinTSDialog, segments):
+    def _new_message(self, dialog: FinTSDialog, segments, tan=None):
         raise NotImplemented()
 
     def get_sepa_accounts(self):
@@ -241,32 +241,25 @@ class FinTS3Client:
             )
         ])
 
-    def send_tan(self, arg):
-        data = str(arg['response'])
-
-        res = FinTSResponse(data)
-        seg = res._find_segment('HITAN')
-        seg = split_for_data_groups(seg)
-        aref = seg[3]
-        segTAN = HKTAN(3, 2, aref, '')
-
-        self.blz = arg['dialog'].blz
-        self.username = arg['dialog'].username
-        self.pin = arg['dialog'].pin
-        self.systemid = arg['dialog'].systemid
-        self.dialogid = arg['dialog'].dialogid
-        self.msgno = arg['dialog'].msgno
-        self.tan_mechs = []
-        self.tan_mechs = [arg['TAN-Verfahren']]
-        self.pintan = ':'.join([self.pin, arg['tan']])
-        msg = FinTSMessage(self.blz, self.username, self.pintan, self.systemid, self.dialogid, self.msgno, [
-            segTAN
-        ], self.tan_mechs)
-
-        res = arg['dialog'].send(msg)
-        arg['dialog'].end()
-
-        return 'Ok'
+    def _create_send_tan_message(self, dialog: FinTSDialog, challenge: TANChallenge, tan):
+        return self._new_message(dialog, [
+            HKTAN(3, '2', challenge.reference, '', challenge.version)
+        ], tan)
+
+    def send_tan(self, challenge: TANChallenge, tan: str):
+        if challenge.tan_process != '4':
+            raise NotImplementedError("TAN process {} currently not implemented".format(challenge.tan_process))
+        with self.pin.protect():
+            logger.debug('Sending HKTAN: {}'.format(self._create_send_tan_message(
+                challenge.dialog, challenge, tan
+            )))
+
+        resp = challenge.dialog.send(self._create_send_tan_message(
+            challenge.dialog, challenge, tan
+        ))
+        logger.debug('Got HKTAN response: {}'.format(resp))
+
+        challenge.dialog.end()
 
     def start_simple_sepa_transfer(self, account: SEPAAccount, tan_method: TANMethod, iban: str, bic: str,
                                    recipient_name: str, amount: Decimal, account_name: str, reason: str,
@@ -292,9 +285,10 @@ class FinTS3Client:
         xml = sepa.export().decode()
         return self.start_sepa_transfer(account, xml, tan_method, tan_description)
 
-    def _get_start_sepa_transfer_message(self, dialog, account: SEPAAccount, pain_message: str, tan_description):
+    def _get_start_sepa_transfer_message(self, dialog, account: SEPAAccount, pain_message: str, tan_method,
+                                         tan_description):
         segHKCCS = HKCCS(3, account, pain_message)
-        segHKTAN = HKTAN(4, 4, '', tan_description)
+        segHKTAN = HKTAN(4, '4', '', tan_description, tan_method.version)
         return self._new_message(dialog, [
             segHKCCS,
             segHKTAN
@@ -308,10 +302,12 @@ class FinTS3Client:
 
         with self.pin.protect():
             logger.debug('Sending HKCCS: {}'.format(self._get_start_sepa_transfer_message(
-                dialog, account, pain_message, tan_description
+                dialog, account, pain_message, tan_method, tan_description
             )))
 
-        resp = dialog.send(self._get_start_sepa_transfer_message(dialog, account, pain_message, tan_description))
+        resp = dialog.send(self._get_start_sepa_transfer_message(
+            dialog, account, pain_message, tan_method, tan_description
+        ))
         logger.debug('Got HKCCS response: {}'.format(resp))
 
         seg = resp._find_segment('HITAN')
@@ -337,6 +333,7 @@ class FinTS3Client:
         dialog = self._new_dialog()
         dialog.sync()
         dialog.init()
+        dialog.end()
         return dialog.tan_mechs
 
     def _create_get_tan_description_message(self, dialog: FinTSDialog):
@@ -377,5 +374,5 @@ class FinTS3PinTanClient(FinTS3Client):
         return dialog
 
     def _new_message(self, dialog: FinTSDialog, segments, tan=None):
-        return FinTSMessage(self.blz, self.username, pin, dialog.systemid, dialog.dialogid, dialog.msgno,
+        return FinTSMessage(self.blz, self.username, self.pin, dialog.systemid, dialog.dialogid, dialog.msgno,
                             segments, dialog.tan_mechs, tan)
index 4da5e5f69cc1e9cfa59280d8fe31b70f933ea352..913172502383188cc888fe57bef156fe68c3288b 100644 (file)
@@ -49,7 +49,9 @@ class TANMethod6(TANMethod):
 
 
 class TANChallenge(DataClass):
-    pass
+    def __init__(self, dialog, *args, **kwargs):
+        self.dialog = dialog
+        super().__init__(*args, **kwargs)
 
 
 class TANChallenge3(TANChallenge):
index 51d29b7415b1f0313c1a5e4c6283cc443d349353..a049fb57dcd6b9552f471bd9ef8fbf4f6a9541b4 100644 (file)
@@ -64,25 +64,37 @@ class HKSYN(FinTS3Segment):
 class HKTAN(FinTS3Segment):
     """
     HKTAN (TAN-Verfahren festlegen)
-    Section C.2.1.2
+    Section B.5.1
     """
     type = 'HKTAN'
 
-    def __init__(self, segno, process, aref, medium):
-        self.version = 3
-        if process == 4:
-            if medium == '':
-                data = [
-                    process
-                ]
+    def __init__(self, segno, process, aref, medium, version):
+        self.version = version
+
+        if process not in ('2', '4'):
+            raise NotImplementedError("HKTAN process {} currently not implemented.".format(process))
+        if version not in (3, 4, 5, 6):
+            raise NotImplementedError("HKTAN version {} currently not implemented.".format(version))
+
+        if process == '4':
+            if medium:
+                if version == 3:
+                    data = [process, '', '', '', '', '', '', '', medium]
+                elif version == 4:
+                    data = [process, '', '', '', '', '', '', '', '', medium]
+                elif version == 5:
+                    data = [process, '', '', '', '', '', '', '', '', '', '', medium]
+                elif version == 6:
+                    data = [process, '', '', '', '', '', '', '', '', '', medium]
             else:
-                data = [
-                    process, '', '', '', '', '', '', '', medium
-                ]
-        else:
-            data = [
-                process, '', aref, '', 'N'
-            ]
+                data = [process]
+        elif process == '2':
+            if version == 6:
+                data = [process, '', '', '', aref, 'N']
+            elif version == 5:
+                data = [process, '', '', '', aref, '', 'N']
+            elif version in (3, 4):
+                data = [process, '', aref, '', 'N']
         super().__init__(segno, data)
 
 
@@ -94,7 +106,7 @@ class HKTAB(FinTS3Segment):
     type = 'HKTAB'
 
     def __init__(self, segno):
-        self.version = 4
+        self.version = 5
         data = [
             '0', 'A'
         ]