echoes/backend/src/api/auth/token.rs
lsy ba17778a8f 数据库:合并自定义字段和设计字段,所有限制移到应用层限制
后端:删除数据库构建需要等级,jwt添加rote信息
前端:修复post,删除插件机制,优化http
2024-12-18 21:54:37 +08:00

83 lines
2.5 KiB
Rust

use crate::common::error::{AppResult, AppResultInto};
use crate::security;
use crate::storage::sql::builder;
use crate::AppState;
use chrono::Duration;
use rocket::{http::Status, post, response::status, serde::json::Json, State};
use serde::{Deserialize, Serialize};
use std::sync::Arc;
use crate::api::Role;
#[derive(Deserialize, Serialize)]
pub struct TokenData {
username: String,
password: String,
}
#[post("/system", format = "application/json", data = "<data>")]
pub async fn token_system(
state: &State<Arc<AppState>>,
data: Json<TokenData>,
) -> AppResult<String> {
let sql = state.sql_get().await.into_app_result()?;
let mut builder = builder::QueryBuilder::new(
builder::SqlOperation::Select,
sql.table_name("users"),
sql.get_type(),
)
.into_app_result()?;
builder
.add_field("password_hash".to_string())
.into_app_result()?
.add_condition(builder::WhereClause::And(vec![
builder::WhereClause::Condition(
builder::Condition::new(
"username".to_string(),
builder::Operator::Eq,
Some(builder::SafeValue::Text(
data.username.clone(),
builder::ValidationLevel::Relaxed,
)),
)
.into_app_result()?,
),
builder::WhereClause::Condition(
builder::Condition::new(
"role".to_string(),
builder::Operator::Eq,
Some(builder::SafeValue::Text(
"administrator".into(),
builder::ValidationLevel::Standard,
)),
)
.into_app_result()?,
),
]));
println!("db: {:?}", sql.get_type());
let values = sql
.get_db()
.execute_query(&builder)
.await
.into_app_result()?;
let password = values
.first()
.and_then(|row| row.get("password_hash"))
.and_then(|val| val.as_str())
.ok_or_else(|| status::Custom(Status::NotFound, "系统用户或密码无效".into()))?;
security::bcrypt::verify_hash(&data.password, password)
.map_err(|_| status::Custom(Status::Forbidden, "密码无效".into()))?;
Ok(security::jwt::generate_jwt(
security::jwt::CustomClaims {
name: "system".into(),
role: Role::Administrator.to_string(),
},
Duration::minutes(1),
)
.into_app_result()?)
}