|
|
@@ -89,8 +89,7 @@ public class GuideFamilyTaskController {
|
|
|
/**
|
|
|
* 会员任务校验:task.memberOnly==1 且家庭非会员 → 拒绝(提示开通会员)
|
|
|
*/
|
|
|
- private Result<?> checkMemberOnly(Long taskId) {
|
|
|
- Task task = taskMapper.selectById(taskId);
|
|
|
+ private Result<?> checkMemberOnly(Task task) {
|
|
|
if (task == null) {
|
|
|
return Result.error("任务不存在");
|
|
|
}
|
|
|
@@ -329,7 +328,16 @@ public class GuideFamilyTaskController {
|
|
|
if (!RolesUtil.hasTeacherRole(role, roles)) { return Result.error("Access denied"); }
|
|
|
Result<Void> denied = requireBound(guideId, familyId);
|
|
|
if (denied != null) return Result.error(denied.getCode(), denied.getMessage());
|
|
|
- Result<?> memberCheck = checkMemberOnly(taskId);
|
|
|
+
|
|
|
+ // SC-T-06/TC-T-09-P 数据隔离:被审任务必须属于路径 familyId,否则拒绝(防跨家庭越权审核 IDOR)
|
|
|
+ Task task = taskMapper.selectById(taskId);
|
|
|
+ if (task == null) {
|
|
|
+ return Result.error("任务不存在");
|
|
|
+ }
|
|
|
+ if (!familyId.equals(task.getFamilyId())) {
|
|
|
+ return Result.error(403, "任务不属于该家庭");
|
|
|
+ }
|
|
|
+ Result<?> memberCheck = checkMemberOnly(task);
|
|
|
if (memberCheck != null) {
|
|
|
return Result.error(memberCheck.getMessage());
|
|
|
}
|
|
|
@@ -373,8 +381,19 @@ public class GuideFamilyTaskController {
|
|
|
|
|
|
for (Long taskId : taskIds) {
|
|
|
try {
|
|
|
+ Task task = taskMapper.selectById(taskId);
|
|
|
+ if (task == null) {
|
|
|
+ failCount++;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ // SC-T-06/TC-T-09-P 数据隔离:被审任务必须属于路径 familyId,
|
|
|
+ // 跨家庭任务跳过且不进入审核(TC-T-18-E 部分失败不影响其他,各自独立不落库)
|
|
|
+ if (!familyId.equals(task.getFamilyId())) {
|
|
|
+ failCount++;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
// 会员任务校验:审核通过会员任务需家庭为会员
|
|
|
- Result<?> memberCheck = checkMemberOnly(taskId);
|
|
|
+ Result<?> memberCheck = checkMemberOnly(task);
|
|
|
if (memberCheck != null) {
|
|
|
failCount++;
|
|
|
continue;
|