fix(diary): 为所有 DTO 添加 Validate derive + handler 调用 validate()
DTO 验证规则: - CreateJournalReq: title 1-200, tags ≤20 - UpdateJournalReq: title 1-200, tags ≤20 - CreateClassReq: name 1-50, school_name ≤100 - JoinClassReq: class_code = 6位 - UpdateClassReq: name 1-50, school_name ≤100 - SyncReq: changes ≤100 条 - CreateTopicReq: title 1-200, description ≤2000 - UpdateTopicReq: title 1-200, description ≤2000 - CreateCommentReq: content 1-1000 - CreateStickerPackReq: name 1-50, description ≤500 - UpdateStickerPackReq: name 1-50, description ≤500 - CreateStickerReq: name 1-30, image_url 1-500 - BindChildReq/DeleteChildDataReq: Validate derive (Uuid 已由 serde 验证) Handler 调用: validate() 放在 require_permission() 之前(先验证输入再检查权限) 审计 ID: 5a-C01, 5a-C02, 5a-C03
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
use axum::extract::{Extension, FromRef, Path, State};
|
||||
use axum::response::Json;
|
||||
use uuid::Uuid;
|
||||
use validator::Validate;
|
||||
|
||||
use erp_core::error::AppError;
|
||||
use erp_core::rbac::require_permission;
|
||||
@@ -37,6 +38,7 @@ where
|
||||
DiaryState: FromRef<S>,
|
||||
S: Clone + Send + Sync + 'static,
|
||||
{
|
||||
req.validate().map_err(|e| AppError::Validation(e.to_string()))?;
|
||||
require_permission(&ctx, "diary.class.manage")?;
|
||||
|
||||
if req.name.trim().is_empty() {
|
||||
@@ -81,6 +83,7 @@ where
|
||||
DiaryState: FromRef<S>,
|
||||
S: Clone + Send + Sync + 'static,
|
||||
{
|
||||
req.validate().map_err(|e| AppError::Validation(e.to_string()))?;
|
||||
require_permission(&ctx, "diary.journal.create")?;
|
||||
|
||||
if req.class_code.trim().is_empty() {
|
||||
@@ -248,6 +251,7 @@ where
|
||||
DiaryState: FromRef<S>,
|
||||
S: Clone + Send + Sync + 'static,
|
||||
{
|
||||
req.validate().map_err(|e| AppError::Validation(e.to_string()))?;
|
||||
require_permission(&ctx, "diary.class.manage")?;
|
||||
|
||||
if let Some(ref name) = req.name {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
use axum::extract::{Extension, FromRef, Path, State};
|
||||
use axum::response::Json;
|
||||
use uuid::Uuid;
|
||||
use validator::Validate;
|
||||
|
||||
use erp_core::error::AppError;
|
||||
use erp_core::rbac::require_permission;
|
||||
@@ -41,6 +42,7 @@ where
|
||||
DiaryState: FromRef<S>,
|
||||
S: Clone + Send + Sync + 'static,
|
||||
{
|
||||
req.validate().map_err(|e| AppError::Validation(e.to_string()))?;
|
||||
require_permission(&ctx, "diary.comment.write")?;
|
||||
|
||||
if req.content.trim().is_empty() {
|
||||
|
||||
@@ -5,6 +5,7 @@ use axum::response::Json;
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
use uuid::Uuid;
|
||||
use validator::Validate;
|
||||
|
||||
use erp_core::error::AppError;
|
||||
use erp_core::rbac::require_permission;
|
||||
@@ -58,6 +59,7 @@ where
|
||||
DiaryState: FromRef<S>,
|
||||
S: Clone + Send + Sync + 'static,
|
||||
{
|
||||
req.validate().map_err(|e| AppError::Validation(e.to_string()))?;
|
||||
require_permission(&ctx, "diary.journal.create")?;
|
||||
|
||||
// 基础验证
|
||||
@@ -145,6 +147,7 @@ where
|
||||
DiaryState: FromRef<S>,
|
||||
S: Clone + Send + Sync + 'static,
|
||||
{
|
||||
req.validate().map_err(|e| AppError::Validation(e.to_string()))?;
|
||||
require_permission(&ctx, "diary.journal.update")?;
|
||||
|
||||
let resp = JournalService::update(
|
||||
|
||||
@@ -5,6 +5,7 @@ use axum::response::Json;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use utoipa::{IntoParams, ToSchema};
|
||||
use uuid::Uuid;
|
||||
use validator::Validate;
|
||||
|
||||
use erp_core::error::AppError;
|
||||
use erp_core::rbac::require_permission;
|
||||
@@ -17,7 +18,7 @@ use crate::state::DiaryState;
|
||||
// ---- 请求/响应 DTO ----
|
||||
|
||||
/// 绑定孩子请求
|
||||
#[derive(Debug, Deserialize, ToSchema)]
|
||||
#[derive(Debug, Deserialize, Validate, ToSchema)]
|
||||
pub struct BindChildReq {
|
||||
/// 孩子的用户 ID
|
||||
pub child_id: Uuid,
|
||||
@@ -42,7 +43,7 @@ pub struct ExportQuery {
|
||||
}
|
||||
|
||||
/// 删除孩子数据请求
|
||||
#[derive(Debug, Deserialize, ToSchema)]
|
||||
#[derive(Debug, Deserialize, Validate, ToSchema)]
|
||||
pub struct DeleteChildDataReq {
|
||||
/// 孩子的用户 ID
|
||||
pub child_id: Uuid,
|
||||
|
||||
@@ -5,6 +5,7 @@ use axum::response::Json;
|
||||
use serde::Deserialize;
|
||||
use utoipa::IntoParams;
|
||||
use uuid::Uuid;
|
||||
use validator::Validate;
|
||||
|
||||
use erp_core::error::AppError;
|
||||
use erp_core::rbac::require_permission;
|
||||
@@ -110,6 +111,7 @@ where
|
||||
DiaryState: FromRef<S>,
|
||||
S: Clone + Send + Sync + 'static,
|
||||
{
|
||||
req.validate().map_err(|e| AppError::Validation(e.to_string()))?;
|
||||
require_permission(&ctx, "diary.class.manage")?;
|
||||
|
||||
if req.name.trim().is_empty() {
|
||||
@@ -155,6 +157,7 @@ where
|
||||
DiaryState: FromRef<S>,
|
||||
S: Clone + Send + Sync + 'static,
|
||||
{
|
||||
req.validate().map_err(|e| AppError::Validation(e.to_string()))?;
|
||||
require_permission(&ctx, "diary.class.manage")?;
|
||||
|
||||
if let Some(ref name) = req.name {
|
||||
@@ -235,6 +238,7 @@ where
|
||||
DiaryState: FromRef<S>,
|
||||
S: Clone + Send + Sync + 'static,
|
||||
{
|
||||
req.validate().map_err(|e| AppError::Validation(e.to_string()))?;
|
||||
require_permission(&ctx, "diary.class.manage")?;
|
||||
|
||||
if req.name.trim().is_empty() {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
use axum::extract::{Extension, FromRef, State};
|
||||
use axum::response::Json;
|
||||
use validator::Validate;
|
||||
|
||||
use erp_core::error::AppError;
|
||||
use erp_core::rbac::require_permission;
|
||||
@@ -38,6 +39,7 @@ where
|
||||
DiaryState: FromRef<S>,
|
||||
S: Clone + Send + Sync + 'static,
|
||||
{
|
||||
req.validate().map_err(|e| AppError::Validation(e.to_string()))?;
|
||||
require_permission(&ctx, "diary.journal.read")?;
|
||||
|
||||
let resp = SyncService::sync(
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
use axum::extract::{Extension, FromRef, Path, State};
|
||||
use axum::response::Json;
|
||||
use uuid::Uuid;
|
||||
use validator::Validate;
|
||||
|
||||
use erp_core::error::AppError;
|
||||
use erp_core::rbac::require_permission;
|
||||
@@ -40,6 +41,7 @@ where
|
||||
DiaryState: FromRef<S>,
|
||||
S: Clone + Send + Sync + 'static,
|
||||
{
|
||||
req.validate().map_err(|e| AppError::Validation(e.to_string()))?;
|
||||
require_permission(&ctx, "diary.topic.assign")?;
|
||||
|
||||
if req.title.trim().is_empty() {
|
||||
@@ -118,6 +120,7 @@ where
|
||||
DiaryState: FromRef<S>,
|
||||
S: Clone + Send + Sync + 'static,
|
||||
{
|
||||
req.validate().map_err(|e| AppError::Validation(e.to_string()))?;
|
||||
require_permission(&ctx, "diary.topic.assign")?;
|
||||
|
||||
if let Some(ref title) = req.title {
|
||||
|
||||
Reference in New Issue
Block a user