Skip to content

Commit

Permalink
Wrap database actions inside spawn_blocking for signup
Browse files Browse the repository at this point in the history
  • Loading branch information
danielalvsaaker committed Aug 19, 2022
1 parent 6fe7624 commit 1e9ce29
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 28 deletions.
6 changes: 6 additions & 0 deletions crates/tf-auth/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 3 additions & 1 deletion crates/tf-auth/src/routes/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -47,7 +49,7 @@ impl<'a> Callback<'a> {
}
}

#[derive(Deserialize)]
#[derive(Deserialize, Clone)]
pub struct UserForm {
pub username: String,
pub password: String,
Expand Down
7 changes: 3 additions & 4 deletions crates/tf-auth/src/routes/oauth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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::<User>()?.traverse::<Authorization>()?;

let authorization = collection.get(&query)?;
let scope = solicitation.pre_grant().scope.clone();

if authorization.is_none()
|| authorization
Expand Down
50 changes: 28 additions & 22 deletions crates/tf-auth/src/routes/signin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::{
resource::user::{User, Username},
Database,
},
error::Error,
error::Result,
templates::SignIn,
};
Expand All @@ -25,7 +26,7 @@ pub fn routes() -> Router {
async fn get_signin(query: Option<Query<Callback<'_>>>) -> 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()
}
Expand All @@ -38,29 +39,34 @@ async fn post_signin(
) -> Result<impl IntoResponse> {
let query = query.as_ref().map(|x| x.as_str());

let hash = db
.root::<Username>()?
.traverse::<User>()?
.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::<Username>()?.traverse::<User>()?;

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::<Username>()?
.traverse::<User>()?
.key(&user.username)?
.unwrap();
session.insert("id", user_id).unwrap();
} else {
session.insert("user", user).unwrap();
Ok(())
})
.is_ok(),
)
}
})
.await??;

if !authorized {
return Ok((
StatusCode::UNAUTHORIZED,
SignIn {
Expand Down
2 changes: 1 addition & 1 deletion crates/tf-models/src/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 1e9ce29

Please sign in to comment.