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 std::error::Error;

use super::jwt_token::Jwt;

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

pub struct FusionAuthVerifier {
    verificiation_service_url: String,
    api_key: Option<String>,
}

impl FusionAuthVerifier {
    pub fn new(verification_service_url: &str, api_key: Option<String>) -> Self {
        Self { 
            verificiation_service_url: verification_service_url.to_string(),
            api_key,
        }
    }

    pub fn get_verification_service_url(&self) -> &str {
        &self.verificiation_service_url
    }

    pub fn get_api_key(&self) -> Option<&str> {
        self.api_key.as_deref()
    }
}

#[async_trait::async_trait]
impl Verifier for FusionAuthVerifier {
    async fn verify_token(&self, token: &str) -> Result<Box<dyn Token>, Box<dyn Error + Send + Sync>> {
        let request = format!("{}/api/jwt/validate", self.verificiation_service_url);
        let resp = reqwest::Client::new()
            .get(request)
            .bearer_auth(token)
            .send()
            .await;

        let resp = match resp {
            Ok(r) => r,
            Err(err) => return Err(Box::new(err)),
        };

        let resp_json = match resp.status() {
            reqwest::StatusCode::OK => resp.json::<Jwt>().await,
            _ => return Err("Invalid token".into()),
        };

        match resp_json {
            Ok(jwt) => Ok(Box::new(jwt)),
            Err(err) => Err(Box::new(err)),
        }
    }
}

// To run this test locally you need to get a valid token from FusionAuth and replace the token in the test
// TODO: automate this test
// #[cfg(test)]
// mod tests {
//     use super::*;
//     #[tokio::test]
//     async fn test_verify_token_valid_token() {
//         let token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImFkZWQwYTdhMCJ9.eyJleHAiOjE3MDkxMjg4ODYsImlhdCI6MTcwOTEyNTI4NiwiaXNzIjoiYWNtZS5jb20iLCJzdWIiOiI2Nzg2ZTU0Mi0zODM3LTRiYmUtYmNjZC00NGQ4ZWYyYTNiYzkiLCJqdGkiOiJmYmY0ZGY2Ny1jOWI3LTQ4OTktYWZlZi1lMWJhYTE2ZGYzZTQiLCJhdXRoZW50aWNhdGlvblR5cGUiOiJQQVNTV09SRCIsImVtYWlsIjoic29tZTJAdGVzdC5pbyIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJzb21lMkB0ZXN0LmlvIiwiYXV0aF90aW1lIjoxNzA5MTI1Mjg2LCJ0aWQiOiI2ZTQ3NWUyZi1mNTNhLTQ5OTEtOGRhMy1kY2Q1NTVjNWNmNGUifQ.Tf5ibEhLN9NJewXFl4s4_rv9P9fUANPkXGbgepWN5cM";
//         let verifier = FusionAuthVerifier::new("http://127.0.0.1:9011", Some("api_key".to_string()));

//         let result = verifier.verify_token(token).await;

//         assert!(result.is_ok());

//         assert_eq!(result.unwrap().get_tenant_id(), "6e475e2f-f53a-4991-8da3-dcd555c5cf4e");
//     }
// }