change_password.rs
171 lignes · 5593 octets
//! Script CLI pour changer le mot de passe d'un utilisateur //! //! Usage: //! cargo run --bin change_password -- `<username>` `<nouveau_password>` //! //! Exemples: //! cargo run --bin change_password -- john-doe "NewPassword123!" //! cargo run --bin change_password -- admin "SecureAdminPass2024" //! //! Options: //! --keep-must-change Garde le flag must_change_password tel quel //! --force-change Force l'utilisateur à changer le password au prochain login use rustwarden_core::config::database; use rustwarden_core::models::user; use rustwarden_core::services::password_service::PasswordService; use sea_orm::{ActiveModelTrait, ColumnTrait, EntityTrait, QueryFilter, Set}; use std::env; #[tokio::main] async fn main() { // Load environment variables dotenvy::dotenv().ok(); // Initialize basic logging tracing_subscriber::fmt() .with_env_filter( tracing_subscriber::EnvFilter::try_from_default_env().unwrap_or_else(|_| "info".into()), ) .init(); // Parse arguments let args: Vec<String> = env::args().collect(); if args.len() < 3 { eprintln!( "❌ Usage: {} <username> <nouveau_password> [options]", args[0] ); eprintln!(); eprintln!("Options:"); eprintln!(" --keep-must-change Garde le flag must_change_password tel quel"); eprintln!( " --force-change Force l'utilisateur à changer le password au prochain login" ); eprintln!(); eprintln!("Exemples:"); eprintln!(" {} john-doe \"NewPassword123!\"", args[0]); eprintln!(" {} admin \"SecurePass2024\" --force-change", args[0]); std::process::exit(1); } let username = &args[1]; let new_password = &args[2]; // Parse options let mut keep_must_change = false; let mut force_change = false; for arg in &args[3..] { match arg.as_str() { "--keep-must-change" => keep_must_change = true, "--force-change" => force_change = true, _ => { eprintln!("⚠️ Option inconnue: {}", arg); } } } // Validate password length (minimum 8 characters) if new_password.len() < 8 { eprintln!("❌ Erreur: Le mot de passe doit contenir au moins 8 caractères"); std::process::exit(1); } println!( "🔐 Changement de mot de passe pour l'utilisateur: {}", username ); println!(); // Connect to database println!("📊 Connexion à la base de données..."); let db = match database::create_connection().await { Ok(conn) => { println!("✅ Connexion établie"); conn } Err(e) => { eprintln!("❌ Erreur de connexion à la base de données: {}", e); std::process::exit(1); } }; // Find user by username println!("🔍 Recherche de l'utilisateur..."); let user = match user::Entity::find() .filter(user::Column::Username.eq(username)) .one(&db) .await { Ok(Some(user)) => { println!("✅ Utilisateur trouvé: {} ({})", user.username, user.email); user } Ok(None) => { eprintln!("❌ Erreur: Utilisateur '{}' introuvable", username); std::process::exit(1); } Err(e) => { eprintln!("❌ Erreur lors de la recherche: {}", e); std::process::exit(1); } }; // Hash the new password println!("🔒 Hachage du nouveau mot de passe..."); let password_hash = match PasswordService::hash_password(new_password).await { Ok(hash) => { println!("✅ Mot de passe haché avec succès"); hash } Err(e) => { eprintln!("❌ Erreur lors du hachage: {}", e); std::process::exit(1); } }; // Determine must_change_password value let must_change_password = if keep_must_change { println!( "ℹ️ Conservation du flag must_change_password existant: {}", user.must_change_password ); user.must_change_password } else if force_change { println!("⚠️ L'utilisateur devra changer son mot de passe au prochain login"); true } else { println!("✅ L'utilisateur pourra se connecter normalement"); false }; // Update user password println!("💾 Mise à jour du mot de passe dans la base de données..."); let mut user_active: user::ActiveModel = user.into(); user_active.password_hash = Set(password_hash); user_active.must_change_password = Set(must_change_password); user_active.updated_at = Set(chrono::Utc::now()); match user_active.update(&db).await { Ok(updated_user) => { println!("✅ Mot de passe mis à jour avec succès!"); println!(); println!("📋 Détails:"); println!(" Utilisateur: {}", updated_user.username); println!(" Email: {}", updated_user.email); println!( " Must change password: {}", updated_user.must_change_password ); println!(" Mis à jour: {}", updated_user.updated_at); println!(); println!("🎉 Opération terminée avec succès!"); } Err(e) => { eprintln!("❌ Erreur lors de la mise à jour: {}", e); std::process::exit(1); } } }
GitRust