use super::OAuthUser; use jwks_client_update::{jwt::Jwt, keyset::KeyStore}; pub trait Bearer { fn token(&self) -> &str; } #[cfg(feature = "actix")] pub mod actix_bearer_auth { use actix_web_httpauth::extractors::bearer::BearerAuth; pub struct ActixBearerAuth { bearer: BearerAuth, } impl From for ActixBearerAuth { fn from(value: BearerAuth) -> Self { Self { bearer: value } } } impl Into for ActixBearerAuth { fn into(self) -> BearerAuth { self.bearer } } impl super::Bearer for ActixBearerAuth { fn token(&self) -> &str { self.bearer.token() } } } #[cfg(feature = "actix")] pub use actix_bearer_auth::ActixBearerAuth; pub struct JWT { pub headers: serde_json::Value, pub claims: serde_json::Value, } impl From for JWT { fn from(value: Jwt) -> Self { Self { headers: value.header().into().unwrap(), claims: value.payload().into().unwrap(), } } } impl JWT { pub fn get_expiry_date(&self) -> Option> { let ts = self.claims.get("exp")?.as_i64()?; chrono::DateTime::from_timestamp(ts, 0) } pub fn get_claim(&self, key: &str) -> Option<&serde_json::Value> { self.claims.get(key) } pub fn get_claim_str(&self, key: &str) -> Option<&str> { self.get_claim(key)?.as_str() } pub fn get_user_id(&self) -> Option<&str> { self.get_claim_str("sub") } pub fn get_session_id(&self) -> Option<&str> { self.get_claim_str("sid") } } pub struct JWKS { pub store: KeyStore, } impl From for JWKS { fn from(value: KeyStore) -> Self { Self { store: value } } } impl JWKS { pub async fn new_from(url: String) -> Result { Ok(Self { store: KeyStore::new_from(url).await?, }) } pub fn auth_from_bearer( &self, bearer: T, ) -> Result { self.store .verify(bearer.token()) .map(|v| OAuthUser::from(&JWT::from(v))) } }