#!/usr/bin/env python3 import os, sys, argparse, datetime import mysql.connector, bcrypt from dotenv import load_dotenv def read_stdin() -> str: data = sys.stdin.read() return data.rstrip("\r\n") def main(): load_dotenv() ap = argparse.ArgumentParser(description="Auth bcrypt locale pour Excel") ap.add_argument("--user", required=True, help="NomUtilisateur (clé primaire)") ap.add_argument("--password-stdin", action="store_true", help="Lire le mot de passe via STDIN (recommandé)") args = ap.parse_args() if not args.password_stdin: print("ERR|Utiliser --password-stdin et fournir le mot de passe via STDIN", flush=True) return 2 password = read_stdin() if not password: print("ERR|Mot de passe vide", flush=True) return 2 # Récupération des infos de connexion depuis .env host = os.getenv("DB_HOST") db = os.getenv("DB_NAME") user = os.getenv("DB_USER") pwd = os.getenv("DB_PASSWORD") try: conn = mysql.connector.connect( host=host, database=db, user=user, password=pwd, connection_timeout=5 ) cur = conn.cursor(dictionary=True) cur.execute(""" SELECT NomUtilisateur, Nom_complet, Site, MotDePasseHash, DateExpiration FROM Utilisateurs WHERE NomUtilisateur = %s LIMIT 1 """, (args.user,)) row = cur.fetchone() except Exception as e: print("ERR|Connexion base impossible", flush=True) return 3 finally: try: cur.close() conn.close() except Exception: pass if not row or not row.get("MotDePasseHash"): print("ERR|Utilisateur ou mot de passe invalide", flush=True) return 1 try: ok = bcrypt.checkpw(password.encode("utf-8"), row["MotDePasseHash"].encode("ascii")) except Exception: ok = False if not ok: print("ERR|Utilisateur ou mot de passe invalide", flush=True) return 1 # Contrôle expiration (si renseignée) exp = row.get("DateExpiration") if exp is not None: today = datetime.date.today() exp_date = exp if isinstance(exp, datetime.date) else getattr(exp, "date", lambda: today)() if exp_date < today: print(f"ERR|Compte expiré le {exp_date.isoformat()}", flush=True) return 2 site = row.get("Site") or "" nom = row.get("Nom_complet") or "" print(f"OK|Site={site}|NomComplet={nom}", flush=True) return 0 if __name__ == "__main__": sys.exit(main())