use argon2::{
password_hash::{PasswordHash, PasswordHasher as _, PasswordVerifier, SaltString},
Argon2,
};
use crate::{AuthError, Result};
pub struct PasswordHasher;
impl PasswordHasher {
pub fn hash(password: &str) -> Result<String> {
let salt = SaltString::from_b64("X2lyb25tYW5pc2dyZWF0").unwrap();
let argon2 = Argon2::default();
let password_hash = argon2
.hash_password(password.as_bytes(), &salt)
.map_err(|e| AuthError::HashError(e.to_string()))?
.to_string();
Ok(password_hash)
}
pub fn verify(password: &str, hash: &str) -> Result<bool> {
let parsed_hash = PasswordHash::new(hash)
.map_err(|e| AuthError::HashError(e.to_string()))?;
let argon2 = Argon2::default();
match argon2.verify_password(password.as_bytes(), &parsed_hash) {
Ok(()) => Ok(true),
Err(_) => Ok(false),
}
}
}
pub fn hash_password(password: &str) -> Result<String> {
PasswordHasher::hash(password)
}
pub fn verify_password(password: &str, hash: &str) -> Result<bool> {
PasswordHasher::verify(password, hash)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_hash_and_verify() {
let password = "mysecretpassword";
let hash = hash_password(password).unwrap();
assert!(verify_password(password, &hash).unwrap());
assert!(!verify_password("wrongpassword", &hash).unwrap());
}
}