From: Henryk Plötz Date: Wed, 22 Aug 2018 21:26:17 +0000 (+0200) Subject: Implement get_tan_descriptions() X-Git-Tag: v2.0.0~1^2~90 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=91d93b5e6a1e816976167927493215a38df02f56;p=thirdparty%2Fpython-fints.git Implement get_tan_descriptions() --- diff --git a/fints/client.py b/fints/client.py index 8f97734..69baffc 100644 --- a/fints/client.py +++ b/fints/client.py @@ -11,6 +11,7 @@ from .dialog import FinTSDialog, FinTSDialogOLD from .formals import ( KTI1, Account3, BankIdentifier, SynchronisationMode, TwoStepParametersCommon, + TANMediaType2, TANMediaClass4, ) from .message import FinTSMessageOLD from .models import ( @@ -23,7 +24,7 @@ from .security import ( ) from .segments import HIBPA3, HIRMS2, HIUPA4 from .segments.accounts import HISPA1, HKSPA, HKSPA1 -from .segments.auth import HKTAB, HKTAN +from .segments.auth import HKTAB, HKTAN, HKTAB4, HKTAB5 from .segments.depot import HKWPD5, HKWPD6 from .segments.dialog import HISYN4, HKSYN3 from .segments.saldo import HKSAL5, HKSAL6, HKSAL7 @@ -175,7 +176,11 @@ class FinTS3Client: version_map = dict((clazz.VERSION, clazz) for clazz in segment_classes) max_version = self.bpd.find_segment_highest_version(parameter_segment_name, version_map.keys()) if not max_version: - raise ValueError('No supported {} version found'.format(parameter_segment_name)) + raise ValueError('No supported {} version found. I support {}, bank supports {}.'.format( + parameter_segment_name, + tuple(version_map.keys()), + tuple(v.header.version for v in self.bpd.find_segments(parameter_segment_name)) + )) return version_map.get(max_version.header.version) @@ -455,31 +460,23 @@ class FinTS3Client: dialog.end() return dialog.tan_mechs - def _create_get_tan_description_message(self, dialog: FinTSDialogOLD): - return self._new_message(dialog, [ - HKTAB(3) - ]) + def get_tan_descriptions(self, media_type = TANMediaType2.ALL, media_class = TANMediaClass4.ALL): + """Get information about TAN lists/generators. - def get_tan_description(self): - """ - TAN method meta data, currently unparsed + Returns tuple of fints.formals.TANUsageOption and a list of fints.formals.TANMedia4 or fints.formals.TANMedia5 objects.""" - :return: str - """ - dialog = self._get_dialog() - dialog.sync() - dialog.init() - - with self.pin.protect(): - logger.debug('Sending HKTAB: {}'.format(self._create_get_tan_description_message(dialog))) + with self._get_dialog() as dialog: + hktab = self._find_highest_supported_command(HKTAB4, HKTAB5) - resp = dialog.send(self._create_get_tan_description_message(dialog)) - logger.debug('Got HKTAB response: {}'.format(resp)) - dialog.end() + seg = hktab( + tan_media_type = media_type, + tan_media_class = str(media_class), + ) - seg = resp._find_segment('HITAB') + response = dialog.send(seg) - return seg[2] + for resp in response.response_segments(seg, 'HITAB'): + return resp.tan_usage_option, list(resp.tan_media_list) class FinTS3PinTanClient(FinTS3Client): diff --git a/fints/formals.py b/fints/formals.py index dfc70cf..49e5f8f 100644 --- a/fints/formals.py +++ b/fints/formals.py @@ -522,3 +522,101 @@ class Timestamp1(DataElementGroup): Source: FinTS Financial Transaction Services, Schnittstellenspezifikation, Messages -- Multibankfähige Geschäftsvorfälle """ date = DataElementField(type='dat', _d="Datum") time = DataElementField(type='tim', required=False, _d="Uhrzeit") + +class TANMediaType2(RepresentableEnum): + """TAN-Medium-Art + + Source: FinTS Financial Transaction Services, Schnittstellenspezifikation, Sicherheitsverfahren PIN/TAN""" + + ALL = '0' #: Alle + ACTIVE = '1' #: Aktiv + AVAILABLE = '2' #: Verfügbar + + +class TANMediaClass3(RepresentableEnum): + """TAN-Medium-Klasse, version 3 + + Source: FinTS Financial Transaction Services, Schnittstellenspezifikation, Sicherheitsverfahren PIN/TAN""" + + ALL = 'A' #: Alle Medien + LIST = 'L' #: Liste + GENERATOR = 'G' #: TAN-Generator + MOBILE = 'M' #: Mobiltelefon mit mobileTAN + SECODER = 'S' #: Secoder + +class TANMediaClass4(RepresentableEnum): + """TAN-Medium-Klasse, version 4 + + Source: FinTS Financial Transaction Services, Schnittstellenspezifikation, Sicherheitsverfahren PIN/TAN""" + + ALL = 'A' #: Alle Medien + LIST = 'L' #: Liste + GENERATOR = 'G' #: TAN-Generator + MOBILE = 'M' #: Mobiltelefon mit mobileTAN + SECODER = 'S' #: Secoder + BILATERAL = 'B' #: Bilateral vereinbart + +class TANMediumStatus(RepresentableEnum): + """Status + + Source: FinTS Financial Transaction Services, Schnittstellenspezifikation, Sicherheitsverfahren PIN/TAN""" + + ACTIVE = '1' #: Aktiv + AVAILABLE = '2' #: Verfügbar + ACTIVE_SUCCESSOR = '3' #: Aktiv Folgekarte + AVAILABLE_SUCCESSOR = '4' #: Verfügbar Folgekarte + +class TANMedia4(DataElementGroup): + """TAN-Medium-Liste, version 4 + + Source: FinTS Financial Transaction Services, Schnittstellenspezifikation, Sicherheitsverfahren PIN/TAN""" + + tan_medium_class = CodeField(enum=TANMediaClass3, _d="TAN-Medium-Klasse") + status = CodeField(enum=TANMediumStatus, _d="Status") + card_number = DataElementField(type='id', required=False, _d="Kartennummer") + card_sequence = DataElementField(type='id', required=False, _d="Kartenfolgenummer") + card_type = DataElementField(type='num', required=False, _d="Kartenart") + account = DataElementGroupField(type=Account3, required=False, _d="Kontonummer Auftraggeber") + valid_from = DataElementField(type='dat', required=False, _d="Gültig ab") + valid_until = DataElementField(type='dat', required=False, _d="Gültig bis") + tan_list_number = DataElementField(type='an', max_length=20, required=False, _d="TAN-Listennummer") + tan_medium_name = DataElementField(type='an', max_length=32, required=False, _d="Bezeichnung des TAN-Mediums") + mobile_number_masked = DataElementField(type='an', max_length=35, required=False, _d="Mobiltelefonnummer, verschleiert") + mobile_number = DataElementField(type='an', max_length=35, required=False, _d="Mobiltelefonnummer") + sms_charge_account = DataElementGroupField(type=KTI1, required=False, _d="SMS-Abbuchungskonto") + number_free_tans = DataElementField(type='num', max_length=3, required=False, _d="Anzahl freie TANs") + last_use = DataElementField(type='dat', required=False, _d="Letzte Benutzung") + active_since = DataElementField(type='dat', required=False, _d="Freigeschaltet am") + +class TANMedia5(DataElementGroup): + """TAN-Medium-Liste, version 5 + + Source: FinTS Financial Transaction Services, Schnittstellenspezifikation, Sicherheitsverfahren PIN/TAN""" + + tan_medium_class = CodeField(enum=TANMediaClass4, _d="TAN-Medium-Klasse") + status = CodeField(enum=TANMediumStatus, _d="Status") + security_function = DataElementField(type='num', required=False, _d="Sicherheitsfunktion, kodiert") + card_number = DataElementField(type='id', required=False, _d="Kartennummer") + card_sequence = DataElementField(type='id', required=False, _d="Kartenfolgenummer") + card_type = DataElementField(type='num', required=False, _d="Kartenart") + account = DataElementGroupField(type=Account3, required=False, _d="Kontonummer Auftraggeber") + valid_from = DataElementField(type='dat', required=False, _d="Gültig ab") + valid_until = DataElementField(type='dat', required=False, _d="Gültig bis") + tan_list_number = DataElementField(type='an', max_length=20, required=False, _d="TAN-Listennummer") + tan_medium_name = DataElementField(type='an', max_length=32, required=False, _d="Bezeichnung des TAN-Mediums") + mobile_number_masked = DataElementField(type='an', max_length=35, required=False, _d="Mobiltelefonnummer, verschleiert") + mobile_number = DataElementField(type='an', max_length=35, required=False, _d="Mobiltelefonnummer") + sms_charge_account = DataElementGroupField(type=KTI1, required=False, _d="SMS-Abbuchungskonto") + number_free_tans = DataElementField(type='num', max_length=3, required=False, _d="Anzahl freie TANs") + last_use = DataElementField(type='dat', required=False, _d="Letzte Benutzung") + active_since = DataElementField(type='dat', required=False, _d="Freigeschaltet am") + +class TANUsageOption(RepresentableEnum): + """TAN-Einsatzoption + + Source: FinTS Financial Transaction Services, Schnittstellenspezifikation, Sicherheitsverfahren PIN/TAN""" + + ALL_ACTIVE = '0' #: Kunde kann alle "aktiven" Medien parallel nutzen + EXACTLY_ONE = '1'#: Kunde kann genau ein Medium zu einer Zeit nutzen + MOBILE_PLUS_GENERATOR = '2' #: Kunde kann ein Mobiltelefon und einen TAN-Generator parallel nutzen + diff --git a/fints/segments/auth.py b/fints/segments/auth.py index 1f0cfbd..ad283bc 100644 --- a/fints/segments/auth.py +++ b/fints/segments/auth.py @@ -1,6 +1,7 @@ from fints.fields import CodeField, DataElementField, DataElementGroupField from fints.formals import ( BankIdentifier, Language2, SynchronisationMode, SystemIDStatus, + TANMediaType2, TANMediaClass4, TANMedia5, TANMediaClass3, TANMedia4, TANUsageOption, ) from fints.utils import fints_escape @@ -134,3 +135,35 @@ class HKTAB(FinTS3SegmentOLD): '0', 'A' ] super().__init__(segno, data) + +class HKTAB4(FinTS3Segment): + """TAN-Generator/Liste anzeigen Bestand, version 4 + + Source: FinTS Financial Transaction Services, Schnittstellenspezifikation, Sicherheitsverfahren PIN/TAN""" + + tan_media_type = CodeField(enum=TANMediaType2, _d="TAN-Medium-Art") + tan_media_class = CodeField(enum=TANMediaClass3, _d="TAN-Medium-Klasse") + +class HITAB4(FinTS3Segment): + """TAN-Generator/Liste anzeigen Bestand Rückmeldung, version 4 + + Source: FinTS Financial Transaction Services, Schnittstellenspezifikation, Sicherheitsverfahren PIN/TAN""" + + tan_usage_option = CodeField(enum=TANUsageOption, _d="TAN_Einsatzoption") + tan_media_list = DataElementGroupField(type=TANMedia4, max_count=99, required=False, _d="TAN-Medium-Liste") + +class HKTAB5(FinTS3Segment): + """TAN-Generator/Liste anzeigen Bestand, version 5 + + Source: FinTS Financial Transaction Services, Schnittstellenspezifikation, Sicherheitsverfahren PIN/TAN""" + + tan_media_type = CodeField(enum=TANMediaType2, _d="TAN-Medium-Art") + tan_media_class = CodeField(enum=TANMediaClass4, _d="TAN-Medium-Klasse") + +class HITAB5(FinTS3Segment): + """TAN-Generator/Liste anzeigen Bestand Rückmeldung, version 5 + + Source: FinTS Financial Transaction Services, Schnittstellenspezifikation, Sicherheitsverfahren PIN/TAN""" + + tan_usage_option = CodeField(enum=TANUsageOption, _d="TAN_Einsatzoption") + tan_media_list = DataElementGroupField(type=TANMedia5, max_count=99, required=False, _d="TAN-Medium-Liste")