use api_core::models::user::User; use async_session::{Session, serde_json}; use async_trait::async_trait; use oauth2::{CsrfToken, Scope}; use redis::AsyncCommands; use sh_util::cache::{CacheKey, RedisManager}; use sqlx::PgPool; use crate::{BasicClient, CSRF_TOKEN, OauthDriver, SessionResponse, error::AuthError}; #[derive(Clone)] pub struct AuthServiceDiscord { database: PgPool, cache: RedisManager, client: BasicClient, } impl AuthServiceDiscord { pub fn new(database: PgPool, client: BasicClient, cache: RedisManager) -> Self { Self { database, client, cache, } } } #[async_trait] impl OauthDriver for AuthServiceDiscord { async fn get_auth_token(&self) -> Result { todo!() } async fn get_user(&self) -> Result { todo!() } async fn create_oauth_session(&self) -> Result { let (auth_url, csrf_token) = self .client .authorize_url(CsrfToken::new_random) .add_scope(Scope::new("identify".to_string())) .url(); let mut session = Session::new(); session.insert(CSRF_TOKEN, &csrf_token).unwrap(); let cache_key = CacheKey::Session(session.id()); let mut cache = self.cache.get().await.unwrap(); cache .set::<_, _, ()>( cache_key, serde_json::to_string(&session).or(Err(AuthError::InvalidSession))?, ) .await?; let cookie = session .into_cookie_value() .ok_or(AuthError::MissingSession)?; Ok(SessionResponse { cookie_value: cookie, auth_url, }) } async fn save_session(&self, user: &User) -> Result<(), AuthError> { todo!() } }