fix(security): resolve audit findings and compilation errors (Phase 6)
Security fixes: - Add startup warning for default JWT secret in config - Add enum validation for priority, recipient_type, channel fields - Add pagination size cap (max 100) via safe_page_size() - Return generic "权限不足" instead of specific permission names Compilation fixes: - Fix missing standard fields in ActiveModel for tokens/process_variables - Fix migration imports for Statement/DatabaseBackend/Uuid - Add version_field to process_definition ActiveModel Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -41,14 +41,30 @@ pub struct SendMessageReq {
|
||||
pub body: String,
|
||||
pub recipient_id: Uuid,
|
||||
#[serde(default = "default_recipient_type")]
|
||||
#[validate(custom(function = "validate_recipient_type"))]
|
||||
pub recipient_type: String,
|
||||
#[serde(default = "default_priority")]
|
||||
#[validate(custom(function = "validate_priority"))]
|
||||
pub priority: String,
|
||||
pub template_id: Option<Uuid>,
|
||||
pub business_type: Option<String>,
|
||||
pub business_id: Option<Uuid>,
|
||||
}
|
||||
|
||||
fn validate_recipient_type(value: &str) -> Result<(), validator::ValidationError> {
|
||||
match value {
|
||||
"user" | "role" | "department" | "all" => Ok(()),
|
||||
_ => Err(validator::ValidationError::new("invalid_recipient_type")),
|
||||
}
|
||||
}
|
||||
|
||||
fn validate_priority(value: &str) -> Result<(), validator::ValidationError> {
|
||||
match value {
|
||||
"normal" | "important" | "urgent" => Ok(()),
|
||||
_ => Err(validator::ValidationError::new("invalid_priority")),
|
||||
}
|
||||
}
|
||||
|
||||
fn default_recipient_type() -> String {
|
||||
"user".to_string()
|
||||
}
|
||||
@@ -68,6 +84,13 @@ pub struct MessageQuery {
|
||||
pub status: Option<String>,
|
||||
}
|
||||
|
||||
impl MessageQuery {
|
||||
/// 获取安全的分页大小(上限 100)。
|
||||
pub fn safe_page_size(&self) -> u64 {
|
||||
self.page_size.unwrap_or(20).min(100)
|
||||
}
|
||||
}
|
||||
|
||||
/// 未读消息计数响应
|
||||
#[derive(Debug, Serialize, ToSchema)]
|
||||
pub struct UnreadCountResp {
|
||||
@@ -99,6 +122,7 @@ pub struct CreateTemplateReq {
|
||||
#[validate(length(min = 1, max = 50, message = "编码不能为空且不超过50字符"))]
|
||||
pub code: String,
|
||||
#[serde(default = "default_channel")]
|
||||
#[validate(custom(function = "validate_channel"))]
|
||||
pub channel: String,
|
||||
#[validate(length(min = 1, max = 200, message = "标题模板不能为空"))]
|
||||
pub title_template: String,
|
||||
@@ -112,6 +136,13 @@ fn default_channel() -> String {
|
||||
"in_app".to_string()
|
||||
}
|
||||
|
||||
fn validate_channel(value: &str) -> Result<(), validator::ValidationError> {
|
||||
match value {
|
||||
"in_app" | "email" | "sms" | "wechat" => Ok(()),
|
||||
_ => Err(validator::ValidationError::new("invalid_channel")),
|
||||
}
|
||||
}
|
||||
|
||||
fn default_language() -> String {
|
||||
"zh-CN".to_string()
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ impl MessageService {
|
||||
query: &MessageQuery,
|
||||
db: &sea_orm::DatabaseConnection,
|
||||
) -> MessageResult<(Vec<MessageResp>, u64)> {
|
||||
let page_size = query.page_size.unwrap_or(20);
|
||||
let page_size = query.safe_page_size();
|
||||
let mut q = message::Entity::find()
|
||||
.filter(message::Column::TenantId.eq(tenant_id))
|
||||
.filter(message::Column::RecipientId.eq(recipient_id))
|
||||
|
||||
Reference in New Issue
Block a user