2026-08-14 18:02:25 +02:00
|
|
|
"""
|
|
|
|
|
Modèles pour les paramètres de l'application
|
|
|
|
|
"""
|
|
|
|
|
from datetime import datetime, timezone
|
|
|
|
|
from app_new.extensions import db
|
2026-08-14 23:46:00 +02:00
|
|
|
import os
|
|
|
|
|
|
|
|
|
|
def _cipher():
|
|
|
|
|
from cryptography.fernet import Fernet
|
|
|
|
|
key = os.environ.get('OUTLOOK_ENCRYPTION_KEY')
|
|
|
|
|
return Fernet(key.encode()) if key else None
|
2026-08-14 18:02:25 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
class AppSettings(db.Model):
|
|
|
|
|
"""Paramètres globaux de l'application."""
|
|
|
|
|
__tablename__ = 'app_settings'
|
|
|
|
|
|
|
|
|
|
id = db.Column(db.Integer, primary_key=True)
|
|
|
|
|
key = db.Column(db.String(100), unique=True, nullable=False, index=True)
|
|
|
|
|
value = db.Column(db.Text, nullable=True)
|
|
|
|
|
description = db.Column(db.String(255), nullable=True)
|
|
|
|
|
is_encrypted = db.Column(db.Boolean, default=False)
|
|
|
|
|
created_at = db.Column(db.DateTime, default=datetime.utcnow)
|
|
|
|
|
updated_at = db.Column(db.DateTime, default=datetime.utcnow, onupdate=datetime.utcnow)
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def get(key, default=None):
|
|
|
|
|
"""Récupère un paramètre par sa clé."""
|
|
|
|
|
setting = AppSettings.query.filter_by(key=key).first()
|
|
|
|
|
if setting:
|
2026-08-14 23:46:00 +02:00
|
|
|
if setting.is_encrypted and setting.value and setting.value.startswith('enc:'):
|
|
|
|
|
cipher = _cipher()
|
|
|
|
|
if not cipher:
|
|
|
|
|
return default
|
|
|
|
|
try:
|
|
|
|
|
return cipher.decrypt(setting.value[4:].encode()).decode()
|
|
|
|
|
except Exception:
|
|
|
|
|
return default
|
2026-08-14 18:02:25 +02:00
|
|
|
return setting.value
|
|
|
|
|
return default
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def set(key, value, description=None, is_encrypted=False):
|
|
|
|
|
"""Définit un paramètre."""
|
2026-08-14 23:46:00 +02:00
|
|
|
stored_value = value
|
|
|
|
|
if is_encrypted and value:
|
|
|
|
|
cipher = _cipher()
|
|
|
|
|
if not cipher:
|
|
|
|
|
raise RuntimeError("OUTLOOK_ENCRYPTION_KEY est requise pour stocker ce secret.")
|
|
|
|
|
stored_value = 'enc:' + cipher.encrypt(value.encode()).decode()
|
2026-08-14 18:02:25 +02:00
|
|
|
setting = AppSettings.query.filter_by(key=key).first()
|
|
|
|
|
if setting:
|
2026-08-14 23:46:00 +02:00
|
|
|
setting.value = stored_value
|
|
|
|
|
setting.is_encrypted = is_encrypted
|
2026-08-14 18:02:25 +02:00
|
|
|
setting.updated_at = datetime.now(timezone.utc)
|
|
|
|
|
if description:
|
|
|
|
|
setting.description = description
|
|
|
|
|
else:
|
|
|
|
|
setting = AppSettings(
|
|
|
|
|
key=key,
|
2026-08-14 23:46:00 +02:00
|
|
|
value=stored_value,
|
2026-08-14 18:02:25 +02:00
|
|
|
description=description,
|
|
|
|
|
is_encrypted=is_encrypted
|
|
|
|
|
)
|
|
|
|
|
db.session.add(setting)
|
|
|
|
|
db.session.commit()
|
|
|
|
|
return setting
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def get_openrouter_api_key():
|
|
|
|
|
"""Récupère la clé API OpenRouter."""
|
|
|
|
|
return AppSettings.get('openrouter_api_key')
|
|
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
|
def set_openrouter_api_key(api_key):
|
|
|
|
|
"""Définit la clé API OpenRouter."""
|
|
|
|
|
return AppSettings.set(
|
|
|
|
|
'openrouter_api_key',
|
|
|
|
|
api_key,
|
|
|
|
|
description='Clé API OpenRouter pour l\'interprétation des emails',
|
|
|
|
|
is_encrypted=True
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
def __repr__(self):
|
2026-08-14 23:46:00 +02:00
|
|
|
return f'<AppSettings {self.key}>'
|