framework_cqrs_lib/cqrs/infra/token/services/
jwt_rsa.rs1use std::fmt::Debug;
2use std::sync::Arc;
3
4use async_trait::async_trait;
5use jsonwebtoken::{Algorithm, decode, decode_header, DecodingKey, Validation};
6use reqwest::Client;
7use serde::{Deserialize, Serialize};
8use serde::de::DeserializeOwned;
9
10use crate::cqrs::infra::cache::CacheAsync;
11use crate::cqrs::core::token::TokenService;
12use crate::cqrs::models::errors::{Error, ResultErr};
13
14pub struct JwtRSATokenService {
15 pub cache: Arc<CacheAsync>,
16 pub http_client: Arc<Client>,
17 pub auth_back_url: String,
18}
19
20impl JwtRSATokenService {
21 pub fn new(cache: Arc<CacheAsync>, http_client: Arc<Client>, auth_back_url: String) -> Self {
22 Self {
23 cache,
24 http_client,
25 auth_back_url,
26 }
27 }
28}
29
30#[async_trait]
31impl TokenService for JwtRSATokenService {
32 async fn decode<CLAIMS: Debug + Serialize + DeserializeOwned>(&self, token: &str) -> ResultErr<CLAIMS> {
33 let header = decode_header(token).map_err(|err| {
34 let message = err.to_string();
35 Error::Simple(format!("decode header token : {message}"))
36 })?;
37
38 let kid = header.kid.ok_or(Error::Simple("jwt invalid, pas de kid dans l'entete".to_string()))?;
39 let maybe_data = self.cache.get(&kid).await;
40
41 let jwk = match maybe_data {
42 Some(data) => {
43 let jwk = serde_json::from_str::<JWK>(data.as_str())
44 .map_err(|err| Error::Simple(err.to_string()))?;
45 Ok(jwk)
46 }
47 None => {
48 let url = format!("{}/v1/jwks/{kid}/public", self.auth_back_url);
49 let response = self.http_client
50 .get(url)
51 .send()
52 .await.map_err(|err| Error::Simple(err.to_string()))?;
53 if response.status() == 200 {
54 let jwk = response.json::<JWK>().await.map_err(|err| Error::Simple(err.to_string()))?;
55 let stringify = serde_json::to_string(&jwk)
56 .map_err(|err| Error::Simple(err.to_string()))?;
57 self.cache.upsert(kid, stringify).await;
58 Ok(jwk)
59 } else {
60 Err(Error::Simple("erreur lors du call authbacku".to_string()))
61 }
62 }
63 }?;
64
65 let decoding_key = DecodingKey::from_rsa_components(
66 jwk.n.as_str(),
67 jwk.e.as_str(),
68 ).map_err(|err| Error::Simple({
69 let error_message = err.to_string();
70 format!("decoding key : {error_message}")
71 }))?;
72
73
74 decode::<CLAIMS>(token, &decoding_key, &Validation::new(Algorithm::RS256))
75 .map(|token_data| token_data.claims)
76 .map_err(|err| {
77 let message = err.to_string();
78 Error::Simple(format!("decode token : {message}"))
79 })
80 }
81}
82
83#[derive(Serialize, Deserialize, Clone, Debug)]
84pub struct JWK {
85 n: String,
86 e: String,
87}