#[cfg(feature = "discord")] pub mod discord; mod error; use api_core::auth::AuthClientConfig; use api_core::models::user::User; pub use error::AuthClientError; use oauth2::{EndpointNotSet, EndpointSet}; type C = oauth2::basic::BasicClient< EndpointSet, EndpointNotSet, EndpointNotSet, EndpointNotSet, EndpointSet, >; #[derive(Clone, Debug)] pub struct BasicClient(C); #[async_trait::async_trait] pub trait OauthDriver: Send + Sync { async fn get_auth_token(&self) -> Result; async fn get_user(&self) -> Result; async fn create_oauth_session(&self) -> Result; async fn save_session(&self, user: &User) -> Result<(), AuthError>; } use oauth2::{AuthUrl, ClientId, ClientSecret, RedirectUrl, TokenUrl}; use std::{convert::TryFrom, ops::Deref}; use crate::error::AuthError; static CSRF_TOKEN: &str = "csrf_token"; impl Deref for BasicClient { type Target = C; fn deref(&self) -> &Self::Target { &self.0 } } impl TryFrom for BasicClient { type Error = AuthClientError; fn try_from(value: AuthClientConfig) -> Result { let auth_url = AuthUrl::new(value.auth_url).map_err(AuthClientError::InvalidAuthUrl)?; let token_url = TokenUrl::new(value.token_uri).map_err(AuthClientError::InvalidTokenUrl)?; let redirect_url = RedirectUrl::new(value.redirect_uri).map_err(AuthClientError::InvalidRedirectUrl)?; Ok(Self( oauth2::basic::BasicClient::new(ClientId::new(value.client_id)) .set_client_secret(ClientSecret::new(value.client_secret)) .set_auth_uri(auth_url) .set_token_uri(token_url) .set_redirect_uri(redirect_url), )) } }