Initial commit: Accounting packages

This commit is contained in:
Ernad Husremovic 2025-08-29 15:20:47 +02:00
commit 4ef34c2317
2661 changed files with 1709616 additions and 0 deletions

View file

@ -0,0 +1,40 @@
from itertools import zip_longest
import requests
from urllib3.util.ssl_ import create_urllib3_context
def calc_check_digits(number: str) -> str:
"""Calculate the extra digits that should be appended to the number to make it a valid number.
Source: python-stdnum iso7064.mod_97_10.calc_check_digits
"""
number_base10 = ''.join(str(int(x, 36)) for x in number)
checksum = int(number_base10) % 97
return '%02d' % ((98 - 100 * checksum) % 97)
def format_rf_reference(number: str) -> str:
"""Format a string into a Structured Creditor Reference.
The Creditor Reference is an international standard (ISO 11649).
Example: `123456789` -> `RF18 1234 5678 9`
"""
check_digits = calc_check_digits('{}RF'.format(number))
return 'RF{} {}'.format(
check_digits,
" ".join("".join(x) for x in zip_longest(*[iter(str(number))]*4, fillvalue=""))
)
class LegacyHTTPAdapter(requests.adapters.HTTPAdapter):
""" An adapter to allow unsafe legacy renegotiation necessary to connect to
gravely outdated ETA production servers.
"""
def init_poolmanager(self, *args, **kwargs):
# This is not defined before Python 3.12
# cfr. https://github.com/python/cpython/pull/93927
# Origin: https://github.com/openssl/openssl/commit/ef51b4b9
OP_LEGACY_SERVER_CONNECT = 0x04
context = create_urllib3_context(options=OP_LEGACY_SERVER_CONNECT)
kwargs["ssl_context"] = context
return super().init_poolmanager(*args, **kwargs)

View file

@ -0,0 +1,73 @@
from types import SimpleNamespace
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.serialization import pkcs12
from OpenSSL import crypto
def load_key_and_certificates(content, password):
private_key, certificate, _dummy = pkcs12.load_key_and_certificates(content, password, backend=default_backend())
def public_key():
public_key = certificate.public_key()
def public_numbers():
public_numbers = public_key.public_numbers()
return SimpleNamespace(
n=public_numbers.n,
e=public_numbers.e,
)
return SimpleNamespace(
public_numbers=public_numbers,
public_bytes=public_key.public_bytes,
)
simple_private_key = SimpleNamespace(
sign=private_key.sign,
private_bytes=private_key.private_bytes,
)
simple_certificate = SimpleNamespace(
fingerprint=certificate.fingerprint,
issuer=SimpleNamespace(
rfc4514_string=certificate.issuer.rfc4514_string,
rdns=[
SimpleNamespace(rfc4514_string=item.rfc4514_string)
for item in certificate.issuer.rdns
],
get_attributes_for_oid=lambda oid: [
SimpleNamespace(value=item.value)
for item in certificate.issuer.get_attributes_for_oid(oid)
]
),
subject=SimpleNamespace(
rfc4514_string=certificate.subject.rfc4514_string,
rdns=[
SimpleNamespace(rfc4514_string=item.rfc4514_string)
for item in certificate.subject.rdns
],
get_attributes_for_oid=lambda oid: [
SimpleNamespace(value=item.value)
for item in certificate.subject.get_attributes_for_oid(oid)
]
),
not_valid_after=certificate.not_valid_after,
not_valid_before=certificate.not_valid_before,
public_key=public_key,
public_bytes=certificate.public_bytes,
serial_number=certificate.serial_number,
)
return simple_private_key, simple_certificate
def crypto_load_certificate(cer_pem):
certificate = crypto.load_certificate(crypto.FILETYPE_PEM, cer_pem)
simple_certificate = SimpleNamespace(
get_notAfter=certificate.get_notAfter,
get_notBefore=certificate.get_notBefore,
get_serial_number=certificate.get_serial_number,
get_subject=lambda: SimpleNamespace(
CN=certificate.get_subject().CN,
serialNumber=certificate.get_subject().serialNumber,
),
)
return simple_certificate