""" Flare – Fernet şifreleme yardımcıları - encrypt(): düz string → "enc:" - decrypt(): enc: → düz string (veya enc: yoksa aynen döner) Anahtar: FLARE_TOKEN_KEY (32-bayt, base64, URL-safe) """ import os from typing import Optional from cryptography.fernet import Fernet, InvalidToken from logger import log_error, log_warning _ENV_KEY = "FLARE_TOKEN_KEY" def _get_key() -> Fernet: """Get encryption key with better error messages""" # Direkt environment variable kullan key = os.getenv(_ENV_KEY) # .env dosyasından yüklemeyi dene if not key: try: from dotenv import load_dotenv load_dotenv() key = os.getenv(_ENV_KEY) except ImportError: pass if not key: error_msg = ( f"{_ENV_KEY} ortam değişkeni tanımlanmadı. " f"Lütfen 32-byte base64 key oluşturun: python generate_key.py" ) log_error(error_msg) raise RuntimeError(error_msg) # Key formatını kontrol et try: return Fernet(key.encode()) except Exception as e: error_msg = ( f"{_ENV_KEY} geçersiz format. " f"32-byte base64 URL-safe key olmalı. " f"Yeni key için: python generate_key.py" ) log_error(error_msg, error=str(e)) raise RuntimeError(error_msg) def encrypt(plain: str) -> str: """düz string → enc:...""" if not plain: log_warning("Empty string passed to encrypt") return "" try: f = _get_key() encrypted = f.encrypt(plain.encode()).decode() return "enc:" + encrypted except Exception as e: log_error("Encryption failed", error=str(e)) raise def decrypt(value: Optional[str]) -> Optional[str]: """enc:... ise çözer, değilse aynen döndürür""" if value is None or not isinstance(value, str): return value if not value.startswith("enc:"): return value token = value.split("enc:", 1)[1] try: f = _get_key() decrypted = f.decrypt(token.encode()).decode() return decrypted except InvalidToken: error_msg = ( "Şifre çözme başarısız. Muhtemel sebepler:\n" "1. FLARE_TOKEN_KEY değişti\n" "2. Şifreli veri bozuldu\n" "3. Farklı bir key ile şifrelendi" ) log_error(error_msg) raise RuntimeError(error_msg) except Exception as e: log_error("Decryption error", error=str(e)) raise