Sécurité et correction sur develop
This commit is contained in:
84
domo91.py
84
domo91.py
@@ -9,6 +9,7 @@ import os
|
|||||||
import random
|
import random
|
||||||
from dotenv import load_dotenv
|
from dotenv import load_dotenv
|
||||||
from datetime import datetime, date, time
|
from datetime import datetime, date, time
|
||||||
|
import bcrypt
|
||||||
|
|
||||||
# Charger les variables d'environnement
|
# Charger les variables d'environnement
|
||||||
load_dotenv()
|
load_dotenv()
|
||||||
@@ -174,7 +175,9 @@ if not st.session_state.get("authenticated"):
|
|||||||
cursor = conn.cursor(dictionary=True)
|
cursor = conn.cursor(dictionary=True)
|
||||||
cursor.execute("SELECT * FROM MotsDePasse WHERE utilisateur = %s", (login,))
|
cursor.execute("SELECT * FROM MotsDePasse WHERE utilisateur = %s", (login,))
|
||||||
result = cursor.fetchone()
|
result = cursor.fetchone()
|
||||||
if result and result["mot_de_passe"] == password:
|
def verifier_password(mot_de_passe_saisi, hash_en_base):
|
||||||
|
return bcrypt.checkpw(mot_de_passe_saisi.encode('utf-8'), hash_en_base.encode('utf-8'))
|
||||||
|
if result and verifier_password(password, result["mot_de_passe"]):
|
||||||
if result["Expiration"] and result["Expiration"] < date.today():
|
if result["Expiration"] and result["Expiration"] < date.today():
|
||||||
st.sidebar.error("⛔ Votre accès a expiré. Veuillez contacter un administrateur.")
|
st.sidebar.error("⛔ Votre accès a expiré. Veuillez contacter un administrateur.")
|
||||||
cursor.close()
|
cursor.close()
|
||||||
@@ -209,12 +212,36 @@ else:
|
|||||||
st.session_state["lieu_autorise"] = None
|
st.session_state["lieu_autorise"] = None
|
||||||
st.rerun()
|
st.rerun()
|
||||||
|
|
||||||
|
def hash_password(password):
|
||||||
|
return bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
|
||||||
|
|
||||||
|
def ajouter_utilisateur(utilisateur, mot_de_passe, role, lieu, expiration):
|
||||||
|
try:
|
||||||
|
conn = mysql.connector.connect(**db_config)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
cursor.execute("SELECT * FROM MotsDePasse WHERE utilisateur = %s", (utilisateur,))
|
||||||
|
if cursor.fetchone():
|
||||||
|
return False, "❌ Utilisateur déjà existant."
|
||||||
|
|
||||||
|
hash_mdp = hash_password(mot_de_passe)
|
||||||
|
cursor.execute("""
|
||||||
|
INSERT INTO MotsDePasse (utilisateur, mot_de_passe, role, Lieu, Expiration)
|
||||||
|
VALUES (%s, %s, %s, %s, %s)
|
||||||
|
""", (utilisateur, hash_mdp, role, lieu, expiration))
|
||||||
|
conn.commit()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
return True, "✅ Utilisateur ajouté avec succès."
|
||||||
|
except Exception as e:
|
||||||
|
return False, f"⚠️ Erreur : {e}"
|
||||||
|
|
||||||
# 📄 Affichage bouton PDF si une date est choisie
|
# 📄 Affichage bouton PDF si une date est choisie
|
||||||
site_pdf = (
|
site_pdf = (
|
||||||
st.session_state.get("lieu_autorise")
|
st.session_state.get("lieu_autorise")
|
||||||
if st.session_state.get("role") != "superviseur"
|
if st.session_state.get("role") != "superviseur"
|
||||||
|
|
||||||
else st.session_state.get("selected_site")
|
else st.session_state.get("selected_site")
|
||||||
)
|
)
|
||||||
date_pdf = st.session_state.get("selected_date")
|
date_pdf = st.session_state.get("selected_date")
|
||||||
if site_pdf and date_pdf:
|
if site_pdf and date_pdf:
|
||||||
st.sidebar.markdown("---")
|
st.sidebar.markdown("---")
|
||||||
@@ -354,7 +381,7 @@ if st.session_state["authenticated"]:
|
|||||||
|
|
||||||
if st.session_state.get("authenticated"):
|
if st.session_state.get("authenticated"):
|
||||||
if st.session_state["role"] == "superviseur":
|
if st.session_state["role"] == "superviseur":
|
||||||
onglets_possibles = ["Accueil", "Statistiques", "Entretien", "Traffic"]
|
onglets_possibles = ["Accueil", "Statistiques", "Entretien", "Traffic", "Utilisateurs"]
|
||||||
|
|
||||||
else:
|
else:
|
||||||
onglets_possibles = ["Accueil", "Entretien"]
|
onglets_possibles = ["Accueil", "Entretien"]
|
||||||
@@ -713,5 +740,52 @@ if st.session_state["authenticated"]:
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
st.error(f"Erreur chargement des connexions : {e}")
|
st.error(f"Erreur chargement des connexions : {e}")
|
||||||
|
|
||||||
except Exception as er:
|
# --- ONGLET UTILISATEURS ---
|
||||||
st.error(f"Erreur MySQL : {er}")
|
elif onglet == "Utilisateurs" and st.session_state.get("role") == "superviseur":
|
||||||
|
st.title("👥 Gestion des utilisateurs")
|
||||||
|
|
||||||
|
# --- Section Ajout ---
|
||||||
|
with st.expander("➕ Ajouter un nouvel utilisateur"):
|
||||||
|
new_user = st.text_input("Nom d'utilisateur")
|
||||||
|
new_pass = st.text_input("Mot de passe", type="password")
|
||||||
|
new_role = st.selectbox("Rôle", ["simple", "superviseur"])
|
||||||
|
new_lieu = None
|
||||||
|
if new_role == "simple":
|
||||||
|
new_lieu = st.selectbox("Lieu autorisé", ["Saclay", "Meudon", "Roissy"])
|
||||||
|
expiration = st.date_input("Date d'expiration (facultative)", value=None)
|
||||||
|
|
||||||
|
if st.button("Créer l'utilisateur"):
|
||||||
|
if new_user and new_pass:
|
||||||
|
success, message = ajouter_utilisateur(
|
||||||
|
utilisateur=new_user,
|
||||||
|
mot_de_passe=new_pass,
|
||||||
|
role=new_role,
|
||||||
|
lieu=new_lieu if new_role == "simple" else None,
|
||||||
|
expiration=expiration if expiration else None
|
||||||
|
)
|
||||||
|
if success:
|
||||||
|
st.success(message)
|
||||||
|
else:
|
||||||
|
st.error(message)
|
||||||
|
else:
|
||||||
|
st.warning("Tous les champs obligatoires doivent être remplis.")
|
||||||
|
|
||||||
|
# --- Section Liste ---
|
||||||
|
st.markdown("### 📋 Utilisateurs existants")
|
||||||
|
try:
|
||||||
|
conn = mysql.connector.connect(**db_config)
|
||||||
|
cursor = conn.cursor(dictionary=True)
|
||||||
|
cursor.execute("SELECT utilisateur, role, Lieu, Expiration FROM MotsDePasse ORDER BY utilisateur")
|
||||||
|
users = cursor.fetchall()
|
||||||
|
cursor.close()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
if users:
|
||||||
|
import pandas as pd
|
||||||
|
|
||||||
|
df_users = pd.DataFrame(users)
|
||||||
|
st.dataframe(df_users)
|
||||||
|
else:
|
||||||
|
st.info("Aucun utilisateur trouvé.")
|
||||||
|
except Exception as e:
|
||||||
|
st.error(f"Erreur lors du chargement des utilisateurs : {e}")
|
||||||
39
hash_passwords.py
Normal file
39
hash_passwords.py
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import mysql.connector
|
||||||
|
import bcrypt
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
import os
|
||||||
|
|
||||||
|
# Charger les variables d'environnement depuis .env
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
conn = mysql.connector.connect(
|
||||||
|
host=os.getenv("DB_HOST"),
|
||||||
|
user=os.getenv("DB_USER"),
|
||||||
|
password=os.getenv("DB_PASSWORD"),
|
||||||
|
database=os.getenv("DB_NAME")
|
||||||
|
)
|
||||||
|
cursor = conn.cursor()
|
||||||
|
|
||||||
|
cursor.execute("SELECT utilisateur, mot_de_passe FROM MotsDePasse")
|
||||||
|
utilisateurs = cursor.fetchall()
|
||||||
|
|
||||||
|
def hash_password(plain_text_password):
|
||||||
|
return bcrypt.hashpw(plain_text_password.encode('utf-8'), bcrypt.gensalt()).decode('utf-8')
|
||||||
|
|
||||||
|
for utilisateur, mot_de_passe in utilisateurs:
|
||||||
|
if mot_de_passe.startswith('$2b$') or mot_de_passe.startswith('$2a$'):
|
||||||
|
print(f"{utilisateur} : déjà haché")
|
||||||
|
continue
|
||||||
|
|
||||||
|
hashe = hash_password(mot_de_passe)
|
||||||
|
cursor.execute("UPDATE MotsDePasse SET mot_de_passe = %s WHERE utilisateur = %s", (hashe, utilisateur))
|
||||||
|
print(f"{utilisateur} : mot de passe haché")
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
print("Mise à jour terminée.")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -11,3 +11,4 @@ paramiko~=3.5.1
|
|||||||
dotenv
|
dotenv
|
||||||
fpdf
|
fpdf
|
||||||
ovh
|
ovh
|
||||||
|
bcrypt
|
||||||
|
|||||||
Reference in New Issue
Block a user