fistinc-auth 0.1.0

Paging types for Fist Inc bank
Documentation
use argon2rs::argon2i_simple;
use async_trait::async_trait;
use chrono::{Duration, Utc};
use fistinc_errors::{CommonError, ServiceResult};
use jsonwebtoken;

use crate::domain::entity::Token;
use crate::domain::entity::User;
use crate::domain::services::UserSecurityService;

pub struct UserSecurityServiceImpl {
    pub salt: String,
    pub jwt_key: String,
    pub expire_duration: Duration,
}

impl UserSecurityServiceImpl {
    pub fn new(salt: &str, jwt_key: &str, expire_duration: Duration) -> Self {
        UserSecurityServiceImpl {
            salt: salt.to_string(),
            jwt_key: jwt_key.to_string(),
            expire_duration,
        }
    }
}

#[async_trait]
impl UserSecurityService for UserSecurityServiceImpl {
    async fn hash(&self, input: &str) -> ServiceResult<String> {
        let result = argon2i_simple(&input, &self.salt)
            .iter()
            .map(|b| format!("{:02x}", b))
            .collect();
        Ok(result)
    }

    async fn verify_hash(&self, hashed: &str, raw: &str) -> ServiceResult<bool> {
        let hashed_curr = self.hash(raw).await?;
        Ok(hashed_curr == hashed)
    }

    async fn token_generator(&self, user: &User) -> ServiceResult<String> {
        let claim = Token {
            email: user.email.clone(),
            role: user.role,
            expire: Utc::now() + self.expire_duration,
        };
        let encoding_key = jsonwebtoken::EncodingKey::from_secret(self.jwt_key.as_ref());
        let token = jsonwebtoken::encode(
            &jsonwebtoken::Header::default(),
            &claim,
            &encoding_key,
        )
            .map_err(|e| CommonError {
                message: e.to_string(),
                code: 500,
            })?;
        Ok(token)
    }

    async fn decode_token(&self, token: &str) -> ServiceResult<Token> {
        let decoding_key = jsonwebtoken::DecodingKey::from_secret(self.jwt_key.as_ref());
        jsonwebtoken::decode::<Token>(
            token,
            &decoding_key,
            &jsonwebtoken::Validation::default(),
        )
            .map(|data| data.claims)
            .map_err(|e| CommonError {
                message: e.to_string(),
                code: 403,
            })
    }
}