]> git.ipfire.org Git - thirdparty/python-fints.git/commitdiff
Work on flicker code/hhduc parsing, make it work with my Sparkasse
authorHenryk Plötz <henryk@ploetzli.ch>
Thu, 6 Sep 2018 21:17:23 +0000 (23:17 +0200)
committerRaphael Michel <mail@raphaelmichel.de>
Mon, 3 Dec 2018 18:34:29 +0000 (19:34 +0100)
fints/client.py
fints/hhd/flicker.py
tests/test_hhd.py [new file with mode: 0644]

index 9a96bb92fd376795f99c98a7156a16066194b5fe..2a181c6e0df6477e00db9b0e6b2c01eea8d7bc4c 100644 (file)
@@ -815,8 +815,6 @@ class FinTS3Client:
             yield self
         self._standing_dialog = None
 
-CHLGUC_RE = re.compile(r'(?:CHLGUC\s*(?P<UCLEN>\d{4})\s*(?P<UC>\d.*?))?CHLGTEXT\s*\d{4}(?P<TEXT>.*)$', re.I | re.S)
-
 class NeedTANResponse(NeedRetryResponse):
     def __init__(self, command_seg, tan_request, resume_method=None, tan_request_structured=False):
         self.command_seg = command_seg
@@ -856,14 +854,17 @@ class NeedTANResponse(NeedRetryResponse):
         self.challenge_hhduc = None
 
         if hasattr(self.tan_request, 'challenge_hhduc'):
-            self.challenge_hhduc = self.tan_request.challenge_hhduc
-
-        match = CHLGUC_RE.match(self.challenge_raw)
-        if match:
-            if not self.challenge_hhduc:
-                if match.group('UCLEN'):
-                    self.challenge_hhduc = match.group('UC')[:int(match.group('UCLEN'))]
-            self.challenge = match.group('TEXT').strip()
+            if self.tan_request.challenge_hhduc:
+                self.challenge_hhduc = self.tan_request.challenge_hhduc.decode('us-ascii')
+
+        if self.challenge.startswith('CHLGUC  '):
+            l = self.challenge[8:12]
+            if l.isdigit():
+                self.challenge_hhduc = self.challenge[12:(12+int(l,10))]
+                self.challenge = self.challenge[(12+int(l,10)):]
+
+        if self.challenge.startswith('CHLGTEXT'):
+            self.challenge = self.challenge[12:]
 
         if self.tan_request_structured:
             self.challenge_html = bleach.clean(
index 81ba59c61d981945a4a683772fb21c2ce2c49046..8d3c830a5581b9c7505667fb3b3043fddac89a72 100644 (file)
@@ -85,6 +85,8 @@ class FlickerCode:
     def parse(self, code):
         length = LC_LENGTH_HHD14 if self.version == HHD_VERSION_14 else LC_LENGTH_HHD13
         self.lc = int(code[0:length])
+        if len(code) < length+self.lc:
+            raise ValueError("lc too large: {} + {} > {}".format(self.lc, length, len(code)))
         code = code[length:]
         code = self.startcode.parse(code)
         self.version = self.startcode.version
diff --git a/tests/test_hhd.py b/tests/test_hhd.py
new file mode 100644 (file)
index 0000000..1c97485
--- /dev/null
@@ -0,0 +1,47 @@
+import pytest
+from fints.hhd.flicker import parse, HHD_VERSION_13
+
+
+# HITAN3:
+#  'challenge' contains a HHD 1.3 code embedded in the normal text payload
+#  field.
+#  Example: 'CHLGUC  00312908881344731012345678900515,00CHLGTEXT0292Sie haben eine ...'
+#    The code in NeedTANResponse._parse_tan_challenge extracts 
+#     '2908881344731012345678900515,00'
+#    from this, as a version 1.3 code. parse() should accept it
+#    (start code: '88134473', IBAN: '1234567890', amount: '15,00')
+
+def test_flicker_hhd13():
+    flicker = parse('2908881344731012345678900515,00')
+
+    assert flicker.version == HHD_VERSION_13
+    assert flicker.lc == 29
+    assert flicker.startcode.data == '88134473'
+    assert flicker.de1.data == '1234567890'
+    assert flicker.de2.data == '15,00'
+    assert flicker.de3.data is None
+
+    assert flicker.render() == '1204881344730512345678901531352C30303B'
+
+
+# The old code in fints.hhd.flicker.clean would add a 0
+def test_flicker_hhd13_old():
+    flicker = parse('02908881344731012345678900515,00')
+
+    assert flicker.version == HHD_VERSION_13
+    assert flicker.lc == 29
+    assert flicker.startcode.data == '88134473'
+
+    assert flicker.render() == '1204881344730512345678901531352C30303B'
+
+
+# From https://github.com/willuhn/hbci4java/blob/master/test/hbci4java/secmech/FlickerTest.java
+#  Maybe we should be able to handle this and others?
+@pytest.mark.xfail
+def test_flicker_hhd13_hbci4java_1():
+    flicker = parse('CHLGUC 002624088715131306389726041,00CHLGTEXT0244 Sie h')
+
+    assert flicker.lc == 24
+    assert flicker.startcode.data == '87151313'
+
+    assert flicker.render() == '0F04871513130338972614312C30303B'