diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java index 8510264b..b7293c79 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/ErrorCodeConstants.java @@ -34,6 +34,8 @@ public interface ErrorCodeConstants { ErrorCode ROLE_IS_DISABLE = new ErrorCode(1_002_002_004, "名字为【{}】的角色已被禁用"); ErrorCode ROLE_ADMIN_CODE_ERROR = new ErrorCode(1_002_002_005, "标识【{}】不能使用"); + ErrorCode ROLE_CAN_NOT_UPDATE_NORMAL_TYPE_ROLE = new ErrorCode(1_002_002_006, "不能操作类型为标准的角色,除非是管理员角色"); + // ========== 用户模块 1-002-003-000 ========== ErrorCode USER_USERNAME_EXISTS = new ErrorCode(1_002_003_000, "用户账号已经存在"); ErrorCode USER_MOBILE_EXISTS = new ErrorCode(1_002_003_001, "手机号已经存在"); diff --git a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/RoleTypeEnum.java b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/RoleTypeEnum.java index 1607b20b..47f7eee4 100644 --- a/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/RoleTypeEnum.java +++ b/yudao-module-system/yudao-module-system-api/src/main/java/cn/iocoder/yudao/module/system/enums/permission/RoleTypeEnum.java @@ -3,6 +3,10 @@ package cn.iocoder.yudao.module.system.enums.permission; import lombok.AllArgsConstructor; import lombok.Getter; +/** + * @author chenbowen + */ + @Getter @AllArgsConstructor public enum RoleTypeEnum { @@ -11,11 +15,16 @@ public enum RoleTypeEnum { * 内置角色 */ SYSTEM(1), + /** + * 标准角色 + */ + NORMAL(2), /** * 自定义角色 */ - CUSTOM(2); + CUSTOM(3); private final Integer type; } + diff --git a/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java b/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java index 86d1fd7c..1c58d41b 100644 --- a/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java +++ b/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceImpl.java @@ -16,6 +16,7 @@ import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMenuMapper; import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleMapper; import cn.iocoder.yudao.module.system.dal.redis.RedisKeyConstants; import cn.iocoder.yudao.module.system.enums.permission.DataScopeEnum; +import cn.iocoder.yudao.module.system.enums.permission.RoleTypeEnum; import cn.iocoder.yudao.module.system.service.dept.DeptService; import cn.iocoder.yudao.module.system.service.user.AdminUserService; import com.baomidou.dynamic.datasource.annotation.DSTransactional; @@ -24,6 +25,7 @@ import com.google.common.base.Suppliers; import com.google.common.collect.Sets; import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.Caching; @@ -33,8 +35,11 @@ import org.springframework.transaction.annotation.Transactional; import java.util.*; import java.util.function.Supplier; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; import static cn.iocoder.yudao.framework.common.util.json.JsonUtils.toJsonString; +import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; +import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.ROLE_CAN_NOT_UPDATE_SYSTEM_TYPE_ROLE; /** * 权限 Service 实现类 @@ -58,6 +63,8 @@ public class PermissionServiceImpl implements PermissionService { private DeptService deptService; @Resource private AdminUserService userService; + @Autowired + private PermissionService permissionService; @Override public boolean hasAnyPermissions(Long userId, String... permissions) { @@ -139,6 +146,12 @@ public class PermissionServiceImpl implements PermissionService { allEntries = true) // allEntries 清空所有缓存,主要一次更新涉及到的 menuIds 较多,反倒批量会更快 }) public void assignRoleMenu(Long roleId, Set menuIds) { + RoleDO role = roleService.getRole(roleId); + Set userRoleIdListByUserId = permissionService.getUserRoleIdListByUserId(getLoginUserId()); + // 如果为标准角色,只允许管理员修改菜单权限 + if (RoleTypeEnum.NORMAL.getType().equals(role.getType()) && !roleService.hasAnySuperAdmin(userRoleIdListByUserId)) { + throw exception(ROLE_CAN_NOT_UPDATE_SYSTEM_TYPE_ROLE); + } // 获得角色拥有菜单编号 Set dbMenuIds = convertSet(roleMenuMapper.selectListByRoleId(roleId), RoleMenuDO::getMenuId); // 计算新增和删除的菜单编号 @@ -269,6 +282,12 @@ public class PermissionServiceImpl implements PermissionService { @Override public void assignRoleDataScope(Long roleId, Integer dataScope, Set dataScopeDeptIds) { + RoleDO role = roleService.getRole(roleId); + Set userRoleIdListByUserId = permissionService.getUserRoleIdListByUserId(getLoginUserId()); + // 如果为标准角色,只允许管理员修改数据权限 + if (RoleTypeEnum.NORMAL.getType().equals(role.getType()) && !roleService.hasAnySuperAdmin(userRoleIdListByUserId)) { + throw exception(ROLE_CAN_NOT_UPDATE_SYSTEM_TYPE_ROLE); + } roleService.updateRoleDataScope(roleId, dataScope, dataScopeDeptIds); } diff --git a/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java b/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java index c18ef31c..ffa1cb9f 100644 --- a/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java +++ b/yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImpl.java @@ -169,6 +169,11 @@ public class RoleServiceImpl implements RoleService { if (RoleTypeEnum.SYSTEM.getType().equals(role.getType())) { throw exception(ROLE_CAN_NOT_UPDATE_SYSTEM_TYPE_ROLE); } + // 标准角色非管理员不允许修改 + if (RoleTypeEnum.NORMAL.getType().equals(role.getType()) + && !RoleCodeEnum.isSuperAdmin(role.getCode())) { + throw exception(ROLE_CAN_NOT_UPDATE_NORMAL_TYPE_ROLE); + } return role; } diff --git a/yudao-module-system/yudao-module-system-server/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java b/yudao-module-system/yudao-module-system-server/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java index 3511034f..1bb04300 100644 --- a/yudao-module-system/yudao-module-system-server/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java +++ b/yudao-module-system/yudao-module-system-server/src/test/java/cn/iocoder/yudao/module/system/service/permission/PermissionServiceTest.java @@ -1,10 +1,13 @@ package cn.iocoder.yudao.module.system.service.permission; import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest; +import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO; import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleMenuDO; import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO; +import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMapper; import cn.iocoder.yudao.module.system.dal.mysql.permission.RoleMenuMapper; import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleMapper; +import cn.iocoder.yudao.module.system.enums.permission.RoleTypeEnum; import cn.iocoder.yudao.module.system.service.dept.DeptService; import cn.iocoder.yudao.module.system.service.user.AdminUserService; import jakarta.annotation.Resource; @@ -33,6 +36,8 @@ public class PermissionServiceTest extends BaseDbUnitTest { @Resource private UserRoleMapper userRoleMapper; + @Resource + private RoleMapper roleMapper; @Resource private RoleServiceImpl roleService; @MockBean @@ -47,7 +52,8 @@ public class PermissionServiceTest extends BaseDbUnitTest { @Test public void testAssignRoleMenu() { // 准备参数 - Long roleId = 1L; + RoleDO role = randomPojo(RoleDO.class, o -> o.setType(RoleTypeEnum.CUSTOM.getType()).setId(1L).setTenantId(0L)); + roleMapper.insert(role); Set menuIds = asSet(200L, 300L); // mock 数据 RoleMenuDO roleMenu01 = randomPojo(RoleMenuDO.class).setRoleId(1L).setMenuId(100L); @@ -58,7 +64,7 @@ public class PermissionServiceTest extends BaseDbUnitTest { roleMenuMapper.insert(roleMenu02); // 调用 - permissionService.assignRoleMenu(roleId, menuIds); + permissionService.assignRoleMenu(role.getId(), menuIds); // 断言 List roleMenuList = roleMenuMapper.selectList(); assertEquals(2, roleMenuList.size()); diff --git a/yudao-module-system/yudao-module-system-server/src/test/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImplTest.java b/yudao-module-system/yudao-module-system-server/src/test/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImplTest.java index 404160e9..8268cd89 100644 --- a/yudao-module-system/yudao-module-system-server/src/test/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImplTest.java +++ b/yudao-module-system/yudao-module-system-server/src/test/java/cn/iocoder/yudao/module/system/service/permission/RoleServiceImplTest.java @@ -151,7 +151,7 @@ public class RoleServiceImplTest extends BaseDbUnitTest { @Test public void testValidateUpdateRole_success() { RoleDO roleDO = randomPojo(RoleDO.class); - roleMapper.insert(roleDO); + roleMapper.insert(roleDO.setType(RoleTypeEnum.CUSTOM.getType())); // 准备参数 Long id = roleDO.getId(); @@ -159,6 +159,25 @@ public class RoleServiceImplTest extends BaseDbUnitTest { roleService.validateRoleForUpdate(id); } + @Test + public void testValidateUpdateRole_fail() { + RoleDO roleDO = randomPojo(RoleDO.class); + roleMapper.insert(roleDO.setType(RoleTypeEnum.SYSTEM.getType())); + // 准备参数 + Long systemRoleId = roleDO.getId(); + + RoleDO normalRoleDO = randomPojo(RoleDO.class); + roleMapper.insert(normalRoleDO.setType(RoleTypeEnum.NORMAL.getType())); + // 准备参数 + Long normalRoleId = normalRoleDO.getId(); + + // 调用,并断言异常 + assertServiceException(() -> roleService.validateRoleForUpdate(normalRoleId), + ROLE_CAN_NOT_UPDATE_NORMAL_TYPE_ROLE); + assertServiceException(() -> roleService.validateRoleForUpdate(systemRoleId), + ROLE_CAN_NOT_UPDATE_SYSTEM_TYPE_ROLE); + } + @Test public void testValidateUpdateRole_roleIdNotExist() { assertServiceException(() -> roleService.validateRoleForUpdate(randomLongId()), ROLE_NOT_EXISTS);