Files
benevoles/backend/app/email/check.py
T
AdamThomasandClaude Sonnet 5 b84f62dfab Emails : robustesse SMTP + diagnostic
- config.py : retrait des identifiants OVH réels remis en dur ; défauts
  neutres (email_enabled=false). Les vraies valeurs vont dans .env.
- open_smtp : le port 465 force le SSL implicite (SMTPS) même si SMTP_SSL=false
  — c'était la cause des envois qui ne partaient pas (connexion en clair sur un
  port TLS -> timeout).
- deliver_many : les erreurs de connexion / auth / rejet sont journalisées
  avec le message du serveur et ne remontent plus (l'appel HTTP n'échoue pas).
- Lien magique : envoi en tâche de fond (BackgroundTasks) comme les
  notifications ; ne bloque plus la réponse.
- app/email/check.py : `python -m app.email.check <destinataire>` — affiche la
  config effective et envoie un email de test, avec la cause exacte en cas
  d'échec.
- Tests : fixture autouse forçant EMAIL_ENABLED=false (aucun test ne touche un
  vrai SMTP, quel que soit le .env local) ; test_full_flow lit l'email capturé
  au lieu des logs. 137 tests OK.
- .env.example : notes port 465 / From = boîte authentifiée / commande check.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017uUsRg7XzopkCPWimwg9ZM
2026-09-10 19:31:02 +02:00

64 lines
1.9 KiB
Python

"""Diagnostic de la configuration SMTP.
docker compose run --rm backend \\
uv run python -m app.email.check destinataire@exemple.fr
Affiche la configuration effective, ouvre une session SMTP et envoie un email
de test. En cas d'échec, imprime la cause exacte renvoyée par le serveur.
"""
import sys
from app.config import get_settings
from app.email.sender import build_message, open_smtp
def main() -> int:
if len(sys.argv) != 2:
print("Usage : python -m app.email.check <destinataire@exemple.fr>")
return 2
recipient = sys.argv[1]
settings = get_settings()
print("Configuration SMTP effective :")
print(f" EMAIL_ENABLED : {settings.email_enabled}")
print(f" SMTP_HOST : {settings.smtp_host}:{settings.smtp_port}")
print(f" SMTP_SSL : {settings.smtp_ssl}")
print(f" SMTP_STARTTLS : {settings.smtp_starttls}")
print(f" SMTP_USER : {settings.smtp_user or '(aucun)'}")
print(f" SMTP_FROM : {settings.smtp_from}")
print()
if not settings.email_enabled:
print("EMAIL_ENABLED est false : aucun envoi réel. Passe-le à true.")
return 1
try:
smtp = open_smtp(settings)
except Exception as exc:
print(f"ÉCHEC connexion / authentification : {exc!r}")
return 1
message = build_message(
recipient,
"Test SMTP — gestion des bénévoles",
"Cet email confirme que la configuration SMTP fonctionne.",
)
try:
with smtp:
smtp.send_message(message)
except Exception as exc:
print(f"ÉCHEC envoi (le serveur a refusé) : {exc!r}")
print(
"Piste fréquente (OVH…) : SMTP_FROM doit être la boîte "
"authentifiée (= SMTP_USER) ou un alias validé."
)
return 1
print(f"OK — email de test envoyé à {recipient}.")
return 0
if __name__ == "__main__":
raise SystemExit(main())