网络参数校验错误消息接入i18n
This commit is contained in:
parent
70162a37f6
commit
9a7271cf83
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -477,6 +477,7 @@ name = "domain"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"i18n",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sqlx",
|
||||
|
@ -3,19 +3,17 @@ use domain::{dto::account::{AuthenticateGooleAccountReq, AuthenticateWithPasswor
|
||||
use library::{context::Context, res::{response::{ ResData, ResResult}, validator}};
|
||||
|
||||
pub async fn authenticate_google(
|
||||
Extension(context): Extension<Context>,
|
||||
Json(req): Json<AuthenticateGooleAccountReq>
|
||||
) -> ResResult<ResData<LoginAccount>> {
|
||||
validator::validate_params(&req, "")?;
|
||||
service::account::authenticate_google(context, req).await
|
||||
validator::validate_params(&req, &req.lang_tag.to_owned().unwrap())?;
|
||||
service::account::authenticate_google(req).await
|
||||
}
|
||||
|
||||
pub async fn authenticate_with_password(
|
||||
Extension(context): Extension<Context>,
|
||||
Json(req): Json<AuthenticateWithPassword>
|
||||
) -> ResResult<ResData<LoginAccount>> {
|
||||
validator::validate_params(&req, "")?;
|
||||
service::sys_account::authenticate_with_password(context, req).await
|
||||
validator::validate_params(&req, &req.lang_tag.to_owned().unwrap())?;
|
||||
service::sys_account::authenticate_with_password(req).await
|
||||
}
|
||||
|
||||
pub async fn refresh_token(
|
||||
|
@ -1,5 +1,6 @@
|
||||
use axum::extract::Query;
|
||||
use axum::Json;
|
||||
use axum::{Extension, Json};
|
||||
use library::context::Context;
|
||||
use validator::Validate;
|
||||
use domain::dto::feedback::FeedbackAdd;
|
||||
use domain::dto::pageable::PageParams;
|
||||
@ -9,11 +10,12 @@ use library::res::response::{ResData, ResResult};
|
||||
|
||||
/// 添加反馈信息
|
||||
pub async fn add_feedback(
|
||||
Extension(context): Extension<Context>,
|
||||
Json(req): Json<FeedbackAdd>
|
||||
) -> ResResult<ResData<()>> {
|
||||
req.validate()?;
|
||||
|
||||
service::feedback::add_feedback(req).await
|
||||
service::feedback::add_feedback(context, req).await
|
||||
}
|
||||
|
||||
/// 获取反馈信息列表
|
||||
|
@ -14,3 +14,5 @@ chrono = { workspace = true, features = ["serde"]}
|
||||
tracing = { workspace = true }
|
||||
tracing-appender = { workspace = true }
|
||||
tracing-subscriber = { workspace = true, features = ["json"] }
|
||||
|
||||
i18n = { path = "../i18n" }
|
@ -3,16 +3,20 @@ use validator::Validate;
|
||||
|
||||
#[derive(Debug, Validate, Deserialize, Serialize)]
|
||||
pub struct AuthenticateWithPassword {
|
||||
#[validate(required(message = "用户名不能为空"), length(min = 1, message = "用户名不能为空"))]
|
||||
#[validate(required(message = "VALIDATE_ACCOUNT_NAME_REQUIRED"), length(min = 1, message = "VALIDATE_ACCOUNT_NAME_REQUIRED"))]
|
||||
pub username: Option<String>,
|
||||
#[validate(required(message = "密码不能为空"), length(min = 1, message = "密码不能为空"))]
|
||||
#[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 = "用户ID Token不能为空"), length(min = 1, message = "用户ID Token不能为空"))]
|
||||
#[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)]
|
||||
|
@ -1,10 +1,9 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use validator::Validate;
|
||||
|
||||
|
||||
#[derive(Debug, Validate, Deserialize, Serialize)]
|
||||
pub struct FeedbackAdd {
|
||||
#[validate(required(message = "用户ID不能为空"))]
|
||||
pub user_id: Option<i64>,
|
||||
#[validate(required(message = "反馈内容不能为空"), length(min = 1, message = "反馈内容不能为空"))]
|
||||
#[validate(required(message = "VALIDATE_FEEDBACK_CONTENT_REQUIRED"), length(min = 1, message = "VALIDATE_FEEDBACK_CONTENT_REQUIRED"))]
|
||||
pub content: Option<String>
|
||||
}
|
@ -7,7 +7,7 @@ use crate::db_result::CountResult;
|
||||
#[derive(Debug, Clone, Deserialize, Default, Serialize)]
|
||||
pub struct Feedback {
|
||||
pub id: i64,
|
||||
pub user_id: i64,
|
||||
pub user_id: String,
|
||||
pub content: String,
|
||||
pub created_at: NaiveDateTime,
|
||||
}
|
||||
|
@ -3,10 +3,10 @@ use std::collections::HashMap;
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
use crate::message_ids::{
|
||||
ACCOUNT_DISABLED, ACCOUNT_NO_PERMISSION, HELLO, INCORRECT_USERNAME_OR_PASSWORD, INVALID_TOKEN,
|
||||
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> = {
|
||||
@ -14,11 +14,14 @@ lazy_static! {
|
||||
map.insert(HELLO, "hello {}");
|
||||
map.insert(ACCOUNT_DISABLED, "account is disabled");
|
||||
map.insert(ACCOUNT_NO_PERMISSION, "account has no permission");
|
||||
map.insert(
|
||||
INCORRECT_USERNAME_OR_PASSWORD,
|
||||
"incorrect username or password",
|
||||
);
|
||||
map.insert(INCORRECT_USERNAME_OR_PASSWORD,"incorrect username or password");
|
||||
map.insert(INVALID_TOKEN, "invalid token");
|
||||
|
||||
map.insert(VALIDATE_FEEDBACK_CONTENT_REQUIRED, "feedback content is required");
|
||||
map.insert(VALIDATE_ACCOUNT_NAME_REQUIRED, "username is required");
|
||||
map.insert(VALIDATE_ACCOUNT_PASSWORD_REQUIRED, "password is required");
|
||||
map.insert(VALIDATE_ACCOUNT_ID_TOKEN_REQUIRED, "ID Token is required");
|
||||
map.insert(VALIDATE_ACCOUNT_LANG_TAG_REQUIRED, "lang tag is required");
|
||||
map
|
||||
};
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ fn get_i18n() -> &'static HashMap<&'static str, HashMap<&'static str, &'static s
|
||||
I18N.get_or_init(init_i18n)
|
||||
}
|
||||
|
||||
pub fn lang(lang_id: &str, message_id: &'static str) -> &'static str {
|
||||
pub fn lang(lang_id: &str, message_id: &str) -> &'static str {
|
||||
get_i18n()
|
||||
.get(lang_id)
|
||||
.and_then(|map| map.get(message_id))
|
||||
|
@ -1,5 +1,11 @@
|
||||
pub const HELLO: &str = "hello";
|
||||
pub const ACCOUNT_DISABLED: &str = "accout is disabled";
|
||||
pub const ACCOUNT_NO_PERMISSION: &str = "account has no permission";
|
||||
pub const INCORRECT_USERNAME_OR_PASSWORD: &str = "Incorrect username or password";
|
||||
pub const INVALID_TOKEN: &str = "invalid token";
|
||||
pub const HELLO: &str = "HELLO";
|
||||
pub const ACCOUNT_DISABLED: &str = "ACCOUNT_DISABLED";
|
||||
pub const ACCOUNT_NO_PERMISSION: &str = "ACCOUNT_NO_PERMISSION";
|
||||
pub const INCORRECT_USERNAME_OR_PASSWORD: &str = "INCORRECT_USERNAME_OR_PASSWORD";
|
||||
pub const INVALID_TOKEN: &str = "INVALID_TOKEN";
|
||||
|
||||
pub const VALIDATE_FEEDBACK_CONTENT_REQUIRED: &'static str = "VALIDATE_FEEDBACK_CONTENT_REQUIRED";
|
||||
pub const VALIDATE_ACCOUNT_NAME_REQUIRED: &'static str = "VALIDATE_ACCOUNT_NAME_REQUIRED";
|
||||
pub const VALIDATE_ACCOUNT_PASSWORD_REQUIRED: &'static str = "VALIDATE_ACCOUNT_PASSWORD_REQUIRED";
|
||||
pub const VALIDATE_ACCOUNT_ID_TOKEN_REQUIRED: &'static str = "VALIDATE_ACCOUNT_ID_TOKEN_REQUIRED";
|
||||
pub const VALIDATE_ACCOUNT_LANG_TAG_REQUIRED: &'static str = "VALIDATE_ACCOUNT_LANG_TAG_REQUIRED";
|
@ -3,7 +3,7 @@ use std::collections::HashMap;
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
use crate::message_ids::{
|
||||
ACCOUNT_DISABLED, ACCOUNT_NO_PERMISSION, HELLO, INCORRECT_USERNAME_OR_PASSWORD, INVALID_TOKEN,
|
||||
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";
|
||||
@ -16,6 +16,12 @@ lazy_static! {
|
||||
map.insert(ACCOUNT_NO_PERMISSION, "账户无权限");
|
||||
map.insert(INCORRECT_USERNAME_OR_PASSWORD, "用户名或密码错误");
|
||||
map.insert(INVALID_TOKEN, "无效令牌");
|
||||
|
||||
map.insert(VALIDATE_FEEDBACK_CONTENT_REQUIRED, "反馈内容不能为空");
|
||||
map.insert(VALIDATE_ACCOUNT_NAME_REQUIRED, "用户名称不能为空");
|
||||
map.insert(VALIDATE_ACCOUNT_PASSWORD_REQUIRED, "密码不能为空");
|
||||
map.insert(VALIDATE_ACCOUNT_ID_TOKEN_REQUIRED, "用户ID Token不能为空");
|
||||
map.insert(VALIDATE_ACCOUNT_LANG_TAG_REQUIRED, "用户语言标识不能为空");
|
||||
map
|
||||
};
|
||||
}
|
||||
|
@ -1,8 +1,9 @@
|
||||
use i18n::message;
|
||||
use validator::Validate;
|
||||
|
||||
use super::response::{ResData, ResErr, ResResult};
|
||||
|
||||
pub fn validate_params(params: &impl Validate, _local: &str) -> ResResult<ResData<()>> {
|
||||
pub fn validate_params(params: &impl Validate, local: &str) -> ResResult<ResData<()>> {
|
||||
let validate_err = params.validate();
|
||||
match validate_err {
|
||||
Ok(_) => Result::Ok(ResData::none()),
|
||||
@ -14,8 +15,7 @@ pub fn validate_params(params: &impl Validate, _local: &str) -> ResResult<ResDat
|
||||
err.field_errors().iter().for_each(|(_field, errs)| {
|
||||
errs.iter().for_each(|e| {
|
||||
let msg = e.message.clone().unwrap_or_default();
|
||||
let msg_str = msg.to_string();
|
||||
errors.push(msg_str)
|
||||
errors.push(message!(local, msg.trim()))
|
||||
});
|
||||
});
|
||||
},
|
||||
@ -24,8 +24,7 @@ pub fn validate_params(params: &impl Validate, _local: &str) -> ResResult<ResDat
|
||||
err.field_errors().iter().for_each(|(_field, errs)| {
|
||||
errs.iter().for_each(|e| {
|
||||
let msg = e.message.clone().unwrap_or_default();
|
||||
let msg_str = msg.to_string();
|
||||
errors.push(msg_str)
|
||||
errors.push(message!(local, msg.trim()))
|
||||
});
|
||||
});
|
||||
}
|
||||
@ -33,8 +32,7 @@ pub fn validate_params(params: &impl Validate, _local: &str) -> ResResult<ResDat
|
||||
validator::ValidationErrorsKind::Field(err) => {
|
||||
err.iter().for_each(|e| {
|
||||
let msg = e.message.clone().unwrap_or_default();
|
||||
let msg_str = msg.to_string();
|
||||
errors.push(msg_str)
|
||||
errors.push(message!(local, msg.trim()))
|
||||
});
|
||||
},
|
||||
};
|
||||
|
@ -15,9 +15,9 @@ use library::token::{generate_refresh_token, generate_token};
|
||||
use library::{db, token};
|
||||
|
||||
pub async fn authenticate_google(
|
||||
context: Context,
|
||||
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!(context.get_lang_id(), ACCOUNT_DISABLED)));
|
||||
return Err(ResErr::system(message!(&lang_tag, ACCOUNT_DISABLED)));
|
||||
}
|
||||
account
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
use domain::dto::feedback::FeedbackAdd;
|
||||
use domain::entities::feedback::Feedback;
|
||||
use library::context::Context;
|
||||
use library::db;
|
||||
use library::res::pageable::Pageable;
|
||||
use library::res::response::{ResData, ResResult};
|
||||
@ -26,9 +27,13 @@ async fn get_feedback_count() -> i64 {
|
||||
}
|
||||
|
||||
/// 添加反馈信息
|
||||
pub async fn add_feedback(req: FeedbackAdd) -> ResResult<ResData<()>> {
|
||||
pub async fn add_feedback(
|
||||
context: Context,
|
||||
req: FeedbackAdd
|
||||
) -> ResResult<ResData<()>> {
|
||||
let account = context.account;
|
||||
match Feedback::add_feedback(&mut Feedback{
|
||||
user_id: req.user_id.unwrap(),
|
||||
user_id: account.id.clone(),
|
||||
content: req.content.unwrap(),
|
||||
..Default::default()
|
||||
}, db!()).await {
|
||||
|
@ -12,22 +12,21 @@ use i18n::{
|
||||
};
|
||||
use library::{
|
||||
cache::account_cache::{CacheAccount, LOGIN_CACHE},
|
||||
context::Context,
|
||||
db,
|
||||
res::response::{ResData, ResErr, ResResult},
|
||||
token::{generate_refresh_token, generate_token},
|
||||
};
|
||||
|
||||
pub async fn authenticate_with_password(
|
||||
context: Context,
|
||||
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!(
|
||||
context.get_lang_id(),
|
||||
&lang_tag,
|
||||
INCORRECT_USERNAME_OR_PASSWORD
|
||||
)));
|
||||
}
|
||||
@ -35,14 +34,14 @@ pub async fn authenticate_with_password(
|
||||
if account.disable_time > Utc::now() {
|
||||
tracing::error!("账户已禁用");
|
||||
return Err(ResErr::auth(message!(
|
||||
context.get_lang_id(),
|
||||
&lang_tag,
|
||||
ACCOUNT_DISABLED
|
||||
)));
|
||||
}
|
||||
if !account.role.is_admin() {
|
||||
tracing::error!("账户不是管理员,无权限");
|
||||
return Err(ResErr::perm(message!(
|
||||
context.get_lang_id(),
|
||||
&lang_tag,
|
||||
ACCOUNT_NO_PERMISSION
|
||||
)));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user