From ed12cb8c367aaa642c21fbe40b8205cf3326da85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E5=8D=9A=E6=96=87?= Date: Mon, 23 Jun 2025 16:52:35 +0800 Subject: [PATCH] =?UTF-8?q?=E6=A0=87=E5=87=86=E8=A7=92=E8=89=B2=E5=8F=AA?= =?UTF-8?q?=E5=85=81=E8=AE=B8=E7=AE=A1=E7=90=86=E5=91=98=E8=BF=9B=E8=A1=8C?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E8=8F=9C=E5=8D=95=E6=9D=83=E9=99=90=E4=B8=8E?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../system/enums/ErrorCodeConstants.java | 2 ++ .../system/enums/permission/RoleTypeEnum.java | 11 +++++++++- .../permission/PermissionServiceImpl.java | 19 +++++++++++++++++ .../service/permission/RoleServiceImpl.java | 5 +++++ .../permission/PermissionServiceTest.java | 10 +++++++-- .../permission/RoleServiceImplTest.java | 21 ++++++++++++++++++- 6 files changed, 64 insertions(+), 4 deletions(-) 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);