24 lines
988 B
Rust
24 lines
988 B
Rust
use argon2::password_hash::{rand_core::OsRng, PasswordHash, PasswordHasher, PasswordVerifier, SaltString};
|
|
use argon2::Argon2;
|
|
|
|
use crate::error::{AppError, AppResult};
|
|
|
|
/// Hash a plaintext password with Argon2id + random salt (PHC string).
|
|
pub fn hash_password(plain: &str) -> AppResult<String> {
|
|
let salt = SaltString::generate(&mut OsRng);
|
|
let hash = Argon2::default()
|
|
.hash_password(plain.as_bytes(), &salt)
|
|
.map_err(|e| AppError::Internal(anyhow::anyhow!("password hash failed: {e}")))?;
|
|
Ok(hash.to_string())
|
|
}
|
|
|
|
/// Verify a plaintext password against a stored PHC hash.
|
|
/// Returns Ok(false) on mismatch, error only on malformed stored hash.
|
|
pub fn verify_password(plain: &str, stored_hash: &str) -> AppResult<bool> {
|
|
let parsed = PasswordHash::new(stored_hash)
|
|
.map_err(|e| AppError::Internal(anyhow::anyhow!("stored hash malformed: {e}")))?;
|
|
Ok(Argon2::default()
|
|
.verify_password(plain.as_bytes(), &parsed)
|
|
.is_ok())
|
|
}
|