jwtvault 0.7.0

Highly flexible library to manage and orchestrate JWT workflow
Documentation
use std::ops::Deref;

use crate::prelude::*;

pub struct ArgonPasswordHasher {
    secret_key: String
}

impl Deref for ArgonPasswordHasher {
    type Target = str;
    fn deref(&self) -> &Self::Target {
        self.secret_key.as_str()
    }
}

impl ArgonPasswordHasher {
    pub fn new<T: AsRef<str>>(secret_key: T) -> Self {
        let secret_key = secret_key.as_ref().to_string();
        Self { secret_key }
    }
}

impl Default for ArgonPasswordHasher {
    fn default() -> Self {
        let manager = CertificateManger::default();
        let secret_key = manager.password_hashing_secret();
        ArgonPasswordHasher::from(secret_key)
    }
}

impl<'a> PasswordHasher<ArgonHasher<'a>> for ArgonPasswordHasher {
    fn hash_user_password<T: AsRef<str>>(&self, user: T, password: T) -> Result<String, Error> {
        let secret_key = self.secret_key.as_str();
        let result = hash_password_with_argon(password.as_ref(), secret_key.as_ref()).map_err(|e| {
            let msg = format!("Login failed for user: {}", user.as_ref());
            let reason = e.to_string();
            LoginFailed::PasswordHashingFailed(msg, reason).into()
        });
        result
    }
    fn verify_user_password<T: AsRef<str>>(&self, user: T, password: T, hash: T) -> Result<bool, Error> {
        let secret_key = self.secret_key.as_str();
        let result = verify_user_password_with_argon(
            password.as_ref(), secret_key.as_ref(), hash.as_ref(),
        ).map_err(|e| {
            let reason = e.to_string();
            let msg = format!("Login verification for user: {} Reason: {}", user.as_ref(), reason);
            let reason = e.to_string();
            LoginFailed::PasswordVerificationFailed(msg, reason).into()
        });
        result
    }
}

impl From<PrivateKey> for ArgonPasswordHasher {
    fn from(secret_key: PrivateKey) -> Self {
        ArgonPasswordHasher::new(secret_key.as_str())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn validate_argon_password_hasher_for_empty_password() {
        let manager = CertificateManger::default();
        let secret = manager.password_hashing_secret();
        let hasher = ArgonPasswordHasher::new(&secret.as_str());
        let result = hasher.hash_user_password("ghost", "");
        assert!(result.is_err());
    }

    #[test]
    fn validate_argon_password_hasher_for_invalid_hash() {
        let manager = CertificateManger::default();
        let secret = manager.password_hashing_secret();
        let hasher = ArgonPasswordHasher::new(&secret.as_str());
        let result = hasher.verify_user_password("user", "clean", "");
        assert!(result.is_err())
    }
}