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