119 lines
3.2 KiB
Rust
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();
|
||
|
|
}
|