admin login handler logic reworked

This commit is contained in:
Mohamad 2024-12-30 14:52:11 +01:00
parent e2abd2ca83
commit 2bf5ae58e5

View File

@ -108,61 +108,73 @@ pub async fn admin_login(
db: web::Data<Arc<Mutex<Connection>>>, db: web::Data<Arc<Mutex<Connection>>>,
credentials: web::Json<LoginCredentials>, credentials: web::Json<LoginCredentials>,
) -> impl Responder { ) -> impl Responder {
let conn = db.lock().unwrap(); let conn = match db.lock() {
Ok(conn) => conn,
Err(_) => return HttpResponse::InternalServerError().body("Database lock error"),
};
let mut stmt = let mut stmt =
match conn.prepare("SELECT username, password_hash FROM admin_users WHERE username = ?1") { match conn.prepare("SELECT username, password_hash FROM admin_users WHERE username = ?1") {
Ok(stmt) => stmt, Ok(stmt) => stmt,
Err(e) => return HttpResponse::InternalServerError().body(format!("Error: {}", e)), Err(e) => {
return HttpResponse::InternalServerError().body(format!("Database error: {}", e))
}
}; };
let admin: Option<AdminUser> = stmt let admin: Option<AdminUser> = match stmt.query_row([&credentials.username], |row| {
.query_row([&credentials.username], |row| { Ok(AdminUser {
Ok(AdminUser { username: row.get(0)?,
username: row.get(0)?, password_hash: row.get(1)?,
password_hash: row.get(1)?,
})
}) })
.ok(); }) {
Ok(admin) => Some(admin),
Err(rusqlite::Error::QueryReturnedNoRows) => None, // No user found
Err(e) => return HttpResponse::InternalServerError().body(format!("Query error: {}", e)),
};
match admin { match admin {
Some(user) => { Some(user) => {
let parsed_hash = PasswordHash::new(&user.password_hash).unwrap(); let parsed_hash = match PasswordHash::new(&user.password_hash) {
let argon2 = Argon2::default(); Ok(hash) => hash,
Err(_) => {
return HttpResponse::InternalServerError()
.body("Invalid password hash format in database")
}
};
let argon2 = Argon2::default();
let is_valid = argon2 let is_valid = argon2
.verify_password(credentials.password.as_bytes(), &parsed_hash) .verify_password(credentials.password.as_bytes(), &parsed_hash)
.is_ok(); .is_ok();
if is_valid { if is_valid {
let expiration = SystemTime::now() let expiration = match SystemTime::now().duration_since(UNIX_EPOCH) {
.duration_since(UNIX_EPOCH) Ok(duration) => duration.as_secs() as usize + 24 * 3600,
.unwrap() Err(_) => return HttpResponse::InternalServerError().body("System time error"),
.as_secs() as usize };
+ 24 * 3600;
let claims = Claims { let claims = Claims {
sub: user.username, sub: user.username,
exp: expiration, exp: expiration,
}; };
let token = encode( let token = match encode(
&Header::default(), &Header::default(),
&claims, &claims,
&EncodingKey::from_secret("your-secret-key".as_ref()), &EncodingKey::from_secret("your-secret-key".as_ref()),
) ) {
.unwrap(); Ok(token) => token,
Err(_) => {
return HttpResponse::InternalServerError().body("Token generation error")
}
};
HttpResponse::Ok().json(json!({ "token": token })) HttpResponse::Ok().json(json!({ "token": token }))
} else { } else {
HttpResponse::Unauthorized().json(json!({ HttpResponse::Unauthorized().json(json!({ "error": "Invalid credentials" }))
"error": "Invalid credentials"
}))
} }
} }
None => HttpResponse::Unauthorized().json(json!({ None => HttpResponse::Unauthorized().json(json!({ "error": "Invalid credentials" })),
"error": "Invalid credentials"
})),
} }
} }