use crate::algorithms::PasswordHasherImpl;
use crate::errors::PasswordError;
use argon2::{
Argon2, Params, PasswordHasher as _, PasswordVerifier as _,
password_hash::{SaltString, PasswordHash as PH},
};
use rand::rngs::OsRng;
pub struct Argon2Impl {
pub params: Params,
}
impl Default for Argon2Impl {
fn default() -> Self {
Self { params: Params::default() }
}
}
impl PasswordHasherImpl for Argon2Impl {
fn hash_password(&self, password: &str) -> Result<String, PasswordError> {
let argon2 = Argon2::default();
let salt = SaltString::generate(&mut OsRng);
match argon2.hash_password(password.as_bytes(), &salt) {
Ok(pw_hash) => Ok(pw_hash.to_string()),
Err(e) => Err(PasswordError::HashError(e.to_string())),
}
}
fn verify_password(&self, password: &str, hashed: &str) -> Result<bool, PasswordError> {
let parsed = match PH::new(hashed) {
Ok(p) => p,
Err(e) => return Err(PasswordError::VerifyError(e.to_string())),
};
let argon2 = Argon2::default();
match argon2.verify_password(password.as_bytes(), &parsed) {
Ok(()) => Ok(true),
Err(argon2::password_hash::Error::Password) => Ok(false),
Err(e) => Err(PasswordError::VerifyError(e.to_string())),
}
}
}