use anyhow::Result; use argon2::password_hash::SaltString; use argon2::{Argon2, PasswordHash, PasswordHasher, PasswordVerifier}; use rand::rngs::OsRng; pub fn hash_password(plain: &str) -> Result { let salt = SaltString::generate(&mut OsRng); let argon2 = Argon2::default(); let hash = argon2 .hash_password(plain.as_bytes(), &salt) .map_err(|e| anyhow::anyhow!("argon2 hash: {e}"))? .to_string(); Ok(hash) } pub fn verify_password(plain: &str, hash: &str) -> Result { let parsed = PasswordHash::new(hash).map_err(|e| anyhow::anyhow!("argon2 parse: {e}"))?; Ok(Argon2::default() .verify_password(plain.as_bytes(), &parsed) .is_ok()) } #[cfg(test)] mod tests { use super::*; #[test] fn hash_and_verify() { let hash = hash_password("hunter2").unwrap(); assert!(verify_password("hunter2", &hash).unwrap()); assert!(!verify_password("hunter3", &hash).unwrap()); } }