From 10178d998e958015cf365086af6e3be2ff3d5d85 Mon Sep 17 00:00:00 2001 From: lijiahangmax Date: Wed, 25 Jun 2025 19:16:04 +0800 Subject: [PATCH] =?UTF-8?q?:tada:=20=E4=BC=98=E5=8C=96=20asset=20=E6=A8=A1?= =?UTF-8?q?=E5=9D=97=E9=80=BB=E8=BE=91.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../asset/api/AssetAuthorizedDataApi.java | 57 ++++ .../visor/module/asset/api/HostApi.java} | 29 +- .../module/asset/api/HostConnectApi.java | 91 ++++++ .../asset/entity/dto/host/HostBaseDTO.java | 73 +++++ .../module/asset/entity/dto/host/HostDTO.java | 121 ++++++++ .../entity/dto/host/HostRdpConfigDTO.java | 106 +++++++ .../entity/dto/host/HostSshConfigDTO.java} | 54 +--- .../module/asset/enums/HostArchTypeEnum.java | 0 .../module/asset/enums/HostOsTypeEnum.java | 0 .../module/asset/enums/HostStatusEnum.java | 0 .../module/asset/enums/HostTypeEnum.java | 29 +- .../orion-visor-module-asset-service/pom.xml | 5 + .../api/impl/AssetAuthorizedDataApiImpl.java | 66 ++++ .../module/asset/api/impl/HostApiImpl.java | 67 ++++ .../asset/api/impl/HostConnectApiImpl.java | 80 +++++ .../controller/AssetStatisticsController.java | 14 +- .../asset/controller/HostController.java | 2 +- .../asset/controller/HostExtraController.java | 2 +- .../asset/convert/HostProviderConvert.java | 53 ++++ .../visor/module/asset/dao/HostConfigDAO.java | 8 + .../cache/AssetStatisticsCacheKeyDefine.java | 14 +- .../define/operator/HostOperatorType.java | 2 +- .../entity/dto/HostIdentityCacheDTO.java | 14 +- .../asset/entity/po/HostTypeCountPO.java | 55 ++++ .../request/host/HostKeyCreateRequest.java | 1 + ...uthTypeEnum.java => HostAuthTypeEnum.java} | 8 +- ...peEnum.java => HostExtraAuthTypeEnum.java} | 6 +- .../config/AbstractHostConfigStrategy.java | 81 +++++ .../host/config/HostConfigStrategyEnum.java | 68 +++++ .../host/config/HostRdpConfigStrategy.java | 107 +++++++ .../{strategy => }/HostSshConfigStrategy.java | 74 ++--- .../host/extra}/HostExtraItemEnum.java | 14 +- .../host/extra/model/HostRdpExtraModel.java | 59 ++++ .../strategy/HostLabelExtraStrategy.java | 14 +- .../extra/strategy/HostRdpExtraStrategy.java | 83 +++++ .../extra/strategy/HostSshExtraStrategy.java | 10 +- .../terminal/TerminalMessageDispatcher.java | 93 ------ .../handler/AbstractTerminalHandler.java | 125 -------- .../handler/TerminalCheckHandler.java | 241 --------------- .../handler/TerminalConnectHandler.java | 192 ------------ .../terminal/manager/TerminalManager.java | 117 ------- .../terminal/session/TerminalSession.java | 136 --------- .../asset/service/AssetStatisticsService.java | 27 +- .../asset/service/HostConnectService.java | 41 ++- .../asset/service/HostExtraService.java | 2 +- .../impl/AssetAuthorizedDataServiceImpl.java | 2 +- .../impl/AssetStatisticsServiceImpl.java | 160 ++-------- .../service/impl/HostConfigServiceImpl.java | 7 +- .../service/impl/HostConnectServiceImpl.java | 286 +++++++++++++----- .../service/impl/HostExtraServiceImpl.java | 2 +- .../service/impl/HostIdentityServiceImpl.java | 2 +- .../service/impl/HostKeyServiceImpl.java | 2 +- .../asset/service/impl/HostServiceImpl.java | 19 +- .../resources/mapper/HostConfigMapper.xml | 14 + .../visor/module/common/utils/SftpUtils.java | 4 +- 55 files changed, 1634 insertions(+), 1305 deletions(-) create mode 100644 orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/api/AssetAuthorizedDataApi.java rename orion-visor-modules/orion-visor-module-asset/{orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/terminal/handler/ITerminalHandler.java => orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/api/HostApi.java} (65%) create mode 100644 orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/api/HostConnectApi.java create mode 100644 orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/entity/dto/host/HostBaseDTO.java create mode 100644 orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/entity/dto/host/HostDTO.java create mode 100644 orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/entity/dto/host/HostRdpConfigDTO.java rename orion-visor-modules/orion-visor-module-asset/{orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/config/model/HostSshConfigModel.java => orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/entity/dto/host/HostSshConfigDTO.java} (69%) rename orion-visor-modules/orion-visor-module-asset/{orion-visor-module-asset-service => orion-visor-module-asset-provider}/src/main/java/org/dromara/visor/module/asset/enums/HostArchTypeEnum.java (100%) rename orion-visor-modules/orion-visor-module-asset/{orion-visor-module-asset-service => orion-visor-module-asset-provider}/src/main/java/org/dromara/visor/module/asset/enums/HostOsTypeEnum.java (100%) rename orion-visor-modules/orion-visor-module-asset/{orion-visor-module-asset-service => orion-visor-module-asset-provider}/src/main/java/org/dromara/visor/module/asset/enums/HostStatusEnum.java (100%) rename orion-visor-modules/orion-visor-module-asset/{orion-visor-module-asset-service => orion-visor-module-asset-provider}/src/main/java/org/dromara/visor/module/asset/enums/HostTypeEnum.java (75%) create mode 100644 orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/api/impl/AssetAuthorizedDataApiImpl.java create mode 100644 orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/api/impl/HostApiImpl.java create mode 100644 orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/api/impl/HostConnectApiImpl.java create mode 100644 orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/convert/HostProviderConvert.java create mode 100644 orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/entity/po/HostTypeCountPO.java rename orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/enums/{HostSshAuthTypeEnum.java => HostAuthTypeEnum.java} (88%) rename orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/enums/{HostExtraSshAuthTypeEnum.java => HostExtraAuthTypeEnum.java} (89%) create mode 100644 orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/config/AbstractHostConfigStrategy.java create mode 100644 orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/config/HostConfigStrategyEnum.java create mode 100644 orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/config/HostRdpConfigStrategy.java rename orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/config/{strategy => }/HostSshConfigStrategy.java (54%) rename orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/{enums => handler/host/extra}/HostExtraItemEnum.java (89%) create mode 100644 orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/extra/model/HostRdpExtraModel.java create mode 100644 orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/extra/strategy/HostRdpExtraStrategy.java delete mode 100644 orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/terminal/TerminalMessageDispatcher.java delete mode 100644 orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/terminal/handler/AbstractTerminalHandler.java delete mode 100644 orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/terminal/handler/TerminalCheckHandler.java delete mode 100644 orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/terminal/handler/TerminalConnectHandler.java delete mode 100644 orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/terminal/manager/TerminalManager.java delete mode 100644 orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/terminal/session/TerminalSession.java diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/api/AssetAuthorizedDataApi.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/api/AssetAuthorizedDataApi.java new file mode 100644 index 00000000..d3ae0ed9 --- /dev/null +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/api/AssetAuthorizedDataApi.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2023 - present Dromara, All rights reserved. + * + * https://visor.dromara.org + * https://visor.dromara.org.cn + * https://visor.orionsec.cn + * + * Members: + * Jiahang Li - ljh1553488six@139.com - author + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dromara.visor.module.asset.api; + +import org.dromara.visor.module.asset.entity.dto.host.HostDTO; +import org.dromara.visor.module.asset.enums.HostTypeEnum; + +import java.util.List; + +/** + * 资产模块 授权数据对外服务 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2024/10/12 16:13 + */ +public interface AssetAuthorizedDataApi { + + /** + * 获取用户已授权&配置已启用的主机id 查询角色 + * + * @param userId userId + * @param type type + * @return hostId + */ + List getUserAuthorizedEnabledHostId(Long userId, HostTypeEnum type); + + /** + * 查询用户已授权并且启用的主机 + * + * @param userId userId + * @param type type + * @return group + */ + List getUserAuthorizedHostList(Long userId, HostTypeEnum type); + +} diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/terminal/handler/ITerminalHandler.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/api/HostApi.java similarity index 65% rename from orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/terminal/handler/ITerminalHandler.java rename to orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/api/HostApi.java index b638accf..33a4dc1e 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/terminal/handler/ITerminalHandler.java +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/api/HostApi.java @@ -20,26 +20,35 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.dromara.visor.module.asset.handler.host.terminal.handler; +package org.dromara.visor.module.asset.api; -import org.dromara.visor.module.asset.handler.host.terminal.model.TerminalBasePayload; -import org.springframework.web.socket.WebSocketSession; +import org.dromara.visor.module.asset.entity.dto.host.HostDTO; + +import java.util.List; /** - * 终端消息处理器 + * 主机 对外服务 * * @author Jiahang Li * @version 1.0.0 - * @since 2023/12/29 18:53 + * @since 2024/10/12 16:14 */ -public interface ITerminalHandler { +public interface HostApi { /** - * 处理消息 + * 通过 id 查询 * - * @param channel channel - * @param payload payload + * @param id id + * @return row */ - void handle(WebSocketSession channel, T payload); + HostDTO selectById(Long id); + + /** + * 通过 id 查询 + * + * @param idList idList + * @return rows + */ + List selectByIdList(List idList); } diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/api/HostConnectApi.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/api/HostConnectApi.java new file mode 100644 index 00000000..fbd89f9f --- /dev/null +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/api/HostConnectApi.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2023 - present Dromara, All rights reserved. + * + * https://visor.dromara.org + * https://visor.dromara.org.cn + * https://visor.orionsec.cn + * + * Members: + * Jiahang Li - ljh1553488six@139.com - author + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dromara.visor.module.asset.api; + +import org.dromara.visor.common.session.config.RdpConnectConfig; +import org.dromara.visor.common.session.config.SshConnectConfig; +import org.dromara.visor.module.asset.entity.dto.host.HostDTO; + +/** + * 主机连接 对外服务 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2024/10/12 23:53 + */ +public interface HostConnectApi { + + /** + * 获取 SSH 连接配置 + * + * @param hostId hostId + * @return session + */ + SshConnectConfig getSshConnectConfig(Long hostId); + + /** + * 使用用户配置获取 SSH 连接配置 + * + * @param hostId hostId + * @param userId userId + * @return session + */ + SshConnectConfig getSshConnectConfig(Long hostId, Long userId); + + /** + * 使用用户配置获取 SSH 连接配置 + * + * @param host host + * @param userId userId + * @return session + */ + SshConnectConfig getSshConnectConfig(HostDTO host, Long userId); + + /** + * 获取 RDP 连接配置 + * + * @param hostId hostId + * @return session + */ + RdpConnectConfig getRdpConnectConfig(Long hostId); + + /** + * 使用用户配置获取 RDP 连接配置 + * + * @param hostId hostId + * @param userId userId + * @return session + */ + RdpConnectConfig getRdpConnectConfig(Long hostId, Long userId); + + /** + * 使用用户配置获取 RDP 连接配置 + * + * @param host host + * @param userId userId + * @return session + */ + RdpConnectConfig getRdpConnectConfig(HostDTO host, Long userId); + + +} diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/entity/dto/host/HostBaseDTO.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/entity/dto/host/HostBaseDTO.java new file mode 100644 index 00000000..e9fba21f --- /dev/null +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/entity/dto/host/HostBaseDTO.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2023 - present Dromara, All rights reserved. + * + * https://visor.dromara.org + * https://visor.dromara.org.cn + * https://visor.orionsec.cn + * + * Members: + * Jiahang Li - ljh1553488six@139.com - author + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dromara.visor.module.asset.entity.dto.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-9-11 14:16 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(name = "HostBaseDTO", description = "主机基本信息 业务响应对象") +public class HostBaseDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "id") + private Long id; + + @Schema(description = "主机类型") + private String types; + + @Schema(description = "系统类型") + private String osType; + + @Schema(description = "系统架构") + private String archType; + + @Schema(description = "主机名称") + private String name; + + @Schema(description = "主机编码") + private String code; + + @Schema(description = "主机地址") + private String address; + + @Schema(description = "主机端口") + private Integer port; + +} diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/entity/dto/host/HostDTO.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/entity/dto/host/HostDTO.java new file mode 100644 index 00000000..eaaf3346 --- /dev/null +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/entity/dto/host/HostDTO.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2023 - present Dromara, All rights reserved. + * + * https://visor.dromara.org + * https://visor.dromara.org.cn + * https://visor.orionsec.cn + * + * Members: + * Jiahang Li - ljh1553488six@139.com - author + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dromara.visor.module.asset.entity.dto.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.Date; +import java.util.Set; + +/** + * 主机 业务对象 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023-9-11 14:16 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(name = "HostDTO", description = "主机 业务对象") +public class HostDTO implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "id") + private Long id; + + @Schema(description = "主机类型") + private String types; + + @Schema(description = "系统类型") + private String osType; + + @Schema(description = "系统架构") + private String archType; + + @Schema(description = "主机名称") + private String name; + + @Schema(description = "主机编码") + private String code; + + @Schema(description = "主机地址") + private String address; + + @Schema(description = "主机端口") + private Integer port; + + @Schema(description = "主机状态") + private String status; + + @Schema(description = "描述") + private String description; + + @Schema(description = "创建时间") + private Date createTime; + + @Schema(description = "修改时间") + private Date updateTime; + + @Schema(description = "创建人") + private String creator; + + @Schema(description = "修改人") + private String updater; + + @Schema(description = "是否收藏") + private Boolean favorite; + + @Schema(description = "分组 id") + private Set groupIdList; + + @Schema(description = "别名") + private String alias; + + @Schema(description = "颜色") + private String color; + + /** + * 转为 base + * + * @return base + */ + public HostBaseDTO toBase() { + return HostBaseDTO.builder() + .id(this.id) + .types(this.types) + .name(this.name) + .code(this.code) + .address(this.address) + .port(this.port) + .build(); + } + +} diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/entity/dto/host/HostRdpConfigDTO.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/entity/dto/host/HostRdpConfigDTO.java new file mode 100644 index 00000000..aed66f70 --- /dev/null +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/entity/dto/host/HostRdpConfigDTO.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2023 - present Dromara, All rights reserved. + * + * https://visor.dromara.org + * https://visor.dromara.org.cn + * https://visor.orionsec.cn + * + * Members: + * Jiahang Li - ljh1553488six@139.com - author + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dromara.visor.module.asset.entity.dto.host; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.dromara.visor.common.handler.data.model.GenericsDataModel; +import org.dromara.visor.common.security.UpdatePasswordAction; + +import javax.validation.constraints.*; + +/** + * 主机 RDP 配置 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/9/13 16:18 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(name = "HostRdpConfigDTO", description = "主机 RDP 配置业务对象") +public class HostRdpConfigDTO implements GenericsDataModel, UpdatePasswordAction { + + @NotNull + @Min(value = 1) + @Max(value = 65535) + @Schema(description = "主机端口") + private Integer port; + + @Size(max = 128) + @Schema(description = "用户名") + private String username; + + @NotBlank + @Size(max = 12) + @Schema(description = "认证方式") + private String authType; + + @Schema(description = "密码") + private String password; + + @Schema(description = "身份id") + private Long identityId; + + @Schema(description = "RDP 版本是否大于8.1") + private Boolean versionGt81; + + @Schema(description = "时区") + private String timezone; + + @Schema(description = "键盘布局") + private String keyboardLayout; + + @Schema(description = "剪切板规范") + private String clipboardNormalize; + + @Schema(description = "域") + private String domain; + + @Schema(description = "预连接id") + private String preConnectionId; + + @Schema(description = "预连接数据") + private String preConnectionBlob; + + @Schema(description = "远程应用") + private String remoteApp; + + @Schema(description = "远程应用路径") + private String remoteAppDir; + + @Schema(description = "远程应用参数") + private String remoteAppArgs; + + @Schema(description = "是否使用新密码 仅参数") + private Boolean useNewPassword; + + @Schema(description = "是否已设置密码 仅返回") + private Boolean hasPassword; + +} diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/config/model/HostSshConfigModel.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/entity/dto/host/HostSshConfigDTO.java similarity index 69% rename from orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/config/model/HostSshConfigModel.java rename to orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/entity/dto/host/HostSshConfigDTO.java index 97df9c7b..4717c811 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/config/model/HostSshConfigModel.java +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/entity/dto/host/HostSshConfigDTO.java @@ -20,8 +20,9 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.dromara.visor.module.asset.handler.host.config.model; +package org.dromara.visor.module.asset.entity.dto.host; +import io.swagger.v3.oas.annotations.media.Schema; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -42,81 +43,58 @@ import javax.validation.constraints.*; @Builder @NoArgsConstructor @AllArgsConstructor -public class HostSshConfigModel implements GenericsDataModel, UpdatePasswordAction { +@Schema(name = "HostSshConfigDTO", description = "主机 SSH 配置业务对象") +public class HostSshConfigDTO implements GenericsDataModel, UpdatePasswordAction { - /** - * 主机端口 - */ @NotNull @Min(value = 1) @Max(value = 65535) + @Schema(description = "主机端口") private Integer port; - /** - * 用户名 - */ @Size(max = 128) + @Schema(description = "用户名") private String username; - /** - * 认证方式 - */ @NotBlank @Size(max = 12) + @Schema(description = "认证方式") private String authType; - /** - * 密码 - */ + @Schema(description = "密码") private String password; - /** - * 身份id - */ + @Schema(description = "身份id") private Long identityId; - /** - * 密钥id - */ + @Schema(description = "密钥id") private Long keyId; - /** - * 连接超时时间 - */ @NotNull @Min(value = 1) @Max(value = 100000) + @Schema(description = "连接超时时间") private Integer connectTimeout; - /** - * SSH输出编码 - */ @NotBlank @Size(max = 12) + @Schema(description = "SSH输出编码") private String charset; - /** - * 文件名称编码 - */ @NotBlank @Size(max = 12) + @Schema(description = "文件名称编码") private String fileNameCharset; - /** - * 文件内容编码 - */ @NotBlank @Size(max = 12) + @Schema(description = "文件内容编码") private String fileContentCharset; - /** - * 是否使用新密码 仅参数 - */ + @Schema(description = "是否使用新密码 仅参数") private Boolean useNewPassword; - /** - * 是否已设置密码 仅返回 - */ + @Schema(description = "是否已设置密码 仅返回") private Boolean hasPassword; } diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/enums/HostArchTypeEnum.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/enums/HostArchTypeEnum.java similarity index 100% rename from orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/enums/HostArchTypeEnum.java rename to orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/enums/HostArchTypeEnum.java diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/enums/HostOsTypeEnum.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/enums/HostOsTypeEnum.java similarity index 100% rename from orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/enums/HostOsTypeEnum.java rename to orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/enums/HostOsTypeEnum.java diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/enums/HostStatusEnum.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/enums/HostStatusEnum.java similarity index 100% rename from orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/enums/HostStatusEnum.java rename to orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/enums/HostStatusEnum.java diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/enums/HostTypeEnum.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/enums/HostTypeEnum.java similarity index 75% rename from orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/enums/HostTypeEnum.java rename to orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/enums/HostTypeEnum.java index 61852b18..206ba242 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/enums/HostTypeEnum.java +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-provider/src/main/java/org/dromara/visor/module/asset/enums/HostTypeEnum.java @@ -22,13 +22,11 @@ */ package org.dromara.visor.module.asset.enums; +import com.alibaba.fastjson.JSON; import lombok.AllArgsConstructor; -import lombok.Getter; import org.dromara.visor.common.constant.Const; -import org.dromara.visor.common.handler.data.GenericsStrategyDefinition; -import org.dromara.visor.common.handler.data.model.GenericsDataModel; -import org.dromara.visor.common.handler.data.strategy.GenericsDataStrategy; -import org.dromara.visor.module.asset.handler.host.config.strategy.HostSshConfigStrategy; +import org.dromara.visor.module.asset.entity.dto.host.HostRdpConfigDTO; +import org.dromara.visor.module.asset.entity.dto.host.HostSshConfigDTO; import java.util.ArrayList; import java.util.Arrays; @@ -37,24 +35,28 @@ import java.util.Objects; import java.util.stream.Collectors; /** - * 主机配置类型枚举 + * 主机类型 * * @author Jiahang Li * @version 1.0.0 - * @since 2023/9/11 14:37 + * @since 2024/10/12 18:12 */ -@Getter @AllArgsConstructor -public enum HostTypeEnum implements GenericsStrategyDefinition { +public enum HostTypeEnum { /** * SSH */ - SSH(HostSshConfigStrategy.class), + SSH(HostSshConfigDTO.class), + + /** + * RDP + */ + RDP(HostRdpConfigDTO.class), ; - private final Class> strategyClass; + private final Class clazz; public static HostTypeEnum of(String type) { if (type == null) { @@ -79,4 +81,9 @@ public enum HostTypeEnum implements GenericsStrategyDefinition { .collect(Collectors.toList()); } + @SuppressWarnings("unchecked") + public T parse(String config) { + return (T) JSON.parseObject(config, this.clazz); + } + } diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/pom.xml b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/pom.xml index 77d4baba..8f09d18d 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/pom.xml +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/pom.xml @@ -32,6 +32,11 @@ orion-visor-module-asset-provider ${revision} + + org.dromara.visor + orion-visor-module-exec-provider + ${revision} + diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/api/impl/AssetAuthorizedDataApiImpl.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/api/impl/AssetAuthorizedDataApiImpl.java new file mode 100644 index 00000000..a947b83f --- /dev/null +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/api/impl/AssetAuthorizedDataApiImpl.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2023 - present Dromara, All rights reserved. + * + * https://visor.dromara.org + * https://visor.dromara.org.cn + * https://visor.orionsec.cn + * + * Members: + * Jiahang Li - ljh1553488six@139.com - author + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dromara.visor.module.asset.api.impl; + +import lombok.extern.slf4j.Slf4j; +import org.dromara.visor.module.asset.api.AssetAuthorizedDataApi; +import org.dromara.visor.module.asset.convert.HostProviderConvert; +import org.dromara.visor.module.asset.entity.dto.host.HostDTO; +import org.dromara.visor.module.asset.entity.vo.AuthorizedHostWrapperVO; +import org.dromara.visor.module.asset.enums.HostTypeEnum; +import org.dromara.visor.module.asset.service.AssetAuthorizedDataService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 资产模块 授权数据对外服务实现 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2024/10/12 18:14 + */ +@Slf4j +@Service +public class AssetAuthorizedDataApiImpl implements AssetAuthorizedDataApi { + + @Resource + private AssetAuthorizedDataService assetAuthorizedDataService; + + @Override + public List getUserAuthorizedEnabledHostId(Long userId, HostTypeEnum type) { + return assetAuthorizedDataService.getUserAuthorizedEnabledHostId(userId, type.name()); + } + + @Override + public List getUserAuthorizedHostList(Long userId, HostTypeEnum type) { + AuthorizedHostWrapperVO wrapper = assetAuthorizedDataService.getUserAuthorizedHost(userId, type.name()); + return wrapper.getHostList() + .stream() + .map(HostProviderConvert.MAPPER::to) + .collect(Collectors.toList()); + } + +} diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/api/impl/HostApiImpl.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/api/impl/HostApiImpl.java new file mode 100644 index 00000000..419a98f6 --- /dev/null +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/api/impl/HostApiImpl.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2023 - present Dromara, All rights reserved. + * + * https://visor.dromara.org + * https://visor.dromara.org.cn + * https://visor.orionsec.cn + * + * Members: + * Jiahang Li - ljh1553488six@139.com - author + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dromara.visor.module.asset.api.impl; + +import cn.orionsec.kit.lang.utils.collect.Lists; +import lombok.extern.slf4j.Slf4j; +import org.dromara.visor.module.asset.api.HostApi; +import org.dromara.visor.module.asset.convert.HostProviderConvert; +import org.dromara.visor.module.asset.dao.HostDAO; +import org.dromara.visor.module.asset.entity.dto.host.HostDTO; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.util.List; +import java.util.stream.Collectors; + +/** + * 主机 对外服务实现类 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2024/10/12 18:27 + */ +@Slf4j +@Service +public class HostApiImpl implements HostApi { + + @Resource + private HostDAO hostDAO; + + @Override + public HostDTO selectById(Long id) { + return HostProviderConvert.MAPPER.to(hostDAO.selectById(id)); + } + + @Override + public List selectByIdList(List idList) { + if (Lists.isEmpty(idList)) { + return Lists.empty(); + } + return hostDAO.selectBatchIds(idList) + .stream() + .map(HostProviderConvert.MAPPER::to) + .collect(Collectors.toList()); + } + +} diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/api/impl/HostConnectApiImpl.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/api/impl/HostConnectApiImpl.java new file mode 100644 index 00000000..6ffcc687 --- /dev/null +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/api/impl/HostConnectApiImpl.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2023 - present Dromara, All rights reserved. + * + * https://visor.dromara.org + * https://visor.dromara.org.cn + * https://visor.orionsec.cn + * + * Members: + * Jiahang Li - ljh1553488six@139.com - author + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dromara.visor.module.asset.api.impl; + +import lombok.extern.slf4j.Slf4j; +import org.dromara.visor.common.session.config.RdpConnectConfig; +import org.dromara.visor.common.session.config.SshConnectConfig; +import org.dromara.visor.module.asset.api.HostConnectApi; +import org.dromara.visor.module.asset.convert.HostProviderConvert; +import org.dromara.visor.module.asset.entity.dto.host.HostDTO; +import org.dromara.visor.module.asset.service.HostConnectService; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; + +/** + * 主机连接 对外服务实现 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2024/10/13 0:03 + */ +@Slf4j +@Service +public class HostConnectApiImpl implements HostConnectApi { + + @Resource + private HostConnectService hostConnectService; + + @Override + public SshConnectConfig getSshConnectConfig(Long hostId) { + return hostConnectService.getSshConnectConfig(hostId); + } + + @Override + public SshConnectConfig getSshConnectConfig(Long hostId, Long userId) { + return hostConnectService.getSshConnectConfig(hostId, userId); + } + + @Override + public SshConnectConfig getSshConnectConfig(HostDTO host, Long userId) { + return hostConnectService.getSshConnectConfig(HostProviderConvert.MAPPER.to(host), userId); + } + + @Override + public RdpConnectConfig getRdpConnectConfig(Long hostId) { + return hostConnectService.getRdpConnectConfig(hostId); + } + + @Override + public RdpConnectConfig getRdpConnectConfig(Long hostId, Long userId) { + return hostConnectService.getRdpConnectConfig(hostId, userId); + } + + @Override + public RdpConnectConfig getRdpConnectConfig(HostDTO host, Long userId) { + return hostConnectService.getRdpConnectConfig(HostProviderConvert.MAPPER.to(host), userId); + } + +} diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/controller/AssetStatisticsController.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/controller/AssetStatisticsController.java index 226c4cb8..7c2ec0d7 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/controller/AssetStatisticsController.java +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/controller/AssetStatisticsController.java @@ -25,11 +25,12 @@ package org.dromara.visor.module.asset.controller; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; +import org.dromara.visor.common.entity.chart.PieChartData; import org.dromara.visor.framework.log.core.annotation.IgnoreLog; import org.dromara.visor.framework.log.core.enums.IgnoreLogMode; import org.dromara.visor.framework.web.core.annotation.RestWrapper; -import org.dromara.visor.module.asset.entity.vo.AssetWorkplaceStatisticsVO; import org.dromara.visor.module.asset.service.AssetStatisticsService; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -42,7 +43,7 @@ import javax.annotation.Resource; * * @author Jiahang Li * @version 1.0.0 - * @since 2024/12/23 16:07 + * @since 2024/12/23 15:56 */ @Tag(name = "asset - 统计服务") @Slf4j @@ -56,10 +57,11 @@ public class AssetStatisticsController { private AssetStatisticsService assetStatisticsService; @IgnoreLog(IgnoreLogMode.RET) - @GetMapping("/get-workplace") - @Operation(summary = "查询工作台统计信息") - public AssetWorkplaceStatisticsVO getWorkplaceStatisticsData() { - return assetStatisticsService.getWorkplaceStatisticsData(); + @GetMapping("/host-type-chart") + @Operation(summary = "查询主机类型图表") + @PreAuthorize("@ss.hasPermission('asset:statistics:query')") + public PieChartData getHostTypeChart() { + return assetStatisticsService.getHostTypeChart(); } } diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/controller/HostController.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/controller/HostController.java index 9520f585..ad09fc43 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/controller/HostController.java +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/controller/HostController.java @@ -143,7 +143,7 @@ public class HostController { @PostMapping("/count") @Operation(summary = "查询主机数量") @PreAuthorize("@ss.hasPermission('asset:host:query')") - public Long getHostExportCount(@Validated @RequestBody HostQueryRequest request) { + public Long getHostCount(@Validated @RequestBody HostQueryRequest request) { return hostService.getHostCount(request); } diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/controller/HostExtraController.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/controller/HostExtraController.java index 2e0e44e3..c52d9739 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/controller/HostExtraController.java +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/controller/HostExtraController.java @@ -32,7 +32,7 @@ import org.dromara.visor.framework.log.core.annotation.IgnoreLog; import org.dromara.visor.framework.log.core.enums.IgnoreLogMode; import org.dromara.visor.framework.web.core.annotation.RestWrapper; import org.dromara.visor.module.asset.entity.request.host.HostExtraUpdateRequest; -import org.dromara.visor.module.asset.enums.HostExtraItemEnum; +import org.dromara.visor.module.asset.handler.host.extra.HostExtraItemEnum; import org.dromara.visor.module.asset.service.HostExtraService; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/convert/HostProviderConvert.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/convert/HostProviderConvert.java new file mode 100644 index 00000000..13071c56 --- /dev/null +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/convert/HostProviderConvert.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2023 - present Dromara, All rights reserved. + * + * https://visor.dromara.org + * https://visor.dromara.org.cn + * https://visor.orionsec.cn + * + * Members: + * Jiahang Li - ljh1553488six@139.com - author + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dromara.visor.module.asset.convert; + +import org.dromara.visor.common.mapstruct.StringConversion; +import org.dromara.visor.module.asset.entity.domain.HostDO; +import org.dromara.visor.module.asset.entity.dto.host.HostBaseDTO; +import org.dromara.visor.module.asset.entity.dto.host.HostDTO; +import org.dromara.visor.module.asset.entity.vo.HostVO; +import org.mapstruct.Mapper; +import org.mapstruct.factory.Mappers; + +/** + * 主机 对外对象转换器 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023-9-11 14:16 + */ +@Mapper(uses = StringConversion.class) +public interface HostProviderConvert { + + HostProviderConvert MAPPER = Mappers.getMapper(HostProviderConvert.class); + + HostDO to(HostDTO host); + + HostDTO to(HostDO domain); + + HostDTO to(HostVO vo); + + HostBaseDTO toBase(HostDO domain); + +} diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/dao/HostConfigDAO.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/dao/HostConfigDAO.java index 53b52021..8903a90b 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/dao/HostConfigDAO.java +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/dao/HostConfigDAO.java @@ -28,6 +28,7 @@ import org.apache.ibatis.annotations.Param; import org.dromara.visor.framework.mybatis.core.mapper.IMapper; import org.dromara.visor.framework.mybatis.core.query.Conditions; import org.dromara.visor.module.asset.entity.domain.HostConfigDO; +import org.dromara.visor.module.asset.entity.po.HostTypeCountPO; import java.util.List; @@ -133,4 +134,11 @@ public interface HostConfigDAO extends IMapper { */ int setIdentityIdWithNull(@Param("identityIdList") List identityIdList); + /** + * 查询启用的主机类型数量 + * + * @return count + */ + List selectEnabledTypeCount(); + } diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/define/cache/AssetStatisticsCacheKeyDefine.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/define/cache/AssetStatisticsCacheKeyDefine.java index 192e94fe..6eea666c 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/define/cache/AssetStatisticsCacheKeyDefine.java +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/define/cache/AssetStatisticsCacheKeyDefine.java @@ -25,12 +25,12 @@ package org.dromara.visor.module.asset.define.cache; import cn.orionsec.kit.lang.define.cache.key.CacheKeyBuilder; import cn.orionsec.kit.lang.define.cache.key.CacheKeyDefine; import cn.orionsec.kit.lang.define.cache.key.struct.RedisCacheStruct; -import org.dromara.visor.module.asset.entity.vo.AssetWorkplaceStatisticsVO; +import com.alibaba.fastjson.JSONObject; import java.util.concurrent.TimeUnit; /** - * 资产模块统计缓存 key + * asset 模块统计缓存 key * * @author Jiahang Li * @version 1.0.0 @@ -38,12 +38,12 @@ import java.util.concurrent.TimeUnit; */ public interface AssetStatisticsCacheKeyDefine { - CacheKeyDefine WORKPLACE_DATA = new CacheKeyBuilder() - .key("data:statistics:asset-workplace:{}:{}") - .desc("资产模块工作台统计 ${userId} ${time}") - .type(AssetWorkplaceStatisticsVO.class) + CacheKeyDefine HOST_TYPE_COUNT = new CacheKeyBuilder() + .key("data:statistics:host:count") + .desc("主机类型数量") + .type(JSONObject.class) .struct(RedisCacheStruct.STRING) - .timeout(10, TimeUnit.MINUTES) + .timeout(1, TimeUnit.DAYS) .build(); } diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/define/operator/HostOperatorType.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/define/operator/HostOperatorType.java index 72890501..f0e614ad 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/define/operator/HostOperatorType.java +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/define/operator/HostOperatorType.java @@ -57,7 +57,7 @@ public class HostOperatorType extends InitializingOperatorTypes { new OperatorType(L, UPDATE, "修改主机 ${name}"), new OperatorType(H, DELETE, "删除主机 ${count} 条"), new OperatorType(M, UPDATE_STATUS, "修改主机状态 ${name} - ${status}"), - new OperatorType(M, UPDATE_CONFIG, "修改主机配置 ${name}"), + new OperatorType(M, UPDATE_CONFIG, "修改主机配置 ${name} - ${type}"), new OperatorType(M, UPDATE_SPEC, "修改主机规格信息 ${name}"), }; } diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/entity/dto/HostIdentityCacheDTO.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/entity/dto/HostIdentityCacheDTO.java index 4cf4f769..ea5b801e 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/entity/dto/HostIdentityCacheDTO.java +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/entity/dto/HostIdentityCacheDTO.java @@ -61,10 +61,16 @@ public class HostIdentityCacheDTO implements LongCacheIdModel, Serializable { @Schema(description = "密钥id") private Long keyId; - @Schema(description = "描述") - private String description; - - @Schema(description = "创建时间 资产页面展示") + /** + * 资产页面展示 + */ + @Schema(description = "创建时间") private Date createTime; + /** + * 资产页面展示 + */ + @Schema(description = "修改时间") + private Date updateTime; + } diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/entity/po/HostTypeCountPO.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/entity/po/HostTypeCountPO.java new file mode 100644 index 00000000..b519b8d4 --- /dev/null +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/entity/po/HostTypeCountPO.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2023 - present Dromara, All rights reserved. + * + * https://visor.dromara.org + * https://visor.dromara.org.cn + * https://visor.orionsec.cn + * + * Members: + * Jiahang Li - ljh1553488six@139.com - author + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dromara.visor.module.asset.entity.po; + +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 2024/7/14 15:03 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Schema(name = "HostTypeCountPO", description = "主机类型数量对象") +public class HostTypeCountPO implements Serializable { + + private static final long serialVersionUID = 1L; + + @Schema(description = "类型") + private String type; + + @Schema(description = "数量") + private Integer count; + +} \ No newline at end of file diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/entity/request/host/HostKeyCreateRequest.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/entity/request/host/HostKeyCreateRequest.java index 35e3edd2..b737a6ae 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/entity/request/host/HostKeyCreateRequest.java +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/entity/request/host/HostKeyCreateRequest.java @@ -61,6 +61,7 @@ public class HostKeyCreateRequest implements Serializable { @Schema(description = "私钥文本") private String privateKey; + @NotBlank @ParamDecrypt @Schema(description = "密码") private String password; diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/enums/HostSshAuthTypeEnum.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/enums/HostAuthTypeEnum.java similarity index 88% rename from orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/enums/HostSshAuthTypeEnum.java rename to orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/enums/HostAuthTypeEnum.java index beec2804..2b9fc6b3 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/enums/HostSshAuthTypeEnum.java +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/enums/HostAuthTypeEnum.java @@ -23,13 +23,13 @@ package org.dromara.visor.module.asset.enums; /** - * 主机认证类型 - ssh + * 主机认证类型 * * @author Jiahang Li * @version 1.0.0 * @since 2023/9/21 19:01 */ -public enum HostSshAuthTypeEnum { +public enum HostAuthTypeEnum { /** * 密码认证 @@ -48,11 +48,11 @@ public enum HostSshAuthTypeEnum { ; - public static HostSshAuthTypeEnum of(String type) { + public static HostAuthTypeEnum of(String type) { if (type == null) { return PASSWORD; } - for (HostSshAuthTypeEnum value : values()) { + for (HostAuthTypeEnum value : values()) { if (value.name().equals(type)) { return value; } diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/enums/HostExtraSshAuthTypeEnum.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/enums/HostExtraAuthTypeEnum.java similarity index 89% rename from orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/enums/HostExtraSshAuthTypeEnum.java rename to orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/enums/HostExtraAuthTypeEnum.java index 9d00cdad..dd210ac8 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/enums/HostExtraSshAuthTypeEnum.java +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/enums/HostExtraAuthTypeEnum.java @@ -29,7 +29,7 @@ package org.dromara.visor.module.asset.enums; * @version 1.0.0 * @since 2023/12/20 21:41 */ -public enum HostExtraSshAuthTypeEnum { +public enum HostExtraAuthTypeEnum { /** * 默认认证方式 @@ -48,11 +48,11 @@ public enum HostExtraSshAuthTypeEnum { ; - public static HostExtraSshAuthTypeEnum of(String type) { + public static HostExtraAuthTypeEnum of(String type) { if (type == null) { return DEFAULT; } - for (HostExtraSshAuthTypeEnum value : values()) { + for (HostExtraAuthTypeEnum value : values()) { if (value.name().equals(type)) { return value; } diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/config/AbstractHostConfigStrategy.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/config/AbstractHostConfigStrategy.java new file mode 100644 index 00000000..b163e928 --- /dev/null +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/config/AbstractHostConfigStrategy.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2023 - present Dromara, All rights reserved. + * + * https://visor.dromara.org + * https://visor.dromara.org.cn + * https://visor.orionsec.cn + * + * Members: + * Jiahang Li - ljh1553488six@139.com - author + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dromara.visor.module.asset.handler.host.config; + +import cn.orionsec.kit.lang.utils.Booleans; +import cn.orionsec.kit.lang.utils.Charsets; +import org.dromara.visor.common.constant.ErrorMessage; +import org.dromara.visor.common.handler.data.model.GenericsDataModel; +import org.dromara.visor.common.handler.data.strategy.AbstractGenericsDataStrategy; +import org.dromara.visor.common.security.UpdatePasswordAction; +import org.dromara.visor.common.utils.AesEncryptUtils; +import org.dromara.visor.common.utils.RsaParamDecryptUtils; +import org.dromara.visor.common.utils.Valid; +import org.dromara.visor.module.asset.enums.HostAuthTypeEnum; + +/** + * 主机配置策略基类 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2025/3/31 19:44 + */ +public abstract class AbstractHostConfigStrategy extends AbstractGenericsDataStrategy { + + public AbstractHostConfigStrategy(Class modelClass) { + super(modelClass); + } + + /** + * 检查加密密码 + * + * @param before before + * @param after after + */ + protected void checkEncryptPassword(String authType, UpdatePasswordAction before, UpdatePasswordAction after) { + // 非密码认证/使用原始密码则直接赋值 + if (!HostAuthTypeEnum.PASSWORD.name().equals(authType) || !Booleans.isTrue(after.getUseNewPassword())) { + if (before != null) { + after.setPassword(before.getPassword()); + } + return; + } + // 检查新密码 + String newPassword = Valid.notBlank(after.getPassword(), ErrorMessage.PASSWORD_MISSING); + // 解密密码 + newPassword = RsaParamDecryptUtils.decrypt(newPassword); + Valid.notBlank(newPassword, ErrorMessage.DECRYPT_ERROR); + // 设置密码 + after.setPassword(AesEncryptUtils.encryptAsString(newPassword)); + } + + /** + * 检查编码格式 + * + * @param charset charset + */ + protected void validCharset(String charset) { + Valid.isTrue(Charsets.isSupported(charset), ErrorMessage.UNSUPPORTED_CHARSET, charset); + } + +} diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/config/HostConfigStrategyEnum.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/config/HostConfigStrategyEnum.java new file mode 100644 index 00000000..17018a08 --- /dev/null +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/config/HostConfigStrategyEnum.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2023 - present Dromara, All rights reserved. + * + * https://visor.dromara.org + * https://visor.dromara.org.cn + * https://visor.orionsec.cn + * + * Members: + * Jiahang Li - ljh1553488six@139.com - author + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dromara.visor.module.asset.handler.host.config; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import org.dromara.visor.common.handler.data.GenericsStrategyDefinition; +import org.dromara.visor.common.handler.data.model.GenericsDataModel; +import org.dromara.visor.common.handler.data.strategy.GenericsDataStrategy; + +/** + * 主机配置类型策略枚举 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/9/11 14:37 + */ +@Getter +@AllArgsConstructor +public enum HostConfigStrategyEnum implements GenericsStrategyDefinition { + + /** + * SSH + */ + SSH(HostSshConfigStrategy.class), + + /** + * RDP + */ + RDP(HostRdpConfigStrategy.class), + + ; + + private final Class> strategyClass; + + public static HostConfigStrategyEnum of(String type) { + if (type == null) { + return null; + } + for (HostConfigStrategyEnum value : values()) { + if (value.name().equals(type)) { + return value; + } + } + return null; + } + +} diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/config/HostRdpConfigStrategy.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/config/HostRdpConfigStrategy.java new file mode 100644 index 00000000..e033e8d8 --- /dev/null +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/config/HostRdpConfigStrategy.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2023 - present Dromara, All rights reserved. + * + * https://visor.dromara.org + * https://visor.dromara.org.cn + * https://visor.orionsec.cn + * + * Members: + * Jiahang Li - ljh1553488six@139.com - author + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.dromara.visor.module.asset.handler.host.config; + +import cn.orionsec.kit.lang.utils.Strings; +import org.dromara.visor.common.constant.Const; +import org.dromara.visor.common.constant.ErrorMessage; +import org.dromara.visor.common.utils.Valid; +import org.dromara.visor.module.asset.dao.HostIdentityDAO; +import org.dromara.visor.module.asset.entity.domain.HostIdentityDO; +import org.dromara.visor.module.asset.entity.dto.host.HostRdpConfigDTO; +import org.dromara.visor.module.asset.enums.HostAuthTypeEnum; +import org.dromara.visor.module.asset.enums.HostIdentityTypeEnum; +import org.dromara.visor.module.asset.enums.HostTypeEnum; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; + +/** + * 主机 RDP 配置策略 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/9/19 14:26 + */ +@Component +public class HostRdpConfigStrategy extends AbstractHostConfigStrategy { + + @Resource + private HostIdentityDAO hostIdentityDAO; + + public HostRdpConfigStrategy() { + super(HostRdpConfigDTO.class); + } + + @Override + public HostRdpConfigDTO getDefault() { + return HostRdpConfigDTO.builder() + .port(3389) + .username(Const.ADMINISTRATOR) + .authType(HostAuthTypeEnum.PASSWORD.name()) + .versionGt81(true) + .timezone("Asia/Shanghai") + .keyboardLayout("en-us-qwerty") + .clipboardNormalize("preserve") + .build(); + } + + @Override + protected void preValid(HostRdpConfigDTO model) { + // 检查主机身份是否存在 + Long identityId = model.getIdentityId(); + if (identityId != null) { + HostIdentityDO identity = Valid.notNull(hostIdentityDAO.selectById(identityId), ErrorMessage.IDENTITY_ABSENT); + Valid.eq(HostIdentityTypeEnum.PASSWORD.name(), identity.getType(), ErrorMessage.CHECK_IDENTITY_PASSWORD); + } + } + + @Override + protected void valid(HostRdpConfigDTO model) { + // 验证填充后的参数 + Valid.valid(model); + } + + @Override + protected void updateFill(HostRdpConfigDTO beforeModel, HostRdpConfigDTO afterModel) { + // 加密密码 + this.checkEncryptPassword(afterModel.getAuthType(), beforeModel, afterModel); + afterModel.setHasPassword(null); + afterModel.setUseNewPassword(null); + } + + @Override + public HostRdpConfigDTO parse(String serialModel) { + return HostTypeEnum.RDP.parse(serialModel); + } + + @Override + public void toView(HostRdpConfigDTO model) { + if (model == null) { + return; + } + model.setHasPassword(Strings.isNotBlank(model.getPassword())); + model.setPassword(null); + } + +} diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/config/strategy/HostSshConfigStrategy.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/config/HostSshConfigStrategy.java similarity index 54% rename from orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/config/strategy/HostSshConfigStrategy.java rename to orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/config/HostSshConfigStrategy.java index d54668ca..fff59664 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/config/strategy/HostSshConfigStrategy.java +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/config/HostSshConfigStrategy.java @@ -20,21 +20,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.dromara.visor.module.asset.handler.host.config.strategy; +package org.dromara.visor.module.asset.handler.host.config; -import cn.orionsec.kit.lang.utils.Booleans; -import cn.orionsec.kit.lang.utils.Charsets; import cn.orionsec.kit.lang.utils.Strings; import org.dromara.visor.common.constant.Const; import org.dromara.visor.common.constant.ErrorMessage; -import org.dromara.visor.common.handler.data.strategy.AbstractGenericsDataStrategy; -import org.dromara.visor.common.utils.AesEncryptUtils; -import org.dromara.visor.common.utils.RsaParamDecryptUtils; import org.dromara.visor.common.utils.Valid; import org.dromara.visor.module.asset.dao.HostIdentityDAO; import org.dromara.visor.module.asset.dao.HostKeyDAO; -import org.dromara.visor.module.asset.enums.HostSshAuthTypeEnum; -import org.dromara.visor.module.asset.handler.host.config.model.HostSshConfigModel; +import org.dromara.visor.module.asset.entity.dto.host.HostSshConfigDTO; +import org.dromara.visor.module.asset.enums.HostAuthTypeEnum; +import org.dromara.visor.module.asset.enums.HostTypeEnum; import org.springframework.stereotype.Component; import javax.annotation.Resource; @@ -47,7 +43,7 @@ import javax.annotation.Resource; * @since 2023/9/19 14:26 */ @Component -public class HostSshConfigStrategy extends AbstractGenericsDataStrategy { +public class HostSshConfigStrategy extends AbstractHostConfigStrategy { @Resource private HostKeyDAO hostKeyDAO; @@ -55,18 +51,16 @@ public class HostSshConfigStrategy extends AbstractGenericsDataStrategy { + + @Resource + private HostIdentityDAO hostIdentityDAO; + + @Resource + private DataPermissionApi dataPermissionApi; + + public HostRdpExtraStrategy() { + super(HostRdpExtraModel.class); + } + + @Override + public HostRdpExtraModel getDefault() { + return HostRdpExtraModel.builder() + .authType(HostExtraAuthTypeEnum.DEFAULT.name()) + .build(); + } + + @Override + public void preValid(HostRdpExtraModel model) { + HostExtraAuthTypeEnum authType = Valid.valid(HostExtraAuthTypeEnum::of, model.getAuthType()); + model.setAuthType(authType.name()); + Long identityId = model.getIdentityId(); + Long userId = SecurityUtils.getLoginUserId(); + // 必填验证 + if (HostExtraAuthTypeEnum.CUSTOM_IDENTITY.equals(authType)) { + Valid.notNull(identityId); + // 验证主机身份是否存在 + Valid.notNull(hostIdentityDAO.selectById(identityId), ErrorMessage.IDENTITY_ABSENT); + // 验证主机身份是否有权限 + Valid.isTrue(dataPermissionApi.hasPermission(DataPermissionTypeEnum.HOST_IDENTITY, userId, identityId), + ErrorMessage.ANY_NO_PERMISSION, + DataPermissionTypeEnum.HOST_IDENTITY.getPermissionName()); + } + } + +} diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/extra/strategy/HostSshExtraStrategy.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/extra/strategy/HostSshExtraStrategy.java index e6ef57d9..e9cceafe 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/extra/strategy/HostSshExtraStrategy.java +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/extra/strategy/HostSshExtraStrategy.java @@ -28,7 +28,7 @@ import org.dromara.visor.common.utils.Valid; import org.dromara.visor.framework.security.core.utils.SecurityUtils; import org.dromara.visor.module.asset.dao.HostIdentityDAO; import org.dromara.visor.module.asset.dao.HostKeyDAO; -import org.dromara.visor.module.asset.enums.HostExtraSshAuthTypeEnum; +import org.dromara.visor.module.asset.enums.HostExtraAuthTypeEnum; import org.dromara.visor.module.asset.handler.host.extra.model.HostSshExtraModel; import org.dromara.visor.module.infra.api.DataPermissionApi; import org.dromara.visor.module.infra.enums.DataPermissionTypeEnum; @@ -62,20 +62,20 @@ public class HostSshExtraStrategy extends AbstractGenericsDataStrategy { - type.getHandler().handle(session, type.parse(payload)); - }); - } else { - // 同步执行 - type.getHandler().handle(session, type.parse(payload)); - } - } catch (Exception e) { - log.error("TerminalDispatchHandler-handleMessage-error id: {}, msg: {}", session.getId(), payload, e); - } - } - - @Override - public void afterConnectionEstablished(WebSocketSession session) { - log.info("TerminalMessageDispatcher-afterConnectionEstablished id: {}", session.getId()); - } - - @Override - public void handleTransportError(WebSocketSession session, Throwable exception) { - log.error("TerminalMessageDispatcher-handleTransportError id: {}", session.getId(), exception); - } - - @Override - public void afterConnectionClosed(WebSocketSession session, CloseStatus status) { - String id = session.getId(); - log.info("TerminalMessageDispatcher-afterConnectionClosed id: {}, code: {}, reason: {}", id, status.getCode(), status.getReason()); - // 关闭会话 - terminalManager.closeSession(id); - } - -} diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/terminal/handler/AbstractTerminalHandler.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/terminal/handler/AbstractTerminalHandler.java deleted file mode 100644 index 1fedcac2..00000000 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/terminal/handler/AbstractTerminalHandler.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2023 - present Dromara, All rights reserved. - * - * https://visor.dromara.org - * https://visor.dromara.org.cn - * https://visor.orionsec.cn - * - * Members: - * Jiahang Li - ljh1553488six@139.com - author - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.dromara.visor.module.asset.handler.host.terminal.handler; - -import org.dromara.visor.common.constant.ErrorMessage; -import org.dromara.visor.framework.biz.operator.log.core.model.OperatorLogModel; -import org.dromara.visor.framework.biz.operator.log.core.service.OperatorLogFrameworkService; -import org.dromara.visor.framework.biz.operator.log.core.utils.OperatorLogs; -import org.dromara.visor.framework.websocket.core.utils.WebSockets; -import org.dromara.visor.module.asset.handler.host.terminal.enums.OutputTypeEnum; -import org.dromara.visor.module.asset.handler.host.terminal.manager.TerminalManager; -import org.dromara.visor.module.asset.handler.host.terminal.model.TerminalBasePayload; -import org.dromara.visor.module.asset.handler.host.terminal.model.TerminalConfig; -import org.dromara.visor.module.asset.handler.host.terminal.session.ITerminalSession; -import org.dromara.visor.module.asset.handler.host.terminal.utils.TerminalUtils; -import org.springframework.web.socket.WebSocketSession; - -import javax.annotation.Resource; -import java.util.Map; - -/** - * 终端消息处理器 基类 - * - * @author Jiahang Li - * @version 1.0.0 - * @since 2023/12/29 18:59 - */ -public abstract class AbstractTerminalHandler implements ITerminalHandler { - - @Resource - protected TerminalManager terminalManager; - - @Resource - private OperatorLogFrameworkService operatorLogFrameworkService; - - /** - * 发送消息 - * - * @param channel channel - * @param type type - * @param body body - * @param E - */ - public void send(WebSocketSession channel, OutputTypeEnum type, E body) { - body.setType(type.getType()); - // 发送消息 - this.send(channel, type.format(body)); - } - - /** - * 发送消息 - * - * @param channel channel - * @param message message - */ - protected void send(WebSocketSession channel, String message) { - WebSockets.sendText(channel, message); - } - - /** - * 保存操作日志 - * - * @param payload payload - * @param channel channel - * @param extra extra - * @param type type - * @param startTime startTime - * @param ex ex - */ - protected void saveOperatorLog(T payload, - WebSocketSession channel, - Map extra, - String type, - long startTime, - Exception ex) { - String channelId = channel.getId(); - String sessionId = payload.getSessionId(); - // 获取会话并且设置参数 - ITerminalSession session = terminalManager.getSession(channelId, sessionId); - if (session != null) { - TerminalConfig config = session.getConfig(); - extra.put(OperatorLogs.HOST_ID, config.getHostId()); - extra.put(OperatorLogs.HOST_NAME, config.getHostName()); - extra.put(OperatorLogs.ADDRESS, config.getAddress()); - } - extra.put(OperatorLogs.CHANNEL_ID, channelId); - extra.put(OperatorLogs.SESSION_ID, sessionId); - // 获取日志 - OperatorLogModel model = TerminalUtils.getOperatorLogModel(channel, extra, type, startTime, ex); - // 保存 - operatorLogFrameworkService.insert(model); - } - - /** - * 获取错误信息 - * - * @param ex ex - * @return msg - */ - protected String getErrorMessage(Exception ex) { - // 获取错误信息 - return ErrorMessage.getErrorMessage(ex, ErrorMessage.OPERATE_ERROR); - } - -} diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/terminal/handler/TerminalCheckHandler.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/terminal/handler/TerminalCheckHandler.java deleted file mode 100644 index 5ce07410..00000000 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/terminal/handler/TerminalCheckHandler.java +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (c) 2023 - present Dromara, All rights reserved. - * - * https://visor.dromara.org - * https://visor.dromara.org.cn - * https://visor.orionsec.cn - * - * Members: - * Jiahang Li - ljh1553488six@139.com - author - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.dromara.visor.module.asset.handler.host.terminal.handler; - -import cn.orionsec.kit.lang.exception.DisabledException; -import cn.orionsec.kit.lang.exception.argument.InvalidArgumentException; -import cn.orionsec.kit.lang.utils.Exceptions; -import cn.orionsec.kit.lang.utils.collect.Maps; -import lombok.extern.slf4j.Slf4j; -import org.dromara.visor.common.constant.ErrorMessage; -import org.dromara.visor.common.constant.ExtraFieldConst; -import org.dromara.visor.common.enums.BooleanBit; -import org.dromara.visor.framework.biz.operator.log.core.model.OperatorLogModel; -import org.dromara.visor.framework.biz.operator.log.core.service.OperatorLogFrameworkService; -import org.dromara.visor.framework.biz.operator.log.core.utils.OperatorLogs; -import org.dromara.visor.framework.websocket.core.utils.WebSockets; -import org.dromara.visor.module.asset.dao.HostDAO; -import org.dromara.visor.module.asset.define.operator.TerminalOperatorType; -import org.dromara.visor.module.asset.entity.domain.HostDO; -import org.dromara.visor.module.asset.entity.domain.TerminalConnectLogDO; -import org.dromara.visor.module.asset.entity.dto.TerminalConnectDTO; -import org.dromara.visor.module.asset.entity.request.host.TerminalConnectLogCreateRequest; -import org.dromara.visor.module.asset.enums.TerminalConnectStatusEnum; -import org.dromara.visor.module.asset.enums.TerminalConnectTypeEnum; -import org.dromara.visor.module.asset.handler.host.terminal.constant.TerminalMessage; -import org.dromara.visor.module.asset.handler.host.terminal.enums.OutputTypeEnum; -import org.dromara.visor.module.asset.handler.host.terminal.model.request.TerminalCheckRequest; -import org.dromara.visor.module.asset.handler.host.terminal.model.response.TerminalCheckResponse; -import org.dromara.visor.module.asset.handler.host.terminal.session.ITerminalSession; -import org.dromara.visor.module.asset.handler.host.terminal.utils.TerminalUtils; -import org.dromara.visor.module.asset.service.HostConnectService; -import org.dromara.visor.module.asset.service.TerminalConnectLogService; -import org.springframework.stereotype.Component; -import org.springframework.web.socket.WebSocketSession; - -import javax.annotation.Resource; -import java.util.Map; - -/** - * 终端连接检查 - * - * @author Jiahang Li - * @version 1.0.0 - * @since 2023/12/29 15:32 - */ -@Slf4j -@Component -public class TerminalCheckHandler extends AbstractTerminalHandler { - - @Resource - private HostDAO hostDAO; - - @Resource - private HostConnectService hostConnectService; - - @Resource - private TerminalConnectLogService terminalConnectLogService; - - @Resource - private OperatorLogFrameworkService operatorLogFrameworkService; - - @Override - public void handle(WebSocketSession channel, TerminalCheckRequest payload) { - Long hostId = payload.getHostId(); - Long userId = WebSockets.getAttr(channel, ExtraFieldConst.USER_ID); - long startTime = System.currentTimeMillis(); - TerminalConnectTypeEnum connectType = TerminalConnectTypeEnum.of(payload.getConnectType()); - String sessionId = payload.getSessionId(); - log.info("TerminalCheckHandler-handle start userId: {}, hostId: {}, sessionId: {}", userId, hostId, sessionId); - // 检查 session 是否存在 - if (this.checkSession(channel, payload)) { - log.info("TerminalCheckHandler-handle present session userId: {}, hostId: {}, sessionId: {}", userId, hostId, sessionId); - return; - } - // 获取主机信息 - HostDO host = this.checkHost(channel, payload, hostId); - if (host == null) { - log.info("TerminalCheckHandler-handle unknown host userId: {}, hostId: {}, sessionId: {}", userId, hostId, sessionId); - return; - } - TerminalConnectDTO connect = null; - Exception ex = null; - try { - // 获取连接信息 - connect = hostConnectService.getSshConnectInfo(host, userId); - connect.setConnectType(connectType.name()); - // 设置到缓存中 - channel.getAttributes().put(sessionId, connect); - log.info("TerminalCheckHandler-handle success userId: {}, hostId: {}, sessionId: {}", userId, hostId, sessionId); - } catch (InvalidArgumentException e) { - ex = e; - log.error("TerminalCheckHandler-handle start error userId: {}, hostId: {}, sessionId: {}", userId, hostId, sessionId, e); - } catch (DisabledException e) { - ex = Exceptions.runtime(TerminalMessage.CONFIG_DISABLED); - log.error("TerminalCheckHandler-handle disabled error userId: {}, hostId: {}, sessionId: {}", userId, hostId, sessionId); - } catch (Exception e) { - ex = Exceptions.runtime(TerminalMessage.CONNECTION_FAILED); - log.error("TerminalCheckHandler-handle exception userId: {}, hostId: {}, sessionId: {}", userId, hostId, sessionId, e); - } - // 记录主机日志 - TerminalConnectLogDO connectLog = this.saveHostLog(channel, userId, host, startTime, ex, sessionId, connectType); - if (connect != null) { - connect.setLogId(connectLog.getId()); - } - // 响应检查结果 - this.send(channel, - OutputTypeEnum.CHECK, - TerminalCheckResponse.builder() - .sessionId(payload.getSessionId()) - .result(BooleanBit.of(ex == null).getValue()) - .msg(ex == null ? null : ex.getMessage()) - .build()); - } - - /** - * 检查会话是否存在 - * - * @param channel channel - * @param payload payload - * @return 是否存在 - */ - private boolean checkSession(WebSocketSession channel, TerminalCheckRequest payload) { - ITerminalSession session = terminalManager.getSession(channel.getId(), payload.getSessionId()); - if (session != null) { - this.sendCheckFailedMessage(channel, payload, ErrorMessage.SESSION_PRESENT); - return true; - } - return false; - } - - /** - * 获取主机信息 - * - * @param channel channel - * @param payload payload - * @param hostId hostId - * @return host - */ - private HostDO checkHost(WebSocketSession channel, TerminalCheckRequest payload, Long hostId) { - // 查询主机信息 - HostDO host = hostDAO.selectById(hostId); - // 不存在返回错误信息 - if (host == null) { - this.sendCheckFailedMessage(channel, payload, ErrorMessage.HOST_ABSENT); - } - return host; - } - - /** - * 发送检查失败消息 - * - * @param channel channel - * @param payload payload - * @param msg msg - */ - private void sendCheckFailedMessage(WebSocketSession channel, TerminalCheckRequest payload, String msg) { - TerminalCheckResponse resp = TerminalCheckResponse.builder() - .sessionId(payload.getSessionId()) - .result(BooleanBit.FALSE.getValue()) - .msg(msg) - .build(); - // 发送 - this.send(channel, OutputTypeEnum.CHECK, resp); - } - - /** - * 记录主机日志 - * - * @param channel channel - * @param userId userId - * @param host host - * @param startTime startTime - * @param ex ex - * @param sessionId sessionId - * @param connectType connectType - * @return connectLog - */ - private TerminalConnectLogDO saveHostLog(WebSocketSession channel, - Long userId, - HostDO host, - long startTime, - Exception ex, - String sessionId, - TerminalConnectTypeEnum connectType) { - Long hostId = host.getId(); - String hostName = host.getName(); - String username = WebSockets.getAttr(channel, ExtraFieldConst.USERNAME); - // 额外参数 - Map extra = Maps.newMap(); - extra.put(OperatorLogs.HOST_ID, hostId); - extra.put(OperatorLogs.HOST_NAME, hostName); - extra.put(OperatorLogs.CONNECT_TYPE, connectType.name()); - extra.put(OperatorLogs.CHANNEL_ID, channel.getId()); - extra.put(OperatorLogs.SESSION_ID, sessionId); - // 日志参数 - OperatorLogModel logModel = TerminalUtils.getOperatorLogModel(channel, extra, - TerminalOperatorType.CONNECT, startTime, ex); - // 记录操作日志 - operatorLogFrameworkService.insert(logModel); - // 记录连接日志 - TerminalConnectLogCreateRequest connectLog = TerminalConnectLogCreateRequest.builder() - .userId(userId) - .username(username) - .hostId(hostId) - .hostName(hostName) - .hostAddress(host.getAddress()) - .status(ex == null ? TerminalConnectStatusEnum.CONNECTING.name() : TerminalConnectStatusEnum.FAILED.name()) - .sessionId(sessionId) - .extra(extra) - .build(); - // 填充其他信息 - extra.put(OperatorLogs.TRACE_ID, logModel.getTraceId()); - extra.put(OperatorLogs.ADDRESS, logModel.getAddress()); - extra.put(OperatorLogs.LOCATION, logModel.getLocation()); - extra.put(OperatorLogs.USER_AGENT, logModel.getUserAgent()); - extra.put(OperatorLogs.ERROR_MESSAGE, logModel.getErrorMessage()); - // 记录连接日志 - return terminalConnectLogService.create(connectType, connectLog); - } - -} diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/terminal/handler/TerminalConnectHandler.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/terminal/handler/TerminalConnectHandler.java deleted file mode 100644 index 335d8bad..00000000 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/terminal/handler/TerminalConnectHandler.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (c) 2023 - present Dromara, All rights reserved. - * - * https://visor.dromara.org - * https://visor.dromara.org.cn - * https://visor.orionsec.cn - * - * Members: - * Jiahang Li - ljh1553488six@139.com - author - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.dromara.visor.module.asset.handler.host.terminal.handler; - -import cn.orionsec.kit.lang.exception.AuthenticationException; -import cn.orionsec.kit.lang.exception.TimeoutException; -import cn.orionsec.kit.lang.exception.argument.InvalidArgumentException; -import cn.orionsec.kit.lang.utils.Exceptions; -import cn.orionsec.kit.lang.utils.collect.Maps; -import cn.orionsec.kit.lang.utils.io.Streams; -import cn.orionsec.kit.net.host.SessionStore; -import lombok.extern.slf4j.Slf4j; -import org.dromara.visor.common.constant.ErrorMessage; -import org.dromara.visor.common.constant.ExtraFieldConst; -import org.dromara.visor.common.enums.BooleanBit; -import org.dromara.visor.framework.websocket.core.utils.WebSockets; -import org.dromara.visor.module.asset.define.config.AppSftpConfig; -import org.dromara.visor.module.asset.entity.dto.TerminalConnectDTO; -import org.dromara.visor.module.asset.enums.TerminalConnectStatusEnum; -import org.dromara.visor.module.asset.enums.TerminalConnectTypeEnum; -import org.dromara.visor.module.asset.handler.host.jsch.SessionStores; -import org.dromara.visor.module.asset.handler.host.terminal.constant.TerminalMessage; -import org.dromara.visor.module.asset.handler.host.terminal.enums.OutputTypeEnum; -import org.dromara.visor.module.asset.handler.host.terminal.model.TerminalConfig; -import org.dromara.visor.module.asset.handler.host.terminal.model.request.TerminalConnectRequest; -import org.dromara.visor.module.asset.handler.host.terminal.model.response.TerminalConnectResponse; -import org.dromara.visor.module.asset.handler.host.terminal.session.ITerminalSession; -import org.dromara.visor.module.asset.handler.host.terminal.session.SftpSession; -import org.dromara.visor.module.asset.handler.host.terminal.session.SshSession; -import org.dromara.visor.module.asset.service.TerminalConnectLogService; -import org.springframework.stereotype.Component; -import org.springframework.web.socket.WebSocketSession; - -import javax.annotation.Resource; -import java.util.Map; - -/** - * 连接主机处理器 - * - * @author Jiahang Li - * @version 1.0.0 - * @since 2023/12/29 15:32 - */ -@Slf4j -@Component -public class TerminalConnectHandler extends AbstractTerminalHandler { - - @Resource - private AppSftpConfig appSftpConfig; - - @Resource - private TerminalConnectLogService terminalConnectLogService; - - @Override - public void handle(WebSocketSession channel, TerminalConnectRequest payload) { - String sessionId = payload.getSessionId(); - log.info("TerminalConnectHandler-handle start sessionId: {}", sessionId); - // 获取终端连接信息 - TerminalConnectDTO connect = WebSockets.getAttr(channel, sessionId); - if (connect == null) { - log.info("TerminalConnectHandler-handle unknown sessionId: {}", sessionId); - this.send(channel, - OutputTypeEnum.CONNECT, - TerminalConnectResponse.builder() - .sessionId(payload.getSessionId()) - .result(BooleanBit.FALSE.getValue()) - .msg(ErrorMessage.SESSION_ABSENT) - .build()); - return; - } - // 移除会话连接信息 - channel.getAttributes().remove(sessionId); - Exception ex = null; - ITerminalSession session = null; - try { - // 连接主机 - session = this.connect(sessionId, connect, channel, payload); - // 添加会话到 manager - terminalManager.addSession(session); - } catch (Exception e) { - ex = e; - Streams.close(session); - // 修改连接状态为失败 - Map extra = Maps.newMap(4); - extra.put(ExtraFieldConst.ERROR_MESSAGE, this.getConnectErrorMessage(e)); - terminalConnectLogService.updateStatusById(connect.getLogId(), TerminalConnectStatusEnum.FAILED, extra); - } - // 返回连接状态 - this.send(channel, - OutputTypeEnum.CONNECT, - TerminalConnectResponse.builder() - .sessionId(payload.getSessionId()) - .result(BooleanBit.of(ex == null).getValue()) - .msg(this.getConnectErrorMessage(ex)) - .build()); - } - - /** - * 连接主机 - * - * @param sessionId sessionId - * @param connect connect - * @param channel channel - * @param body body - * @return channel - */ - private ITerminalSession connect(String sessionId, - TerminalConnectDTO connect, - WebSocketSession channel, - TerminalConnectRequest body) { - String connectType = connect.getConnectType(); - ITerminalSession session = null; - try { - // 连接配置 - TerminalConfig config = TerminalConfig.builder() - .logId(connect.getLogId()) - .hostId(connect.getHostId()) - .hostName(connect.getHostName()) - .address(connect.getHostAddress()) - .charset(connect.getCharset()) - .fileNameCharset(connect.getFileNameCharset()) - .fileContentCharset(connect.getFileContentCharset()) - .filePreviewSize(appSftpConfig.getPreviewSize()) - .build(); - // 建立连接 - SessionStore sessionStore = SessionStores.openSessionStore(connect); - if (TerminalConnectTypeEnum.SSH.name().equals(connectType)) { - // 打开 ssh 会话 - SshSession sshSession = new SshSession(sessionId, channel, sessionStore, config); - sshSession.connect(body.getTerminalType(), body.getCols(), body.getRows()); - session = sshSession; - } else if (TerminalConnectTypeEnum.SFTP.name().equals(connectType)) { - // 打开 sftp 会话 - SftpSession sftpSession = new SftpSession(sessionId, channel, sessionStore, config); - sftpSession.connect(); - session = sftpSession; - } - log.info("TerminalConnectHandler-handle success sessionId: {}", sessionId); - return session; - } catch (Exception e) { - Streams.close(session); - log.error("TerminalConnectHandler-handle error sessionId: {}", sessionId, e); - throw e; - } - } - - /** - * 获取建立连接错误信息 - * - * @param e e - * @return errorMessage - */ - private String getConnectErrorMessage(Exception e) { - if (e == null) { - return null; - } - if (Exceptions.isCausedBy(e, TimeoutException.class)) { - // 连接超时 - return TerminalMessage.CONNECTION_TIMEOUT; - } else if (Exceptions.isCausedBy(e, AuthenticationException.class)) { - // 认证失败 - return TerminalMessage.AUTHENTICATION_FAILURE; - } else if (Exceptions.isCausedBy(e, InvalidArgumentException.class)) { - // 参数错误 - return e.getMessage(); - } else { - // 其他错误 - return TerminalMessage.SERVER_UNREACHABLE; - } - } - -} diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/terminal/manager/TerminalManager.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/terminal/manager/TerminalManager.java deleted file mode 100644 index 39c8bc1b..00000000 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/terminal/manager/TerminalManager.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2023 - present Dromara, All rights reserved. - * - * https://visor.dromara.org - * https://visor.dromara.org.cn - * https://visor.orionsec.cn - * - * Members: - * Jiahang Li - ljh1553488six@139.com - author - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.dromara.visor.module.asset.handler.host.terminal.manager; - -import cn.orionsec.kit.lang.define.collect.MultiConcurrentHashMap; -import cn.orionsec.kit.lang.utils.collect.Maps; -import cn.orionsec.kit.lang.utils.io.Streams; -import org.dromara.visor.module.asset.handler.host.terminal.session.ITerminalSession; -import org.springframework.stereotype.Component; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * 终端管理器 - * - * @author Jiahang Li - * @version 1.0.0 - * @since 2024/1/3 11:35 - */ -@Component -public class TerminalManager { - - /** - * 会话存储器 - */ - private final MultiConcurrentHashMap channelSessions = MultiConcurrentHashMap.create(); - - /** - * 添加会话 - * - * @param session session - */ - public void addSession(ITerminalSession session) { - channelSessions.put(session.getChannelId(), session.getSessionId(), session); - } - - /** - * 通过 channel 关闭会话 - * - * @param channelId channelId - */ - public void closeSession(String channelId) { - // 获取并移除 - ConcurrentHashMap session = channelSessions.remove(channelId); - if (!Maps.isEmpty(session)) { - session.values().forEach(Streams::close); - } - } - - /** - * 通过 channel + sessionId 关闭会话 - * - * @param channelId channelId - * @param sessionId sessionId - */ - public void closeSession(String channelId, String sessionId) { - // 获取并移除 - ITerminalSession session = channelSessions.removeElement(channelId, sessionId); - if (session != null) { - Streams.close(session); - } - } - - /** - * 获取会话 - * - * @param channelId channelId - * @param sessionId sessionId - * @param T - * @return session - */ - @SuppressWarnings("unchecked") - public T getSession(String channelId, String sessionId) { - return (T) channelSessions.get(channelId, sessionId); - } - - /** - * 获取会话 - * - * @param channelId channelId - * @return session - */ - public Map getSession(String channelId) { - return channelSessions.get(channelId); - } - - /** - * 获取全部会话 - * - * @return session - */ - public MultiConcurrentHashMap getChannelSessions() { - return channelSessions; - } - -} diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/terminal/session/TerminalSession.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/terminal/session/TerminalSession.java deleted file mode 100644 index 09865c72..00000000 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/handler/host/terminal/session/TerminalSession.java +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2023 - present Dromara, All rights reserved. - * - * https://visor.dromara.org - * https://visor.dromara.org.cn - * https://visor.orionsec.cn - * - * Members: - * Jiahang Li - ljh1553488six@139.com - author - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.dromara.visor.module.asset.handler.host.terminal.session; - -import cn.orionsec.kit.spring.SpringHolder; -import lombok.Getter; -import lombok.extern.slf4j.Slf4j; -import org.dromara.visor.common.enums.BooleanBit; -import org.dromara.visor.framework.websocket.core.utils.WebSockets; -import org.dromara.visor.module.asset.enums.TerminalConnectStatusEnum; -import org.dromara.visor.module.asset.handler.host.terminal.constant.TerminalMessage; -import org.dromara.visor.module.asset.handler.host.terminal.enums.OutputTypeEnum; -import org.dromara.visor.module.asset.handler.host.terminal.model.TerminalConfig; -import org.dromara.visor.module.asset.handler.host.terminal.model.response.TerminalCloseResponse; -import org.dromara.visor.module.asset.service.TerminalConnectLogService; -import org.springframework.web.socket.WebSocketSession; - -/** - * 终端会话基类 - * - * @author Jiahang Li - * @version 1.0.0 - * @since 2024/2/4 16:51 - */ -@Slf4j -public abstract class TerminalSession implements ITerminalSession { - - @Getter - protected final String sessionId; - - protected final WebSocketSession channel; - - @Getter - protected final TerminalConfig config; - - @Getter - protected volatile boolean closed; - - protected volatile boolean forceOffline; - - public TerminalSession(String sessionId, WebSocketSession channel, TerminalConfig config) { - this.sessionId = sessionId; - this.channel = channel; - this.config = config; - } - - /** - * 释放资源 - */ - protected abstract void releaseResource(); - - /** - * 发送关闭消息 - */ - protected void sendCloseMessage() { - log.info("TerminalSession close {}, forClose: {}, forceOffline: {}", sessionId, this.closed, this.forceOffline); - // 发送关闭信息 - TerminalCloseResponse resp = TerminalCloseResponse.builder() - .type(OutputTypeEnum.CLOSE.getType()) - .sessionId(this.sessionId) - .forceClose(BooleanBit.of(this.forceOffline).getValue()) - .msg(this.forceOffline ? TerminalMessage.FORCED_OFFLINE : TerminalMessage.CONNECTION_CLOSED) - .build(); - WebSockets.sendText(channel, OutputTypeEnum.CLOSE.format(resp)); - } - - @Override - public void close() { - log.info("terminal close {}", sessionId); - // 检查并且关闭 - if (this.checkAndClose()) { - // 修改状态 - SpringHolder.getBean(TerminalConnectLogService.class) - .updateStatusById(config.getLogId(), TerminalConnectStatusEnum.COMPLETE, null); - } - } - - @Override - public void forceOffline() { - log.info("terminal forceOffline {}", sessionId); - this.forceOffline = true; - // 关闭 - this.checkAndClose(); - } - - /** - * 检查并且关闭会话 - * - * @return close - */ - private boolean checkAndClose() { - if (closed) { - return false; - } - this.closed = true; - // 释放资源 - try { - this.releaseResource(); - } catch (Exception e) { - log.error("terminal release error {}", sessionId, e); - } - // 发送关闭信息 - try { - this.sendCloseMessage(); - } catch (Exception e) { - log.error("terminal send close error {}", sessionId, e); - } - return true; - } - - @Override - public String getChannelId() { - return channel.getId(); - } - -} diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/AssetStatisticsService.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/AssetStatisticsService.java index a3897081..bff79191 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/AssetStatisticsService.java +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/AssetStatisticsService.java @@ -22,41 +22,22 @@ */ package org.dromara.visor.module.asset.service; -import org.dromara.visor.common.entity.chart.LineSingleChartData; -import org.dromara.visor.module.asset.entity.vo.AssetWorkplaceStatisticsVO; -import org.dromara.visor.module.asset.enums.ExecSourceEnum; +import org.dromara.visor.common.entity.chart.PieChartData; /** * 资产模块统计服务 * * @author Jiahang Li * @version 1.0.0 - * @since 2024/12/23 22:24 + * @since 2025/3/7 16:26 */ public interface AssetStatisticsService { /** - * 查询工作台统计信息 + * 获取主机类型图表 * * @return data */ - AssetWorkplaceStatisticsVO getWorkplaceStatisticsData(); - - /** - * 获取用户终端连接日志数量图表 - * - * @param userId userId - * @return data - */ - LineSingleChartData getTerminalConnectCountChart(Long userId); - - /** - * 获取用户执行日志数量图表 - * - * @param userId userId - * @param source source - * @return chart - */ - LineSingleChartData getUserExecLogCountChart(Long userId, ExecSourceEnum source); + PieChartData getHostTypeChart(); } diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/HostConnectService.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/HostConnectService.java index 12562a99..fee71a48 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/HostConnectService.java +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/HostConnectService.java @@ -22,8 +22,9 @@ */ package org.dromara.visor.module.asset.service; +import org.dromara.visor.common.session.config.RdpConnectConfig; +import org.dromara.visor.common.session.config.SshConnectConfig; import org.dromara.visor.module.asset.entity.domain.HostDO; -import org.dromara.visor.module.asset.entity.dto.TerminalConnectDTO; import org.dromara.visor.module.asset.entity.request.host.HostTestConnectRequest; /** @@ -43,29 +44,55 @@ public interface HostConnectService { void testHostConnect(HostTestConnectRequest request); /** - * 获取 SSH 连接信息 + * 获取 SSH 连接配置 * * @param hostId hostId * @return session */ - TerminalConnectDTO getSshConnectInfo(Long hostId); + SshConnectConfig getSshConnectConfig(Long hostId); /** - * 使用用户配置获取 SSH 连接信息 + * 使用用户配置获取 SSH 连接配置 * * @param hostId hostId * @param userId userId * @return session */ - TerminalConnectDTO getSshConnectInfo(Long hostId, Long userId); + SshConnectConfig getSshConnectConfig(Long hostId, Long userId); /** - * 使用用户配置获取 SSH 连接信息 + * 使用用户配置获取 SSH 连接配置 * * @param host host * @param userId userId * @return session */ - TerminalConnectDTO getSshConnectInfo(HostDO host, Long userId); + SshConnectConfig getSshConnectConfig(HostDO host, Long userId); + + /** + * 获取 RDP 连接配置 + * + * @param hostId hostId + * @return session + */ + RdpConnectConfig getRdpConnectConfig(Long hostId); + + /** + * 使用用户配置获取 RDP 连接配置 + * + * @param hostId hostId + * @param userId userId + * @return session + */ + RdpConnectConfig getRdpConnectConfig(Long hostId, Long userId); + + /** + * 使用用户配置获取 RDP 连接配置 + * + * @param host host + * @param userId userId + * @return session + */ + RdpConnectConfig getRdpConnectConfig(HostDO host, Long userId); } diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/HostExtraService.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/HostExtraService.java index 2a512c05..6d9a2ae5 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/HostExtraService.java +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/HostExtraService.java @@ -24,7 +24,7 @@ package org.dromara.visor.module.asset.service; import org.dromara.visor.common.handler.data.model.GenericsDataModel; import org.dromara.visor.module.asset.entity.request.host.HostExtraUpdateRequest; -import org.dromara.visor.module.asset.enums.HostExtraItemEnum; +import org.dromara.visor.module.asset.handler.host.extra.HostExtraItemEnum; import org.dromara.visor.module.asset.handler.host.extra.model.HostSpecExtraModel; import java.util.List; diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/AssetAuthorizedDataServiceImpl.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/AssetAuthorizedDataServiceImpl.java index 92e2afe3..ab109f1a 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/AssetAuthorizedDataServiceImpl.java +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/AssetAuthorizedDataServiceImpl.java @@ -34,8 +34,8 @@ import org.dromara.visor.module.asset.convert.HostGroupConvert; import org.dromara.visor.module.asset.dao.HostDAO; import org.dromara.visor.module.asset.entity.request.asset.AssetAuthorizedDataQueryRequest; import org.dromara.visor.module.asset.entity.vo.*; -import org.dromara.visor.module.asset.enums.HostExtraItemEnum; import org.dromara.visor.module.asset.enums.HostStatusEnum; +import org.dromara.visor.module.asset.handler.host.extra.HostExtraItemEnum; import org.dromara.visor.module.asset.handler.host.extra.model.HostLabelExtraModel; import org.dromara.visor.module.asset.service.AssetAuthorizedDataService; import org.dromara.visor.module.asset.service.HostIdentityService; diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/AssetStatisticsServiceImpl.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/AssetStatisticsServiceImpl.java index 61a17d53..730e18c7 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/AssetStatisticsServiceImpl.java +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/AssetStatisticsServiceImpl.java @@ -22,157 +22,61 @@ */ package org.dromara.visor.module.asset.service.impl; -import cn.orionsec.kit.lang.utils.collect.Lists; -import cn.orionsec.kit.lang.utils.time.Dates; -import org.dromara.visor.common.entity.StatisticsRange; -import org.dromara.visor.common.entity.chart.LineSingleChartData; +import cn.orionsec.kit.lang.utils.Objects1; +import cn.orionsec.kit.lang.utils.collect.Maps; +import com.alibaba.fastjson.JSONObject; +import org.dromara.visor.common.entity.chart.PieChartData; import org.dromara.visor.framework.redis.core.utils.RedisStrings; -import org.dromara.visor.framework.security.core.utils.SecurityUtils; -import org.dromara.visor.module.asset.convert.ExecLogConvert; -import org.dromara.visor.module.asset.convert.TerminalConnectLogConvert; -import org.dromara.visor.module.asset.dao.ExecJobDAO; -import org.dromara.visor.module.asset.dao.ExecLogDAO; -import org.dromara.visor.module.asset.dao.TerminalConnectLogDAO; +import org.dromara.visor.framework.redis.core.utils.barrier.CacheBarriers; +import org.dromara.visor.module.asset.dao.HostConfigDAO; import org.dromara.visor.module.asset.define.cache.AssetStatisticsCacheKeyDefine; -import org.dromara.visor.module.asset.entity.domain.ExecJobDO; -import org.dromara.visor.module.asset.entity.domain.ExecLogDO; -import org.dromara.visor.module.asset.entity.domain.TerminalConnectLogDO; -import org.dromara.visor.module.asset.entity.po.ExecLogCountPO; -import org.dromara.visor.module.asset.entity.po.TerminalConnectLogCountPO; -import org.dromara.visor.module.asset.entity.vo.AssetWorkplaceStatisticsVO; -import org.dromara.visor.module.asset.entity.vo.ExecLogVO; -import org.dromara.visor.module.asset.entity.vo.TerminalConnectLogVO; -import org.dromara.visor.module.asset.enums.ExecSourceEnum; +import org.dromara.visor.module.asset.entity.po.HostTypeCountPO; +import org.dromara.visor.module.asset.enums.HostTypeEnum; import org.dromara.visor.module.asset.service.AssetStatisticsService; import org.springframework.stereotype.Service; import javax.annotation.Resource; -import java.util.Date; +import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; /** * 资产模块统计服务实现 * * @author Jiahang Li * @version 1.0.0 - * @since 2024/12/23 20:47 + * @since 2025/3/7 16:26 */ @Service public class AssetStatisticsServiceImpl implements AssetStatisticsService { @Resource - private ExecJobDAO execJobDAO; - - @Resource - private ExecLogDAO execLogDAO; - - @Resource - private TerminalConnectLogDAO terminalConnectLogDAO; + private HostConfigDAO hostConfigDAO; @Override - public AssetWorkplaceStatisticsVO getWorkplaceStatisticsData() { - Long userId = SecurityUtils.getLoginUserId(); - // 读取缓存 - String cacheKey = AssetStatisticsCacheKeyDefine.WORKPLACE_DATA.format(userId, Dates.current(Dates.YMD2)); - AssetWorkplaceStatisticsVO data = RedisStrings.getJson(cacheKey, AssetStatisticsCacheKeyDefine.WORKPLACE_DATA); - if (data == null) { - // 查询执行的计划任务数量 - int execJobCount = execJobDAO.of() - .createWrapper() - .eq(ExecJobDO::getExecUserId, userId) - .then() - .count() - .intValue(); - // 查询批量执行次数图表 - LineSingleChartData execLogCountChart = this.getUserExecLogCountChart(userId, ExecSourceEnum.BATCH); - List execLogCountData = execLogCountChart.getData(); - int execLogCount = execLogCountData.stream() - .mapToInt(Integer::intValue) - .sum(); - // 查询终端连接次数图表 - LineSingleChartData terminalConnectCountChart = this.getTerminalConnectCountChart(userId); - List terminalConnectCountData = terminalConnectCountChart.getData(); - int terminalConnectCount = terminalConnectCountData.stream() - .mapToInt(Integer::intValue) - .sum(); - data = AssetWorkplaceStatisticsVO.builder() - .execJobCount(execJobCount) - .todayExecCommandCount(Lists.last(execLogCountData)) - .weekExecCommandCount(execLogCount) - .todayTerminalConnectCount(Lists.last(terminalConnectCountData)) - .weekTerminalConnectCount(terminalConnectCount) - .execCommandChart(execLogCountChart) - .terminalConnectChart(terminalConnectCountChart) - .build(); + public PieChartData getHostTypeChart() { + // 查询缓存 + JSONObject cache = RedisStrings.getJson(AssetStatisticsCacheKeyDefine.HOST_TYPE_COUNT); + if (Maps.isEmpty(cache)) { + cache = new JSONObject(); + // 查询数据库 + List typeCountList = hostConfigDAO.selectEnabledTypeCount(); + for (HostTypeCountPO typeCount : typeCountList) { + cache.put(typeCount.getType(), typeCount.getCount()); + } + // 设置屏障 防止穿透 + CacheBarriers.STRING_MAP.check(cache); // 设置缓存 - RedisStrings.setJson(cacheKey, AssetStatisticsCacheKeyDefine.WORKPLACE_DATA, data); + RedisStrings.set(AssetStatisticsCacheKeyDefine.HOST_TYPE_COUNT, cache); } - // 查询命令执行记录 - List execLogList = execLogDAO.of() - .createWrapper() - .eq(ExecLogDO::getUserId, userId) - .eq(ExecLogDO::getSource, ExecSourceEnum.BATCH.name()) - .orderByDesc(ExecLogDO::getId) - .then() - .limit(10) - .list(ExecLogConvert.MAPPER::to); - data.setExecLogList(execLogList); - // 查询终端连接记录 - List connectList = terminalConnectLogDAO.of() - .createWrapper() - .eq(TerminalConnectLogDO::getUserId, userId) - .orderByDesc(TerminalConnectLogDO::getId) - .then() - .limit(10) - .list(TerminalConnectLogConvert.MAPPER::to); - data.setTerminalConnectList(connectList); - return data; - } - - @Override - public LineSingleChartData getUserExecLogCountChart(Long userId, ExecSourceEnum source) { - Date endTime = new Date(); - Date startTime = Dates.stream() - .clearHms() - .addDay(-6) - .get(); - List rangeDays = StatisticsRange.WEEK.getDateRanges(startTime); - // 查询连接数量 - Map countMap = execLogDAO.selectExecLogCount(userId, source.name(), startTime, endTime) - .stream() - .collect(Collectors.toMap(ExecLogCountPO::getExecDate, ExecLogCountPO::getCount)); - // 构建每天的数据 - List data = rangeDays.stream() - .map(s -> countMap.getOrDefault(s, 0)) - .collect(Collectors.toList()); - return LineSingleChartData.builder() - .x(rangeDays) - .data(data) - .build(); - } - - @Override - public LineSingleChartData getTerminalConnectCountChart(Long userId) { - Date endTime = new Date(); - Date startTime = Dates.stream() - .clearHms() - .addDay(-6) - .get(); - List rangeDays = StatisticsRange.WEEK.getDateRanges(startTime); - // 查询连接数量 - Map countMap = terminalConnectLogDAO.selectConnectLogUserCount(userId, startTime, endTime) - .stream() - .collect(Collectors.toMap(TerminalConnectLogCountPO::getConnectDate, TerminalConnectLogCountPO::getCount)); - // 构建每天的数据 - List data = rangeDays.stream() - .map(s -> countMap.getOrDefault(s, 0)) - .collect(Collectors.toList()); - return LineSingleChartData.builder() - .x(rangeDays) - .data(data) - .build(); + // 删除屏障 + CacheBarriers.STRING_MAP.remove(cache); + // 查询类型数量 + Map data = new HashMap<>(); + for (HostTypeEnum value : HostTypeEnum.values()) { + data.put(value.name(), Objects1.def(cache.getInteger(value.name()), 0)); + } + return new PieChartData(data); } } diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/HostConfigServiceImpl.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/HostConfigServiceImpl.java index d3370f8d..fba78e3c 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/HostConfigServiceImpl.java +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/HostConfigServiceImpl.java @@ -40,6 +40,7 @@ import org.dromara.visor.module.asset.entity.request.host.HostConfigQueryRequest import org.dromara.visor.module.asset.entity.request.host.HostConfigUpdateRequest; import org.dromara.visor.module.asset.enums.HostStatusEnum; import org.dromara.visor.module.asset.enums.HostTypeEnum; +import org.dromara.visor.module.asset.handler.host.config.HostConfigStrategyEnum; import org.dromara.visor.module.asset.service.HostConfigService; import org.springframework.stereotype.Service; @@ -78,7 +79,7 @@ public class HostConfigServiceImpl implements HostConfigService { Valid.notNull(host, ErrorMessage.HOST_ABSENT); OperatorLogs.add(OperatorLogs.NAME, host.getName()); // 获取处理策略 - HostTypeEnum strategy = HostTypeEnum.of(type); + HostConfigStrategyEnum strategy = HostConfigStrategyEnum.of(type); GenericsDataModel newConfig = strategy.parse(request.getConfig()); // 查询配置 HostConfigDO record = hostConfigDAO.selectByHostIdType(hostId, type); @@ -123,7 +124,7 @@ public class HostConfigServiceImpl implements HostConfigService { String configValue = originHostConfigMap.get(type); if (Strings.isBlank(configValue)) { // 获取默认值 - configValue = HostTypeEnum.of(type).getDefault().serial(); + configValue = HostConfigStrategyEnum.of(type).getDefault().serial(); } HostConfigDO newConfig = HostConfigDO.builder() .hostId(newId) @@ -152,7 +153,7 @@ public class HostConfigServiceImpl implements HostConfigService { @Override public T getHostConfigView(HostConfigQueryRequest request) { String type = request.getType(); - HostTypeEnum strategy = HostTypeEnum.of(type); + HostConfigStrategyEnum strategy = HostConfigStrategyEnum.of(type); // 查询配置 HostConfigDO record = hostConfigDAO.selectByHostIdType(request.getHostId(), type); if (record == null) { diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/HostConnectServiceImpl.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/HostConnectServiceImpl.java index 7602b986..085e44b1 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/HostConnectServiceImpl.java +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/HostConnectServiceImpl.java @@ -27,6 +27,10 @@ import cn.orionsec.kit.lang.utils.io.Streams; import cn.orionsec.kit.net.host.SessionStore; import lombok.extern.slf4j.Slf4j; import org.dromara.visor.common.constant.ErrorMessage; +import org.dromara.visor.common.session.config.BaseConnectConfig; +import org.dromara.visor.common.session.config.RdpConnectConfig; +import org.dromara.visor.common.session.config.SshConnectConfig; +import org.dromara.visor.common.session.ssh.SessionStores; import org.dromara.visor.common.utils.Valid; import org.dromara.visor.module.asset.dao.HostDAO; import org.dromara.visor.module.asset.dao.HostIdentityDAO; @@ -34,12 +38,16 @@ import org.dromara.visor.module.asset.dao.HostKeyDAO; import org.dromara.visor.module.asset.entity.domain.HostDO; import org.dromara.visor.module.asset.entity.domain.HostIdentityDO; import org.dromara.visor.module.asset.entity.domain.HostKeyDO; -import org.dromara.visor.module.asset.entity.dto.TerminalConnectDTO; +import org.dromara.visor.module.asset.entity.dto.host.HostRdpConfigDTO; +import org.dromara.visor.module.asset.entity.dto.host.HostSshConfigDTO; import org.dromara.visor.module.asset.entity.request.host.HostTestConnectRequest; -import org.dromara.visor.module.asset.enums.*; -import org.dromara.visor.module.asset.handler.host.config.model.HostSshConfigModel; +import org.dromara.visor.module.asset.enums.HostAuthTypeEnum; +import org.dromara.visor.module.asset.enums.HostExtraAuthTypeEnum; +import org.dromara.visor.module.asset.enums.HostIdentityTypeEnum; +import org.dromara.visor.module.asset.enums.HostTypeEnum; +import org.dromara.visor.module.asset.handler.host.extra.HostExtraItemEnum; +import org.dromara.visor.module.asset.handler.host.extra.model.HostRdpExtraModel; import org.dromara.visor.module.asset.handler.host.extra.model.HostSshExtraModel; -import org.dromara.visor.module.asset.handler.host.jsch.SessionStores; import org.dromara.visor.module.asset.service.AssetAuthorizedDataService; import org.dromara.visor.module.asset.service.HostConfigService; import org.dromara.visor.module.asset.service.HostConnectService; @@ -92,68 +100,93 @@ public class HostConnectServiceImpl implements HostConnectService { // SSH 连接测试 SessionStore sessionStore = null; try { - TerminalConnectDTO info = this.getSshConnectInfo(id); - sessionStore = SessionStores.openSessionStore(info); + SshConnectConfig config = this.getSshConnectConfig(id); + sessionStore = SessionStores.openSessionStore(config); } catch (Exception e) { throw Exceptions.app(e.getMessage(), e); } finally { Streams.close(sessionStore); } } + // TODO: 其他连接方式 } @Override - public TerminalConnectDTO getSshConnectInfo(Long hostId) { - log.info("HostConnectService.getSshConnectInfo-withHost hostId: {}", hostId); + public SshConnectConfig getSshConnectConfig(Long hostId) { + log.info("HostConnectService.getSshConnectConfig-withHost hostId: {}", hostId); // 查询主机 HostDO host = hostDAO.selectById(hostId); // 查询主机配置 - HostSshConfigModel config = hostConfigService.getHostConfig(hostId, HostTypeEnum.SSH.name()); + HostSshConfigDTO config = hostConfigService.getHostConfig(hostId, HostTypeEnum.SSH.name()); // 获取配置 - return this.getHostConnectInfo(host, config, null); + return this.getSshConnectConfig(host, config, null); } @Override - public TerminalConnectDTO getSshConnectInfo(Long hostId, Long userId) { + public SshConnectConfig getSshConnectConfig(Long hostId, Long userId) { // 查询主机 HostDO host = hostDAO.selectById(hostId); Valid.notNull(host, ErrorMessage.HOST_ABSENT); // 获取配置 - return this.getSshConnectInfo(host, userId); + return this.getSshConnectConfig(host, userId); } @Override - public TerminalConnectDTO getSshConnectInfo(HostDO host, Long userId) { + public SshConnectConfig getSshConnectConfig(HostDO host, Long userId) { Long hostId = host.getId(); - log.info("HostConnectService.getSshConnectInfo hostId: {}, userId: {}", hostId, userId); - // 验证主机是否有权限 - List hostIdList = assetAuthorizedDataService.getUserAuthorizedHostId(userId); - Valid.isTrue(hostIdList.contains(hostId), - ErrorMessage.ANY_NO_PERMISSION, - DataPermissionTypeEnum.HOST_GROUP.getPermissionName()); + log.info("HostConnectService.getSshConnectConfig hostId: {}, userId: {}", hostId, userId); + // 验证权限 + this.validHostAuthorized(userId, hostId); // 获取主机配置 - HostSshConfigModel config = hostConfigService.getHostConfig(hostId, HostTypeEnum.SSH.name()); + HostSshConfigDTO config = hostConfigService.getHostConfig(hostId, HostTypeEnum.SSH.name()); Valid.notNull(config, ErrorMessage.CONFIG_ABSENT); // 查询主机额外配置 HostSshExtraModel extra = hostExtraService.getHostExtra(userId, hostId, HostExtraItemEnum.SSH); if (extra != null) { - HostExtraSshAuthTypeEnum extraAuthType = HostExtraSshAuthTypeEnum.of(extra.getAuthType()); - if (HostExtraSshAuthTypeEnum.CUSTOM_KEY.equals(extraAuthType)) { - // 验证主机密钥是否有权限 - Valid.notNull(extra.getKeyId(), ErrorMessage.KEY_ABSENT); - Valid.isTrue(dataPermissionApi.hasPermission(DataPermissionTypeEnum.HOST_KEY, userId, extra.getKeyId()), - ErrorMessage.ANY_NO_PERMISSION, - DataPermissionTypeEnum.HOST_KEY.getPermissionName()); - } else if (HostExtraSshAuthTypeEnum.CUSTOM_IDENTITY.equals(extraAuthType)) { - // 验证主机身份是否有权限 - Valid.notNull(extra.getIdentityId(), ErrorMessage.IDENTITY_ABSENT); - Valid.isTrue(dataPermissionApi.hasPermission(DataPermissionTypeEnum.HOST_IDENTITY, userId, extra.getIdentityId()), - ErrorMessage.ANY_NO_PERMISSION, - DataPermissionTypeEnum.HOST_IDENTITY.getPermissionName()); - } + // 验证额外认证方式 + this.validExtraAuthentication(userId, extra.getAuthType(), extra.getKeyId(), extra.getIdentityId()); } // 获取连接配置 - return this.getHostConnectInfo(host, config, extra); + return this.getSshConnectConfig(host, config, extra); + } + + @Override + public RdpConnectConfig getRdpConnectConfig(Long hostId) { + log.info("HostConnectService.getRdpConnectConfig-withHost hostId: {}", hostId); + // 查询主机 + HostDO host = hostDAO.selectById(hostId); + // 查询主机配置 + HostRdpConfigDTO config = hostConfigService.getHostConfig(hostId, HostTypeEnum.RDP.name()); + // 获取配置 + return this.getRdpConnectConfig(host, config, null); + } + + @Override + public RdpConnectConfig getRdpConnectConfig(Long hostId, Long userId) { + // 查询主机 + HostDO host = hostDAO.selectById(hostId); + Valid.notNull(host, ErrorMessage.HOST_ABSENT); + // 获取配置 + return this.getRdpConnectConfig(host, userId); + } + + @Override + public RdpConnectConfig getRdpConnectConfig(HostDO host, Long userId) { + Long hostId = host.getId(); + log.info("HostConnectService.getRdpConnectConfig hostId: {}, userId: {}", hostId, userId); + // 验证权限 + this.validHostAuthorized(userId, hostId); + // 获取主机配置 + HostRdpConfigDTO config = hostConfigService.getHostConfig(hostId, HostTypeEnum.RDP.name()); + Valid.notNull(config, ErrorMessage.CONFIG_ABSENT); + // 查询主机额外配置 + HostRdpExtraModel extra = hostExtraService.getHostExtra(userId, hostId, HostExtraItemEnum.RDP); + if (extra != null) { + // 验证额外认证方式 + this.validExtraAuthentication(userId, extra.getAuthType(), null, extra.getIdentityId()); + } + // 获取连接配置 + return this.getRdpConnectConfig(host, config, extra); } /** @@ -162,46 +195,41 @@ public class HostConnectServiceImpl implements HostConnectService { * @param host host * @param config config * @param extra extra - * @return session + * @return info */ - private TerminalConnectDTO getHostConnectInfo(HostDO host, - HostSshConfigModel config, - HostSshExtraModel extra) { - // 填充认证信息 - TerminalConnectDTO conn = new TerminalConnectDTO(); - conn.setOsType(host.getOsType()); - conn.setArchType(host.getArchType()); - conn.setHostId(host.getId()); - conn.setHostName(host.getName()); - conn.setHostCode(host.getCode()); - conn.setHostAddress(host.getAddress()); - conn.setHostPort(config.getPort()); - conn.setTimeout(config.getConnectTimeout()); - conn.setCharset(config.getCharset()); - conn.setFileNameCharset(config.getFileNameCharset()); - conn.setFileContentCharset(config.getFileContentCharset()); - + private SshConnectConfig getSshConnectConfig(HostDO host, + HostSshConfigDTO config, + HostSshExtraModel extra) { + SshConnectConfig connectConfig = SshConnectConfig.builder() + .hostPort(config.getPort()) + .timeout(config.getConnectTimeout()) + .charset(config.getCharset()) + .fileNameCharset(config.getFileNameCharset()) + .fileContentCharset(config.getFileContentCharset()) + .build(); + // 填充基础主机信息 + this.setBaseConnectConfig(connectConfig, host); // 获取自定义认证方式 - HostExtraSshAuthTypeEnum extraAuthType = Optional.ofNullable(extra) + HostExtraAuthTypeEnum extraAuthType = Optional.ofNullable(extra) .map(HostSshExtraModel::getAuthType) - .map(HostExtraSshAuthTypeEnum::of) + .map(HostExtraAuthTypeEnum::of) .orElse(null); - if (HostExtraSshAuthTypeEnum.CUSTOM_KEY.equals(extraAuthType)) { + if (HostExtraAuthTypeEnum.CUSTOM_KEY.equals(extraAuthType)) { // 自定义密钥 - config.setAuthType(HostSshAuthTypeEnum.KEY.name()); + config.setAuthType(HostAuthTypeEnum.KEY.name()); config.setKeyId(extra.getKeyId()); if (extra.getUsername() != null) { config.setUsername(extra.getUsername()); } - } else if (HostExtraSshAuthTypeEnum.CUSTOM_IDENTITY.equals(extraAuthType)) { + } else if (HostExtraAuthTypeEnum.CUSTOM_IDENTITY.equals(extraAuthType)) { // 自定义身份 - config.setAuthType(HostSshAuthTypeEnum.IDENTITY.name()); + config.setAuthType(HostAuthTypeEnum.IDENTITY.name()); config.setIdentityId(extra.getIdentityId()); } // 身份认证 - HostSshAuthTypeEnum authType = HostSshAuthTypeEnum.of(config.getAuthType()); - if (HostSshAuthTypeEnum.IDENTITY.equals(authType)) { + HostAuthTypeEnum authType = HostAuthTypeEnum.of(config.getAuthType()); + if (HostAuthTypeEnum.IDENTITY.equals(authType)) { // 身份认证 Valid.notNull(config.getIdentityId(), ErrorMessage.IDENTITY_ABSENT); HostIdentityDO identity = hostIdentityDAO.selectById(config.getIdentityId()); @@ -210,32 +238,146 @@ public class HostConnectServiceImpl implements HostConnectService { HostIdentityTypeEnum identityType = HostIdentityTypeEnum.of(identity.getType()); if (HostIdentityTypeEnum.PASSWORD.equals(identityType)) { // 密码类型 - authType = HostSshAuthTypeEnum.PASSWORD; + authType = HostAuthTypeEnum.PASSWORD; config.setPassword(identity.getPassword()); } else if (HostIdentityTypeEnum.KEY.equals(identityType)) { // 密钥类型 - authType = HostSshAuthTypeEnum.KEY; + authType = HostAuthTypeEnum.KEY; config.setKeyId(identity.getKeyId()); } } // 填充认证信息 - conn.setUsername(config.getUsername()); - if (HostSshAuthTypeEnum.PASSWORD.equals(authType)) { + connectConfig.setUsername(config.getUsername()); + if (HostAuthTypeEnum.PASSWORD.equals(authType)) { // 密码认证 - conn.setPassword(config.getPassword()); - } else if (HostSshAuthTypeEnum.KEY.equals(authType)) { + connectConfig.setPassword(config.getPassword()); + } else if (HostAuthTypeEnum.KEY.equals(authType)) { // 密钥认证 Long keyId = config.getKeyId(); Valid.notNull(keyId, ErrorMessage.KEY_ABSENT); HostKeyDO key = hostKeyDAO.selectById(keyId); Valid.notNull(key, ErrorMessage.KEY_ABSENT); - conn.setKeyId(keyId); - conn.setPublicKey(key.getPublicKey()); - conn.setPrivateKey(key.getPrivateKey()); - conn.setPrivateKeyPassword(key.getPassword()); + connectConfig.setKeyId(keyId); + connectConfig.setPublicKey(key.getPublicKey()); + connectConfig.setPrivateKey(key.getPrivateKey()); + connectConfig.setPrivateKeyPassword(key.getPassword()); } - return conn; + return connectConfig; + } + + /** + * 获取 RDP 连接信息 + * + * @param host host + * @param config config + * @return info + */ + private RdpConnectConfig getRdpConnectConfig(HostDO host, + HostRdpConfigDTO config, + HostRdpExtraModel extra) { + // 填充认证信息 + RdpConnectConfig connectConfig = RdpConnectConfig.builder() + .hostPort(config.getPort()) + .versionGt81(config.getVersionGt81()) + .timezone(config.getTimezone()) + .keyboardLayout(config.getKeyboardLayout()) + .clipboardNormalize(config.getClipboardNormalize()) + .domain(config.getDomain()) + .preConnectionId(config.getPreConnectionId()) + .preConnectionBlob(config.getPreConnectionBlob()) + .remoteApp(config.getRemoteApp()) + .remoteAppDir(config.getRemoteAppDir()) + .remoteAppArgs(config.getRemoteAppArgs()) + .build(); + // 填充基础主机信息 + this.setBaseConnectConfig(connectConfig, host); + if (extra != null) { + // 设置低带宽模式 + connectConfig.setLowBandwidthMode(extra.getLowBandwidthMode()); + // 获取自定义认证方式 + HostExtraAuthTypeEnum extraAuthType = HostExtraAuthTypeEnum.of(extra.getAuthType()); + if (HostExtraAuthTypeEnum.CUSTOM_IDENTITY.equals(extraAuthType)) { + // 自定义身份 + config.setAuthType(HostAuthTypeEnum.IDENTITY.name()); + config.setIdentityId(extra.getIdentityId()); + } + } + + // 身份认证 + HostAuthTypeEnum authType = HostAuthTypeEnum.of(config.getAuthType()); + if (HostAuthTypeEnum.IDENTITY.equals(authType)) { + // 身份认证 - 仅密码 + authType = HostAuthTypeEnum.PASSWORD; + Valid.notNull(config.getIdentityId(), ErrorMessage.IDENTITY_ABSENT); + HostIdentityDO identity = hostIdentityDAO.selectById(config.getIdentityId()); + Valid.notNull(identity, ErrorMessage.IDENTITY_ABSENT); + // 设置身份信息 + config.setUsername(identity.getUsername()); + config.setPassword(identity.getPassword()); + } + + // 填充认证信息 + connectConfig.setUsername(config.getUsername()); + if (HostAuthTypeEnum.PASSWORD.equals(authType)) { + // 密码认证 + connectConfig.setPassword(config.getPassword()); + } + return connectConfig; + } + + /** + * 验证主机权限 + * + * @param userId userId + * @param hostId hostId + */ + private void validHostAuthorized(Long userId, Long hostId) { + // 验证主机是否有权限 + List hostIdList = assetAuthorizedDataService.getUserAuthorizedHostId(userId); + Valid.isTrue(hostIdList.contains(hostId), + ErrorMessage.ANY_NO_PERMISSION, + DataPermissionTypeEnum.HOST_GROUP.getPermissionName()); + } + + /** + * 验证额外认证方式 + * + * @param userId userId + * @param authType authType + * @param keyId keyId + * @param identityId identityId + */ + private void validExtraAuthentication(Long userId, String authType, Long keyId, Long identityId) { + HostExtraAuthTypeEnum extraAuthType = HostExtraAuthTypeEnum.of(authType); + if (HostExtraAuthTypeEnum.CUSTOM_KEY.equals(extraAuthType)) { + // 验证主机密钥是否有权限 + Valid.notNull(keyId, ErrorMessage.KEY_ABSENT); + Valid.isTrue(dataPermissionApi.hasPermission(DataPermissionTypeEnum.HOST_KEY, userId, keyId), + ErrorMessage.ANY_NO_PERMISSION, + DataPermissionTypeEnum.HOST_KEY.getPermissionName()); + } else if (HostExtraAuthTypeEnum.CUSTOM_IDENTITY.equals(extraAuthType)) { + // 验证主机身份是否有权限 + Valid.notNull(identityId, ErrorMessage.IDENTITY_ABSENT); + Valid.isTrue(dataPermissionApi.hasPermission(DataPermissionTypeEnum.HOST_IDENTITY, userId, identityId), + ErrorMessage.ANY_NO_PERMISSION, + DataPermissionTypeEnum.HOST_IDENTITY.getPermissionName()); + } + } + + /** + * 设置基础主机信息 + * + * @param config config + * @param host host + */ + private void setBaseConnectConfig(BaseConnectConfig config, HostDO host) { + config.setOsType(host.getOsType()); + config.setArchType(host.getArchType()); + config.setHostId(host.getId()); + config.setHostName(host.getName()); + config.setHostCode(host.getCode()); + config.setHostAddress(host.getAddress()); } } diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/HostExtraServiceImpl.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/HostExtraServiceImpl.java index fadede43..3add637b 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/HostExtraServiceImpl.java +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/HostExtraServiceImpl.java @@ -28,7 +28,7 @@ import org.dromara.visor.common.handler.data.model.GenericsDataModel; import org.dromara.visor.common.utils.Valid; import org.dromara.visor.framework.security.core.utils.SecurityUtils; import org.dromara.visor.module.asset.entity.request.host.HostExtraUpdateRequest; -import org.dromara.visor.module.asset.enums.HostExtraItemEnum; +import org.dromara.visor.module.asset.handler.host.extra.HostExtraItemEnum; import org.dromara.visor.module.asset.handler.host.extra.model.HostSpecExtraModel; import org.dromara.visor.module.asset.service.HostExtraService; import org.dromara.visor.module.infra.api.DataExtraApi; diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/HostIdentityServiceImpl.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/HostIdentityServiceImpl.java index e6ad6036..ea267b1e 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/HostIdentityServiceImpl.java +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/HostIdentityServiceImpl.java @@ -298,8 +298,8 @@ public class HostIdentityServiceImpl implements HostIdentityService { return hostIdentityDAO.wrapper() .eq(HostIdentityDO::getId, request.getId()) .eq(HostIdentityDO::getType, request.getType()) - .eq(HostIdentityDO::getKeyId, request.getKeyId()) .like(HostIdentityDO::getName, request.getName()) + .eq(HostIdentityDO::getKeyId, request.getKeyId()) .like(HostIdentityDO::getUsername, request.getUsername()) .like(HostIdentityDO::getDescription, request.getDescription()) .and(Strings.isNotEmpty(searchValue), c -> c diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/HostKeyServiceImpl.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/HostKeyServiceImpl.java index 8e6f086f..0e3d5980 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/HostKeyServiceImpl.java +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/HostKeyServiceImpl.java @@ -214,7 +214,7 @@ public class HostKeyServiceImpl implements HostKeyService { OperatorLogs.add(OperatorLogs.NAME, name); // 删除数据库 int effect = hostKeyDAO.deleteBatchIds(idList); - // 删除关联 + // 删除身份关联 hostIdentityDAO.setKeyWithNull(idList); // 删除主机配置 hostConfigDAO.setKeyIdWithNull(idList); diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/HostServiceImpl.java b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/HostServiceImpl.java index 0dc34d70..e009b498 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/HostServiceImpl.java +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/java/org/dromara/visor/module/asset/service/impl/HostServiceImpl.java @@ -37,19 +37,25 @@ import org.dromara.visor.common.enums.EnableStatus; import org.dromara.visor.common.utils.Valid; import org.dromara.visor.framework.biz.operator.log.core.utils.OperatorLogs; import org.dromara.visor.framework.redis.core.utils.RedisMaps; +import org.dromara.visor.framework.redis.core.utils.RedisStrings; import org.dromara.visor.framework.redis.core.utils.barrier.CacheBarriers; import org.dromara.visor.module.asset.convert.HostConvert; import org.dromara.visor.module.asset.dao.HostConfigDAO; import org.dromara.visor.module.asset.dao.HostDAO; +import org.dromara.visor.module.asset.define.cache.AssetStatisticsCacheKeyDefine; import org.dromara.visor.module.asset.define.cache.HostCacheKeyDefine; import org.dromara.visor.module.asset.entity.domain.HostDO; import org.dromara.visor.module.asset.entity.dto.HostCacheDTO; import org.dromara.visor.module.asset.entity.request.host.*; import org.dromara.visor.module.asset.entity.vo.HostVO; -import org.dromara.visor.module.asset.enums.HostExtraItemEnum; import org.dromara.visor.module.asset.enums.HostStatusEnum; +import org.dromara.visor.module.asset.handler.host.extra.HostExtraItemEnum; import org.dromara.visor.module.asset.handler.host.extra.model.HostSpecExtraModel; -import org.dromara.visor.module.asset.service.*; +import org.dromara.visor.module.asset.service.HostConfigService; +import org.dromara.visor.module.asset.service.HostExtraService; +import org.dromara.visor.module.asset.service.HostService; +import org.dromara.visor.module.exec.api.ExecJobApi; +import org.dromara.visor.module.exec.api.ExecTemplateApi; import org.dromara.visor.module.infra.api.DataExtraApi; import org.dromara.visor.module.infra.api.DataGroupRelApi; import org.dromara.visor.module.infra.api.FavoriteApi; @@ -95,10 +101,10 @@ public class HostServiceImpl implements HostService { private HostExtraService hostExtraService; @Resource - private ExecJobHostService execJobHostService; + private ExecJobApi execJobApi; @Resource - private ExecTemplateHostService execTemplateHostService; + private ExecTemplateApi execTemplateApi; @Resource private TagRelApi tagRelApi; @@ -324,9 +330,9 @@ public class HostServiceImpl implements HostService { // 删除主机配置 hostConfigDAO.deleteByHostIdList(idList); // 删除计划任务主机 - execJobHostService.deleteByHostIdList(idList); + execJobApi.deleteByHostIdList(idList); // 删除执行模板主机 - execTemplateHostService.deleteByHostIdList(idList); + execTemplateApi.deleteByHostIdList(idList); // 删除分组 dataGroupRelApi.deleteByRelIdList(DataGroupTypeEnum.HOST, idList); // 删除 tag 引用 @@ -340,6 +346,7 @@ public class HostServiceImpl implements HostService { @Override public void clearCache() { RedisMaps.scanKeysDelete(HostCacheKeyDefine.HOST_INFO.format("*")); + RedisStrings.delete(AssetStatisticsCacheKeyDefine.HOST_TYPE_COUNT.getKey()); } /** diff --git a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/resources/mapper/HostConfigMapper.xml b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/resources/mapper/HostConfigMapper.xml index b2e760a9..a7c2522d 100644 --- a/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/resources/mapper/HostConfigMapper.xml +++ b/orion-visor-modules/orion-visor-module-asset/orion-visor-module-asset-service/src/main/resources/mapper/HostConfigMapper.xml @@ -16,6 +16,12 @@ + + + + + + id, host_id, type, status, config, create_time, update_time, creator, updater, deleted @@ -39,4 +45,12 @@ + + diff --git a/orion-visor-modules/orion-visor-module-common/src/main/java/org/dromara/visor/module/common/utils/SftpUtils.java b/orion-visor-modules/orion-visor-module-common/src/main/java/org/dromara/visor/module/common/utils/SftpUtils.java index 098d6385..2c662e1f 100644 --- a/orion-visor-modules/orion-visor-module-common/src/main/java/org/dromara/visor/module/common/utils/SftpUtils.java +++ b/orion-visor-modules/orion-visor-module-common/src/main/java/org/dromara/visor/module/common/utils/SftpUtils.java @@ -22,8 +22,6 @@ */ package org.dromara.visor.module.common.utils; -import org.dromara.visor.module.common.config.AppSftpConfig; -import org.dromara.visor.module.common.entity.dto.SftpFileBackupDTO; import cn.orionsec.kit.lang.constant.Letters; import cn.orionsec.kit.lang.utils.Booleans; import cn.orionsec.kit.lang.utils.Strings; @@ -32,6 +30,8 @@ import cn.orionsec.kit.net.host.sftp.SftpExecutor; import cn.orionsec.kit.net.host.sftp.SftpFile; import cn.orionsec.kit.spring.SpringHolder; import com.alibaba.fastjson.JSON; +import org.dromara.visor.module.common.config.AppSftpConfig; +import org.dromara.visor.module.common.entity.dto.SftpFileBackupDTO; /** * sftp 工具类