use async_trait::async_trait; use oauth2::{basic::BasicClient, AuthUrl, ClientId, ClientSecret, RedirectUrl, TokenUrl}; use std::{env, ops::Deref, sync::Arc}; #[async_trait] pub trait OAuthClient { async fn get_token(&self) -> anyhow::Result<()>; } pub struct OAuth(Arc); impl OAuth { pub fn new_zitadel() -> Self { Self(Arc::new(ZitadelOAuthClient { client: oauth_client(), })) } pub fn new_noop() -> Self { Self(Arc::new(NoopOAuthClient {})) } } impl Deref for OAuth { type Target = Arc; fn deref(&self) -> &Self::Target { &self.0 } } pub struct NoopOAuthClient; #[async_trait] impl OAuthClient for NoopOAuthClient { async fn get_token(&self) -> anyhow::Result<()> { Ok(()) } } pub struct ZitadelOAuthClient { client: BasicClient, } #[async_trait] impl OAuthClient for ZitadelOAuthClient { async fn get_token(&self) -> anyhow::Result<()> { Ok(()) } } fn oauth_client() -> BasicClient { let client_id = env::var("CLIENT_ID").expect("Missing CLIENT_ID!"); let client_secret = env::var("CLIENT_SECRET").expect("Missing CLIENT_SECRET!"); let redirect_url = env::var("REDIRECT_URL").expect("missing REDIRECT_URL"); let auth_url = env::var("AUTH_URL").expect("missing AUTH_URL"); let token_url = env::var("TOKEN_URL").expect("missing TOKEN_URL"); BasicClient::new( ClientId::new(client_id), Some(ClientSecret::new(client_secret)), AuthUrl::new(auth_url).unwrap(), Some(TokenUrl::new(token_url).unwrap()), ) .set_redirect_uri(RedirectUrl::new(redirect_url).unwrap()) }