feat: 数据分组授权.

This commit is contained in:
lijiahang
2023-11-23 17:19:42 +08:00
parent 1188502bb6
commit 2230d4ed8b
30 changed files with 727 additions and 74 deletions

View File

@@ -0,0 +1,45 @@
package com.orion.ops.module.asset.controller;
import com.orion.ops.framework.log.core.annotation.IgnoreLog;
import com.orion.ops.framework.log.core.enums.IgnoreLogMode;
import com.orion.ops.framework.security.core.utils.SecurityUtils;
import com.orion.ops.framework.web.core.annotation.RestWrapper;
import com.orion.ops.module.asset.entity.vo.HostGroupTreeVO;
import com.orion.ops.module.asset.service.HostGroupService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* 资产模块 授权数据服务
*
* @author Jiahang Li
* @version 1.0.0
* @since 2023/11/23 14:10
*/
@Tag(name = "asset - 授权数据服务")
@Slf4j
@Validated
@RestWrapper
@RestController
@RequestMapping("/asset/authorized-data")
public class AssetDataController {
@Resource
private HostGroupService hostGroupService;
@IgnoreLog(IgnoreLogMode.RET)
@GetMapping("/host-group")
@Operation(summary = "查询已授权的主机分组")
public List<HostGroupTreeVO> getAuthorizedHostGroup() {
return hostGroupService.getUserAuthorizedHostGroup(SecurityUtils.getLoginUserId());
}
}

View File

