diff options
| author | rtkay123 <dev@kanjala.com> | 2026-02-10 23:38:02 +0200 |
|---|---|---|
| committer | rtkay123 <dev@kanjala.com> | 2026-02-10 23:38:02 +0200 |
| commit | 4f30128feb0715f05c103fec20aa6cba61e60984 (patch) | |
| tree | 8291d4accb1bdf98c9afb0dca9686aa34880c62f /lib | |
| parent | 375da0e07f2b3e88c2f6db0e6f4565b3ad555b95 (diff) | |
| download | sellershut-4f30128feb0715f05c103fec20aa6cba61e60984.tar.bz2 sellershut-4f30128feb0715f05c103fec20aa6cba61e60984.zip | |
feat: db create account
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/auth-service/Cargo.toml | 1 | ||||
| -rw-r--r-- | lib/auth-service/src/client/http.rs | 56 | ||||
| -rw-r--r-- | lib/auth-service/src/client/mod.rs | 29 | ||||
| -rw-r--r-- | lib/auth-service/src/lib.rs | 3 | ||||
| -rw-r--r-- | lib/auth-service/src/service/mod.rs | 71 |
5 files changed, 148 insertions, 12 deletions
diff --git a/lib/auth-service/Cargo.toml b/lib/auth-service/Cargo.toml index c3b9be7..2cea550 100644 --- a/lib/auth-service/Cargo.toml +++ b/lib/auth-service/Cargo.toml @@ -10,6 +10,7 @@ documentation.workspace = true async-session.workspace = true async-trait.workspace = true oauth2 = "5.0.0" +reqwest = { workspace = true, features = ["rustls"] } secrecy = "0.10.3" serde_json = "1.0.149" shared-svc = { workspace = true, features = ["cache"] } diff --git a/lib/auth-service/src/client/http.rs b/lib/auth-service/src/client/http.rs new file mode 100644 index 0000000..5621fb0 --- /dev/null +++ b/lib/auth-service/src/client/http.rs @@ -0,0 +1,56 @@ +use std::ops::Deref; + +use oauth2::http; + +#[derive(Clone, Debug)] +pub struct HttpAuthClient(reqwest::Client); + +impl From<reqwest::Client> for HttpAuthClient { + fn from(value: reqwest::Client) -> Self { + Self(value) + } +} + +impl Deref for HttpAuthClient { + type Target = reqwest::Client; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl<'c> oauth2::AsyncHttpClient<'c> for HttpAuthClient { + type Error = oauth2::HttpClientError<reqwest::Error>; + + #[cfg(target_arch = "wasm32")] + type Future = Pin<Box<dyn Future<Output = Result<HttpResponse, Self::Error>> + 'c>>; + #[cfg(not(target_arch = "wasm32"))] + type Future = std::pin::Pin< + Box<dyn Future<Output = Result<oauth2::HttpResponse, Self::Error>> + Send + Sync + 'c>, + >; + + fn call(&'c self, request: oauth2::HttpRequest) -> Self::Future { + Box::pin(async move { + let response = self + .0 + .execute(request.try_into().map_err(Box::new)?) + .await + .map_err(Box::new)?; + + let mut builder = http::Response::builder().status(response.status()); + + #[cfg(not(target_arch = "wasm32"))] + { + builder = builder.version(response.version()); + } + + for (name, value) in response.headers().iter() { + builder = builder.header(name, value); + } + + builder + .body(response.bytes().await.map_err(Box::new)?.to_vec()) + .map_err(oauth2::HttpClientError::Http) + }) + } +} diff --git a/lib/auth-service/src/client/mod.rs b/lib/auth-service/src/client/mod.rs index 45260fb..e02672b 100644 --- a/lib/auth-service/src/client/mod.rs +++ b/lib/auth-service/src/client/mod.rs @@ -1,3 +1,6 @@ +pub(crate) mod http; +use std::ops::Deref; + use oauth2::{ AuthUrl, ClientId, ClientSecret, CsrfToken, EndpointNotSet, EndpointSet, RedirectUrl, Scope, TokenUrl, @@ -8,16 +11,24 @@ use url::Url; use crate::{AuthServiceError, Provider}; +type Inner = oauth2::basic::BasicClient< + EndpointSet, + EndpointNotSet, + EndpointNotSet, + EndpointNotSet, + EndpointSet, +>; + #[derive(Debug, Clone)] -pub struct OauthClient( - oauth2::basic::BasicClient< - EndpointSet, - EndpointNotSet, - EndpointNotSet, - EndpointNotSet, - EndpointSet, - >, -); +pub struct OauthClient(Inner); + +impl Deref for OauthClient { + type Target = Inner; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} #[derive(Debug)] pub struct ClientConfig { diff --git a/lib/auth-service/src/lib.rs b/lib/auth-service/src/lib.rs index 0965f86..61ff230 100644 --- a/lib/auth-service/src/lib.rs +++ b/lib/auth-service/src/lib.rs @@ -1,9 +1,12 @@ +pub use oauth2; pub mod client; mod service; +pub use client::http::HttpAuthClient; pub use service::*; use thiserror::Error; +#[derive(Debug)] pub enum Provider { Discord, } diff --git a/lib/auth-service/src/service/mod.rs b/lib/auth-service/src/service/mod.rs index 5150221..80b29de 100644 --- a/lib/auth-service/src/service/mod.rs +++ b/lib/auth-service/src/service/mod.rs @@ -1,15 +1,71 @@ use async_session::{Result, Session, SessionStore}; use async_trait::async_trait; use shared_svc::cache::{CacheKey, RedisManager, redis::AsyncCommands}; -use sqlx::PgPool; +use sqlx::{PgPool, Postgres, Transaction}; use tracing::{debug, instrument}; +use crate::Provider; + +#[async_trait] +pub trait AccountMgr { + async fn get_apid_by_email(&self, email: &str) -> Result<Option<String>>; + async fn create_account(&self, provider: Provider, provider_user_id: &str, ap_id: &str); + async fn create_account_step( + &self, + provider: Provider, + provider_user_id: &str, + ap_id: &str, + email: &str, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result; + async fn persist_session(&self); +} + #[derive(Debug, Clone)] pub struct AuthService { cache: RedisManager, database: PgPool, } +#[async_trait] +impl AccountMgr for AuthService { + #[instrument(skip(self))] + async fn get_apid_by_email(&self, email: &str) -> Result<Option<String>> { + todo!() + } + + #[instrument(skip(self))] + async fn create_account(&self, provider: Provider, provider_user_id: &str, ap_id: &str) { + todo!() + } + #[instrument(skip(self, transaction))] + async fn create_account_step( + &self, + provider: Provider, + provider_user_id: &str, + ap_id: &str, + email: &str, + transaction: &mut Transaction<'_, Postgres>, + ) -> Result { + sqlx::query!( + "insert into account + (provider_id, provider_user_id, email, ap_id) + values ($1, $2, $3, $4) + ", + "", + provider_user_id, + "", + ap_id + ) + .execute(&mut **transaction) + .await?; + todo!() + } + + #[instrument(skip(self))] + async fn persist_session(&self) {} +} + impl AuthService { pub fn new(cache: &RedisManager, database: &PgPool) -> Self { Self { @@ -26,9 +82,18 @@ impl SessionStore for AuthService { #[doc = " The input is expected to be the value of an identifying"] #[doc = " cookie. This will then be parsed by the session middleware"] #[doc = " into a session if possible"] - #[instrument(skip(self))] + #[instrument(skip(self, cookie_value))] async fn load_session(&self, cookie_value: String) -> Result<Option<Session>> { - todo!() + debug!("getting session"); + let id = Session::id_from_cookie_value(&cookie_value)?; + let mut client = self.cache.get().await?; + let session = client + .get::<_, Option<Vec<u8>>>(CacheKey::Session(&id)) + .await?; + match session { + Some(value) => Ok(Some(serde_json::from_slice(&value)?)), + None => Ok(None), + } } #[doc = " Store a session on the storage backend."] |
