Ajout notification par mail à la création d'user

This commit is contained in:
2025-11-09 00:48:01 +01:00
parent 498d04b1d1
commit b638d333b5

View File

@@ -130,14 +130,17 @@ def hash_password(plain: str, rounds: int = 12) -> str:
salt = bcrypt.gensalt(rounds=rounds)
return bcrypt.hashpw(plain.encode("utf-8"), salt).decode("utf-8")
def user_exists(cur, username: str, email: str) -> bool:
cur.execute(
"SELECT COUNT(*) FROM Utilisateurs WHERE NomUtilisateur=%s OR email=%s",
(username, email),
)
def user_exists(cur, username: str) -> bool:
cur.execute("SELECT COUNT(*) FROM Utilisateurs WHERE NomUtilisateur=%s", (username,))
(count,) = cur.fetchone()
return count > 0
def find_users_by_email(cnx, email: str):
with cnx.cursor(dictionary=True) as cur:
cur.execute(
"SELECT NomUtilisateur, Site FROM Utilisateurs WHERE email=%s ORDER BY NomUtilisateur",
(email,),
)
return cur.fetchall()
def list_users(cnx, limit: int = 500, include_password=False):
fields = [
"NomUtilisateur", "Nom_complet", "Site", "DateExpiration",
@@ -159,8 +162,10 @@ def insert_user(cnx, username, full_name, site, password, expires, phone, email,
pwd_hash = hash_password(password)
with cnx.cursor() as cur:
if user_exists(cur, username, email):
raise RuntimeError("Nom d'utilisateur ou email déjà existant.")
# ✅ vérif uniquement sur NomUtilisateur
if user_exists(cur, username):
raise RuntimeError("Nom d'utilisateur déjà existant.")
if store_plain:
cur.execute(
"""
@@ -181,6 +186,7 @@ def insert_user(cnx, username, full_name, site, password, expires, phone, email,
)
return pwd_hash
def get_user_details(cnx, username: str):
with cnx.cursor(dictionary=True) as cur:
cur.execute(
@@ -362,8 +368,10 @@ with tab_list:
except Exception as e:
st.warning(f"Impossible de lister les utilisateurs : {e}")
# -----------------------
# ONGLET CREER
# -----------------------
# --- Onglet Créer ---
with tab_create:
with st.form("create_user_form", clear_on_submit=False):
st.subheader("Nouveau compte")
@@ -381,19 +389,33 @@ with tab_create:
c7, c8 = st.columns(2)
password = c7.text_input("Mot de passe", type="password")
password2 = c8.text_input("Confirmer", type="password")
store_plain = st.checkbox("Stocker le mot de passe en clair (déconseillé)", value=False)
col_cb1, col_cb2 = st.columns([1.2, 1])
# si tu stockes encore le mot de passe en clair dans la table
store_plain = col_cb1.checkbox("Stocker le mot de passe en clair (déconseillé)", value=False)
# ✅ nouvelle case pour l'e-mail de bienvenue à la création
notify_welcome = col_cb2.checkbox("Envoyer un e-mail de bienvenue", value=True,
help="Enverra l'identifiant, le nom, le site et le mot de passe en clair")
submitted = st.form_submit_button("Créer l'utilisateur", use_container_width=True)
if submitted:
if not username or not full_name or not site or not email:
st.error("Champs requis manquants.")
elif not EMAIL_RE.match(email):
st.error("Format de-mail invalide.")
elif password != password2:
st.error("Les mots de passe ne correspondent pas.")
else:
try:
cnx = pool.get_connection()
try:
# 🔎 avertir si l'e-mail existe déjà (mais on n'empêche pas)
dup = find_users_by_email(cnx, email)
if dup:
liste = ", ".join(f"{u['NomUtilisateur']}@{u['Site']}" for u in dup)
st.info(f"Cet e-mail est déjà utilisé par : {liste}")
pwd_hash = insert_user(
cnx, username=username, full_name=full_name, site=site,
password=password, expires=expires, phone=phone, email=email,
@@ -401,9 +423,44 @@ with tab_create:
)
finally:
cnx.close()
st.success("Utilisateur créé avec succès ✅")
st.caption("Hash (MotDePasseHash) :")
st.code(pwd_hash)
# ✉️ Mail de bienvenue (optionnel)
if notify_welcome:
try:
subj = f"[Compte créé] Vos accès — {site}"
body_txt = (
"Bonjour,\n\n"
"Votre compte a été créé.\n\n"
f"Nom dutilisateur : {username}\n"
f"Nom complet : {full_name}\n"
f"Site : {site}\n"
f"Mot de passe : {password}\n"
f"Date d'expiration: {expires.strftime('%Y-%m-%d')}\n\n"
"Cordialement."
)
body_html = f"""
<html><body>
<p>Bonjour,</p>
<p>Votre compte a été créé.</p>
<table cellpadding="6" cellspacing="0" border="0" style="border-collapse:collapse">
<tr><td><b>Nom dutilisateur</b></td><td>{username}</td></tr>
<tr><td><b>Nom complet</b></td><td>{full_name}</td></tr>
<tr><td><b>Site</b></td><td>{site}</td></tr>
<tr><td><b>Mot de passe</b></td><td style="font-family:monospace">{password}</td></tr>
<tr><td><b>Date d'expiration</b></td><td>{expires.strftime('%Y-%m-%d')}</td></tr>
</table>
<p>Cordialement.</p>
</body></html>
"""
send_mail(email, subj, body_txt, body_html)
st.success(f"✉️ E-mail de bienvenue envoyé à {email}")
except Exception as e_mail:
st.warning(f"E-mail non envoyé : {e_mail}")
except mysql.connector.Error as db_err:
if db_err.errno == errorcode.ER_ACCESS_DENIED_ERROR:
st.error("Identifiants MySQL invalides.")
@@ -412,7 +469,10 @@ with tab_create:
except Exception as e:
st.error(f"Erreur : {e}")
# --- Onglet Modifier ---
# -----------------------
# ONGLET MODIFIER
# -----------------------
with tab_edit:
st.subheader("Modifier un utilisateur existant")
try:
@@ -495,8 +555,10 @@ with tab_edit:
st.error(f"Erreur MySQL : {db_err}")
except Exception as e:
st.error(f"Erreur : {e}")
# -----------------------
# ONGLET SECURITE
# -----------------------
# --- Onglet Sécurité ---
with tab_security:
st.subheader("Réinitialiser le mot de passe (bcrypt)")
try: