Implement password authentication
This commit is contained in:
@ -1,7 +1,8 @@
|
||||
use crate::constants::StaticConstraints;
|
||||
use crate::controllers::HttpResult;
|
||||
use crate::models::{User, UserID};
|
||||
use crate::services::rate_limiter_service::RatedAction;
|
||||
use crate::services::{rate_limiter_service, users_service};
|
||||
use crate::services::{login_token_service, rate_limiter_service, users_service};
|
||||
use actix_remote_ip::RemoteIP;
|
||||
use actix_web::{web, HttpResponse};
|
||||
|
||||
@ -173,3 +174,56 @@ pub async fn reset_password(remote_ip: RemoteIP, req: web::Json<ResetPasswordBod
|
||||
|
||||
Ok(HttpResponse::Accepted().finish())
|
||||
}
|
||||
|
||||
#[derive(serde::Deserialize)]
|
||||
pub struct PasswordLoginQuery {
|
||||
mail: String,
|
||||
password: String,
|
||||
}
|
||||
|
||||
/// Handle login with password
|
||||
pub async fn password_login(remote_ip: RemoteIP, req: web::Json<PasswordLoginQuery>) -> HttpResult {
|
||||
// Rate limiting
|
||||
if rate_limiter_service::should_block_action(remote_ip.0, RatedAction::FailedPasswordLogin)
|
||||
.await?
|
||||
{
|
||||
return Ok(HttpResponse::TooManyRequests().finish());
|
||||
}
|
||||
|
||||
// Get user account
|
||||
let user = match users_service::get_by_mail(&req.mail).await {
|
||||
Ok(u) => u,
|
||||
Err(e) => {
|
||||
log::error!("Auth failed: could not find account by mail! {}", e);
|
||||
rate_limiter_service::record_action(remote_ip.0, RatedAction::FailedPasswordLogin)
|
||||
.await?;
|
||||
return Ok(HttpResponse::Unauthorized().json("Identifiants incorrects"));
|
||||
}
|
||||
};
|
||||
|
||||
if !user.check_password(&req.password) {
|
||||
log::error!("Auth failed: invalid password for mail {}", user.email);
|
||||
rate_limiter_service::record_action(remote_ip.0, RatedAction::FailedPasswordLogin).await?;
|
||||
return Ok(HttpResponse::Unauthorized().json("Identifiants incorrects"));
|
||||
}
|
||||
|
||||
finish_login(&user).await
|
||||
}
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
struct LoginResponse {
|
||||
user_id: UserID,
|
||||
token: String,
|
||||
}
|
||||
|
||||
async fn finish_login(user: &User) -> HttpResult {
|
||||
if !user.active {
|
||||
log::error!("Auth failed: account for mail {} is disabled!", user.email);
|
||||
return Ok(HttpResponse::ExpectationFailed().json("Ce compte est désactivé !"));
|
||||
}
|
||||
|
||||
Ok(HttpResponse::Ok().json(LoginResponse {
|
||||
user_id: user.id(),
|
||||
token: login_token_service::gen_new_token(user).await?,
|
||||
}))
|
||||
}
|
||||
|
Reference in New Issue
Block a user