diff --git a/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/security/LoginUser.java b/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/security/LoginUser.java index 8249ce41..4c9f47be 100644 --- a/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/security/LoginUser.java +++ b/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/security/LoginUser.java @@ -35,6 +35,6 @@ public class LoginUser { private Long timestamp; @Schema(description = "角色") - private List roles; + private List roles; } diff --git a/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/security/UserRole.java b/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/security/UserRole.java new file mode 100644 index 00000000..5f5dcb7a --- /dev/null +++ b/orion-ops-framework/orion-ops-framework-common/src/main/java/com/orion/ops/framework/common/security/UserRole.java @@ -0,0 +1,28 @@ +package com.orion.ops.framework.common.security; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.*; + +/** + * 用户角色 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/11/20 23:39 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@EqualsAndHashCode(onlyExplicitlyIncluded = true) +@Schema(name = "UserRole", description = "用户角色") +public class UserRole { + + @EqualsAndHashCode.Include + @Schema(description = "id") + private Long id; + + @Schema(description = "角色") + private String code; + +} diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/PermissionService.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/PermissionService.java index 975b559b..7df9485e 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/PermissionService.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/PermissionService.java @@ -22,7 +22,7 @@ public interface PermissionService { * * @return cache */ - Map getRoleCache(); + Map getRoleCache(); /** * 获取 菜单缓存 以作角色权限直接引用 @@ -36,7 +36,7 @@ public interface PermissionService { * * @return cache */ - Map> getRoleMenuCache(); + Map> getRoleMenuCache(); /** * 初始化权限缓存 diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/SystemUserRoleService.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/SystemUserRoleService.java index 9edf0f53..8aadf978 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/SystemUserRoleService.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/SystemUserRoleService.java @@ -40,9 +40,9 @@ public interface SystemUserRoleService { /** * 删除用户缓存中的角色 * - * @param roleCode roleCode + * @param roleId roleId * @param userIdList userIdList */ - void deleteUserCacheRoleAsync(String roleCode, List userIdList); + void deleteUserCacheRoleAsync(Long roleId, List userIdList); } diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/AuthenticationServiceImpl.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/AuthenticationServiceImpl.java index e017c0ad..6c908201 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/AuthenticationServiceImpl.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/AuthenticationServiceImpl.java @@ -10,6 +10,7 @@ import com.orion.ops.framework.biz.operator.log.core.uitls.OperatorLogs; import com.orion.ops.framework.common.constant.Const; import com.orion.ops.framework.common.constant.ErrorMessage; import com.orion.ops.framework.common.security.LoginUser; +import com.orion.ops.framework.common.security.UserRole; import com.orion.ops.framework.common.utils.CryptoUtils; import com.orion.ops.framework.common.utils.IpUtils; import com.orion.ops.framework.common.utils.Valid; @@ -20,7 +21,6 @@ import com.orion.ops.module.infra.convert.SystemUserConvert; import com.orion.ops.module.infra.dao.SystemUserDAO; import com.orion.ops.module.infra.dao.SystemUserRoleDAO; import com.orion.ops.module.infra.define.cache.UserCacheKeyDefine; -import com.orion.ops.module.infra.entity.domain.SystemRoleDO; import com.orion.ops.module.infra.entity.domain.SystemUserDO; import com.orion.ops.module.infra.entity.dto.LoginTokenDTO; import com.orion.ops.module.infra.entity.dto.LoginTokenIdentityDTO; @@ -289,16 +289,16 @@ public class AuthenticationServiceImpl implements AuthenticationService { Long id = user.getId(); // 查询用户角色 List roleIds = systemUserRoleDAO.selectRoleIdByUserId(id); - List roleCodeList = permissionService.getRoleCache() + List roleList = permissionService.getRoleCache() .values() .stream() .filter(s -> roleIds.contains(s.getId())) - .map(SystemRoleDO::getCode) + .map(r -> new UserRole(r.getId(), r.getCode())) .collect(Collectors.toList()); // 设置用户缓存 String userInfoKey = UserCacheKeyDefine.USER_INFO.format(id); LoginUser loginUser = SystemUserConvert.MAPPER.toLoginUser(user); - loginUser.setRoles(roleCodeList); + loginUser.setRoles(roleList); RedisStrings.setJson(userInfoKey, UserCacheKeyDefine.USER_INFO, loginUser); return loginUser; } diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/PermissionServiceImpl.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/PermissionServiceImpl.java index e246fa06..4459ca6b 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/PermissionServiceImpl.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/PermissionServiceImpl.java @@ -4,6 +4,7 @@ import com.orion.lang.utils.Arrays1; import com.orion.lang.utils.collect.Lists; import com.orion.ops.framework.common.constant.Const; import com.orion.ops.framework.common.security.LoginUser; +import com.orion.ops.framework.common.security.UserRole; import com.orion.ops.framework.security.core.utils.SecurityUtils; import com.orion.ops.module.infra.convert.SystemMenuConvert; import com.orion.ops.module.infra.convert.SystemUserConvert; @@ -51,13 +52,13 @@ import java.util.stream.Stream; public class PermissionServiceImpl implements PermissionService { @Getter - private final Map roleCache = new HashMap<>(); + private final Map roleCache = new HashMap<>(); @Getter private final List menuCache = new ArrayList<>(); @Getter - private final Map> roleMenuCache = new HashMap<>(); + private final Map> roleMenuCache = new HashMap<>(); @Resource private SystemRoleDAO systemRoleDAO; @@ -87,10 +88,8 @@ public class PermissionServiceImpl implements PermissionService { roleMenuCache.clear(); // 加载所有角色 List roles = systemRoleDAO.selectList(null); - Map roleRel = roles.stream() - .collect(Collectors.toMap(SystemRoleDO::getId, Function.identity())); for (SystemRoleDO role : roles) { - roleCache.put(role.getCode(), role); + roleCache.put(role.getId(), role); } // 加载所有菜单信息 List menuList = systemMenuDAO.selectList(null); @@ -103,17 +102,14 @@ public class PermissionServiceImpl implements PermissionService { .stream() .collect(Collectors.groupingBy(SystemRoleMenuDO::getRoleId, Collectors.mapping(SystemRoleMenuDO::getMenuId, Collectors.toList()))) - .forEach((rid, mids) -> { + .forEach((roleId, menuIdList) -> { // 获取菜单引用 - List roleMenus = mids.stream() + List roleMenus = menuIdList.stream() .map(menuMapping::get) .filter(Objects::nonNull) .collect(Collectors.toList()); // 获取角色引用 - Optional.ofNullable(rid) - .map(roleRel::get) - .map(SystemRoleDO::getCode) - .ifPresent(code -> roleMenuCache.put(code, roleMenus)); + roleMenuCache.put(roleId, roleMenus); }); log.info("initPermissionCache-end used: {}ms", System.currentTimeMillis() - start); } @@ -121,7 +117,7 @@ public class PermissionServiceImpl implements PermissionService { @Override public boolean hasRole(String role) { // 获取用户角色 - List roles = this.getUserEnabledRoles(); + List roles = this.getUserEnabledRoleCode(); if (roles.isEmpty()) { return false; } @@ -132,7 +128,7 @@ public class PermissionServiceImpl implements PermissionService { @Override public boolean hasPermission(String permission) { // 获取用户角色 - List roles = this.getUserEnabledRoles(); + List roles = this.getUserEnabledRoleCode(); if (roles.isEmpty()) { return false; } @@ -150,7 +146,7 @@ public class PermissionServiceImpl implements PermissionService { return true; } // 获取用户角色 - List roles = this.getUserEnabledRoles(); + List roles = this.getUserEnabledRoleCode(); if (roles.isEmpty()) { return false; } @@ -170,7 +166,7 @@ public class PermissionServiceImpl implements PermissionService { @Override public List getUserMenuList() { // 获取用户角色 - List roles = this.getUserEnabledRoles(); + List roles = this.getUserEnabledRoleCode(); if (roles.isEmpty()) { return Lists.empty(); } @@ -206,7 +202,7 @@ public class PermissionServiceImpl implements PermissionService { // 获取用户系统偏好 Future> systemPreference = preferenceService.getPreferenceAsync(id, PreferenceTypeEnum.SYSTEM); // 获取用户角色 - List roles = this.getUserEnabledRoles(); + List roles = this.getUserEnabledRoleCode(); // 获取用户权限 List permissions; if (roles.isEmpty()) { @@ -266,32 +262,27 @@ public class PermissionServiceImpl implements PermissionService { * * @return roles */ - private List getUserEnabledRoles() { + private List getUserEnabledRoleCode() { // 获取当前用户角色 - List roles = Optional.ofNullable(SecurityUtils.getLoginUser()) + List userRoles = Optional.ofNullable(SecurityUtils.getLoginUser()) .map(LoginUser::getRoles) - .orElse(Lists.empty()); - if (Lists.isEmpty(roles)) { + .orElse(null); + if (Lists.isEmpty(userRoles)) { return Lists.empty(); } - // 过滤未启用的角色 - return roles.stream() - .filter(this::checkRoleEnabled) + // 获取角色编码 + List roleCodes = userRoles.stream() + .map(UserRole::getId) + .map(roleCache::get) + .filter(Objects::nonNull) + // 过滤未启用的角色 + .filter(r -> RoleStatusEnum.ENABLED.getStatus().equals(r.getStatus())) + .map(SystemRoleDO::getCode) .collect(Collectors.toList()); - } - - /** - * 检查角色是否启用 - * - * @param role role - * @return 是否启用 - */ - private boolean checkRoleEnabled(String role) { - SystemRoleDO systemRole = roleCache.get(role); - if (systemRole == null) { - return false; + if (Lists.isEmpty(roleCodes)) { + return Lists.empty(); } - return RoleStatusEnum.ENABLED.getStatus().equals(systemRole.getStatus()); + return roleCodes; } } diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemRoleMenuServiceImpl.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemRoleMenuServiceImpl.java index a2e35313..a75c17c6 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemRoleMenuServiceImpl.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemRoleMenuServiceImpl.java @@ -104,12 +104,8 @@ public class SystemRoleMenuServiceImpl implements SystemRoleMenuService { effect += insertMenuIdList.size(); } // 更新缓存 - Map> cache = permissionService.getRoleMenuCache(); - List roleCache = cache.get(role.getCode()); - if (Lists.isEmpty(roleCache)) { - roleCache = new ArrayList<>(); - cache.put(role.getCode(), roleCache); - } + Map> cache = permissionService.getRoleMenuCache(); + List roleCache = cache.computeIfAbsent(roleId, s -> new ArrayList<>()); roleCache.clear(); roleCache.addAll(SystemMenuConvert.MAPPER.toCache(menuList)); return effect; diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemRoleServiceImpl.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemRoleServiceImpl.java index c6319075..2d077a79 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemRoleServiceImpl.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemRoleServiceImpl.java @@ -67,7 +67,7 @@ public class SystemRoleServiceImpl implements SystemRoleService { int effect = systemRoleDAO.insert(record); log.info("SystemRoleService-createSystemRole effect: {}, domain: {}", effect, JSON.toJSONString(record)); // 设置到缓存 - permissionService.getRoleCache().put(record.getCode(), record); + permissionService.getRoleCache().put(record.getId(), record); return record.getId(); } @@ -87,7 +87,7 @@ public class SystemRoleServiceImpl implements SystemRoleService { int effect = systemRoleDAO.updateById(updateRecord); log.info("SystemRoleService-updateSystemRoleById effect: {}, updateRecord: {}", effect, JSON.toJSONString(updateRecord)); // 设置到缓存 - SystemRoleDO roleCache = permissionService.getRoleCache().get(record.getCode()); + SystemRoleDO roleCache = permissionService.getRoleCache().get(id); roleCache.setName(updateRecord.getName()); return effect; } @@ -112,7 +112,7 @@ public class SystemRoleServiceImpl implements SystemRoleService { int effect = systemRoleDAO.updateById(updateRecord); log.info("SystemRoleService-updateRoleStatus effect: {}, updateRecord: {}", effect, JSON.toJSONString(updateRecord)); // 修改缓存状态 - SystemRoleDO roleCache = permissionService.getRoleCache().get(record.getCode()); + SystemRoleDO roleCache = permissionService.getRoleCache().get(id); roleCache.setStatus(status); return effect; } @@ -173,11 +173,11 @@ public class SystemRoleServiceImpl implements SystemRoleService { // 删除角色菜单关联 effect += systemRoleMenuDAO.deleteByRoleId(id); // 删除角色缓存 - permissionService.getRoleCache().remove(code); + permissionService.getRoleCache().remove(id); // 删除菜单缓存 - permissionService.getRoleMenuCache().remove(code); + permissionService.getRoleMenuCache().remove(id); // 删除用户缓存中的角色 - systemUserRoleService.deleteUserCacheRoleAsync(code, userIdList); + systemUserRoleService.deleteUserCacheRoleAsync(id, userIdList); return effect; } diff --git a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemUserRoleServiceImpl.java b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemUserRoleServiceImpl.java index 660d997c..bcf79a4d 100644 --- a/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemUserRoleServiceImpl.java +++ b/orion-ops-module-infra/orion-ops-module-infra-service/src/main/java/com/orion/ops/module/infra/service/impl/SystemUserRoleServiceImpl.java @@ -4,6 +4,7 @@ import com.orion.lang.utils.collect.Lists; import com.orion.ops.framework.biz.operator.log.core.uitls.OperatorLogs; import com.orion.ops.framework.common.constant.ErrorMessage; import com.orion.ops.framework.common.security.LoginUser; +import com.orion.ops.framework.common.security.UserRole; import com.orion.ops.framework.common.utils.Valid; import com.orion.ops.framework.redis.core.utils.RedisStrings; import com.orion.ops.module.infra.dao.SystemRoleDAO; @@ -101,25 +102,25 @@ public class SystemUserRoleServiceImpl implements SystemUserRoleService { effect += addUserRoles.size(); // 更新缓存中的角色 RedisStrings.processSetJson(UserCacheKeyDefine.USER_INFO, s -> { - List roleCodeList = userRoles.stream() - .map(SystemRoleDO::getCode) + List roles = userRoles.stream() + .map(role -> new UserRole(role.getId(), role.getCode())) .collect(Collectors.toList()); - s.setRoles(roleCodeList); + s.setRoles(roles); }, userId); return effect; } @Override @Async("asyncExecutor") - public void deleteUserCacheRoleAsync(String roleCode, List userIdList) { + public void deleteUserCacheRoleAsync(Long roleId, List userIdList) { for (Long userId : userIdList) { RedisStrings.processSetJson(UserCacheKeyDefine.USER_INFO, s -> { - List roles = s.getRoles(); + List roles = s.getRoles(); if (Lists.isEmpty(roles)) { return; } // 移除角色 - roles.remove(roleCode); + roles.removeIf(role -> roleId.equals(role.getId())); }, userId); } } diff --git a/orion-ops-ui/src/api/user/auth.ts b/orion-ops-ui/src/api/user/auth.ts index fa8610f5..f41560ce 100644 --- a/orion-ops-ui/src/api/user/auth.ts +++ b/orion-ops-ui/src/api/user/auth.ts @@ -1,3 +1,4 @@ +import type { MenuQueryResponse } from '@/api/system/menu'; import axios from 'axios'; /** @@ -15,6 +16,22 @@ export interface LoginResponse { token: string; } +/** + * 用户权限响应 + */ +export interface UserPermissionResponse { + user: { + id: number; + username: string; + nickname: string; + avatar: string; + systemPreference: Record; + tippedKeys: Array; + }; + roles: Array; + permissions: Array; +} + /** * 登录 */ @@ -33,12 +50,12 @@ export function logout() { * 获取用户信息 */ export function getUserPermission() { - return axios.get('/infra/permission/user'); + return axios.get('/infra/permission/user'); } /** * 获取菜单列表 */ export function getMenuList() { - return axios.get('/infra/permission/menu'); + return axios.get>('/infra/permission/menu'); } diff --git a/orion-ops-ui/src/hooks/permission.ts b/orion-ops-ui/src/hooks/permission.ts index 582249d7..241478d0 100644 --- a/orion-ops-ui/src/hooks/permission.ts +++ b/orion-ops-ui/src/hooks/permission.ts @@ -58,7 +58,7 @@ export default function usePermission() { * 是否有角色 */ hasAnyRole(role: string[]) { - return userStore.roles?.includes('*') || + return userStore.roles?.includes('admin') || role.map(s => userStore.roles?.includes(s)) .filter(Boolean).length > 0; } diff --git a/orion-ops-ui/src/views/asset/host-group/components/host-transfer.vue b/orion-ops-ui/src/views/asset/host-group/components/host-transfer.vue index 492876bd..e32357b5 100644 --- a/orion-ops-ui/src/views/asset/host-group/components/host-transfer.vue +++ b/orion-ops-ui/src/views/asset/host-group/components/host-transfer.vue @@ -28,8 +28,8 @@ diff --git a/orion-ops-ui/src/views/user/role/components/role-table.vue b/orion-ops-ui/src/views/user/role/components/role-table.vue index c216b00e..921c655f 100644 --- a/orion-ops-ui/src/views/user/role/components/role-table.vue +++ b/orion-ops-ui/src/views/user/role/components/role-table.vue @@ -80,7 +80,7 @@ type="warning" @ok="toggleRoleStatus(record)"> @@ -89,7 +89,7 @@ @@ -108,7 +108,7 @@ type="warning" @ok="deleteRow(record)"> @@ -134,7 +134,7 @@ import { Message } from '@arco-design/web-vue'; import useLoading from '@/hooks/loading'; import columns from '../types/table.columns'; - import { roleStatusKey } from '../types/const'; + import { roleStatusKey, AdminCode } from '../types/const'; import { usePagination } from '@/types/table'; import { useDictStore } from '@/store'; diff --git a/orion-ops-ui/src/views/user/role/types/const.ts b/orion-ops-ui/src/views/user/role/types/const.ts index 8e6d9e61..1d380341 100644 --- a/orion-ops-ui/src/views/user/role/types/const.ts +++ b/orion-ops-ui/src/views/user/role/types/const.ts @@ -1,3 +1,6 @@ +// 管理员角色编码 +export const AdminCode = 'admin'; + // 角色状态 export const RoleStatus = { // 停用