Files
helios-server-rs/src/user/dal.rs
2024-07-28 14:24:53 +00:00

119 lines
3.2 KiB
Rust

use diesel::prelude::*;
use crate::model::{db_model, schema};
use std::error::Error;
use std::fmt::Debug;
use pbkdf2::password_hash::{PasswordHash, PasswordVerifier};
use pbkdf2::Pbkdf2;
use serde_json::json;
pub async fn add_user(app_state: crate::AppState, username: String, password: String, mail: String) -> Result<(), ()> {
let conn = app_state
.db
.get()
.await
.map_err(|_| {
println!("fail to get db connection");
()
})?;
let target_username = username.clone();
// 1. check if current username exists.
let res = conn.interact(
move |conn| {
schema::users::table
.filter(schema::users::username.eq(target_username.clone()))
.count()
.get_result::<i64>(conn)
})
.await
.map_err(|res| {
()
})?
.map_err(|res| {
()
})?;
println!("ret {}", res);
if res > 0 {
println!("user already exists.");
return Ok(());
}
let new_user_form = db_model::UserForm {
username: username.clone(),
password: password.clone(),
mail: mail.clone(),
};
// 2. adding user
let add_res = conn.interact(
move |conn| {
diesel::insert_into(schema::users::table)
.values(&new_user_form)
.returning(db_model::User::as_returning())
.get_result(conn)
})
.await
.map_err(|e| {
()
})?
.map_err(|e| {
()
})?;
let out = json!(add_res);
println!("new user {}", out.to_string());
Ok(())
}
pub async fn check_user_psw(app_state: crate::AppState, username: String, password: String) -> bool {
let conn_res = app_state
.db
.get()
.await
.map_err(|_| {
println!("fail to get db connection");
()
});
let conn = match conn_res {
Ok(res) => res,
Err(err) => { return false; }
};
// 1. get psw hash
let query_username = username.clone();
let user_rr = conn.interact(
|conn| {
schema::users::table
.filter(schema::users::username.eq(query_username))
.select(db_model::User::as_select())
.get_results(conn)
})
.await;
let user_res = match user_rr {
Ok(res) => res,
Err(_) => return false,
};
println!("get user_res success");
let user = match user_res {
Ok(u) => u,
Err(_) => return false,
};
println!("get user success");
if user.len() != 1 {
return false;
}
println!("get uniq user success");
let cur_user = user.get(0);
let psw = match cur_user {
Some(usr) => usr.password.clone(),
None => "".to_string(),
};
println!("comparing psw, get {}, stored {}.", password.clone(), psw.clone());
let hash_res = PasswordHash::new(psw.as_str());
let hash = match hash_res {
Ok(rs) => rs,
Err(_) => return false,
};
let check_res = Pbkdf2.verify_password(password.as_bytes(), &hash);
return check_res.is_ok();
}