41 lines
1.4 KiB
Python
41 lines
1.4 KiB
Python
import base64
|
||
import hashlib
|
||
import json
|
||
|
||
from cryptography.fernet import Fernet, InvalidToken
|
||
from django.conf import settings
|
||
|
||
from commerce.models import IntegrationConnection
|
||
|
||
|
||
class CredentialError(ValueError):
|
||
pass
|
||
|
||
|
||
def _fernet() -> Fernet:
|
||
configured_key = getattr(settings, "COMMERCE_CREDENTIAL_KEY", "").strip()
|
||
if configured_key:
|
||
key = configured_key.encode("ascii")
|
||
else:
|
||
digest = hashlib.sha256(
|
||
f"commerce-integrations:{settings.SECRET_KEY}".encode()
|
||
).digest()
|
||
key = base64.urlsafe_b64encode(digest)
|
||
return Fernet(key)
|
||
|
||
|
||
def encrypt_credentials(credentials: dict[str, str]) -> str:
|
||
payload = json.dumps(credentials, ensure_ascii=False).encode()
|
||
return _fernet().encrypt(payload).decode("ascii")
|
||
|
||
|
||
def decrypt_credentials(connection: IntegrationConnection) -> dict[str, str]:
|
||
try:
|
||
payload = _fernet().decrypt(connection.encrypted_credentials.encode("ascii"))
|
||
value = json.loads(payload)
|
||
except (InvalidToken, UnicodeError, ValueError, TypeError) as exc:
|
||
raise CredentialError("Не удалось расшифровать реквизиты подключения.") from exc
|
||
if not isinstance(value, dict):
|
||
raise CredentialError("Некорректный формат реквизитов подключения.")
|
||
return {str(key): str(item) for key, item in value.items()}
|