refactor(backend): replace unwraps with typed errors
This commit is contained in:
@@ -6,8 +6,13 @@ use axum::{Json, Router, extract::State, http::StatusCode, routing::post};
|
||||
use rand::RngExt;
|
||||
use serde::Deserialize;
|
||||
use tower_cookies::{Cookie, Cookies};
|
||||
use tracing::warn;
|
||||
|
||||
use crate::{error::LoftError, model::UserRepository, web::AUTH_TOKEN};
|
||||
use crate::{
|
||||
error::{LoftError, Result},
|
||||
model::UserRepository,
|
||||
web::AUTH_TOKEN,
|
||||
};
|
||||
|
||||
pub fn routes_auth(user_repository: UserRepository) -> Router {
|
||||
Router::new()
|
||||
@@ -22,24 +27,26 @@ async fn login(
|
||||
cookies: Cookies,
|
||||
Json(payload): Json<LoginPayload>,
|
||||
) -> Result<StatusCode, LoftError> {
|
||||
let user = user_repository.find_by_username(&payload.username).await?;
|
||||
// TODO: replace unwrap with ?
|
||||
let parsed_hash = PasswordHash::new(&user.password_hash).unwrap();
|
||||
if Argon2::default()
|
||||
.verify_password(payload.password.as_bytes(), &parsed_hash)
|
||||
.is_ok()
|
||||
{
|
||||
let expires_at = chrono::Utc::now() + chrono::Duration::days(1);
|
||||
let cookie = create_cookie();
|
||||
let auth_token = cookie.value();
|
||||
cookies.add(cookie.clone());
|
||||
user_repository
|
||||
.create_session(user.id, auth_token, expires_at)
|
||||
.await?;
|
||||
} else {
|
||||
let user = user_repository
|
||||
.find_by_username(&payload.username)
|
||||
.await?
|
||||
.ok_or(LoftError::LoginFail)?;
|
||||
let parsed_hash = PasswordHash::new(&user.password_hash)?;
|
||||
let password_verification =
|
||||
Argon2::default().verify_password(payload.password.as_bytes(), &parsed_hash);
|
||||
|
||||
if password_verification.is_err() {
|
||||
return Err(LoftError::LoginFail);
|
||||
}
|
||||
|
||||
let expires_at = chrono::Utc::now() + chrono::Duration::days(1);
|
||||
let cookie = create_cookie();
|
||||
let auth_token = cookie.value();
|
||||
cookies.add(cookie.clone());
|
||||
user_repository
|
||||
.create_session(user.id, auth_token, expires_at)
|
||||
.await?;
|
||||
|
||||
Ok(StatusCode::OK)
|
||||
}
|
||||
|
||||
@@ -63,22 +70,24 @@ async fn register(
|
||||
) -> Result<StatusCode, LoftError> {
|
||||
if user_repository
|
||||
.find_by_username(&payload.username)
|
||||
.await
|
||||
.is_ok()
|
||||
.await?
|
||||
.is_some()
|
||||
{
|
||||
warn!(
|
||||
"Register fail, username {} already exists",
|
||||
&payload.username
|
||||
); // also fix "Login fail" typo
|
||||
return Err(LoftError::RegisterFail);
|
||||
}
|
||||
|
||||
let salt = SaltString::generate(&mut OsRng);
|
||||
let argon2 = Argon2::default();
|
||||
// TODO: replace unwrap
|
||||
let password_hash = argon2
|
||||
.hash_password(payload.password.as_bytes(), &salt)
|
||||
.unwrap()
|
||||
let password_hash = &argon2
|
||||
.hash_password(payload.password.as_bytes(), &salt)?
|
||||
.to_string();
|
||||
|
||||
user_repository
|
||||
.create_user(&payload.username, &password_hash)
|
||||
.create_user(&payload.username, password_hash)
|
||||
.await?;
|
||||
|
||||
Ok(StatusCode::CREATED)
|
||||
@@ -135,7 +144,7 @@ mod tests {
|
||||
dotenvy::from_filename(".env.test").ok();
|
||||
let database_url = std::env::var("DATABASE_URL").expect("DATABASE_URL must be set");
|
||||
let pool = PgPool::connect(&database_url).await.unwrap();
|
||||
let user_repository = UserRepository::new(pool).unwrap();
|
||||
let user_repository = UserRepository::new(pool);
|
||||
user_repository
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user