This commit is contained in:
李运家 2024-06-03 09:42:11 +08:00
commit 7c571063a5
5 changed files with 93 additions and 9 deletions

View File

@ -1,6 +1,6 @@
use axum::Json; use axum::Json;
use axum_extra::extract::WithRejection; use axum_extra::extract::WithRejection;
use domain::dto::account::AuthenticateGooleAccountReq; use domain::dto::account::{AuthenticateGooleAccountReq, AuthenticateWithPassword};
use library::resp::{rejection::IRejection, response::{ ResOK, ResResult}}; use library::resp::{rejection::IRejection, response::{ ResOK, ResResult}};
use validator::Validate; use validator::Validate;
@ -13,3 +13,11 @@ pub async fn authenticate_google(
Ok(ResOK(None)) Ok(ResOK(None))
} }
pub async fn authenticate_with_password(
WithRejection(Json(req), _): IRejection<Json<AuthenticateWithPassword>>
) -> ResResult<ResOK<(String, String)>> {
req.validate()?;
service::sys_account::authenticate_with_password(req).await
}

View File

@ -9,14 +9,29 @@ pub(crate) fn init() -> Router {
let open = Router::new().route("/", get(|| async { "hello" })); let open = Router::new().route("/", get(|| async { "hello" }));
let auth: Router = Router::new() let auth: Router = Router::new()
.route("/account/google", post(controller::account::authenticate_google)) .route(
.route("/feedback", post(controller::feedback::add_feedback).get(controller::feedback::get_feedback_list_by_page)) "/account/google",
.layer(axum::middleware::from_fn(library::middleware::req_token::authenticate_access_token)); post(controller::account::authenticate_google),
)
.route(
"/account/sys",
post(controller::account::authenticate_with_password),
)
.route(
"/feedback",
post(controller::feedback::add_feedback)
.get(controller::feedback::get_feedback_list_by_page),
)
.layer(axum::middleware::from_fn(
library::middleware::req_token::authenticate_access_token,
));
Router::new() Router::new()
.nest("/", open) .nest("/", open)
.nest("/v1", auth) .nest("/gm/v1", auth)
.layer(axum::middleware::from_fn(library::middleware::req_log::handle)) .layer(axum::middleware::from_fn(
library::middleware::req_log::handle,
))
.layer(axum::middleware::from_fn(library::middleware::cors::handle)) .layer(axum::middleware::from_fn(library::middleware::cors::handle))
.layer( .layer(
TraceLayer::new_for_http().make_span_with(|request: &Request<Body>| { TraceLayer::new_for_http().make_span_with(|request: &Request<Body>| {
@ -32,5 +47,7 @@ pub(crate) fn init() -> Router {
tracing::error_span!("request_id", id = req_id) tracing::error_span!("request_id", id = req_id)
}), }),
) )
.layer(axum::middleware::from_fn(library::middleware::req_id::handle)) .layer(axum::middleware::from_fn(
library::middleware::req_id::handle,
))
} }

View File

@ -1,3 +1,5 @@
use std::fmt::Display;
use chrono::{DateTime, Utc}; use chrono::{DateTime, Utc};
use sqlx::{Error, PgPool}; use sqlx::{Error, PgPool};
use sqlx::types::{chrono, JsonValue}; use sqlx::types::{chrono, JsonValue};
@ -14,6 +16,15 @@ impl Default for Role {
} }
} }
impl Display for Role {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Role::Admin => write!(f, "admin"),
Role::User => write!(f, "user"),
}
}
}
// impl sqlx::Type<sqlx::Postgres> for Role { // impl sqlx::Type<sqlx::Postgres> for Role {
// fn type_info() -> sqlx::postgres::PgTypeInfo { // fn type_info() -> sqlx::postgres::PgTypeInfo {
// sqlx::postgres::PgTypeInfo::with_name("CHAR(1)") // sqlx::postgres::PgTypeInfo::with_name("CHAR(1)")
@ -202,4 +213,32 @@ impl Account {
} }
} }
} }
pub async fn add_account(&self, db_pool: &PgPool) -> Result<Option<Account>, Error> {
match sqlx::query_as!(
Account,
r#"
insert into account
(username, password, lang_tag, role)
values
($1, $2, $3, $4) returning *
"#,
self.username,
self.password,
self.lang_tag,
self.role.to_string()
).fetch_one(db_pool).await {
Ok(account) => {
return Ok(Some(account));
}
Err(Error::RowNotFound) => {
return Ok(None);
}
Err(e) => {
tracing::error!("add_account error: {:?}", e);
return Err(e);
}
}
}
} }

View File

@ -7,7 +7,8 @@ use crate::{cache::login_cache::LOGIN_CACHE, config, token::Claims};
const WHITE_LIST: &[(&str, &str)] = &[ const WHITE_LIST: &[(&str, &str)] = &[
("GET", "/api/v1/users/:id"), ("GET", "/api/v1/users/:id"),
("POST", "/api/v1/orders"), ("POST", "/api/v1/orders"),
("GET", "/feedback") ("GET", "/feedback"),
("POST", "/account/sys"),
]; ];
pub async fn authenticate_access_token(mut req: Request, next: Next) -> Response { pub async fn authenticate_access_token(mut req: Request, next: Next) -> Response {

View File

@ -8,9 +8,10 @@ use library::{
}; };
pub async fn authticate_with_password( pub async fn authenticate_with_password(
req: AuthenticateWithPassword, req: AuthenticateWithPassword,
) -> ResResult<ResOK<(String, String)>> { ) -> ResResult<ResOK<(String, String)>> {
let account = let account =
Account::find_with_password(req.username.unwrap(), req.password.unwrap(), db!()).await?; Account::find_with_password(req.username.unwrap(), req.password.unwrap(), db!()).await?;
if account.is_none() { if account.is_none() {
@ -42,3 +43,21 @@ pub async fn authticate_with_password(
Ok(ResOK(Some((token, refresh_token)))) Ok(ResOK(Some((token, refresh_token))))
} }
pub async fn add_account() -> ResResult<ResOK<()>> {
let account = Account::add_account(
&Account {
username: "admin".to_string(),
password: Some("123456".as_bytes().to_vec()),
role: Role::Admin,
..Default::default()
},
db!(),
)
.await?;
if account.is_none() {
tracing::error!("添加用户失败");
return Err(ResErr::service("添加用户失败"));
}
Ok(ResOK(None))
}