diff --git a/crates/backend/src/controller.rs b/crates/backend/src/controller.rs index 7af3245..d243ed8 100644 --- a/crates/backend/src/controller.rs +++ b/crates/backend/src/controller.rs @@ -1,3 +1,5 @@ +mod auth; mod user; +pub use auth::AuthController; pub use user::UserController; diff --git a/crates/backend/src/controller/auth.rs b/crates/backend/src/controller/auth.rs new file mode 100644 index 0000000..de0e326 --- /dev/null +++ b/crates/backend/src/controller/auth.rs @@ -0,0 +1,44 @@ +use actix_web::{ + error::{ErrorBadRequest, ErrorInternalServerError}, + web, Responder, +}; +use argon2::{Argon2, PasswordHash, PasswordVerifier}; +use sea_orm::{ColumnTrait, EntityTrait, QueryFilter}; +use serde::Deserialize; + +use crate::AppState; + +use super::user::UserWithoutPassword; + +#[derive(Deserialize)] +pub struct LoginRequest { + email: String, + password: String, +} + +pub struct AuthController; + +impl AuthController { + pub async fn login( + state: web::Data, + login: web::Json, + ) -> actix_web::Result { + let db = &state.db; + let login = login.into_inner(); + + let user = entity::user::Entity::find() + .filter(entity::user::Column::Email.eq(login.email)) + .one(db) + .await + .map_err(ErrorInternalServerError)? + .ok_or(ErrorBadRequest("Login Failed"))?; + + let argon2 = Argon2::default(); + let parsed_hash = PasswordHash::new(&user.hash).map_err(ErrorInternalServerError)?; + argon2 + .verify_password(login.password.as_bytes(), &parsed_hash) + .map_err(ErrorBadRequest)?; + + Ok(web::Json(UserWithoutPassword::from(user))) + } +} diff --git a/crates/backend/src/controller/user.rs b/crates/backend/src/controller/user.rs index e38e558..814c778 100644 --- a/crates/backend/src/controller/user.rs +++ b/crates/backend/src/controller/user.rs @@ -3,7 +3,7 @@ use argon2::{ password_hash::{rand_core::OsRng, PasswordHasher, SaltString}, Argon2, }; -use sea_orm::{ActiveModelTrait, ActiveValue, DatabaseConnection, EntityTrait}; +use sea_orm::{ActiveModelTrait, ActiveValue, EntityTrait}; use serde::{Deserialize, Serialize}; use uuid::Uuid; @@ -69,7 +69,6 @@ impl UserController { name: ActiveValue::Set(user.name), email: ActiveValue::Set(user.email), hash: ActiveValue::Set(password_hash.to_string()), - salt: ActiveValue::Set(salt.to_string()), }; let result = user.insert(db).await.map_err(ErrorInternalServerError)?; diff --git a/crates/backend/src/routes.rs b/crates/backend/src/routes.rs index 0a20d5a..e4b7cac 100644 --- a/crates/backend/src/routes.rs +++ b/crates/backend/src/routes.rs @@ -1,4 +1,4 @@ -use crate::controller::UserController; +use crate::controller::{AuthController, UserController}; use actix_web::web; pub fn config(cfg: &mut web::ServiceConfig) { @@ -9,6 +9,7 @@ pub fn config(cfg: &mut web::ServiceConfig) { .get(UserController::list_users) .post(UserController::create_user), ) - .service(web::resource("/users/{user_id}")), + .service(web::resource("/users/{user_id}")) + .service(web::scope("/auth").route("/login", web::post().to(AuthController::login))), ); }