refactor(backend): replace unwraps with typed errors

This commit is contained in:
2026-06-13 12:38:44 +03:00
parent 21d65af470
commit 2616896ecb
6 changed files with 181 additions and 201 deletions

View File

@@ -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
}