feat: implement argon2id and expect passwords to be pre-hashed
This commit is contained in:
parent
3461218025
commit
87edb9dd12
4 changed files with 86 additions and 49 deletions
|
@ -1,4 +1,5 @@
|
|||
use actix_web::{error, post, web, Error, HttpResponse};
|
||||
use argon2::{Argon2, PasswordHash, PasswordVerifier};
|
||||
use regex::Regex;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use futures::StreamExt;
|
||||
|
@ -40,15 +41,22 @@ pub async fn res(mut payload: web::Payload, data: web::Data<Data>) -> Result<Htt
|
|||
// FIXME: This regex doesnt seem to be working
|
||||
let username_regex = Regex::new(r"[a-zA-Z0-9.-_]").unwrap();
|
||||
|
||||
// Password is expected to be hashed using SHA3-384
|
||||
let password_regex = Regex::new(r"/[0-9a-f]{96}/i").unwrap();
|
||||
|
||||
if !password_regex.is_match(&login_information.password) {
|
||||
return Ok(HttpResponse::Forbidden().json(r#"{ "password_hashed": false }"#));
|
||||
}
|
||||
|
||||
if email_regex.is_match(&login_information.username) {
|
||||
if let Ok(password) = sqlx::query_scalar("SELECT password FROM users WHERE email = $1").bind(login_information.username).fetch_one(&data.pool).await {
|
||||
return Ok(login(login_information.password, password))
|
||||
return Ok(login(data.argon2.clone(), login_information.password, password))
|
||||
}
|
||||
|
||||
return Ok(HttpResponse::Unauthorized().finish())
|
||||
} else if username_regex.is_match(&login_information.username) {
|
||||
if let Ok(password) = sqlx::query_scalar("SELECT password FROM users WHERE username = $1").bind(login_information.username).fetch_one(&data.pool).await {
|
||||
return Ok(login(login_information.password, password))
|
||||
return Ok(login(data.argon2.clone(), login_information.password, password))
|
||||
}
|
||||
|
||||
return Ok(HttpResponse::Unauthorized().finish())
|
||||
|
@ -57,14 +65,18 @@ pub async fn res(mut payload: web::Payload, data: web::Data<Data>) -> Result<Htt
|
|||
Ok(HttpResponse::Unauthorized().finish())
|
||||
}
|
||||
|
||||
fn login(request_password: String, database_password: String) -> HttpResponse {
|
||||
if request_password == database_password {
|
||||
return HttpResponse::Ok().json(Response {
|
||||
access_token: "bogus".to_string(),
|
||||
expires_in: 0,
|
||||
refresh_token: "bogus".to_string(),
|
||||
})
|
||||
fn login(argon2: Argon2, request_password: String, database_password: String) -> HttpResponse {
|
||||
if let Ok(parsed_hash) = PasswordHash::new(&database_password) {
|
||||
if argon2.verify_password(request_password.as_bytes(), &parsed_hash).is_ok() {
|
||||
return HttpResponse::Ok().json(Response {
|
||||
access_token: "bogus".to_string(),
|
||||
expires_in: 0,
|
||||
refresh_token: "bogus".to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
return HttpResponse::Unauthorized().finish()
|
||||
}
|
||||
|
||||
HttpResponse::Unauthorized().finish()
|
||||
|
||||
HttpResponse::InternalServerError().finish()
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue