添加限制本人分配用户角色、设置菜单权限

This commit is contained in:
yangsb
2024-04-23 15:02:58 +08:00
parent c26fabb760
commit 2bd039c9d9
11 changed files with 74 additions and 12 deletions
@@ -32,6 +32,7 @@ public interface ErrorCodeConstants {
ErrorCode ROLE_CAN_NOT_UPDATE_SYSTEM_TYPE_ROLE = new ErrorCode(1_002_002_003, "不能操作类型为系统内置的角色"); ErrorCode ROLE_CAN_NOT_UPDATE_SYSTEM_TYPE_ROLE = new ErrorCode(1_002_002_003, "不能操作类型为系统内置的角色");
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_ME_ERROR = 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, "用户账号已经存在");
@@ -42,6 +43,7 @@ public interface ErrorCodeConstants {
ErrorCode USER_PASSWORD_FAILED = new ErrorCode(1_002_003_005, "用户密码校验失败"); ErrorCode USER_PASSWORD_FAILED = new ErrorCode(1_002_003_005, "用户密码校验失败");
ErrorCode USER_IS_DISABLE = new ErrorCode(1_002_003_006, "名字为【{}】的用户已被禁用"); ErrorCode USER_IS_DISABLE = new ErrorCode(1_002_003_006, "名字为【{}】的用户已被禁用");
ErrorCode USER_COUNT_MAX = new ErrorCode(1_002_003_008, "创建用户失败,原因:超过组织最大组织配额({})!"); ErrorCode USER_COUNT_MAX = new ErrorCode(1_002_003_008, "创建用户失败,原因:超过组织最大组织配额({})!");
ErrorCode USER_ME_ERROR = new ErrorCode(1_002_003_009, "不可操作用户自身");
// ========== 部门模块 1-002-004-000 ========== // ========== 部门模块 1-002-004-000 ==========
ErrorCode DEPT_NAME_DUPLICATE = new ErrorCode(1_002_004_000, "已经存在该名字的部门"); ErrorCode DEPT_NAME_DUPLICATE = new ErrorCode(1_002_004_000, "已经存在该名字的部门");
@@ -115,6 +117,8 @@ public interface ErrorCodeConstants {
ErrorCode TENANT_PACKAGE_NOT_EXISTS = new ErrorCode(1_002_016_000, "组织套餐不存在"); ErrorCode TENANT_PACKAGE_NOT_EXISTS = new ErrorCode(1_002_016_000, "组织套餐不存在");
ErrorCode TENANT_PACKAGE_USED = new ErrorCode(1_002_016_001, "组织正在使用该套餐,请给组织重新设置套餐后再尝试删除"); ErrorCode TENANT_PACKAGE_USED = new ErrorCode(1_002_016_001, "组织正在使用该套餐,请给组织重新设置套餐后再尝试删除");
ErrorCode TENANT_PACKAGE_DISABLE = new ErrorCode(1_002_016_002, "名字为【{}】的组织套餐已被禁用"); ErrorCode TENANT_PACKAGE_DISABLE = new ErrorCode(1_002_016_002, "名字为【{}】的组织套餐已被禁用");
ErrorCode TENANT_PACKAGE_DEPT_EXIT = new ErrorCode(1_002_016_003, "无法修改内置组织权限套餐");
ErrorCode TENANT_PACKAGE_DELETED_EXIT = new ErrorCode(1_002_016_004, "无法删除内置组织权限套餐");
// ========== 错误码模块 1-002-017-000 ========== // ========== 错误码模块 1-002-017-000 ==========
ErrorCode ERROR_CODE_NOT_EXISTS = new ErrorCode(1_002_017_000, "错误码不存在"); ErrorCode ERROR_CODE_NOT_EXISTS = new ErrorCode(1_002_017_000, "错误码不存在");
@@ -26,6 +26,7 @@ import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static com.cf.imes.framework.common.pojo.CommonResult.success; import static com.cf.imes.framework.common.pojo.CommonResult.success;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ROLE_ME_ERROR;
import static com.cf.imes.module.system.service.organ.OrganServiceImpl.ORGAN_ADMIN_ROLE_ID; import static com.cf.imes.module.system.service.organ.OrganServiceImpl.ORGAN_ADMIN_ROLE_ID;
import static com.cf.imes.module.system.service.organ.OrganServiceImpl.ORGAN_STAFF_ROLE_ID; import static com.cf.imes.module.system.service.organ.OrganServiceImpl.ORGAN_STAFF_ROLE_ID;
@@ -58,8 +59,16 @@ public class PermissionController {
public CommonResult<Boolean> assignRoleMenu(@Validated @RequestBody PermissionAssignRoleMenuReqVO reqVO) { public CommonResult<Boolean> assignRoleMenu(@Validated @RequestBody PermissionAssignRoleMenuReqVO reqVO) {
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser(); LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
if(!loginUser.getIsSupAdmin() && ( Objects.equals(reqVO.getRoleId(), ORGAN_ADMIN_ROLE_ID) || Objects.equals(reqVO.getRoleId(), ORGAN_STAFF_ROLE_ID))) { if(!loginUser.getIsSupAdmin() && ( Objects.equals(reqVO.getRoleId(), ORGAN_ADMIN_ROLE_ID) || Objects.equals(reqVO.getRoleId(), ORGAN_STAFF_ROLE_ID))) {
throw new ServiceException(11541, "内置角色无权修改"); throw new ServiceException(11541, "内置角色无权修改菜单权限");
} }
if(Objects.equals(reqVO.getRoleId(), 1L)) {
throw new ServiceException(11541, "内置角色无权修改菜单权限");
}
Set<Long> roleIds = permissionService.getUserRoleIdListByUserId(loginUser.getId());
if (roleIds.contains(reqVO.getRoleId())) {
throw new ServiceException(11541, "无法修改自身的角色菜单权限");
}
if(Objects.equals(reqVO.getRoleId(), ORGAN_ADMIN_ROLE_ID) || Objects.equals(reqVO.getRoleId(), ORGAN_STAFF_ROLE_ID)) { if(Objects.equals(reqVO.getRoleId(), ORGAN_ADMIN_ROLE_ID) || Objects.equals(reqVO.getRoleId(), ORGAN_STAFF_ROLE_ID)) {
} else { } else {
// 开启多组织的情况下,需要过滤掉未开通的菜单 // 开启多组织的情况下,需要过滤掉未开通的菜单
@@ -100,8 +109,13 @@ public class PermissionController {
@PostMapping("/bath-assign-user-role") @PostMapping("/bath-assign-user-role")
@PreAuthorize("@ss.hasPermission('system:permission:assign-user-role')") @PreAuthorize("@ss.hasPermission('system:permission:assign-user-role')")
public CommonResult<Boolean> bathAssignUserRole(@Validated @RequestBody List<PermissionAssignUserRoleReqVO> listReqVO) { public CommonResult<Boolean> bathAssignUserRole(@Validated @RequestBody List<PermissionAssignUserRoleReqVO> listReqVO) {
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
Set<Long> userIds = listReqVO.stream().map(PermissionAssignUserRoleReqVO::getUserId).collect(Collectors.toSet());
if (userIds.contains(loginUser.getId())) {
throw new ServiceException(ROLE_ME_ERROR);
}
Set<Long> roleIds = listReqVO.stream().flatMap(e -> e.getRoleIds().stream()).collect(Collectors.toSet()); Set<Long> roleIds = listReqVO.stream().flatMap(e -> e.getRoleIds().stream()).collect(Collectors.toSet());
if(!SecurityFrameworkUtils.getLoginUser().getIsSupAdmin()) { if(!loginUser.getIsSupAdmin()) {
if(roleIds.contains(ORGAN_ADMIN_ROLE_ID) || roleIds.contains(ORGAN_STAFF_ROLE_ID)) { if(roleIds.contains(ORGAN_ADMIN_ROLE_ID) || roleIds.contains(ORGAN_STAFF_ROLE_ID)) {
throw new ServiceException(11541, "内置角色无权修改"); throw new ServiceException(11541, "内置角色无权修改");
} }
@@ -32,6 +32,7 @@ import java.io.IOException;
import java.util.Comparator; import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.stream.Collectors;
import static com.cf.imes.framework.common.pojo.CommonResult.success; import static com.cf.imes.framework.common.pojo.CommonResult.success;
import static com.cf.imes.framework.operatelog.core.enums.OperateTypeEnum.EXPORT; import static com.cf.imes.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
@@ -109,8 +110,9 @@ public class RoleController {
@GetMapping({"/list-all-simple", "/simple-list"}) @GetMapping({"/list-all-simple", "/simple-list"})
@Operation(summary = "获取角色精简信息列表", description = "只包含被开启的角色,主要用于前端的下拉选项") @Operation(summary = "获取角色精简信息列表", description = "只包含被开启的角色,主要用于前端的下拉选项")
public CommonResult<List<RoleSimpleRespVO>> getSimpleRoleList() { public CommonResult<List<RoleSimpleRespVO>> getSimpleRoleList(@RequestParam(value = "organId", required = false) Long organId) {
List<RoleDO> list = roleService.getRoleListByStatus(singleton(CommonStatusEnum.ENABLE.getStatus())); List<RoleDO> list = roleService.getRoleListByStatus(singleton(CommonStatusEnum.ENABLE.getStatus()), organId);
//List<RoleDO> roleDOS = list.stream().filter(f -> !Objects.equals(f.getId(), 1L)).sorted(Comparator.comparing(RoleDO::getSort)).toList();
list.sort(Comparator.comparing(RoleDO::getSort)); list.sort(Comparator.comparing(RoleDO::getSort));
return success(BeanUtils.toBean(list, RoleSimpleRespVO.class)); return success(BeanUtils.toBean(list, RoleSimpleRespVO.class));
} }
@@ -39,7 +39,8 @@ public interface RoleMapper extends BaseMapperX<RoleDO> {
lambdaQueryWrapperX.likeIfPresent(RoleDO::getName, reqVO.getName()) lambdaQueryWrapperX.likeIfPresent(RoleDO::getName, reqVO.getName())
.likeIfPresent(RoleDO::getCode, reqVO.getCode()) .likeIfPresent(RoleDO::getCode, reqVO.getCode())
.eqIfPresent(RoleDO::getStatus, reqVO.getStatus()) .eqIfPresent(RoleDO::getStatus, reqVO.getStatus())
.betweenIfPresent(BaseDO::getCreateTime, reqVO.getCreateTime()) .betweenIfPresent(RoleDO::getCreateTime, reqVO.getCreateTime())
.ne(RoleDO::getId, 1)
.orderByDesc(RoleDO::getId); .orderByDesc(RoleDO::getId);
return selectPage(reqVO, lambdaQueryWrapperX); return selectPage(reqVO, lambdaQueryWrapperX);
@@ -53,8 +54,12 @@ public interface RoleMapper extends BaseMapperX<RoleDO> {
return selectOne(RoleDO::getCode, code, RoleDO::getOrganId, organId); return selectOne(RoleDO::getCode, code, RoleDO::getOrganId, organId);
} }
default List<RoleDO> selectListByStatus(@Nullable Collection<Integer> statuses) { default List<RoleDO> selectListByStatus(@Nullable Collection<Integer> statuses, Long organId) {
return selectList(RoleDO::getStatus, statuses); return selectList(new LambdaQueryWrapperX<RoleDO>()
.eqIfPresent(RoleDO::getOrganId, organId)
.eq(RoleDO::getStatus, statuses)
.ne(RoleDO::getId, 1)
);
} }
} }
@@ -242,8 +242,8 @@ public class OrganServiceImpl implements OrganService {
public void updateOrganRoleMenu(Long organId, Set<Long> menuIds) { public void updateOrganRoleMenu(Long organId, Set<Long> menuIds) {
OrganUtils.execute(organId, () -> { OrganUtils.execute(organId, () -> {
// 获得所有角色 // 获得所有角色
List<RoleDO> roles = roleService.getRoleList(); List<RoleDO> roles = roleService.getMeAndDefaultRoleList();
roles.forEach(role -> Assert.isTrue(organId.equals(role.getOrganId()), "角色({}/{}) 组织不匹配", roles.forEach(role -> Assert.isTrue(organId.equals(role.getOrganId()) || role.getOrganId().equals(0L), "角色({}/{}) 组织不匹配",
role.getId(), role.getOrganId(), organId)); // 兜底校验 role.getId(), role.getOrganId(), organId)); // 兜底校验
// 重新分配每个角色的权限 // 重新分配每个角色的权限
roles.forEach(role -> { roles.forEach(role -> {
@@ -15,6 +15,9 @@ import java.util.List;
*/ */
public interface TenantPackageService { public interface TenantPackageService {
long SYSTEM_ORGAN_PACKAGE_ID = 116;
long SYSTEM_SUPER_PACKAGE_ID = 0;
/** /**
* 创建组织套餐 * 创建组织套餐
* *
@@ -16,6 +16,7 @@ import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.List; import java.util.List;
import java.util.Objects;
import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception; import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.*; import static com.cf.imes.module.system.enums.ErrorCodeConstants.*;
@@ -50,6 +51,10 @@ public class TenantPackageServiceImpl implements TenantPackageService {
public void updateTenantPackage(TenantPackageSaveReqVO updateReqVO) { public void updateTenantPackage(TenantPackageSaveReqVO updateReqVO) {
// 校验存在 // 校验存在
TenantPackageDO tenantPackage = validateTenantPackageExists(updateReqVO.getId()); TenantPackageDO tenantPackage = validateTenantPackageExists(updateReqVO.getId());
if(Objects.equals(tenantPackage.getId(), SYSTEM_ORGAN_PACKAGE_ID) || Objects.equals(tenantPackage.getId(), SYSTEM_SUPER_PACKAGE_ID)) {
throw exception(TENANT_PACKAGE_DEPT_EXIT);
}
// 更新 // 更新
TenantPackageDO updateObj = BeanUtils.toBean(updateReqVO, TenantPackageDO.class); TenantPackageDO updateObj = BeanUtils.toBean(updateReqVO, TenantPackageDO.class);
tenantPackageMapper.updateById(updateObj); tenantPackageMapper.updateById(updateObj);
@@ -64,6 +69,10 @@ public class TenantPackageServiceImpl implements TenantPackageService {
public void deleteTenantPackage(Long id) { public void deleteTenantPackage(Long id) {
// 校验存在 // 校验存在
validateTenantPackageExists(id); validateTenantPackageExists(id);
if(Objects.equals(id, SYSTEM_ORGAN_PACKAGE_ID) || Objects.equals(id, SYSTEM_SUPER_PACKAGE_ID)) {
throw exception(TENANT_PACKAGE_DELETED_EXIT);
}
// 校验正在使用 // 校验正在使用
validateOrganUsed(id); validateOrganUsed(id);
// 删除 // 删除
@@ -11,6 +11,7 @@ import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.cf.imes.framework.organ.core.aop.OrganIgnore; import com.cf.imes.framework.organ.core.aop.OrganIgnore;
import com.cf.imes.framework.organ.core.context.OrganContextHolder; import com.cf.imes.framework.organ.core.context.OrganContextHolder;
import com.cf.imes.framework.organ.core.db.OrganBaseDO; import com.cf.imes.framework.organ.core.db.OrganBaseDO;
import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils;
import com.cf.imes.module.system.api.permission.dto.DeptDataPermissionRespDTO; import com.cf.imes.module.system.api.permission.dto.DeptDataPermissionRespDTO;
import com.cf.imes.module.system.controller.admin.permission.vo.permission.PermissionAssignUserRoleReqVO; import com.cf.imes.module.system.controller.admin.permission.vo.permission.PermissionAssignUserRoleReqVO;
import com.cf.imes.module.system.dal.dataobject.permission.MenuDO; import com.cf.imes.module.system.dal.dataobject.permission.MenuDO;
@@ -39,8 +40,10 @@ import java.util.*;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.Supplier;
import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.cf.imes.framework.common.util.collection.CollectionUtils.convertSet; import static com.cf.imes.framework.common.util.collection.CollectionUtils.convertSet;
import static com.cf.imes.framework.common.util.json.JsonUtils.toJsonString; import static com.cf.imes.framework.common.util.json.JsonUtils.toJsonString;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.ROLE_ME_ERROR;
import static com.cf.imes.module.system.service.organ.OrganServiceImpl.ORGAN_ADMIN_ROLE_ID; import static com.cf.imes.module.system.service.organ.OrganServiceImpl.ORGAN_ADMIN_ROLE_ID;
import static com.cf.imes.module.system.service.organ.OrganServiceImpl.ORGAN_STAFF_ROLE_ID; import static com.cf.imes.module.system.service.organ.OrganServiceImpl.ORGAN_STAFF_ROLE_ID;
@@ -266,6 +269,9 @@ public class PermissionServiceImpl implements PermissionService {
@DSTransactional // 多数据源,使用 @DSTransactional 保证本地事务,以及数据源的切换 @DSTransactional // 多数据源,使用 @DSTransactional 保证本地事务,以及数据源的切换
@CacheEvict(value = RedisKeyConstants.USER_ROLE_ID_LIST, key = "#userId") @CacheEvict(value = RedisKeyConstants.USER_ROLE_ID_LIST, key = "#userId")
public void assignUserRole(Long userId, Set<Long> roleIds, Long organId) { public void assignUserRole(Long userId, Set<Long> roleIds, Long organId) {
if(Objects.equals(userId, SecurityFrameworkUtils.getLoginUserId())) {
throw exception(ROLE_ME_ERROR);
}
// 获得用户拥有角色编号 // 获得用户拥有角色编号
Set<Long> dbRoleIds = convertSet(userRoleMapper.selectListByUserId(userId), Set<Long> dbRoleIds = convertSet(userRoleMapper.selectListByUserId(userId),
UserRoleDO::getRoleId); UserRoleDO::getRoleId);
@@ -105,7 +105,7 @@ public interface RoleService {
* @param statuses 筛选的状态 * @param statuses 筛选的状态
* @return 角色列表 * @return 角色列表
*/ */
List<RoleDO> getRoleListByStatus(Collection<Integer> statuses); List<RoleDO> getRoleListByStatus(Collection<Integer> statuses, Long organId);
/** /**
* 获得所有角色列表 * 获得所有角色列表
@@ -114,6 +114,13 @@ public interface RoleService {
*/ */
List<RoleDO> getRoleList(); List<RoleDO> getRoleList();
/**
* 获得自己组织与0号组织的所有角色列表
*
* @return 角色列表
*/
List<RoleDO> getMeAndDefaultRoleList();
/** /**
* 获得角色分页 * 获得角色分页
* *
@@ -197,16 +197,17 @@ public class RoleServiceImpl implements RoleService {
@Override @Override
@OrganIgnore @OrganIgnore
public List<RoleDO> getRoleListByStatus(Collection<Integer> statuses) { public List<RoleDO> getRoleListByStatus(Collection<Integer> statuses, Long organId) {
LoginUser loginUser = SecurityFrameworkUtils.getLoginUser(); LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
assert loginUser != null; assert loginUser != null;
if(!loginUser.getIsSupAdmin()) { if(!loginUser.getIsSupAdmin()) {
return roleMapper.selectList(new LambdaQueryWrapperX<RoleDO>() return roleMapper.selectList(new LambdaQueryWrapperX<RoleDO>()
.in(RoleDO::getStatus, statuses) .in(RoleDO::getStatus, statuses)
.in(RoleDO::getOrganId, loginUser.getOrganId(), 0L) .in(RoleDO::getOrganId, loginUser.getOrganId(), 0L)
.ne(RoleDO::getId, 1)
); );
} }
return roleMapper.selectListByStatus(statuses); return roleMapper.selectListByStatus(statuses, organId);
} }
@Override @Override
@@ -214,6 +215,13 @@ public class RoleServiceImpl implements RoleService {
return roleMapper.selectList(); return roleMapper.selectList();
} }
@Override
public List<RoleDO> getMeAndDefaultRoleList() {
return roleMapper.selectList(new LambdaQueryWrapperX<RoleDO>()
.in(RoleDO::getOrganId, Arrays.asList(0L, OrganContextHolder.getOrganId()))
);
}
@Override @Override
public List<RoleDO> getRoleList(Collection<Long> ids) { public List<RoleDO> getRoleList(Collection<Long> ids) {
if (CollectionUtil.isEmpty(ids)) { if (CollectionUtil.isEmpty(ids)) {
@@ -53,6 +53,7 @@ import java.util.stream.Collectors;
import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception; import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.cf.imes.framework.common.util.collection.CollectionUtils.convertList; import static com.cf.imes.framework.common.util.collection.CollectionUtils.convertList;
import static com.cf.imes.framework.common.util.collection.CollectionUtils.convertSet; import static com.cf.imes.framework.common.util.collection.CollectionUtils.convertSet;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.USER_ME_ERROR;
import static com.cf.imes.module.system.service.organ.OrganServiceImpl.ORGAN_ADMIN_ROLE_ID; import static com.cf.imes.module.system.service.organ.OrganServiceImpl.ORGAN_ADMIN_ROLE_ID;
/** /**
@@ -229,6 +230,9 @@ public class AdminUserServiceImpl implements AdminUserService {
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void deleteUser(Long id) { public void deleteUser(Long id) {
if(Objects.equals(id, SecurityFrameworkUtils.getLoginUserId())) {
throw exception(USER_ME_ERROR);
}
// 校验用户存在 // 校验用户存在
validateUserExists(id); validateUserExists(id);
// 删除用户 // 删除用户