fix(diary): 修复日记列表 IDOR — 非管理角色只能查看自己的日记

- list_journals: 学生/家长等非管理角色强制 author_id = ctx.user_id
- get_journal: 非管理角色查看他人日记返回 404(避免信息泄露)
- 老师/管理员角色保留查看任意日记的能力(点评/管理需要)
- 家长应通过 parent_service 专用端点查看孩子日记

审计 ID: S-07
This commit is contained in:
iven
2026-06-03 01:08:00 +08:00
parent 9ce300ddb9
commit af7d3f65fd

View File

@@ -105,6 +105,13 @@ where
require_permission(&ctx, "diary.journal.read")?;
let resp = JournalService::get_by_id(ctx.tenant_id, id, &state.db).await?;
// IDOR 修复:非管理角色只能查看自己的日记
if !ctx.roles.iter().any(|r| r == "teacher" || r == "admin") {
if resp.author_id != ctx.user_id {
return Err(AppError::NotFound(format!("日记 {} 不存在", id)));
}
}
Ok(Json(ApiResponse::ok(resp)))
}
@@ -238,9 +245,21 @@ where
let page = params.page.unwrap_or(1);
let page_size = params.page_size.unwrap_or(20).min(100);
// IDOR 修复:非管理角色只能查看自己的日记
// - 学生:强制 author_id = ctx.user_id
// - 老师/管理员:允许查看所有日记
// - 家长:应通过 parent_service 专用端点查看孩子日记
let author_id = if ctx.roles.iter().any(|r| r == "teacher" || r == "admin") {
// 管理角色可查看任意作者的日记
params.author_id
} else {
// 学生/家长等非管理角色只能查看自己的日记
Some(ctx.user_id)
};
let (items, total) = JournalService::list(
ctx.tenant_id,
params.author_id,
author_id,
params.mood,
params.date_from,
params.date_to,