net-token-verifier 0.3.0

This crate defines core traits and structures for fusion auth token verifications in the net-stalker project.
Documentation
use serde::Serialize;
use serde::Deserialize;

use crate::core::verifier::token::Token;
use crate::core::verifier::token::TokenError;

// TODO: need to add JWT builder with option fields so we can construct JWT with only required fields

#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct JwtData {
    exp: Option<i64>,
    iat: Option<i64>,
    iss: Option<String>,
    jti: Option<String>,
    sub: Option<String>,
    auth_time: Option<i64>,
    #[serde(rename = "authenticationType")]
    authentication_type: Option<String>,
    email: Option<String>,
    email_verified: Option<bool>,
    preferred_username: Option<String>,
    tid: Option<String>,
}

#[derive(Default)]
pub struct JwtBuilder {
    jwt: JwtData,
}

impl JwtBuilder {
    pub fn with_iat(mut self, iat: i64) -> Self {
        self.jwt.iat = Some(iat);
        self
    }

    pub fn with_iss(mut self, iss: String) -> Self {
        self.jwt.iss = Some(iss);
        self
    }

    pub fn with_jti(mut self, jti: String) -> Self {
        self.jwt.jti = Some(jti);
        self
    }

    pub fn with_sub(mut self, sub: String) -> Self {
        self.jwt.sub = Some(sub);
        self
    }

    pub fn with_auth_time(mut self, auth_time: i64) -> Self {
        self.jwt.auth_time = Some(auth_time);
        self
    }

    pub fn with_authentication_type(mut self, authentication_type: String) -> Self {
        self.jwt.authentication_type = Some(authentication_type);
        self
    }

    pub fn with_email(mut self, email: String) -> Self {
        self.jwt.email = Some(email);
        self
    }

    pub fn with_email_verified(mut self, email_verified: bool) -> Self {
        self.jwt.email_verified = Some(email_verified);
        self
    }

    pub fn with_preferred_username(mut self, preferred_username: String) -> Self {
        self.jwt.preferred_username = Some(preferred_username);
        self
    }

    pub fn with_tenant_id(mut self, tid: String) -> Self {
        self.jwt.tid = Some(tid);
        self
    }

    pub fn build(self) -> Jwt {
        Jwt { jwt: self.jwt }
    }
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Jwt {
    jwt: JwtData,
}

impl Token for Jwt {
    fn get_tenant_id(&self) -> Result<&str, TokenError> {
        match self.get_tid() {
            Some(tid) => Ok(tid),
            None => Err(TokenError::MissingTenantId),
        }
    }
}

impl Jwt {
    pub fn get_exp(&self) -> Option<i64> {
        self.jwt.exp
    }

    pub fn get_iat(&self) -> Option<i64> {
        self.jwt.iat
    }

    pub fn get_iss(&self) -> Option<&str> {
        self.jwt.iss.as_deref()
    }

    pub fn get_jti(&self) -> Option<&str> {
        self.jwt.jti.as_deref()
    }

    pub fn get_sub(&self) -> Option<&str> {
        self.jwt.sub.as_deref()
    }

    pub fn get_auth_time(&self) -> Option<i64> {
        self.jwt.auth_time
    }

    pub fn get_authentication_type(&self) -> Option<&str> {
        self.jwt.authentication_type.as_deref()
    }

    pub fn get_email(&self) -> Option<&str> {
        self.jwt.email.as_deref()
    }

    pub fn is_email_verified(&self) -> Option<bool> {
        self.jwt.email_verified
    }

    pub fn get_preferred_username(&self) -> Option<&str> {
        self.jwt.preferred_username.as_deref()
    }

    fn get_tid(&self) -> Option<&str> {
        self.jwt.tid.as_deref()
    }
}


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

    #[test]
    fn test_jwt_builder() {
        let jwt = JwtBuilder::default()
            .with_jti("1234567890".to_string())
            .with_sub("user123".to_string())
            .with_auth_time(1629876543)
            .with_authentication_type("password".to_string())
            .with_email("user@example.com".to_string())
            .with_email_verified(true)
            .with_preferred_username("user123".to_string())
            .with_tenant_id("tenant123".to_string())
            .build();

        assert_eq!(jwt.get_jti(), Some("1234567890"));
        assert_eq!(jwt.get_sub(), Some("user123"));
        assert_eq!(jwt.get_auth_time(), Some(1629876543));
        assert_eq!(jwt.get_authentication_type(), Some("password"));
        assert_eq!(jwt.get_email(), Some("user@example.com"));
        assert_eq!(jwt.is_email_verified(), Some(true));
        assert_eq!(jwt.get_preferred_username(), Some("user123"));
        assert_eq!(jwt.get_tid(), Some("tenant123"));
    }
}