diff --git a/crates/tf-auth/src/error.rs b/crates/tf-auth/src/error.rs index 2d381e5..8fc0859 100644 --- a/crates/tf-auth/src/error.rs +++ b/crates/tf-auth/src/error.rs @@ -32,6 +32,12 @@ pub enum Error { #[from] source: oxide_auth_axum::WebError, }, + + #[error("{source}")] + JoinError { + #[from] + source: tokio::task::JoinError, + }, } impl IntoResponse for Error { diff --git a/crates/tf-auth/src/routes/mod.rs b/crates/tf-auth/src/routes/mod.rs index 541902a..0d8c72b 100644 --- a/crates/tf-auth/src/routes/mod.rs +++ b/crates/tf-auth/src/routes/mod.rs @@ -8,6 +8,8 @@ pub fn routes() -> Router { let session_layer = { let store = axum_sessions::async_session::MemoryStore::new(); axum_sessions::SessionLayer::new(store, nanoid::nanoid!(128).as_bytes()) + // TODO: Set based on config + .with_secure(false) }; Router::new() @@ -47,7 +49,7 @@ impl<'a> Callback<'a> { } } -#[derive(Deserialize)] +#[derive(Deserialize, Clone)] pub struct UserForm { pub username: String, pub password: String, diff --git a/crates/tf-auth/src/routes/oauth.rs b/crates/tf-auth/src/routes/oauth.rs index c78242f..e85ba10 100644 --- a/crates/tf-auth/src/routes/oauth.rs +++ b/crates/tf-auth/src/routes/oauth.rs @@ -16,7 +16,7 @@ use axum::{ }; use axum_sessions::extractors::ReadableSession; use oxide_auth::{ - endpoint::{OwnerConsent, QueryParameter, Solicitation}, + endpoint::{OwnerConsent, QueryParameter, Solicitation, PreGrant}, frontends::simple::endpoint::FnSolicitor, }; use oxide_auth_axum::{OAuthRequest, OAuthResponse, WebError}; @@ -80,18 +80,17 @@ async fn post_authorize( if let Consent::Allow = consent { tokio::task::spawn_blocking({ let db = db.clone(); - let solicitation = solicitation.into_owned(); + let PreGrant { client_id, scope, .. } = solicitation.pre_grant().clone(); move || { let query = AuthorizationQuery { user, - client: solicitation.pre_grant().client_id.parse()?, + client: client_id.parse()?, }; let collection = db.root::()?.traverse::()?; let authorization = collection.get(&query)?; - let scope = solicitation.pre_grant().scope.clone(); if authorization.is_none() || authorization diff --git a/crates/tf-auth/src/routes/signin.rs b/crates/tf-auth/src/routes/signin.rs index cf238b7..0394234 100644 --- a/crates/tf-auth/src/routes/signin.rs +++ b/crates/tf-auth/src/routes/signin.rs @@ -4,6 +4,7 @@ use crate::{ resource::user::{User, Username}, Database, }, + error::Error, error::Result, templates::SignIn, }; @@ -25,7 +26,7 @@ pub fn routes() -> Router { async fn get_signin(query: Option>>) -> impl IntoResponse { let query = &query .as_ref() - .map(|Query(x)| serde_urlencoded::to_string(x).unwrap()) + .and_then(|Query(x)| serde_urlencoded::to_string(x).ok()) .unwrap_or_default(); SignIn { query }.into_response() } @@ -38,29 +39,33 @@ async fn post_signin( ) -> Result { let query = query.as_ref().map(|x| x.as_str()); - let hash = db - .root::()? - .traverse::()? - .get(&user.username)? - .map(|x| x.password) - .unwrap_or_default(); + let authorized = tokio::task::spawn_blocking({ + let db = db.clone(); + let user = user.clone(); + move || { + let collection = db.root::()?.traverse::()?; - let authorized = PasswordHash::new(&hash) - .map(|x| { - Argon2::default() - .verify_password(user.password.as_bytes(), &x) - .is_ok() - }) - .unwrap_or_default(); + Ok::<_, Error>( + collection + .get(&user.username)? + .ok_or(argon2::password_hash::Error::Password) + .map_err(Error::from) + .and_then(|User { password, .. }| { + let hash = PasswordHash::new(&password)?; + Ok(Argon2::default().verify_password(&user.password.as_bytes(), &hash)?) + }) + .and_then(|_| { + let user = collection.key(&user.username)?.ok_or(Error::NotFound)?; - if authorized { - let user_id = db - .root::()? - .traverse::()? - .key(&user.username)? - .unwrap(); - session.insert("id", user_id).unwrap(); - } else { + Ok(session.insert("user", user).unwrap()) + }) + .is_ok(), + ) + } + }) + .await??; + + if !authorized { return Ok(( StatusCode::UNAUTHORIZED, SignIn { diff --git a/crates/tf-models/src/query.rs b/crates/tf-models/src/query.rs index 5accd15..5fbaee3 100644 --- a/crates/tf-models/src/query.rs +++ b/crates/tf-models/src/query.rs @@ -8,7 +8,7 @@ pub struct ActivityQuery { pub id: ActivityId, } -#[derive(Clone, Serialize, Deserialize)] +#[derive(Clone, Copy, Serialize, Deserialize)] pub struct ClientQuery { pub user_id: UserId, pub id: ClientId,