elunez / eladmin

eladmin jpa 版本:项目基于 Spring Boot 2.6.4、 Jpa、 Spring Security、Redis、Vue的前后端分离的后台管理系统,项目采用分模块开发方式, 权限控制采用 RBAC,支持数据字典与数据权限管理,支持一键生成前后端代码,支持动态路由
https://eladmin.vip/demo
Apache License 2.0
21.04k stars 7.33k forks source link

getDeptIds(UserDto user)提取的机构权限错乱, 这个方法绝对是不稳定的 , 给的逻辑不对 ❌ #801

Closed LonelyTear closed 1 year ago

LonelyTear commented 1 year ago

🚩问题描述: getDeptIds(UserDto user)这个方法绝对是不稳定的 , 给的逻辑不对

🚩版本: 不知道这项目的版本在哪看, 总之2023/07/03 18:00:00 的时候还是这样子的

🚩环境:本地/线上

🚩复现步骤: 根据用户查角色没有按角色级别排序 , 默认按的角色id大小排的正序 , 当查出的角色顺序是 本级 , 全部 , 自定义 , 则用户只有本级机构权限; 当查出的角色顺序是 自定义 , 全部 , 本级 , 则用户只有自定义机构权限; 当查出的角色顺序是 自定义1, 全部, 自定义2 , 自定义3 , 则用户只有自定义1的机构权限, 追加一堆角色会导致机构权限乱七八糟的! 一会有这个机构权限, 一会没有的那个机构权限. 总结 : 遇到全部就会直接退出循环, 把最近累计的机构返回 , 这一点和只有一个"全部"这个类型的的角色时返回的空机构相违背.

🚩代码位置: https://github.com/elunez/eladmin/blob/master/eladmin-system/src/main/java/me/zhengjie/modules/system/service/impl/DataServiceImpl.java

🚩日志提供:直接看视频↓

🚩视频🎬: 【eladmin角色机构权限bug-哔哩哔哩】 https://b23.tv/PRAr9Xx

🚩代码说明:

@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "data")
public class DataServiceImpl implements DataService {

    private final RoleService roleService;
    private final DeptService deptService;

    /**
     * 用户角色改变时需清理缓存
     * @param user /
     * @return /
     */
    @Override
    //@Cacheable(key = "'user:' + #p0.id")//需要还原
    public List<Long> getDeptIds(UserDto user) {
        // 用于存储部门id
        Set<Long> deptIds = new HashSet<>();
        // 查询用户角色
        List<RoleSmallDto> roleSet = roleService.findByUsersId(user.getId());
        // 获取对应的部门ID
        for (RoleSmallDto role : roleSet) {
            DataScopeEnum dataScopeEnum = DataScopeEnum.find(role.getDataScope());//dataScope有 全部 , 本级 , 自定义 三种 
            switch (Objects.requireNonNull(dataScopeEnum)) {
                case THIS_LEVEL:
                    deptIds.add(user.getDept().getId());
                    break;
                case CUSTOMIZE:
                    deptIds.addAll(getCustomize(deptIds, role));
                    break;
                default:
                    return new ArrayList<>(deptIds);
            }
        }
        return new ArrayList<>(deptIds);
    }
}

如果按照作者的本意设计, 遇到"全部"这个类型的角色就不返回机构编码的话, 那

                default:
                    return new ArrayList<>(deptIds);

应该改成

                default:
                    return new ArrayList<>();//去掉累加的deptIds

最终像下面这样才合理

@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "data")
public class DataServiceImpl implements DataService {

    private final RoleService roleService;
    private final DeptService deptService;

    /**
     * 用户角色改变时需清理缓存
     * @param user /
     * @return /
     */
    @Override
    //@Cacheable(key = "'user:' + #p0.id")//需要还原
    public List<Long> getDeptIds(UserDto user) {
        // 用于存储部门id
        Set<Long> deptIds = new HashSet<>();
        // 查询用户角色
        List<RoleSmallDto> roleSet = roleService.findByUsersId(user.getId());
        // 获取对应的部门ID
        for (RoleSmallDto role : roleSet) {
            DataScopeEnum dataScopeEnum = DataScopeEnum.find(role.getDataScope());//dataScope有 全部 , 本级 , 自定义 三种 
            switch (Objects.requireNonNull(dataScopeEnum)) {
                case THIS_LEVEL:
                    deptIds.add(user.getDept().getId());
                    break;
                case CUSTOMIZE:
                    deptIds.addAll(getCustomize(deptIds, role));
                    break;
                default:
                    return new ArrayList<>();
            }
        }
        return new ArrayList<>(deptIds);
    }
}
elunez commented 1 year ago

感谢,已修复