aboutsummaryrefslogtreecommitdiffstats
path: root/src/server/driver
diff options
context:
space:
mode:
Diffstat (limited to 'src/server/driver')
-rw-r--r--src/server/driver/auth.rs39
-rw-r--r--src/server/driver/mod.rs50
2 files changed, 88 insertions, 1 deletions
diff --git a/src/server/driver/auth.rs b/src/server/driver/auth.rs
index 9215372..28e9285 100644
--- a/src/server/driver/auth.rs
+++ b/src/server/driver/auth.rs
@@ -1,8 +1,17 @@
+use anyhow::Result;
+use async_session::{Session, SessionStore};
+use async_trait::async_trait;
use bon::Builder;
use oauth2::{AuthUrl, ClientId, ClientSecret, EndpointNotSet, EndpointSet, RedirectUrl, TokenUrl};
use secrecy::{ExposeSecret, SecretString};
+use tracing::{instrument, trace};
-#[derive(Builder)]
+use crate::server::driver::Services;
+
+pub(super) static COOKIE_NAME: &str = "SESSION";
+pub(super) static CSRF_TOKEN: &str = "csrf_token";
+
+#[derive(Builder, Debug)]
pub struct ClientOptions {
client_id: String,
client_secret: SecretString,
@@ -20,6 +29,7 @@ pub type OauthClient = oauth2::basic::BasicClient<
>;
pub fn oauth_client(opts: &ClientOptions) -> anyhow::Result<OauthClient> {
+ dbg!(&opts);
let redirect_url = RedirectUrl::new(opts.redirect_url.to_owned())?;
let client_id = ClientId::new(opts.client_id.to_owned());
let auth_url = AuthUrl::new(opts.auth_url.to_owned())?;
@@ -32,3 +42,30 @@ pub fn oauth_client(opts: &ClientOptions) -> anyhow::Result<OauthClient> {
.set_token_uri(token_url)
.set_redirect_uri(redirect_url))
}
+
+#[async_trait]
+impl SessionStore for Services {
+ #[instrument(skip(self))]
+ async fn load_session(&self, cookie_value: String) -> Result<Option<Session>> {
+ let id = Session::id_from_cookie_value(&cookie_value)?;
+ let mut connection = self.database.acquire().await?;
+
+ todo!()
+ }
+
+ #[instrument(skip(self, session), fields(id = session.id()))]
+ async fn store_session(&self, session: Session) -> Result<Option<String>> {
+ let id = session.id();
+ trace!("storing session");
+ let mut connection = self.database.acquire().await?;
+ Ok(session.into_cookie_value())
+ }
+
+ async fn destroy_session(&self, session: Session) -> Result<()> {
+ todo!()
+ }
+
+ async fn clear_store(&self) -> Result<()> {
+ todo!()
+ }
+}
diff --git a/src/server/driver/mod.rs b/src/server/driver/mod.rs
index c006cb0..2debff2 100644
--- a/src/server/driver/mod.rs
+++ b/src/server/driver/mod.rs
@@ -1,11 +1,21 @@
#[cfg(feature = "oauth")]
pub mod auth;
+#[cfg(feature = "oauth")]
+use async_session::Session;
use async_trait::async_trait;
+#[cfg(feature = "oauth")]
+use axum::{
+ http::HeaderMap,
+ response::{IntoResponse, Redirect},
+};
+#[cfg(feature = "oauth")]
+use oauth2::CsrfToken;
use sqlx::PgPool;
use crate::{config::DatabaseOptions, server::state::database};
+#[derive(Debug, Clone)]
pub struct Services {
database: PgPool,
// oauth: OauthClient,
@@ -22,6 +32,13 @@ impl Services {
#[async_trait]
pub trait SellershutDriver: Send + Sync + 'static {
async fn hello(&self);
+
+ #[cfg(feature = "oauth")]
+ async fn create_auth_session(
+ &self,
+ csrf_token: &CsrfToken,
+ auth_url: &url::Url,
+ ) -> anyhow::Result<(HeaderMap, Redirect)>;
}
#[async_trait]
@@ -29,4 +46,37 @@ impl SellershutDriver for Services {
async fn hello(&self) {
todo!()
}
+
+ #[cfg(feature = "oauth")]
+ async fn create_auth_session(
+ &self,
+ csrf_token: &CsrfToken,
+ auth_url: &url::Url,
+ ) -> anyhow::Result<(HeaderMap, Redirect)> {
+ use anyhow::Context;
+ use async_session::SessionStore;
+ use axum::{
+ http::{HeaderMap, header::SET_COOKIE},
+ response::Redirect,
+ };
+
+ use crate::server::driver::auth::{COOKIE_NAME, CSRF_TOKEN};
+
+ let mut session = Session::new();
+ session.insert(CSRF_TOKEN, csrf_token)?;
+
+ let res = self
+ .store_session(session)
+ .await?
+ .context("missing csrf token")?;
+
+ let cookie = format!("{COOKIE_NAME}={res}; SameSite=Lax; HttpOnly; Secure; Path=/");
+ let mut headers = HeaderMap::new();
+ headers.insert(
+ SET_COOKIE,
+ cookie.parse().context("failed to parse cookie")?,
+ );
+
+ Ok((headers, Redirect::to(auth_url.as_str())))
+ }
}