白名单接口增加WhiteContext

This commit is contained in:
李运家 2024-06-21 11:10:42 +08:00
parent dd5533ab31
commit 485f772715
8 changed files with 46 additions and 25 deletions

View File

@ -1,19 +1,21 @@
use axum::{Extension, Json};
use domain::{dto::account::{AuthenticateGooleAccountReq, AuthenticateWithPassword, RefreshToken}, vo::account::{LoginAccount, RefreshTokenResult}};
use library::{context::Context, res::{response::{ ResData, ResResult}, validator}};
use library::{context::{Context, WhiteContext}, res::{response::{ ResData, ResResult}, validator}};
pub async fn authenticate_google(
Extension(context): Extension<WhiteContext>,
Json(req): Json<AuthenticateGooleAccountReq>
) -> ResResult<ResData<LoginAccount>> {
validator::validate_params(&req, &req.lang_tag.to_owned().unwrap())?;
service::account::authenticate_google(req).await
validator::validate_params(&req, context.get_lang_tag())?;
service::account::authenticate_google(context, req).await
}
pub async fn authenticate_with_password(
Extension(context): Extension<WhiteContext>,
Json(req): Json<AuthenticateWithPassword>
) -> ResResult<ResData<LoginAccount>> {
validator::validate_params(&req, &req.lang_tag.to_owned().unwrap())?;
service::sys_account::authenticate_with_password(req).await
validator::validate_params(&req, context.get_lang_tag())?;
service::sys_account::authenticate_with_password(context, req).await
}
pub async fn refresh_token(

View File

@ -7,16 +7,12 @@ pub struct AuthenticateWithPassword {
pub username: Option<String>,
#[validate(required(message = "VALIDATE_ACCOUNT_PASSWORD_REQUIRED"), length(min = 1, message = "VALIDATE_ACCOUNT_PASSWORD_REQUIRED"))]
pub password: Option<String>,
#[validate(required(message = "VALIDATE_ACCOUNT_LANG_TAG_REQUIRED"), length(min = 1, message = "VALIDATE_ACCOUNT_LANG_TAG_REQUIRED"))]
pub lang_tag: Option<String>,
}
#[derive(Debug, Validate, Deserialize, Serialize)]
pub struct AuthenticateGooleAccountReq {
#[validate(required(message = "VALIDATE_ACCOUNT_ID_TOKEN_REQUIRED"), length(min = 1, message = "VALIDATE_ACCOUNT_ID_TOKEN_REQUIRED"))]
pub id_token: Option<String>,
#[validate(required(message = "VALIDATE_ACCOUNT_LANG_TAG_REQUIRED"), length(min = 1, message = "VALIDATE_ACCOUNT_LANG_TAG_REQUIRED"))]
pub lang_tag: Option<String>,
}
#[derive(Debug, Validate, Deserialize, Serialize)]

View File

@ -6,7 +6,7 @@ use crate::message_ids::{
ACCOUNT_DISABLED, ACCOUNT_NO_PERMISSION, HELLO, INCORRECT_USERNAME_OR_PASSWORD, INVALID_TOKEN, VALIDATE_ACCOUNT_ID_TOKEN_REQUIRED, VALIDATE_ACCOUNT_LANG_TAG_REQUIRED, VALIDATE_ACCOUNT_NAME_REQUIRED, VALIDATE_ACCOUNT_PASSWORD_REQUIRED, VALIDATE_FEEDBACK_CONTENT_REQUIRED
};
pub const LANGUAGE_ID: &str = "en_US";
pub const LANGUAGE_ID: &str = "en-US";
lazy_static! {
pub static ref MESSAGE: HashMap<&'static str, &'static str> = {

View File

@ -6,7 +6,7 @@ use crate::message_ids::{
ACCOUNT_DISABLED, ACCOUNT_NO_PERMISSION, HELLO, INCORRECT_USERNAME_OR_PASSWORD, INVALID_TOKEN, VALIDATE_ACCOUNT_ID_TOKEN_REQUIRED, VALIDATE_ACCOUNT_LANG_TAG_REQUIRED, VALIDATE_ACCOUNT_NAME_REQUIRED, VALIDATE_ACCOUNT_PASSWORD_REQUIRED, VALIDATE_FEEDBACK_CONTENT_REQUIRED
};
pub const LANGUAGE_ID: &str = "zh_CN";
pub const LANGUAGE_ID: &str = "zh-CN";
lazy_static! {
pub static ref MESSAGE: HashMap<&'static str, &'static str> = {

View File

@ -18,7 +18,18 @@ impl Context {
&self.token
}
pub fn get_lang_id(&self) -> &String {
pub fn get_lang_tag(&self) -> &String {
&self.account.lang_tag
}
}
#[derive(Debug, Clone)]
pub struct WhiteContext {
pub lang_tag: String,
}
impl WhiteContext {
pub fn get_lang_tag(&self) -> &String {
&self.lang_tag
}
}

View File

@ -2,7 +2,7 @@ use axum::{extract::Request, middleware::Next, response::{IntoResponse, Response
use http::{header, StatusCode};
use jsonwebtoken::{decode, DecodingKey, Validation};
use crate::{cache::account_cache::LOGIN_CACHE, config, context::Context, token::Claims};
use crate::{cache::account_cache::LOGIN_CACHE, config, context::{Context, WhiteContext}, token::Claims};
const WHITE_LIST: &[(&str, &str)] = &[
("POST", "/account/sys"),
@ -16,6 +16,21 @@ pub async fn authenticate_ctx(mut req: Request, next: Next) -> Response {
if WHITE_LIST.into_iter().find(|item| {
return item.0 == method && item.1 == uri;
}).is_some() {
// 解析语言
let language_header = req.headers().get(header::ACCEPT_LANGUAGE);
let language = match language_header {
Some(value) => {
let value_str: Vec<&str> = value.to_str().unwrap_or("zh-CN").split(',').collect();
tracing::info!("language: {:?}", value_str);
if value_str.is_empty() {
String::from("zh-CN")
} else {
String::from(value_str[0])
}
},
None => String::from("zh-CN"),
};
req.extensions_mut().insert(WhiteContext { lang_tag: language });
return next.run(req).await;
}

View File

@ -7,7 +7,7 @@ use domain::vo::account::{LoginAccount, RefreshTokenResult};
use i18n::message;
use i18n::message_ids::{ACCOUNT_DISABLED, INVALID_TOKEN};
use library::cache::account_cache::{CacheAccount, LOGIN_CACHE};
use library::context::Context;
use library::context::{Context, WhiteContext};
use library::res::response::ResErr::ErrPerm;
use library::res::response::{ResData, ResErr, ResResult};
use library::social::google::GOOGLE_SOCIAL;
@ -15,9 +15,9 @@ use library::token::{generate_refresh_token, generate_token};
use library::{db, token};
pub async fn authenticate_google(
context: WhiteContext,
req: AuthenticateGooleAccountReq,
) -> ResResult<ResData<LoginAccount>> {
let lang_tag = req.lang_tag.unwrap();
let verify_result = GOOGLE_SOCIAL
.verify_id_token(&req.id_token.unwrap())
.await
@ -47,7 +47,7 @@ pub async fn authenticate_google(
tracing::info!("账户已存在, {:?}", account);
if account.disable_time > Utc::now() {
tracing::error!("账户已禁用");
return Err(ResErr::system(message!(&lang_tag, ACCOUNT_DISABLED)));
return Err(ResErr::system(message!(context.get_lang_tag(), ACCOUNT_DISABLED)));
}
account
}
@ -86,7 +86,7 @@ pub async fn refresh_token(
let account = context.account.clone();
if token::verify_refresh_token(&refresh_token).is_err() {
return Err(ResErr::params(message!(context.get_lang_id(), INVALID_TOKEN)));
return Err(ResErr::params(message!(context.get_lang_tag(), INVALID_TOKEN)));
}
let refresh_token = RefreshTokenResult {

View File

@ -11,22 +11,19 @@ use i18n::{
message_ids::{ACCOUNT_DISABLED, ACCOUNT_NO_PERMISSION, INCORRECT_USERNAME_OR_PASSWORD},
};
use library::{
cache::account_cache::{CacheAccount, LOGIN_CACHE},
db,
res::response::{ResData, ResErr, ResResult},
token::{generate_refresh_token, generate_token},
cache::account_cache::{CacheAccount, LOGIN_CACHE}, context::WhiteContext, db, res::response::{ResData, ResErr, ResResult}, token::{generate_refresh_token, generate_token}
};
pub async fn authenticate_with_password(
context: WhiteContext,
req: AuthenticateWithPassword,
) -> ResResult<ResData<LoginAccount>> {
let lang_tag = req.lang_tag.unwrap();
let account =
Account::find_with_password(req.username.unwrap(), req.password.unwrap(), db!()).await?;
if account.is_none() {
tracing::info!("登录用户失败,用户查询为空");
return Err(ResErr::params(message!(
&lang_tag,
context.get_lang_tag(),
INCORRECT_USERNAME_OR_PASSWORD
)));
}
@ -34,14 +31,14 @@ pub async fn authenticate_with_password(
if account.disable_time > Utc::now() {
tracing::error!("账户已禁用");
return Err(ResErr::auth(message!(
&lang_tag,
context.get_lang_tag(),
ACCOUNT_DISABLED
)));
}
if !account.role.is_admin() {
tracing::error!("账户不是管理员,无权限");
return Err(ResErr::perm(message!(
&lang_tag,
context.get_lang_tag(),
ACCOUNT_NO_PERMISSION
)));
}