前端项目初始化提交
This commit is contained in:
151
私人文件查看权限更新.md
Normal file
151
私人文件查看权限更新.md
Normal file
@@ -0,0 +1,151 @@
|
||||
私人文件权限控制修改文档
|
||||
|
||||
📋 修改概述
|
||||
|
||||
修改目标:实现私人文件(isPublic=0)的严格访问控制,确保只有文件所有者本人可以查看和访问。
|
||||
修改时间:2026-05-06 修改文件:FileServiceImpl.java
|
||||
|
||||
影响范围:文件查询、文件详情查看、文件内容下载/预览功能
|
||||
|
||||
🔍 问题分析
|
||||
原有问题
|
||||
在修改前,系统的文件权限控制存在以下安全漏洞:
|
||||
私人文件未隔离:即使是 isPublic=0 的私人文件,同部门的其他用户也能看到和访问
|
||||
权限检查缺失:checkFilePermission 方法没有区分文件的公开/私人属性
|
||||
查询过滤不足:pageFiles 方法在列表查询时未排除他人的私人文件
|
||||
安全隐患
|
||||
❌ 用户A上传的私人文件,同部门的用户B也能看到
|
||||
❌ 部门管理员可以查看所有本部门用户的私人文件
|
||||
❌ 隐私数据可能被未授权人员访问
|
||||
|
||||
✅ 修改内容
|
||||
修改点 1:增强权限检查逻辑
|
||||
位置:第 475-506 行 方法:checkFilePermission(File file, User user)
|
||||
修改前代码
|
||||
|
||||
private void checkFilePermission(top.tqx.demo_1.entity.File file, top.tqx.demo_1.entity.User user) {
|
||||
Integer userType = user.getUserType();
|
||||
Long currentUserId = user.getId();
|
||||
Long currentDeptId = user.getDeptId();
|
||||
|
||||
if (userType.equals(CommonConstant.RoleType.SUPER_ADMIN)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (userType.equals(CommonConstant.RoleType.DEPT_ADMIN)) {
|
||||
if (!file.getDeptId().equals(currentDeptId)) {
|
||||
throw new RuntimeException("无权限查看此文件");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (userType.equals(CommonConstant.RoleType.NORMAL_USER)) {
|
||||
if (!file.getDeptId().equals(currentDeptId)) {
|
||||
throw new RuntimeException("无权限查看此文件");
|
||||
}
|
||||
if (!file.getUploadUserId().equals(currentUserId)) {
|
||||
throw new RuntimeException("无权限查看此文件");
|
||||
}
|
||||
if (file.getAuditStatus() != null && file.getAuditStatus() == 0) {
|
||||
throw new RuntimeException("文件待审核,暂时无法查看");
|
||||
}
|
||||
}
|
||||
修改后代码
|
||||
|
||||
private void checkFilePermission(top.tqx.demo_1.entity.File file, top.tqx.demo_1.entity.User user) {
|
||||
Integer userType = user.getUserType();
|
||||
Long currentUserId = user.getId();
|
||||
Long currentDeptId = user.getDeptId();
|
||||
|
||||
// 超级管理员拥有所有权限
|
||||
if (userType.equals(CommonConstant.RoleType.SUPER_ADMIN)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 【新增】私人文件权限检查:只有上传者本人可访问
|
||||
if (file.getIsPublic() != null && file.getIsPublic() == 0) {
|
||||
if (!file.getUploadUserId().equals(currentUserId)) {
|
||||
throw new RuntimeException("无权限查看此私人文件");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// 公开文件的部门权限检查
|
||||
if (userType.equals(CommonConstant.RoleType.DEPT_ADMIN)) {
|
||||
if (!file.getDeptId().equals(currentDeptId)) {
|
||||
throw new RuntimeException("无权限查看此文件");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (userType.equals(CommonConstant.RoleType.NORMAL_USER)) {
|
||||
if (!file.getDeptId().equals(currentDeptId)) {
|
||||
throw new RuntimeException("无权限查看此文件");
|
||||
}
|
||||
if (file.getAuditStatus() != null && file.getAuditStatus() == 0) {
|
||||
throw new RuntimeException("文件待审核,暂时无法查看");
|
||||
}
|
||||
}
|
||||
|
||||
关键改进
|
||||
✅ 优先检查私人文件:在任何其他权限判断之前,先判断是否为私人文件 ✅ 严格所有者验证:私人文件必须满足 uploadUserId == currentUserId ✅ 提前返回机制:私人文件检查通过后直接返回,避免后续逻辑干扰
|
||||
|
||||
修改点 2:增强列表查询过滤
|
||||
位置:第 48-87 行 方法:pageFiles(Integer pageNum, Integer pageSize, String fileName, User user)
|
||||
修改前代码
|
||||
|
||||
```
|
||||
if (userType.equals(CommonConstant.RoleType.SUPER_ADMIN)) {
|
||||
wrapper.eq(File::getStatus, CommonConstant.STATUS_ENABLE);
|
||||
} else if (userType.equals(CommonConstant.RoleType.DEPT_ADMIN)) {
|
||||
wrapper.eq(File::getStatus, CommonConstant.STATUS_ENABLE);
|
||||
wrapper.and(w -> w.eq(File::getDeptId, currentDeptId)
|
||||
.or().eq(File::getUploadUserId, currentUserId));
|
||||
} else if (userType.equals(CommonConstant.RoleType.NORMAL_USER)) {
|
||||
wrapper.eq(File::getStatus, CommonConstant.STATUS_ENABLE);
|
||||
wrapper.ne(File::getAuditStatus, 0);
|
||||
wrapper.and(w -> w.eq(File::getDeptId, currentDeptId)
|
||||
.or().eq(File::getUploadUserId, currentUserId));
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
修改后代码
|
||||
|
||||
```
|
||||
if (userType.equals(CommonConstant.RoleType.SUPER_ADMIN)) {
|
||||
wrapper.eq(File::getStatus, CommonConstant.STATUS_ENABLE);
|
||||
} else if (userType.equals(CommonConstant.RoleType.DEPT_ADMIN)) {
|
||||
wrapper.eq(File::getStatus, CommonConstant.STATUS_ENABLE);
|
||||
wrapper.and(w -> w.eq(File::getDeptId, currentDeptId)
|
||||
.or().eq(File::getUploadUserId, currentUserId));
|
||||
// 【新增】排除他人私人文件
|
||||
wrapper.and(w -> w.ne(File::getIsPublic, 0)
|
||||
.or().eq(File::getUploadUserId, currentUserId));
|
||||
} else if (userType.equals(CommonConstant.RoleType.NORMAL_USER)) {
|
||||
wrapper.eq(File::getStatus, CommonConstant.STATUS_ENABLE);
|
||||
wrapper.ne(File::getAuditStatus, 0);
|
||||
wrapper.and(w -> w.eq(File::getDeptId, currentDeptId)
|
||||
.or().eq(File::getUploadUserId, currentUserId));
|
||||
// 【新增】排除他人私人文件
|
||||
wrapper.and(w -> w.ne(File::getIsPublic, 0)
|
||||
.or().eq(File::getUploadUserId, currentUserId));
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
SQL 逻辑说明
|
||||
新增的过滤条件生成的 SQL 逻辑为:
|
||||
|
||||
```
|
||||
-- 对于部门管理员和普通用户
|
||||
WHERE ...
|
||||
AND (
|
||||
is_public != 0 -- 非私人文件
|
||||
OR upload_user_id = currentUserId -- 或者是自己上传的文件
|
||||
)
|
||||
|
||||
```
|
||||
|
||||
关键改进
|
||||
✅ 数据库层过滤:在查询阶段就排除他人私人文件,提升性能和安全性 ✅ 双重保护:既在查询层过滤,又在访问层检查,形成纵深防御 ✅ 保留自身访问:用户可以查看自己的私人文件(包括已上传的私人文件)
|
||||
Reference in New Issue
Block a user