From: Henryk Plötz Date: Tue, 14 Aug 2018 14:50:16 +0000 (+0200) Subject: Improve documentation X-Git-Tag: v2.0.0~1^2~108 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c5e9d756723d2d4105905a4dbcf8192a75921621;p=thirdparty%2Fpython-fints.git Improve documentation --- diff --git a/docs/developer.rst b/docs/developer.rst index 5bd9943..e887237 100644 --- a/docs/developer.rst +++ b/docs/developer.rst @@ -180,7 +180,7 @@ ____________ :inherited-members: :undoc-members: :show-inheritance: - :exclude-members: print_nested + :exclude-members: print_nested, naive_parse, find_subclass, is_unset :member-order: bysource diff --git a/fints/fields.py b/fints/fields.py index e366420..dc1c514 100644 --- a/fints/fields.py +++ b/fints/fields.py @@ -235,6 +235,26 @@ class CodeField(AlphanumericField): ## FIXME: Not further implemented, might want to use Enums + def __init__(self, enum=None, *args, **kwargs): + if enum: + self._DOC_TYPE = enum + self._enum = enum + else: + self._enum = None + super().__init__(*args, **kwargs) + + def _parse_value(self, value): + retval = super()._parse_value(value) + if self._enum: + retval = self._enum(retval) + return retval + + def _render_value(self, value): + retval = value + if self._enum: + retval = str(value.value) + return super()._render_value(retval) + class CountryField(FixedLengthMixin, DigitsField): type = 'ctr' _FIXED_LENGTH = [3] diff --git a/fints/formals.py b/fints/formals.py index 4a65cbb..65b0929 100644 --- a/fints/formals.py +++ b/fints/formals.py @@ -2,8 +2,7 @@ import re from fints.types import * # The order is important! from fints.fields import * -from fints.utils import ShortReprMixin - +from fints.utils import RepresentableEnum, ShortReprMixin class DataElementGroup(Container): pass @@ -19,27 +18,64 @@ class ReferenceMessage(DataElementGroup): dialogue_id = DataElementField(type='id') message_number = NumericField(max_length=4) +class SecurityMethod(RepresentableEnum): + DDV = 'DDV' + RAH = 'RAH' + RDH = 'RDH' + PIN = 'PIN' + class SecurityProfile(DataElementGroup): - security_method = DataElementField(type='code', length=3) - security_method_version = DataElementField(type='num') + "Sicherheitsprofil" + security_method = CodeField(enum=SecurityMethod, length=3, _d="Sicherheitsverfahren") + security_method_version = DataElementField(type='num', _d="Version des Sicherheitsverfahrens") + +class IdentifiedRole(RepresentableEnum): + MS = '1' #: Message Sender + MR = '2' #: Message Receiver class SecurityIdentificationDetails(DataElementGroup): - name_party = DataElementField(type='code', max_length=3) + identified_role = CodeField(IdentifiedRole, max_length=3) cid = DataElementField(type='bin', max_length=256) - identifier_party = DataElementField(type='id') + identifier = DataElementField(type='id') + +class DateTimeType(RepresentableEnum): + STS = '1' #: Sicherheitszeitstempel + CRT = '6' #: Certificate Revocation Time class SecurityDateTime(DataElementGroup): - datetime_type = DataElementField(type='code', max_length=3) + date_time_type = CodeField(DateTimeType, max_length=3) date = DataElementField(type='dat', required=False) time = DataElementField(type='tim', required=False) +class UsageEncryption(RepresentableEnum): + OSY = '2' #: Owner Symmetric + +class OperationMode(RepresentableEnum): + CBC = '2' #: Cipher Block Chaining + ISO_9796_1 = '16' #: ISO 9796-1 (bei RDH) + ISO_9796_2_RANDOM = '17' #: ISO 9796-2 mit Zufallszahl (bei RDH) + PKCS1V15 = '18' #: RSASSA-PKCS#1 V1.5 (bei RDH); RSAES-PKCS#1 V1.5 (bei RAH, RDH) + PSS = '19' #: RSASSA-PSS (bei RAH, RDH) + ZZZ = '999' #: Gegenseitig vereinbart (DDV: Retail-MAC) + +class EncryptionAlgorithmCoded(RepresentableEnum): + TWOKEY3DES = '13' #: 2-Key-Triple-DES + AES256 = '14' #: AES-256 + +class AlgorithmParameterName(RepresentableEnum): + KYE = '5' #: Symmetrischer Schlüssel, verschlüsselt mit symmetrischem Schlüssel + KYP = '6' #: Symmetrischer Schlüssel, verschlüsselt mit öffentlichem Schlüssel + +class AlgorithmParameterIVName(RepresentableEnum): + IVC = '1' #: Initialization value, clear text + class EncryptionAlgorithm(DataElementGroup): - usage_encryption = DataElementField(type='code', max_length=3) - operation_mode = DataElementField(type='code', max_length=3) - encryption_algorithm = DataElementField(type='code', max_length=3) + usage_encryption = CodeField(UsageEncryption, max_length=3) + operation_mode = CodeField(OperationMode, max_length=3) + encryption_algorithm = CodeField(EncryptionAlgorithmCoded, max_length=3) algorithm_parameter_value = DataElementField(type='bin', max_length=512) - algorithm_parameter_name = DataElementField(type='code', max_length=3) - algorithm_parameter_iv_name = DataElementField(type='code', max_length=3) + algorithm_parameter_name = CodeField(AlgorithmParameterName, max_length=3) + algorithm_parameter_iv_name = CodeField(AlgorithmParameterIVName, max_length=3) algorithm_parameter_iv_value = DataElementField(type='bin', max_length=512, required=False) class HashAlgorithm(DataElementGroup): @@ -57,10 +93,16 @@ class BankIdentifier(DataElementGroup): country_identifier = DataElementField(type='ctr') bank_code = DataElementField(type='an', max_length=30) +class KeyType(RepresentableEnum): + "Schlüsselart" + D = 'D' #: Schlüssel zur Erzeugung digitaler Signaturen + S = 'S' #: Signierschlüssel + V = 'V' #: Chiffrierschlüssel + class KeyName(DataElementGroup): bank_identifier = DataElementGroupField(type=BankIdentifier) user_id = DataElementField(type='id') - key_type = DataElementField(type='code', length=1) + key_type = CodeField(KeyType, length=1, _d="Schlüsselart") key_number = DataElementField(type='num', max_length=3) key_version = DataElementField(type='num', max_length=3) @@ -256,3 +298,23 @@ class AccountInternational(DataElementGroup): account_number = DataElementField(type='id') subaccount_number = DataElementField(type='id') bank_identifier = DataElementGroupField(type=BankIdentifier) + +class SecurityRole(RepresentableEnum): + ISS = '1' + CON = '3' + WIT = '4' + +class CompressionFunction(RepresentableEnum): + NULL = '0' #: Keine Kompression + LZW = '1' #: Lempel, Ziv, Welch + COM = '2' #: Optimized LZW + LZSS = '3' #: Lempel, Ziv + LZHuf = '4' #: LZ + Huffman Coding + ZIP = '5' #: PKZIP + GZIP = '6' #: deflate (http://www.gzip.org/zlib) + BZIP2 = '7' #: bzip2 (http://sourceware.cygnus.com/bzip2/) + ZZZ = '999' #: Gegenseitig vereinbart + +class SecurityApplicationArea(RepresentableEnum): + SHM = '1' #: Signaturkopf und HBCI-Nutzdaten + SHT = '2' #: Von Signaturkopf bis Signaturabschluss diff --git a/fints/segments/__init__.py b/fints/segments/__init__.py index 60d4097..a9f70eb 100644 --- a/fints/segments/__init__.py +++ b/fints/segments/__init__.py @@ -7,10 +7,12 @@ from fints.formals import ( HashAlgorithm, KeyName, ParameterPinTan, ParameterTwostepTAN1, ParameterTwostepTAN2, ParameterTwostepTAN3, ParameterTwostepTAN4, ParameterTwostepTAN5, ParameterTwostepTAN6, ReferenceMessage, Response, - SecurityDateTime, SecurityIdentificationDetails, SecurityProfile, + SecurityDateTime, SecurityIdentificationDetails, SecurityProfile, SecurityRole, SegmentHeader, SegmentSequenceField, SignatureAlgorithm, SupportedHBCIVersions2, SupportedLanguages2, UserDefinedSignature, + CompressionFunction, SecurityApplicationArea, ) +from fints.fields import CodeField from fints.utils import SubclassesMixin, classproperty TYPE_VERSION_RE = re.compile(r'^([A-Z]+)(\d+)$') @@ -87,41 +89,46 @@ class HNHBK3(FinTS3Segment): reference_message = DataElementGroupField(type=ReferenceMessage, required=False) class HNHBS1(FinTS3Segment): + "Nachrichtenabschluss" message_number = DataElementField(type='num', max_length=4) class HNVSD1(FinTS3Segment): - data = SegmentSequenceField() + "Verschlüsselte Daten" + data = SegmentSequenceField(_d="Daten, verschlüsselt") class HNVSK3(FinTS3Segment): - security_profile = DataElementGroupField(type=SecurityProfile) - security_function = DataElementField(type='code', max_length=3) - security_role = DataElementField(type='code', max_length=3) - security_identification_details = DataElementGroupField(type=SecurityIdentificationDetails) - security_datetime = DataElementGroupField(type=SecurityDateTime) - encryption_algorithm = DataElementGroupField(type=EncryptionAlgorithm) - key_name = DataElementGroupField(type=KeyName) - compression_function = DataElementField(type='code', max_length=3) - certificate = DataElementGroupField(type=Certificate, required=False) + "Verschlüsselungskopf" + security_profile = DataElementGroupField(type=SecurityProfile, _d="Sicherheitsprofil") + security_function = DataElementField(type='code', max_length=3, _d="Sicherheitsfunktion, kodiert") + security_role = CodeField(SecurityRole, max_length=3, _d="Rolle des Sicherheitslieferanten, kodiert") + security_identification_details = DataElementGroupField(type=SecurityIdentificationDetails, _d="Sicherheitsidentifikation, Details") + security_datetime = DataElementGroupField(type=SecurityDateTime, _d="Sicherheitsdatum und -uhrzeit") + encryption_algorithm = DataElementGroupField(type=EncryptionAlgorithm, _d="Verschlüsselungsalgorithmus") + key_name = DataElementGroupField(type=KeyName, _d="Schlüsselname") + compression_function = CodeField(CompressionFunction, max_length=3, _d="Komprimierungsfunktion") + certificate = DataElementGroupField(type=Certificate, required=False, _d="Zertifikat") class HNSHK4(FinTS3Segment): - security_profile = DataElementGroupField(type=SecurityProfile) - security_function = DataElementField(type='code', max_length=3) - security_reference = DataElementField(type='an', max_length=14) - security_application_area = DataElementField(type='code', max_length=3) - security_role = DataElementField(type='code', max_length=3) - security_identification_details = DataElementGroupField(type=SecurityIdentificationDetails) - security_reference_number = DataElementField(type='num', max_length=16) - security_datetime = DataElementGroupField(type=SecurityDateTime) - hash_algorithm = DataElementGroupField(type=HashAlgorithm) - signature_algorithm = DataElementGroupField(type=SignatureAlgorithm) - key_name = DataElementGroupField(type=KeyName) - certificate = DataElementGroupField(type=Certificate, required=False) + "Signaturkopf" + security_profile = DataElementGroupField(type=SecurityProfile, _d="Sicherheitsprofil") + security_function = DataElementField(type='code', max_length=3, _d="Sicherheitsfunktion, kodiert") + security_reference = DataElementField(type='an', max_length=14, _d="Sicherheitskontrollreferenz") + security_application_area = CodeField(SecurityApplicationArea, max_length=3, _d="Bereich der Sicherheitsapplikation, kodiert") + security_role = CodeField(SecurityRole, max_length=3, _d="Rolle des Sicherheitslieferanten, kodiert") + security_identification_details = DataElementGroupField(type=SecurityIdentificationDetails, _d="Sicherheitsidentifikation, Details") + security_reference_number = DataElementField(type='num', max_length=16, _d="Sicherheitsreferenznummer") + security_datetime = DataElementGroupField(type=SecurityDateTime, _d="Sicherheitsdatum und -uhrzeit") + hash_algorithm = DataElementGroupField(type=HashAlgorithm, _d="Hashalgorithmus") + signature_algorithm = DataElementGroupField(type=SignatureAlgorithm, _d="Signaturalgorithmus") + key_name = DataElementGroupField(type=KeyName, _d="Schlüsselname") + certificate = DataElementGroupField(type=Certificate, required=False, _d="Zertifikat") class HNSHA2(FinTS3Segment): - security_reference = DataElementField(type='an', max_length=14) - validation_result = DataElementField(type='bin', max_length=512, required=False) - user_defined_signature = DataElementGroupField(type=UserDefinedSignature, required=False) + "Signaturabschluss" + security_reference = DataElementField(type='an', max_length=14, _d="Sicherheitskontrollreferenz") + validation_result = DataElementField(type='bin', max_length=512, required=False, _d="Validierungsresultat") + user_defined_signature = DataElementGroupField(type=UserDefinedSignature, required=False, _d="Benutzerdefinierte Signatur") class HIRMG2(FinTS3Segment): responses = DataElementGroupField(type=Response, min_count=1, max_count=99) diff --git a/fints/utils.py b/fints/utils.py index 987847d..440f8cd 100644 --- a/fints/utils.py +++ b/fints/utils.py @@ -1,6 +1,7 @@ import re from contextlib import contextmanager from datetime import datetime +from enum import Enum import mt940 @@ -247,3 +248,11 @@ class Password(str): def replace(self, *args, **kwargs): return self.__str__().replace(*args, **kwargs) + +class RepresentableEnum(Enum): + def __repr__(self): + return "{}.{}.{}".format(self.__class__.__module__, self.__class__.__name__, self.name) + + def __str__(self): + return self.value +