@@ -6,6 +6,8 @@ import com.orion.ops.framework.log.core.annotation.IgnoreLog;
import com.orion.ops.framework.log.core.enums.IgnoreLogMode;
import com.orion.ops.framework.web.core.annotation.RestWrapper;
import com.orion.ops.module.asset.define.operator.HostGroupOperatorType;
import com.orion.ops.module.asset.entity.request.host.HostGroupGrantQueryRequest;
import com.orion.ops.module.asset.entity.request.host.HostGroupGrantRequest;
import com.orion.ops.module.asset.entity.request.host.HostGroupRelUpdateRequest;
import com.orion.ops.module.asset.entity.vo.HostGroupTreeVO;
import com.orion.ops.module.asset.service.HostGroupService;
@@ -45,7 +47,7 @@ public class HostGroupController {
@OperatorLog(HostGroupOperatorType.CREATE)
@PostMapping("/create")
@Operation(summary = "创建主机分组 - 管理")
@Operation(summary = "创建主机分组")
@PreAuthorize("@ss.hasPermission('asset:host-group:create')")
public Long createHostGroup(@Validated @RequestBody DataGroupCreateDTO request) {
return hostGroupService.createHostGroup(request);
@@ -53,7 +55,7 @@ public class HostGroupController {
@IgnoreLog(IgnoreLogMode.RET)
@GetMapping("/tree")
@Operation(summary = "查询主机分组 - 管理")
@Operation(summary = "查询主机分组")
@PreAuthorize("@ss.hasPermission('asset:host-group:query')")
public List<HostGroupTreeVO> queryHostGroupTree() {
return hostGroupService.queryHostGroupTree();
@@ -61,7 +63,7 @@ public class HostGroupController {
@OperatorLog(HostGroupOperatorType.RENAME)
@PutMapping("/rename")
@Operation(summary = "修改名称 - 管理")
@Operation(summary = "修改名称")
@PreAuthorize("@ss.hasPermission('asset:host-group:update')")
public Integer updateHostGroupName(@Validated @RequestBody DataGroupRenameDTO request) {
return hostGroupService.updateHostGroupName(request);
@@ -69,7 +71,7 @@ public class HostGroupController {
@OperatorLog(HostGroupOperatorType.MOVE)
@PutMapping("/move")
@Operation(summary = "移动位置 - 管理")
@Operation(summary = "移动位置")
@PreAuthorize("@ss.hasPermission('asset:host-group:update')")
public Integer moveHostGroup(@Validated @RequestBody DataGroupMoveDTO request) {
return hostGroupService.moveHostGroup(request);
@@ -77,7 +79,7 @@ public class HostGroupController {
@OperatorLog(HostGroupOperatorType.DELETE)
@DeleteMapping("/delete")
@Operation(summary = "删除主机分组 - 管理")
@Operation(summary = "删除主机分组")
@PreAuthorize("@ss.hasPermission('asset:host-group:delete')")
public Integer deleteHostGroup(@RequestParam("id") Long id) {
return hostGroupService.deleteHostGroup(id);
@@ -85,7 +87,7 @@ public class HostGroupController {
@IgnoreLog(IgnoreLogMode.RET)
@GetMapping("/rel-list")
@Operation(summary = "查询分组内主机 - 管理")
@Operation(summary = "查询分组内主机")
@Parameter(name = "groupId", description = "groupId", required = true)
@PreAuthorize("@ss.hasPermission('asset:host-group:query')")
public Set<Long> queryHostGroupRel(@RequestParam("groupId") Long groupId) {
@@ -93,13 +95,33 @@ public class HostGroupController {
}
@OperatorLog(HostGroupOperatorType.UPDATE_REL)
@PostMapping("/update-rel")
@Operation(summary = "修改分组内主机 - 管理")
@PreAuthorize("@ss.hasPermission('asset:host:update')")
@PutMapping("/update-rel")
@Operation(summary = "修改分组内主机")
@PreAuthorize("@ss.hasPermission('asset:host-group:update')")
public HttpWrapper<?> updateHostGroupRel(@Validated @RequestBody HostGroupRelUpdateRequest request) {
hostGroupService.updateHostGroupRel(request);
return HttpWrapper.ok();
}
// TODO 日志 host-group:grant
// TODO 菜单 asset:host-group:grant
@IgnoreLog(IgnoreLogMode.RET)
@GetMapping("/get-authorized-group")
@Operation(summary = "获取已授权的分组")
@PreAuthorize("@ss.hasPermission('asset:host-group:grant')")
public List<Long> getAuthorizedHostGroup(@RequestParam HostGroupGrantQueryRequest request) {
return hostGroupService.getAuthorizedHostGroup(request);
}
@OperatorLog(HostGroupOperatorType.GRANT)
@PutMapping("/grant")
@Operation(summary = "主机分组授权")
@PreAuthorize("@ss.hasPermission('asset:host-group:grant')")
public HttpWrapper<?> grantHostGroup(@RequestBody HostGroupGrantRequest request) {
hostGroupService.grantHostGroup(request);
return HttpWrapper.ok();
}
}

View File

@@ -26,6 +26,8 @@ public class HostGroupOperatorType extends InitializingOperatorTypes {
public static final String UPDATE_REL = "host-group:update-rel";
public static final String GRANT = "host-group:grant";
@Override
public OperatorType[] types() {
return new OperatorType[]{
@@ -34,6 +36,7 @@ public class HostGroupOperatorType extends InitializingOperatorTypes {
new OperatorType(L, MOVE, "移动主机分组 <sb>${source}</sb> 到 <sb>${target}(${position})</sb>"),
new OperatorType(H, DELETE, "删除主机分组 <sb>${groupName}</sb>"),
new OperatorType(M, UPDATE_REL, "修改分组内主机 <sb>${groupName}</sb>"),
new OperatorType(H, GRANT, "将主机分组权限授予 <sb>${type}</sb> <sb>${name}</sb>"),
};
}

View File

@@ -0,0 +1,31 @@
package com.orion.ops.module.asset.entity.request.host;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* 主机分组 查询请求对象
*
* @author Jiahang Li
* @version 1.0.0
* @since 2023/11/23 11:56
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "HostGroupQueryRequest", description = "主机分组 查询请求对象")
public class HostGroupGrantQueryRequest implements Serializable {
@Schema(description = "用户id")
private Long userId;
@Schema(description = "角色id")
private Long roleId;
}

View File

@@ -0,0 +1,35 @@
package com.orion.ops.module.asset.entity.request.host;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
/**
* 主机分组 授权请求对象
*
* @author Jiahang Li
* @version 1.0.0
* @since 2023/11/23 11:56
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "HostGroupGrantRequest", description = "主机分组 授权请求对象")
public class HostGroupGrantRequest implements Serializable {
@Schema(description = "用户id")
private Long userId;
@Schema(description = "角色id")
private Long roleId;
@Schema(description = "分组id")
private List<Long> groupIdList;
}

View File

@@ -1,6 +1,7 @@
package com.orion.ops.module.asset.entity.vo;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.orion.ops.framework.common.entity.TreeNode;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
@@ -8,6 +9,7 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
/**
@@ -22,7 +24,8 @@ import java.util.List;
@NoArgsConstructor
@AllArgsConstructor
@Schema(name = "HostGroupTreeVO", description = "主机秘钥 视图响应对象")
public class HostGroupTreeVO implements Serializable {
public class HostGroupTreeVO implements TreeNode<HostGroupTreeVO>, Serializable {
private static final long serialVersionUID = 1L;
@JsonProperty("key")
@@ -36,7 +39,13 @@ public class HostGroupTreeVO implements Serializable {
@Schema(description = "组名称")
private String name;
@Schema(description = "排序")
private Integer sort;
@Schema(description = "子节点")
private List<HostGroupTreeVO> children;
@Schema(description = "分组内主机id")
private Collection<Long> hosts;
}

View File

@@ -1,5 +1,7 @@
package com.orion.ops.module.asset.service;
import com.orion.ops.module.asset.entity.request.host.HostGroupGrantQueryRequest;
import com.orion.ops.module.asset.entity.request.host.HostGroupGrantRequest;
import com.orion.ops.module.asset.entity.request.host.HostGroupRelUpdateRequest;
import com.orion.ops.module.asset.entity.vo.HostGroupTreeVO;
import com.orion.ops.module.infra.entity.dto.data.DataGroupCreateDTO;
@@ -72,4 +74,27 @@ public interface HostGroupService {
*/
void updateHostGroupRel(HostGroupRelUpdateRequest request);
/**
* 获取已授权的分组
*
* @param request request
* @return grantGroupId
*/
List<Long> getAuthorizedHostGroup(HostGroupGrantQueryRequest request);
/**
* 授权主机分组
*
* @param request request
*/
void grantHostGroup(HostGroupGrantRequest request);
/**
* 查询用户已授权的主机分组和主机
*
* @param userId userId
* @return group
*/
List<HostGroupTreeVO> getUserAuthorizedHostGroup(Long userId);
}

View File

@@ -1,23 +1,27 @@
package com.orion.ops.module.asset.service.impl;
import com.orion.lang.utils.collect.Lists;
import com.orion.ops.framework.common.constant.Const;
import com.orion.ops.framework.common.constant.ErrorMessage;
import com.orion.ops.framework.common.utils.TreeUtils;
import com.orion.ops.framework.common.utils.Valid;
import com.orion.ops.module.asset.convert.HostGroupConvert;
import com.orion.ops.module.asset.entity.request.host.HostGroupGrantQueryRequest;
import com.orion.ops.module.asset.entity.request.host.HostGroupGrantRequest;
import com.orion.ops.module.asset.entity.request.host.HostGroupRelUpdateRequest;
import com.orion.ops.module.asset.entity.vo.HostGroupTreeVO;
import com.orion.ops.module.asset.service.HostGroupService;
import com.orion.ops.module.infra.api.DataGroupApi;
import com.orion.ops.module.infra.api.DataGroupRelApi;
import com.orion.ops.module.infra.api.DataPermissionApi;
import com.orion.ops.module.infra.entity.dto.data.DataGroupCreateDTO;
import com.orion.ops.module.infra.entity.dto.data.DataGroupDTO;
import com.orion.ops.module.infra.entity.dto.data.DataGroupMoveDTO;
import com.orion.ops.module.infra.entity.dto.data.DataGroupRenameDTO;
import com.orion.ops.module.infra.api.*;
import com.orion.ops.module.infra.entity.dto.data.*;
import com.orion.ops.module.infra.enums.DataGroupTypeEnum;
import com.orion.ops.module.infra.enums.DataPermissionTypeEnum;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
@@ -39,6 +43,12 @@ public class HostGroupServiceImpl implements HostGroupService {
@Resource
private DataPermissionApi dataPermissionApi;
@Resource
private SystemRoleApi systemRoleApi;
@Resource
private SystemUserApi systemUserApi;
@Override
public Long createHostGroup(DataGroupCreateDTO request) {
return dataGroupApi.createDataGroup(DataGroupTypeEnum.HOST, request);
@@ -80,4 +90,93 @@ public class HostGroupServiceImpl implements HostGroupService {
dataGroupRelApi.updateGroupRel(request.getGroupId(), request.getHostIdList());
}
@Override
public List<Long> getAuthorizedHostGroup(HostGroupGrantQueryRequest request) {
Long userId = request.getUserId();
Long roleId = request.getRoleId();
Valid.isTrue(userId != null || roleId != null);
if (userId != null) {
// 查询用户数据
return dataPermissionApi.getRelIdListByUserId(DataPermissionTypeEnum.HOST_GROUP, userId);
} else {
// 查询角色数据
return dataPermissionApi.getRelIdListByRoleId(DataPermissionTypeEnum.HOST_GROUP, roleId);
}
}
@Override
public void grantHostGroup(HostGroupGrantRequest request) {
Long userId = request.getUserId();
Long roleId = request.getRoleId();
Valid.isTrue(userId != null || roleId != null);
if (userId != null) {
// 检测用户是否存在
Valid.notNull(systemUserApi.getUserById(userId), ErrorMessage.USER_ABSENT);
}
if (roleId != null) {
// 检测角色是否存在
Valid.notNull(systemRoleApi.getRoleById(roleId), ErrorMessage.ROLE_ABSENT);
}
// 授权
DataPermissionUpdateDTO grant = DataPermissionUpdateDTO.builder()
.roleId(roleId)
.userId(userId)
.relIdList(request.getGroupIdList())
.build();
dataPermissionApi.updateDataPermission(DataPermissionTypeEnum.HOST_GROUP, grant);
}
@Override
public List<HostGroupTreeVO> getUserAuthorizedHostGroup(Long userId) {
if (systemUserApi.isAdminUser(userId)) {
// 管理员查询所有
return this.buildUserAuthorizedHostGroup(null);
} else {
// 其他用户查询授权的分组
List<Long> authorizedGroupIdList = dataPermissionApi.getUserAuthorizedRelIdList(DataPermissionTypeEnum.HOST_GROUP, userId);
if (authorizedGroupIdList.isEmpty()) {
return Lists.empty();
}
return this.buildUserAuthorizedHostGroup(authorizedGroupIdList);
}
}
/**
* 构建授权的主机分组树
*
* @param authorizedGroupIdList authorizedGroupIdList
* @return tree
*/
private List<HostGroupTreeVO> buildUserAuthorizedHostGroup(List<Long> authorizedGroupIdList) {
// 查询分组
List<DataGroupDTO> dataGroup = dataGroupApi.getDataGroupList(DataGroupTypeEnum.HOST);
// 过滤分组
if (!Lists.isEmpty(authorizedGroupIdList)) {
// 构建已授权的分组
List<DataGroupDTO> relNodes = new ArrayList<>();
TreeUtils.getAllNodes(dataGroup, authorizedGroupIdList, relNodes);
dataGroup = relNodes;
}
// 查询分组引用
Map<Long, Set<Long>> groupRel = dataGroupRelApi.getGroupRelList(DataGroupTypeEnum.HOST);
// 设置组内数据
List<HostGroupTreeVO> groupList = HostGroupConvert.MAPPER.toList(dataGroup);
if (Lists.isEmpty(authorizedGroupIdList)) {
// 设置全部数据
groupList.forEach(s -> s.setHosts(groupRel.get(s.getId())));
} else {
// 仅设置已授权的数据
groupList.stream()
.filter(s -> authorizedGroupIdList.contains(s.getId()))
.forEach(s -> s.setHosts(groupRel.get(s.getId())));
}
// 构建树
HostGroupTreeVO rootNode = HostGroupTreeVO.builder()
.id(Const.ROOT_PARENT_ID)
.sort(Const.DEFAULT_SORT)
.build();
TreeUtils.buildGroupTree(rootNode, groupList);
return rootNode.getChildren();
}
}