后端:精简JWT声明结构,优化用户注册功能,优化查询构建器
This commit is contained in:
parent
8071a16510
commit
33b53b3663
@ -16,3 +16,4 @@ ed25519-dalek = "2.1.1"
|
|||||||
rand = "0.8.5"
|
rand = "0.8.5"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
regex = "1.11.1"
|
regex = "1.11.1"
|
||||||
|
bcrypt = "0.16"
|
||||||
|
@ -10,8 +10,7 @@ use rand::{SeedableRng, RngCore};
|
|||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
#[derive(Debug, Serialize, Deserialize, Clone)]
|
||||||
pub struct CustomClaims {
|
pub struct CustomClaims {
|
||||||
pub user_id: String,
|
pub name: String,
|
||||||
pub device_ua: String,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum SecretKey {
|
pub enum SecretKey {
|
||||||
|
@ -276,4 +276,28 @@ impl QueryBuilder {
|
|||||||
|
|
||||||
Ok((sql, values))
|
Ok((sql, values))
|
||||||
}
|
}
|
||||||
|
pub fn fields(mut self, fields: Vec<ValidatedValue>) -> Self {
|
||||||
|
self.fields = fields;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn params(mut self, params: HashMap<ValidatedValue, ValidatedValue>) -> Self {
|
||||||
|
self.params = params;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn where_clause(mut self, clause: WhereClause) -> Self {
|
||||||
|
self.where_clause = Some(clause);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn order_by(mut self, order: ValidatedValue) -> Self {
|
||||||
|
self.order_by = Some(order);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn limit(mut self, limit: i32) -> Self {
|
||||||
|
self.limit = Some(limit);
|
||||||
|
self
|
||||||
|
}
|
||||||
}
|
}
|
@ -31,7 +31,7 @@ impl Error for DatabaseError {}
|
|||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait DatabaseTrait: Send + Sync {
|
pub trait DatabaseTrait: Send + Sync {
|
||||||
async fn connect(database: config::SqlConfig) -> Result<Self, Box<dyn Error>>
|
async fn connect(database: &config::SqlConfig) -> Result<Self, Box<dyn Error>>
|
||||||
where
|
where
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
async fn execute_query<'a>(
|
async fn execute_query<'a>(
|
||||||
@ -53,7 +53,7 @@ impl Database {
|
|||||||
&self.db
|
&self.db
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn link(database: config::SqlConfig) -> Result<Self, Box<dyn Error>> {
|
pub async fn link(database: &config::SqlConfig) -> Result<Self, Box<dyn Error>> {
|
||||||
let db = match database.db_type.as_str() {
|
let db = match database.db_type.as_str() {
|
||||||
"postgresql" => postgresql::Postgresql::connect(database).await?,
|
"postgresql" => postgresql::Postgresql::connect(database).await?,
|
||||||
_ => return Err("unknown database type".into()),
|
_ => return Err("unknown database type".into()),
|
||||||
|
@ -34,7 +34,7 @@ impl DatabaseTrait for Postgresql {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn connect(db_config: config::SqlConfig) -> Result<Self, Box<dyn Error>> {
|
async fn connect(db_config: &config::SqlConfig) -> Result<Self, Box<dyn Error>> {
|
||||||
let connection_str = format!(
|
let connection_str = format!(
|
||||||
"postgres://{}:{}@{}:{}/{}",
|
"postgres://{}:{}@{}:{}/{}",
|
||||||
db_config.user, db_config.password, db_config.address, db_config.port, db_config.db_name
|
db_config.user, db_config.password, db_config.address, db_config.port, db_config.db_name
|
||||||
|
0
backend/src/database/relational/uilts.rs
Normal file
0
backend/src/database/relational/uilts.rs
Normal file
@ -49,7 +49,7 @@ impl AppState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn link_sql(&self, config: config::SqlConfig) -> AppResult<()> {
|
async fn link_sql(&self, config: config::SqlConfig) -> AppResult<()> {
|
||||||
let database = relational::Database::link(config)
|
let database = relational::Database::link(&config)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| AppError::Database(e.to_string()))?;
|
.map_err(|e| AppError::Database(e.to_string()))?;
|
||||||
*self.db.lock().await = Some(database);
|
*self.db.lock().await = Some(database);
|
||||||
@ -63,8 +63,7 @@ impl AppState {
|
|||||||
#[get("/system")]
|
#[get("/system")]
|
||||||
async fn token_system(_state: &State<AppState>) -> Result<status::Custom<String>, status::Custom<String>> {
|
async fn token_system(_state: &State<AppState>) -> Result<status::Custom<String>, status::Custom<String>> {
|
||||||
let claims = auth::jwt::CustomClaims {
|
let claims = auth::jwt::CustomClaims {
|
||||||
user_id: "system".into(),
|
name: "system".into(),
|
||||||
device_ua: "system".into(),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
auth::jwt::generate_jwt(claims, Duration::seconds(1))
|
auth::jwt::generate_jwt(claims, Duration::seconds(1))
|
||||||
@ -73,6 +72,7 @@ async fn token_system(_state: &State<AppState>) -> Result<status::Custom<String>
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#[launch]
|
#[launch]
|
||||||
async fn rocket() -> _ {
|
async fn rocket() -> _ {
|
||||||
let config = config::Config::read().expect("Failed to read config");
|
let config = config::Config::read().expect("Failed to read config");
|
||||||
@ -94,11 +94,28 @@ async fn rocket() -> _ {
|
|||||||
|
|
||||||
if ! config.info.install {
|
if ! config.info.install {
|
||||||
rocket_builder = rocket_builder
|
rocket_builder = rocket_builder
|
||||||
.mount("/", rocket::routes![routes::install]);
|
.mount("/", rocket::routes![routes::intsall::install]);
|
||||||
}
|
}
|
||||||
|
|
||||||
rocket_builder = rocket_builder
|
rocket_builder = rocket_builder
|
||||||
.mount("/auth/token", routes![token_system]);
|
.mount("/auth/token", rocket::routes![token_system])
|
||||||
|
.mount("/", rocket::routes![routes::intsall::test]);
|
||||||
|
|
||||||
rocket_builder
|
rocket_builder
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_placeholder() {
|
||||||
|
let config = config::Config::read().expect("Failed to read config");
|
||||||
|
|
||||||
|
let state = AppState {
|
||||||
|
db: Arc::new(Mutex::new(None)),
|
||||||
|
configure: Arc::new(Mutex::new(config.clone())),
|
||||||
|
};
|
||||||
|
state.link_sql(config.sql_config.clone())
|
||||||
|
.await
|
||||||
|
.expect("Failed to connect to database");
|
||||||
|
let sql=state.get_sql().await.expect("Failed to get sql");
|
||||||
|
let _=routes::person::insert(&sql,routes::person::RegisterData{ name: String::from("test"), email: String::from("lsy22@vip.qq.com"), password:String::from("test") }).await.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -1,71 +1,93 @@
|
|||||||
use serde::{Deserialize,Serialize};
|
use serde::{Deserialize,Serialize};
|
||||||
use crate::{config,utils};
|
use crate::{config,utils};
|
||||||
use crate::database::{relational,relational::builder};
|
use crate::database::relational;
|
||||||
use crate::{AppState,AppError,AppResult};
|
use crate::{AppState,AppError,AppResult};
|
||||||
use rocket::{
|
use rocket::{
|
||||||
get, post,
|
post,
|
||||||
http::Status,
|
http::Status,
|
||||||
response::status,
|
response::status,
|
||||||
serde::json::Json,
|
serde::json::Json,
|
||||||
State,
|
State,
|
||||||
};
|
};
|
||||||
use std::collections::HashMap;
|
use crate::routes::person;
|
||||||
|
use crate::auth;
|
||||||
|
use chrono::Duration;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
struct InstallData{
|
pub struct InstallData{
|
||||||
name:String,
|
name:String,
|
||||||
email:String,
|
email:String,
|
||||||
password:String,
|
password:String,
|
||||||
sql_config: config::SqlConfig
|
sql_config: config::SqlConfig
|
||||||
|
|
||||||
}
|
}
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
struct InstallReplyData{
|
pub struct InstallReplyData{
|
||||||
token:String,
|
token:String,
|
||||||
name:String,
|
name:String,
|
||||||
password:String,
|
password:String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[post("/test", format = "application/json", data = "<data>")]
|
||||||
#[post("/install", format = "application/json", data = "<data>")]
|
pub async fn test(
|
||||||
async fn install(
|
|
||||||
data: Json<InstallData>,
|
data: Json<InstallData>,
|
||||||
state: &State<AppState>
|
state: &State<AppState>
|
||||||
) -> AppResult<status::Custom<Json<InstallReplyData>>, AppError> {
|
) -> Result<status::Custom<String>, status::Custom<String>> {
|
||||||
|
let data=data.into_inner();
|
||||||
|
|
||||||
|
|
||||||
|
let sql= state.get_sql().await.map_err(|e| e)?;
|
||||||
|
|
||||||
|
let _ = person::insert(&sql,person::RegisterData{ name: data.name.clone(), email: data.email, password:data.password });
|
||||||
|
Ok(status::Custom(Status::Ok, "Installation successful".to_string()))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[post("/install", format = "application/json", data = "<data>")]
|
||||||
|
pub async fn install(
|
||||||
|
data: Json<InstallData>,
|
||||||
|
state: &State<AppState>
|
||||||
|
) -> Result<status::Custom<Json<InstallReplyData>>, status::Custom<String>> {
|
||||||
let mut config = state.configure.lock().await;
|
let mut config = state.configure.lock().await;
|
||||||
if config.info.install {
|
if config.info.install {
|
||||||
return Err(AppError::Database("Database already initialized".to_string()));
|
return Err(status::Custom(Status::BadRequest, "Database already initialized".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let data=data.into_inner();
|
let data=data.into_inner();
|
||||||
|
|
||||||
relational::Database::initial_setup(data.sql_config.clone())
|
relational::Database::initial_setup(data.sql_config.clone())
|
||||||
.await
|
.await
|
||||||
.map_err(|e| AppError::Database(e.to_string()))?;
|
.map_err(|e| status::Custom(Status::InternalServerError, e.to_string()))?;
|
||||||
|
|
||||||
config.info.install = true;
|
config.info.install = true;
|
||||||
|
|
||||||
state.link_sql(data.sql_config.clone());
|
state.link_sql(data.sql_config.clone()).await?;
|
||||||
let sql= state.get_sql()
|
let sql= state.get_sql().await?;
|
||||||
.await?
|
|
||||||
.get_db();
|
|
||||||
|
|
||||||
|
|
||||||
let system_name=utils::generate_random_string(20);
|
let system_name=utils::generate_random_string(20);
|
||||||
let system_password=utils::generate_random_string(20);
|
let system_password=utils::generate_random_string(20);
|
||||||
|
|
||||||
let mut builder = builder::QueryBuilder::new(builder::SqlOperation::Insert,String::from("persons"))?;
|
let _ = person::insert(&sql,person::RegisterData{ name: data.name.clone(), email: data.email, password:data.password }).await?;
|
||||||
|
let _ = person::insert(&sql,person::RegisterData{ name: system_name.clone(), email: String::from("author@lsy22.com"), password:system_name.clone() }).await?;
|
||||||
let user_params=HashMap::new();
|
let token = auth::jwt::generate_jwt(
|
||||||
user_params.insert("person_name", data.name);
|
auth::jwt::CustomClaims{name:data.name.clone()},
|
||||||
user_params.insert("person_email", data.email);
|
Duration::days(7)
|
||||||
user_params.insert("person_password", data.password);
|
).map_err(|e| status::Custom(Status::Unauthorized, e.to_string()))?;
|
||||||
user_params.insert("person_role", data.name);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
config::Config::write(config.clone())
|
config::Config::write(config.clone())
|
||||||
.map_err(|e| AppError::Config(e.to_string()))?;
|
.map_err(|e| status::Custom(Status::InternalServerError, e.to_string()))?;
|
||||||
Ok()
|
Ok(
|
||||||
|
status::Custom(
|
||||||
|
Status::Ok,
|
||||||
|
Json(InstallReplyData{
|
||||||
|
token:token,
|
||||||
|
name: system_name,
|
||||||
|
password: system_password
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
@ -1,6 +1,8 @@
|
|||||||
mod intsall;
|
pub mod intsall;
|
||||||
|
pub mod person;
|
||||||
use rocket::routes;
|
use rocket::routes;
|
||||||
|
|
||||||
pub fn create_routes() -> routes {
|
// pub fn create_routes() -> Vec<rocket::Route> {
|
||||||
routes!["/", intsall::install]
|
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
68
backend/src/routes/person.rs
Normal file
68
backend/src/routes/person.rs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
use serde::{Deserialize,Serialize};
|
||||||
|
use crate::{config,utils};
|
||||||
|
use crate::database::{relational,relational::builder};
|
||||||
|
use crate::{AppError,AppResult};
|
||||||
|
use rocket::{
|
||||||
|
get, post,
|
||||||
|
http::Status,
|
||||||
|
response::status,
|
||||||
|
serde::json::Json,
|
||||||
|
State,
|
||||||
|
};
|
||||||
|
use std::collections::HashMap;
|
||||||
|
use bcrypt::{hash, verify, DEFAULT_COST};
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Deserialize, Serialize)]
|
||||||
|
pub struct LoginData{
|
||||||
|
pub name:String,
|
||||||
|
pub password:String
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct RegisterData{
|
||||||
|
pub name:String,
|
||||||
|
pub email:String,
|
||||||
|
pub password:String
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn insert(sql:&relational::Database,data:RegisterData) -> AppResult<()>{
|
||||||
|
let hashed_password = hash(data.password, DEFAULT_COST).expect("Failed to hash password");
|
||||||
|
|
||||||
|
|
||||||
|
let mut user_params=HashMap::new();
|
||||||
|
user_params.insert(
|
||||||
|
builder::ValidatedValue::Identifier(String::from("person_name"))
|
||||||
|
,
|
||||||
|
builder::ValidatedValue::PlainText(data.name)
|
||||||
|
);
|
||||||
|
user_params.insert(
|
||||||
|
builder::ValidatedValue::Identifier(String::from("person_email"))
|
||||||
|
,
|
||||||
|
builder::ValidatedValue::PlainText(data.email)
|
||||||
|
);
|
||||||
|
user_params.insert(
|
||||||
|
builder::ValidatedValue::Identifier(String::from("person_password"))
|
||||||
|
,
|
||||||
|
builder::ValidatedValue::PlainText(hashed_password)
|
||||||
|
);
|
||||||
|
|
||||||
|
let builder = builder::QueryBuilder::new(builder::SqlOperation::Insert,String::from("persons"))
|
||||||
|
.map_err(|e|{
|
||||||
|
AppError::Database(format!("Error while building query: {}", e.to_string()))
|
||||||
|
})?
|
||||||
|
.params(user_params)
|
||||||
|
;
|
||||||
|
|
||||||
|
let _= sql.get_db().execute_query(&builder).await.map_err(|e|{
|
||||||
|
AppError::Database(format!("Travel during execution: {}", e.to_string()))
|
||||||
|
})?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn delete(){}
|
||||||
|
|
||||||
|
pub fn update(){}
|
||||||
|
|
||||||
|
pub fn select(){}
|
||||||
|
|
||||||
|
pub fn check(){}
|
Loading…
Reference in New Issue
Block a user