密钥相关部分代码逻辑修改
This commit is contained in:
parent
28ed6b5c92
commit
16edaef984
@ -7,9 +7,18 @@ import com.jcraft.jsch.JSchException;
|
|||||||
import com.jcraft.jsch.Session;
|
import com.jcraft.jsch.Session;
|
||||||
import com.jcraft.jsch.SftpATTRS;
|
import com.jcraft.jsch.SftpATTRS;
|
||||||
import com.jcraft.jsch.SftpException;
|
import com.jcraft.jsch.SftpException;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -66,8 +75,7 @@ public class FileTreeComponent {
|
|||||||
try {
|
try {
|
||||||
sftp.ls(path, selector);
|
sftp.ls(path, selector);
|
||||||
} catch (SftpException e) {
|
} catch (SftpException e) {
|
||||||
log.error("读取远程文件目录结构失败 [错误码: {}, 信息: {}]",
|
log.error("读取远程文件目录结构失败, 信息: {}]", e.getMessage(), e);
|
||||||
e.id, e.getMessage(), e);
|
|
||||||
throw exception(READ_REMOTE_DIRECTORY_FAIL);
|
throw exception(READ_REMOTE_DIRECTORY_FAIL);
|
||||||
}
|
}
|
||||||
return new ArrayList<>(entries);
|
return new ArrayList<>(entries);
|
||||||
@ -211,4 +219,122 @@ public class FileTreeComponent {
|
|||||||
}
|
}
|
||||||
return fileInfoMap;
|
return fileInfoMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 上传到远程服务器
|
||||||
|
public void uploadToRemoteServer(Path tempFilePath, String safeFilename, String remoteFilePath) {
|
||||||
|
// 上传文件(使用原始文件名)
|
||||||
|
try {
|
||||||
|
sftp.put(tempFilePath.toString(), remoteFilePath + safeFilename);
|
||||||
|
} catch (SftpException e) {
|
||||||
|
throw exception(UPLOAD_REMOTE_FILE_ERROR);
|
||||||
|
} finally {
|
||||||
|
// 清理临时文件
|
||||||
|
cleanupTempFile(tempFilePath);
|
||||||
|
}
|
||||||
|
log.info("文件上传成功: {} -> {}{}", tempFilePath, remoteFilePath, safeFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
//下载文件
|
||||||
|
public void downloadFile(String remoteFilePath, HttpServletResponse httpServletResponse) {
|
||||||
|
InputStream inputStream = null;
|
||||||
|
OutputStream outputStream = null;
|
||||||
|
try {
|
||||||
|
// 获取文件信息并判断是否为文件夹
|
||||||
|
SftpATTRS attrs = sftp.lstat(remoteFilePath);
|
||||||
|
if (attrs.isDir()) {
|
||||||
|
httpServletResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
|
||||||
|
log.error("无法下载文件夹: {}", remoteFilePath);
|
||||||
|
throw exception(DOWNLOAD_FOLDER_NOT_ALLOWED);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 处理文件下载逻辑
|
||||||
|
String fileName = Paths.get(remoteFilePath).getFileName().toString();
|
||||||
|
|
||||||
|
// 设置响应头
|
||||||
|
httpServletResponse.setContentType("application/octet-stream");
|
||||||
|
httpServletResponse.setHeader("Content-Disposition", "attachment; filename=\"" + encodeFileName(fileName) + "\"");
|
||||||
|
httpServletResponse.setContentLengthLong(attrs.getSize());
|
||||||
|
|
||||||
|
// 流式传输文件
|
||||||
|
inputStream = sftp.get(remoteFilePath);
|
||||||
|
outputStream = httpServletResponse.getOutputStream();
|
||||||
|
|
||||||
|
byte[] buffer = new byte[8192];
|
||||||
|
int bytesRead;
|
||||||
|
while ((bytesRead = inputStream.read(buffer)) != -1) {
|
||||||
|
outputStream.write(buffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
outputStream.flush();
|
||||||
|
} catch (SftpException e) {
|
||||||
|
httpServletResponse.setStatus(HttpServletResponse.SC_NOT_FOUND);
|
||||||
|
log.error("远程文件不存在: {}", remoteFilePath, e);
|
||||||
|
throw exception(PATH_NOT_EXISTS);
|
||||||
|
} catch (IOException e) {
|
||||||
|
httpServletResponse.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||||
|
log.error("远程文件传输失败:{}", e.getMessage());
|
||||||
|
throw exception(REMOTE_FILE_TRANSFER_FAIL);
|
||||||
|
} finally {
|
||||||
|
// 关闭资源
|
||||||
|
closeQuietly(outputStream);
|
||||||
|
closeQuietly(inputStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//删除远程机器文件
|
||||||
|
public void deleteRemoteFile(String remoteFilePath) {
|
||||||
|
try {
|
||||||
|
// 检查文件是否存在
|
||||||
|
if (checkFileExists(remoteFilePath, sftp)) {
|
||||||
|
sftp.rm(remoteFilePath);
|
||||||
|
log.info("文件删除成功: {}", remoteFilePath);
|
||||||
|
} else {
|
||||||
|
log.error("文件不存在,无法删除");
|
||||||
|
throw exception(PATH_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
} catch (SftpException e) {
|
||||||
|
log.error("删除文件时出错: {}", e.getMessage());
|
||||||
|
throw exception(DELETE_REMOTE_FILE_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清理临时文件
|
||||||
|
private void cleanupTempFile(Path filePath) {
|
||||||
|
if (filePath != null && Files.exists(filePath)) {
|
||||||
|
try {
|
||||||
|
Files.delete(filePath);
|
||||||
|
log.debug("临时文件已删除: {}", filePath);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.warn("临时文件删除失败: {}", filePath, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String encodeFileName(String fileName) {
|
||||||
|
return URLEncoder.encode(fileName, StandardCharsets.UTF_8).replaceAll("\\+", "%20");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void closeQuietly(AutoCloseable closeable) {
|
||||||
|
if (closeable != null) {
|
||||||
|
try {
|
||||||
|
closeable.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("关闭资源失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 辅助方法:检查文件是否存在
|
||||||
|
private boolean checkFileExists(String filePath, ChannelSftp sftp) {
|
||||||
|
try {
|
||||||
|
sftp.lstat(filePath);
|
||||||
|
return true;
|
||||||
|
} catch (SftpException e) {
|
||||||
|
if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,230 +1,220 @@
|
|||||||
//package cd.casic.module.machine.component;
|
package cd.casic.module.machine.component;
|
||||||
//
|
|
||||||
//import cd.casic.framework.commons.exception.ServiceException;
|
import cd.casic.framework.commons.exception.ServiceException;
|
||||||
//import cd.casic.module.machine.dal.dataobject.MachineInfoDO;
|
import cd.casic.module.machine.dal.dataobject.MachineInfoDO;
|
||||||
//import cd.casic.module.machine.enums.AuthenticationType;
|
import cd.casic.module.machine.enums.AuthenticationType;
|
||||||
//import cd.casic.module.machine.enums.ConnectionStatus;
|
import cd.casic.module.machine.enums.ConnectionStatus;
|
||||||
//import cd.casic.module.machine.enums.SSHChanelType;
|
import cd.casic.module.machine.enums.SSHChanelType;
|
||||||
//import cd.casic.module.machine.service.SecretKeyService;
|
import cd.casic.module.machine.service.SecretKeyService;
|
||||||
//import com.jcraft.jsch.Channel;
|
import com.jcraft.jsch.Channel;
|
||||||
//import com.jcraft.jsch.ChannelExec;
|
import com.jcraft.jsch.ChannelExec;
|
||||||
//import com.jcraft.jsch.JSch;
|
import com.jcraft.jsch.JSch;
|
||||||
//import com.jcraft.jsch.JSchException;
|
import com.jcraft.jsch.JSchException;
|
||||||
//import com.jcraft.jsch.Session;
|
import com.jcraft.jsch.Session;
|
||||||
//import lombok.Data;
|
import lombok.Data;
|
||||||
//import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
//import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
//import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
//import org.springframework.web.socket.TextMessage;
|
import org.springframework.web.socket.TextMessage;
|
||||||
//import org.springframework.web.socket.WebSocketSession;
|
import org.springframework.web.socket.WebSocketSession;
|
||||||
//
|
|
||||||
//import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
//import java.io.IOException;
|
import java.io.IOException;
|
||||||
//import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
//import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
//import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
//import java.util.Properties;
|
import java.util.Properties;
|
||||||
//
|
|
||||||
//import static cd.casic.framework.commons.exception.util.ServiceExceptionUtil.exception;
|
import static cd.casic.framework.commons.exception.util.ServiceExceptionUtil.exception;
|
||||||
//import static cd.casic.module.machine.contants.MachineErrorCodeConstants.SECRET_KEY_NULL;
|
import static cd.casic.module.machine.contants.MachineErrorCodeConstants.*;
|
||||||
//import static cd.casic.module.machine.contants.MachineErrorCodeConstants.*;
|
|
||||||
//
|
@Slf4j
|
||||||
//@Slf4j
|
@Data
|
||||||
//@Data
|
@Component
|
||||||
//@Component
|
public class WebSocketConnection {
|
||||||
//public class WebSocketConnection {
|
private SecretKeyService secretKeyService;
|
||||||
// private SecretKeyService secretKeyService;
|
private MachineInfoDO machineInfo;
|
||||||
//
|
private ConnectionStatus connectionStatus = ConnectionStatus.DISCONNECTED;
|
||||||
// private MachineInfoDO machineInfo;
|
private Session sshSession;
|
||||||
// private ConnectionStatus connectionStatus = ConnectionStatus.DISCONNECTED;
|
|
||||||
// private Session sshSession;
|
public WebSocketConnection(SecretKeyService secretKeyService) {
|
||||||
//
|
this.secretKeyService = secretKeyService;
|
||||||
// public WebSocketConnection(SecretKeyService secretKeyService) {
|
}
|
||||||
// this.secretKeyService = secretKeyService;
|
|
||||||
// }
|
private static final int CONNECTION_TIMEOUT = 5000; // 连接超时时间(毫秒)
|
||||||
//
|
|
||||||
// private static final int CONNECTION_TIMEOUT = 5000; // 连接超时时间(毫秒)
|
public void initConnection(MachineInfoDO machineInfo) {
|
||||||
//
|
try {
|
||||||
// public void initConnection(MachineInfoDO machineInfo) {
|
this.machineInfo = machineInfo;
|
||||||
// try {
|
this.sshSession = doConnect(machineInfo);
|
||||||
// this.machineInfo = machineInfo;
|
log.info("已成功建立 SSH 连接至 {} ", machineInfo.getHostIp());
|
||||||
// this.sshSession = doConnect(machineInfo);
|
this.connectionStatus = ConnectionStatus.CONNECTING;
|
||||||
// log.info("已成功建立 SSH 连接至 {} ", machineInfo.getHostIp());
|
} catch (ServiceException e) {
|
||||||
// this.connectionStatus = ConnectionStatus.CONNECTING;
|
log.warn("SSH 连接失败: {}", e.getMessage());
|
||||||
// } catch (ServiceException e) {
|
throw e;
|
||||||
// log.warn("SSH 连接失败: {}", e.getMessage());
|
}
|
||||||
// throw e;
|
}
|
||||||
// }
|
|
||||||
// }
|
public void disconnect() {
|
||||||
//
|
if (sshSession != null && sshSession.isConnected()) {
|
||||||
// public void disconnect() {
|
try {
|
||||||
// if (sshSession != null && sshSession.isConnected()) {
|
sshSession.disconnect();
|
||||||
// try {
|
log.info("SSH连接关闭: {}", machineInfo.getHostIp());
|
||||||
// sshSession.disconnect();
|
} catch (Exception e) {
|
||||||
// log.info("SSH连接关闭: {}", machineInfo.getHostIp());
|
log.error("关闭SSH连接失败: {}", e.getMessage());
|
||||||
// } catch (Exception e) {
|
throw exception(CLOSE_CLOSE_SESSION_ERROR);
|
||||||
// log.error("关闭SSH连接失败: {}", e.getMessage());
|
}
|
||||||
// throw exception(CLOSE_CLOSE_SESSION_ERROR);
|
}
|
||||||
// }
|
connectionStatus = ConnectionStatus.DISCONNECTED;
|
||||||
// }
|
}
|
||||||
// connectionStatus = ConnectionStatus.DISCONNECTED;
|
|
||||||
// }
|
/**
|
||||||
//
|
* 执行远程命令,支持超时和中断处理
|
||||||
// /**
|
*/
|
||||||
// * 执行远程命令,支持超时和中断处理
|
public void executeCommand(WebSocketSession webSocketSession, String command) {
|
||||||
// */
|
// 1. 检查连接状态
|
||||||
// public void executeCommand(WebSocketSession webSocketSession, String command) {
|
if (sshSession == null || !sshSession.isConnected()) {
|
||||||
// // 1. 检查连接状态
|
sendErrorMessage(webSocketSession, "SSH连接未建立或已断开");
|
||||||
// if (sshSession == null || !sshSession.isConnected()) {
|
return;
|
||||||
// sendErrorMessage(webSocketSession, "SSH连接未建立或已断开");
|
}
|
||||||
// return;
|
try {
|
||||||
// }
|
// 2. 创建SSH命令执行通道
|
||||||
// try {
|
Channel channel;
|
||||||
// // 2. 创建SSH命令执行通道
|
try {
|
||||||
// Channel channel;
|
channel = sshSession.openChannel(SSHChanelType.EXEC.getMessage());
|
||||||
// try {
|
} catch (JSchException e) {
|
||||||
// channel = sshSession.openChannel(SSHChanelType.EXEC.getMessage());
|
throw exception(CREATE_CHANEL_ERROR);
|
||||||
// } catch (JSchException e) {
|
}
|
||||||
// throw exception(CREATE_CHANEL_ERROR);
|
((ChannelExec) channel).setCommand(command);
|
||||||
// }
|
// 3. 设置输入/输出流
|
||||||
// ((ChannelExec) channel).setCommand(command);
|
channel.setInputStream(null);
|
||||||
// // 3. 设置输入/输出流
|
((ChannelExec) channel).setErrStream(System.err);
|
||||||
// channel.setInputStream(null);
|
// 4. 获取命令输出流
|
||||||
// ((ChannelExec) channel).setErrStream(System.err);
|
InputStream inputStream = channel.getInputStream();
|
||||||
// // 4. 获取命令输出流
|
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
|
||||||
// InputStream inputStream = channel.getInputStream();
|
BufferedReader reader = new BufferedReader(inputStreamReader);
|
||||||
// InputStreamReader inputStreamReader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
|
// 5. 连接并执行命令
|
||||||
// BufferedReader reader = new BufferedReader(inputStreamReader);
|
channel.connect();
|
||||||
// // 5. 连接并执行命令
|
// 6. 读取命令输出并实时发送给客户端
|
||||||
// channel.connect();
|
String line;
|
||||||
// // 6. 读取命令输出并实时发送给客户端
|
while ((line = reader.readLine()) != null) {
|
||||||
// String line;
|
// 实时发送输出到客户端
|
||||||
// while ((line = reader.readLine()) != null) {
|
webSocketSession.sendMessage(new TextMessage(line));
|
||||||
// // 实时发送输出到客户端
|
}
|
||||||
// webSocketSession.sendMessage(new TextMessage(line));
|
// 7. 等待命令执行完成
|
||||||
// }
|
int exitStatus = channel.getExitStatus();
|
||||||
// // 7. 等待命令执行完成
|
// 8. 发送命令执行完毕的消息
|
||||||
// int exitStatus = channel.getExitStatus();
|
webSocketSession.sendMessage(new TextMessage(
|
||||||
// // 8. 发送命令执行完毕的消息
|
"[系统] 命令执行完毕,退出状态: " + exitStatus
|
||||||
// webSocketSession.sendMessage(new TextMessage(
|
));
|
||||||
// "[系统] 命令执行完毕,退出状态: " + exitStatus
|
// 9. 关闭通道
|
||||||
// ));
|
channel.disconnect();
|
||||||
// // 9. 关闭通道
|
} catch (JSchException | IOException e) {
|
||||||
// channel.disconnect();
|
throw exception(EXECUTE_COMMAND_FAIL);
|
||||||
// } catch (JSchException | IOException e) {
|
}
|
||||||
// throw exception(EXECUTE_COMMAND_FAIL);
|
}
|
||||||
// }
|
|
||||||
// }
|
// 发送错误消息的辅助方法
|
||||||
//
|
public void sendErrorMessage(WebSocketSession webSocketSession, String message) {
|
||||||
// // 发送错误消息的辅助方法
|
try {
|
||||||
// public void sendErrorMessage(WebSocketSession webSocketSession, String message) {
|
if (webSocketSession.isOpen()) {
|
||||||
// try {
|
webSocketSession.sendMessage(new TextMessage("[错误] " + message));
|
||||||
// if (webSocketSession.isOpen()) {
|
}
|
||||||
// webSocketSession.sendMessage(new TextMessage("[错误] " + message));
|
} catch (IOException e) {
|
||||||
// }
|
log.error("发送错误消息失败", e);
|
||||||
// } catch (IOException e) {
|
throw exception(WEBSOCKET_SEND_MESSAGE_ERROR);
|
||||||
// log.error("发送错误消息失败", e);
|
}
|
||||||
// throw exception(WEBSOCKET_SEND_MESSAGE_ERROR);
|
}
|
||||||
// }
|
|
||||||
// }
|
/**
|
||||||
//
|
* 实际执行连接逻辑
|
||||||
// /**
|
*/
|
||||||
// * 实际执行连接逻辑
|
private Session doConnect(MachineInfoDO machineInfo) {
|
||||||
// */
|
JSch jsch = new JSch();
|
||||||
// private Session doConnect(MachineInfoDO machineInfo) {
|
// 配置认证方式
|
||||||
// JSch jsch = new JSch();
|
configureAuthentication(jsch, machineInfo);
|
||||||
// // 配置认证方式
|
Session session;
|
||||||
// configureAuthentication(jsch, machineInfo);
|
// 创建SSH会话
|
||||||
// Session session;
|
try {
|
||||||
// // 创建SSH会话
|
session = jsch.getSession(
|
||||||
// try {
|
machineInfo.getUsername(),
|
||||||
// session = jsch.getSession(
|
machineInfo.getHostIp(),
|
||||||
// machineInfo.getUsername(),
|
machineInfo.getSshPort() != null ? machineInfo.getSshPort() : 22
|
||||||
// machineInfo.getHostIp(),
|
);
|
||||||
// machineInfo.getSshPort() != null ? machineInfo.getSshPort() : 22
|
} catch (JSchException e) {
|
||||||
// );
|
throw exception(CREATE_SESSION_ERROR);
|
||||||
// } catch (JSchException e) {
|
}
|
||||||
// throw exception(CREATE_SESSION_ERROR);
|
// 配置连接参数
|
||||||
// }
|
configureSession(session, machineInfo);
|
||||||
// // 配置连接参数
|
// 建立连接
|
||||||
// configureSession(session, machineInfo);
|
try {
|
||||||
// // 建立连接
|
session.connect(CONNECTION_TIMEOUT);
|
||||||
// try {
|
} catch (JSchException e) {
|
||||||
// session.connect(CONNECTION_TIMEOUT);
|
throw exception(SESSION_CONNECT_ERROR);
|
||||||
// } catch (JSchException e) {
|
}
|
||||||
// throw exception(SESSION_CONNECT_ERROR);
|
return session;
|
||||||
// }
|
}
|
||||||
// return session;
|
|
||||||
// }
|
/**
|
||||||
//
|
* 配置认证方式(密码或密钥)
|
||||||
//// /**
|
*/
|
||||||
//// * 配置认证方式(密码或密钥)
|
private void configureAuthentication(JSch jsch, MachineInfoDO machineInfo) {
|
||||||
//// */
|
if (machineInfo.getAuthenticationType() == AuthenticationType.SECRET_KEY.getCode()) {
|
||||||
//// private void configureAuthentication(JSch jsch, MachineInfoDO machineInfo) {
|
// 密钥认证
|
||||||
//// if (machineInfo.getAuthenticationType() == AuthenticationType.SECRET_KEY.getCode()) {
|
if (machineInfo.getSecretKeyId() == null) {
|
||||||
//// // 密钥认证
|
throw exception(SECRET_KEY_NULL);
|
||||||
//// if (machineInfo.getSecretKeyId() == null) {
|
}
|
||||||
//// throw exception(SECRET_KEY_NULL);
|
String pubKeyContent = secretKeyService.getPublicKeyContent(machineInfo.getSecretKeyId());
|
||||||
//// }
|
// 验证秘钥格式
|
||||||
//// String pubKeyContent = secretKeyService.getKeyContent(machineInfo.getSecretKeyId());
|
if (!pubKeyContent.startsWith("-----BEGIN")) {
|
||||||
//// // 验证秘钥格式
|
log.error("无效的密钥格式{}", pubKeyContent);
|
||||||
//// if (!pubKeyContent.startsWith("-----BEGIN")) {
|
throw exception(INVALID_kEY_FORMAT);
|
||||||
//// log.error("无效的密钥格式{}", pubKeyContent);
|
}
|
||||||
//// throw exception(INVALID_kEY_FORMAT);
|
try {
|
||||||
//// }
|
// 尝试加载秘钥私钥
|
||||||
//// try {
|
jsch.addIdentity(
|
||||||
//// // 尝试加载秘钥私钥
|
machineInfo.getName(),
|
||||||
//// jsch.addIdentity(
|
pubKeyContent.getBytes(StandardCharsets.UTF_8),
|
||||||
//// machineInfo.getName(),
|
null,
|
||||||
//// pubKeyContent.getBytes(StandardCharsets.UTF_8),
|
null
|
||||||
//// null,
|
);
|
||||||
//// null
|
log.info("密钥加载成功 {}", machineInfo.getHostIp());
|
||||||
//// );
|
} catch (JSchException e) {
|
||||||
//// log.info("密钥加载成功 {}", machineInfo.getHostIp());
|
log.error("密钥加载失败: {}", e.getMessage());
|
||||||
//// } catch (JSchException e) {
|
throw exception(READ_SECRET_CONTENT_ERROR);
|
||||||
//// log.error("密钥加载失败: {}", e.getMessage());
|
}
|
||||||
//// throw exception(READ_SECRET_CONTENT_ERROR);
|
} else if (machineInfo.getAuthenticationType() == AuthenticationType.PASSWORD.getCode()) {
|
||||||
//// }
|
// 密码认证
|
||||||
//// } else if (machineInfo.getAuthenticationType() == AuthenticationType.PASSWORD.getCode()) {
|
if (!StringUtils.hasText(machineInfo.getPassword())) {
|
||||||
//// // 密码认证
|
throw exception(PASSWORD_NOT_EXISTS);
|
||||||
//// if (!StringUtils.hasText(machineInfo.getPassword())) {
|
}
|
||||||
//// throw exception(PASSWORD_NOT_EXISTS);
|
} else {
|
||||||
//// }
|
log.error("不支持该验证类型:{}", machineInfo.getAuthenticationType());
|
||||||
//// } else {
|
throw exception(NOT_SUPPORT_AUTHENTICATION_TYPE);
|
||||||
//// log.error("不支持该验证类型:{}", machineInfo.getAuthenticationType());
|
}
|
||||||
//// throw exception(NOT_SUPPORT_AUTHENTICATION_TYPE);
|
}
|
||||||
//// }
|
|
||||||
//// }
|
/**
|
||||||
//
|
* 配置SSH会话参数(安全增强)
|
||||||
// /**
|
*/
|
||||||
// * 配置SSH会话参数(安全增强)
|
private void configureSession(Session session, MachineInfoDO machineInfo) {
|
||||||
// */
|
Properties config = new Properties();
|
||||||
// private void configureSession(Session session, MachineInfoDO machineInfo) {
|
// 根据认证类型配置不同的认证策略
|
||||||
// Properties config = new Properties();
|
if (machineInfo.getAuthenticationType() == 1) { // 密码认证
|
||||||
// // 根据认证类型配置不同的认证策略
|
// 设置密码
|
||||||
// if (machineInfo.getAuthenticationType() == 1) { // 密码认证
|
session.setPassword(machineInfo.getPassword());
|
||||||
// // 设置密码
|
config.put("StrictHostKeyChecking", "no");
|
||||||
// session.setPassword(machineInfo.getPassword());
|
// 仅使用密码认证(禁用其他认证方式)
|
||||||
// config.put("StrictHostKeyChecking", "no");
|
config.put("PreferredAuthentications", "password");
|
||||||
// // 仅使用密码认证(禁用其他认证方式)
|
// 禁用公钥相关配置(避免干扰)
|
||||||
// config.put("PreferredAuthentications", "password");
|
config.put("PubkeyAuthentication", "no");
|
||||||
// // 禁用公钥相关配置(避免干扰)
|
} else { // 密钥认证
|
||||||
// config.put("PubkeyAuthentication", "no");
|
// 保持默认认证顺序(公钥优先)
|
||||||
// } else { // 密钥认证
|
config.put("PreferredAuthentications", "publicKey,password,keyboard-interactive");
|
||||||
// try {
|
}
|
||||||
// String preKeyPath = secretKeyService.getSecretKey(machineInfo.getSecretKeyId()).getPath();
|
config.put("ServerAliveInterval", "30"); // 每30秒发送一次心跳
|
||||||
// JSch jsch = new JSch();
|
config.put("ServerAliveCountMax", "3"); // 允许3次心跳失败
|
||||||
// jsch.addIdentity(preKeyPath); // 添加私钥
|
session.setConfig(config);
|
||||||
// // 保持默认认证顺序(公钥优先)
|
}
|
||||||
// config.put("PreferredAuthentications", "publicKey,password,keyboard-interactive");
|
|
||||||
// } catch (JSchException e) {
|
}
|
||||||
// log.error("SSH密钥配置失败", e);
|
|
||||||
// throw exception(SSH_KEY_CONFIGURATION_FAIL);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// config.put("ServerAliveInterval", "30"); // 每30秒发送一次心跳
|
|
||||||
// config.put("ServerAliveCountMax", "3"); // 允许3次心跳失败
|
|
||||||
// session.setConfig(config);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//}
|
|
||||||
|
@ -1,114 +1,70 @@
|
|||||||
//package cd.casic.module.machine.component;
|
package cd.casic.module.machine.component;
|
||||||
//
|
|
||||||
//import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
//import org.springframework.web.socket.WebSocketSession;
|
|
||||||
//
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
//import java.util.Collection;
|
|
||||||
//import java.util.concurrent.ConcurrentHashMap;
|
@Component("machineWebSocketSessionManger")
|
||||||
//
|
//管理webSocketSession
|
||||||
//@Component("machineWebSocketSessionManger")
|
public class WebSocketSessionManager {
|
||||||
////管理webSocketSession
|
|
||||||
//public class WebSocketSessionManager {
|
//webSocketSessionId - WebSocketConnection 与远程机器的会话管理
|
||||||
//
|
private static final ConcurrentHashMap<String, WebSocketConnection> sessionConnectionMap = new ConcurrentHashMap<>();
|
||||||
// //webSocketSessionId - WebSocketSession 保存 WebSocketSession 对象与会话 ID 的映射
|
|
||||||
// private static final ConcurrentHashMap<String, WebSocketSession> WebSocketSessionMap = new ConcurrentHashMap<>();
|
//机器id - WebSocketConnection
|
||||||
//
|
private static final ConcurrentHashMap<Long, WebSocketConnection> webSocketSessionConnectionMap = new ConcurrentHashMap<>();
|
||||||
// //webSocketSessionId - WebSocketConnection 与远程机器的会话管理
|
|
||||||
// private static final ConcurrentHashMap<String, WebSocketConnection> sessionConnectionMap = new ConcurrentHashMap<>();
|
public static void addWebSocketConnection(String sessionId, WebSocketConnection connection) {
|
||||||
//
|
sessionConnectionMap.put(sessionId, connection);
|
||||||
// //机器id - WebSocketConnection
|
}
|
||||||
// private static final ConcurrentHashMap<Long, WebSocketConnection> webSocketSessionConnectionMap = new ConcurrentHashMap<>();
|
|
||||||
//
|
/**
|
||||||
// public static void addWebSocketSession(String sessionId, WebSocketSession session) {
|
* 获取 WebSocketConnection
|
||||||
// WebSocketSessionMap.put(sessionId, session);
|
*/
|
||||||
// }
|
public static WebSocketConnection getWebSocketConnection(String sessionId) {
|
||||||
//
|
return sessionConnectionMap.get(sessionId);
|
||||||
// /**
|
}
|
||||||
// * 获取 WebSocketSession
|
|
||||||
// */
|
/**
|
||||||
// public static WebSocketSession getWebSocketSession(String sessionId) {
|
* 移除 WebSocketConnection
|
||||||
// return WebSocketSessionMap.get(sessionId);
|
*/
|
||||||
// }
|
public static void removeWebSocketConnection(String sessionId) {
|
||||||
//
|
sessionConnectionMap.remove(sessionId);
|
||||||
// /**
|
}
|
||||||
// * 移除 WebSocketSession
|
|
||||||
// */
|
/**
|
||||||
// public static void removeWebSocketSession(String sessionId) {
|
* 获取所有 WebSocketConnection
|
||||||
// WebSocketSessionMap.remove(sessionId);
|
*/
|
||||||
// }
|
public static ConcurrentHashMap<Long, WebSocketConnection> getAllWebSocketConnections() {
|
||||||
//
|
return webSocketSessionConnectionMap;
|
||||||
// /**
|
}
|
||||||
// * 检查 sessionId 是否存在
|
|
||||||
// */
|
/**
|
||||||
// public static boolean containsWebSocketSession(String sessionId) {
|
* 添加 WebSocketConnection
|
||||||
// return WebSocketSessionMap.containsKey(sessionId);
|
*/
|
||||||
// }
|
public static void addWebSocketConnectionByMachineId(Long machineId, WebSocketConnection connection) {
|
||||||
//
|
webSocketSessionConnectionMap.put(machineId, connection);
|
||||||
// /**
|
}
|
||||||
// * 获取所有 WebSocketSession
|
|
||||||
// */
|
/**
|
||||||
// public static Collection<WebSocketSession> getAllWebSocketSessions() {
|
* 获取 WebSocketConnection
|
||||||
// return WebSocketSessionMap.values();
|
*/
|
||||||
// }
|
public static WebSocketConnection getWebSocketConnectionByMachineId(Long machineId) {
|
||||||
//
|
return webSocketSessionConnectionMap.get(machineId);
|
||||||
// public static void addWebSocketConnection(String sessionId, WebSocketConnection connection) {
|
}
|
||||||
// sessionConnectionMap.put(sessionId, connection);
|
|
||||||
// }
|
/**
|
||||||
//
|
* 移除 WebSocketConnection
|
||||||
// /**
|
*/
|
||||||
// * 获取 WebSocketConnection
|
public static void removeWebSocketConnectionByMachineId(Long machineId) {
|
||||||
// */
|
webSocketSessionConnectionMap.remove(machineId);
|
||||||
// public static WebSocketConnection getWebSocketConnection(String sessionId) {
|
}
|
||||||
// return sessionConnectionMap.get(sessionId);
|
|
||||||
// }
|
/**
|
||||||
//
|
* 检查 machineId 是否存在
|
||||||
// /**
|
*/
|
||||||
// * 移除 WebSocketConnection
|
public static boolean containsMachineId(Long machineId) {
|
||||||
// */
|
return webSocketSessionConnectionMap.containsKey(machineId);
|
||||||
// public static void removeWebSocketConnection(String sessionId) {
|
}
|
||||||
// sessionConnectionMap.remove(sessionId);
|
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * 检查 sessionId 是否存在
|
|
||||||
// */
|
|
||||||
// public static boolean containsWebSocketConnection(String sessionId) {
|
|
||||||
// return sessionConnectionMap.containsKey(sessionId);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * 获取所有 WebSocketConnection
|
|
||||||
// */
|
|
||||||
// public static ConcurrentHashMap<Long, WebSocketConnection> getAllWebSocketConnections() {
|
|
||||||
// return webSocketSessionConnectionMap;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * 添加 WebSocketConnection
|
|
||||||
// */
|
|
||||||
// public static void addWebSocketConnectionByMachineId(Long machineId, WebSocketConnection connection) {
|
|
||||||
// webSocketSessionConnectionMap.put(machineId, connection);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * 获取 WebSocketConnection
|
|
||||||
// */
|
|
||||||
// public static WebSocketConnection getWebSocketConnectionByMachineId(Long machineId) {
|
|
||||||
// return webSocketSessionConnectionMap.get(machineId);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * 移除 WebSocketConnection
|
|
||||||
// */
|
|
||||||
// public static void removeWebSocketConnectionByMachineId(Long machineId) {
|
|
||||||
// webSocketSessionConnectionMap.remove(machineId);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * 检查 machineId 是否存在
|
|
||||||
// */
|
|
||||||
// public static boolean containsMachineId(Long machineId) {
|
|
||||||
// return webSocketSessionConnectionMap.containsKey(machineId);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//}
|
|
||||||
|
@ -1,40 +1,40 @@
|
|||||||
//package cd.casic.module.machine.configuration;
|
package cd.casic.module.machine.configuration;
|
||||||
//
|
|
||||||
//import cd.casic.module.machine.Interceptor.WebSocketHandshakeInterceptor;
|
import cd.casic.module.machine.Interceptor.WebSocketHandshakeInterceptor;
|
||||||
//import cd.casic.module.machine.handler.MachineWebSocketHandler;
|
import cd.casic.module.machine.handler.MachineWebSocketHandler;
|
||||||
//import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
//import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
//import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
//import org.springframework.web.socket.config.annotation.EnableWebSocket;
|
import org.springframework.web.socket.config.annotation.EnableWebSocket;
|
||||||
//import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
|
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
|
||||||
//import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
|
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
|
||||||
//import org.springframework.web.socket.server.standard.ServerEndpointExporter;
|
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
|
||||||
//import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean;
|
import org.springframework.web.socket.server.standard.ServletServerContainerFactoryBean;
|
||||||
//
|
|
||||||
//@Configuration
|
@Configuration
|
||||||
//@EnableWebSocket
|
@EnableWebSocket
|
||||||
////WebSocket端点配置
|
//WebSocket端点配置
|
||||||
//public class WebSocketConfig implements WebSocketConfigurer {
|
public class WebSocketConfig implements WebSocketConfigurer {
|
||||||
// @Resource
|
@Resource
|
||||||
// private MachineWebSocketHandler machineWebSocketHandler;
|
private MachineWebSocketHandler machineWebSocketHandler;
|
||||||
//
|
|
||||||
// @Resource
|
@Resource
|
||||||
// private WebSocketHandshakeInterceptor webSocketHandshakeInterceptor;
|
private WebSocketHandshakeInterceptor webSocketHandshakeInterceptor;
|
||||||
//
|
|
||||||
// @Override
|
@Override
|
||||||
// public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
|
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
|
||||||
// registry.addHandler(machineWebSocketHandler, "/ssh/terminal")
|
registry.addHandler(machineWebSocketHandler, "/ssh/terminal")
|
||||||
// .addInterceptors(webSocketHandshakeInterceptor)
|
.addInterceptors(webSocketHandshakeInterceptor)
|
||||||
// .setAllowedOrigins("*"); // 允许跨域(生产环境需限制)
|
.setAllowedOrigins("*"); // 允许跨域(生产环境需限制)
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// @Bean
|
@Bean
|
||||||
// public ServletServerContainerFactoryBean createWebSocketContainer() {
|
public ServletServerContainerFactoryBean createWebSocketContainer() {
|
||||||
// return new ServletServerContainerFactoryBean();
|
return new ServletServerContainerFactoryBean();
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// @Bean
|
@Bean
|
||||||
// public ServerEndpointExporter serverEndpointExporter() {
|
public ServerEndpointExporter serverEndpointExporter() {
|
||||||
// return new ServerEndpointExporter();
|
return new ServerEndpointExporter();
|
||||||
// }
|
}
|
||||||
//}
|
}
|
||||||
|
@ -19,13 +19,6 @@ public interface MachineErrorCodeConstants {
|
|||||||
ErrorCode MACHINE_ENABLE = new ErrorCode(1_003_000_009, "机器启用中");
|
ErrorCode MACHINE_ENABLE = new ErrorCode(1_003_000_009, "机器启用中");
|
||||||
ErrorCode MACHINE_UN_ENABLE = new ErrorCode(1_003_000_010, "机器不可用");
|
ErrorCode MACHINE_UN_ENABLE = new ErrorCode(1_003_000_010, "机器不可用");
|
||||||
|
|
||||||
// ========== 文件操作模块 1-003-001-000 ==========
|
|
||||||
ErrorCode UPLOADING_FILE_FAIL = new ErrorCode(1_003_001_000, "上传文件失败");
|
|
||||||
ErrorCode DOWNLOAD_FILE_FAIL = new ErrorCode(1_003_001_001, "下载失败");
|
|
||||||
ErrorCode FILENAME_NULL = new ErrorCode(1_003_001_002, "文件名为空");
|
|
||||||
ErrorCode READ_FILE_FAIL = new ErrorCode(1_003_001_003, "读取文件失败");
|
|
||||||
ErrorCode DELETE_FILE_FAIL = new ErrorCode(1_003_001_004, "删除文件失败");
|
|
||||||
|
|
||||||
// ========== 机器环境变量模块 1-003-002-000 ==========
|
// ========== 机器环境变量模块 1-003-002-000 ==========
|
||||||
ErrorCode MACHINE_ENV_NULL = new ErrorCode(1_003_002_000, "机器环境变量为空");
|
ErrorCode MACHINE_ENV_NULL = new ErrorCode(1_003_002_000, "机器环境变量为空");
|
||||||
ErrorCode MACHINE_ENV_NOT_EXISTS = new ErrorCode(1_003_002_001, "机器不存在");
|
ErrorCode MACHINE_ENV_NOT_EXISTS = new ErrorCode(1_003_002_001, "机器不存在");
|
||||||
@ -41,28 +34,20 @@ public interface MachineErrorCodeConstants {
|
|||||||
// ========== 密钥模块 1-003-004-000 ==========
|
// ========== 密钥模块 1-003-004-000 ==========
|
||||||
ErrorCode SECRET_KEY_NULL = new ErrorCode(1_003_004_000, "密钥为空");
|
ErrorCode SECRET_KEY_NULL = new ErrorCode(1_003_004_000, "密钥为空");
|
||||||
ErrorCode SECRET_KEY_NOT_EXISTS = new ErrorCode(1_003_004_001, "密钥不存在");
|
ErrorCode SECRET_KEY_NOT_EXISTS = new ErrorCode(1_003_004_001, "密钥不存在");
|
||||||
ErrorCode SECRET_KEY_PATH_NULL = new ErrorCode(1_003_004_002, "密钥路径为空");
|
ErrorCode INVALID_kEY_FORMAT = new ErrorCode(1_003_004_002, "无效的密钥格式");
|
||||||
ErrorCode INVALID_kEY_FORMAT = new ErrorCode(1_003_004_003, "无效的密钥格式");
|
ErrorCode READ_SECRET_CONTENT_ERROR = new ErrorCode(1_003_004_003, "读取密钥加载失败");
|
||||||
ErrorCode READ_SECRET_CONTENT_ERROR = new ErrorCode(1_003_004_004, "读取密钥加载失败");
|
|
||||||
|
|
||||||
// ========== 其他模块 1-003-005-000 ==========
|
|
||||||
ErrorCode OSS_PARAM_NULL = new ErrorCode(1_003_005_000, "oss参数无法读取");
|
|
||||||
ErrorCode FILE_UPLOAD_ERROR = new ErrorCode(1_003_005_001, "文件上传失败");
|
|
||||||
ErrorCode FILE_DOWNLOAD_ERROR = new ErrorCode(1_003_005_002, "文件下载失败");
|
|
||||||
|
|
||||||
//========== 会话连接模块 1-003-006-000 ==========
|
//========== 会话连接模块 1-003-006-000 ==========
|
||||||
ErrorCode SESSION_CONNECT_ERROR = new ErrorCode(1_003_006_001, "会话连接失败");
|
ErrorCode SESSION_CONNECT_ERROR = new ErrorCode(1_003_006_001, "会话连接失败");
|
||||||
ErrorCode CLOSE_CLOSE_SESSION_ERROR = new ErrorCode(1_003_006_002, "关闭连接失败");
|
ErrorCode CLOSE_CLOSE_SESSION_ERROR = new ErrorCode(1_003_006_002, "关闭连接失败");
|
||||||
ErrorCode SESSION_NOT_CONNECT = new ErrorCode(1_003_006_003, "会话未连接");
|
ErrorCode EXECUTE_COMMAND_FAIL = new ErrorCode(1_003_006_003, "命令执行失败");
|
||||||
ErrorCode EXECUTE_COMMAND_FAIL = new ErrorCode(1_003_006_004, "命令执行失败");
|
ErrorCode PASSWORD_NOT_EXISTS = new ErrorCode(1_003_006_004, "密码不存在");
|
||||||
ErrorCode PASSWORD_NOT_EXISTS = new ErrorCode(1_003_006_005, "密码不存在");
|
ErrorCode NOT_SUPPORT_AUTHENTICATION_TYPE = new ErrorCode(1_003_006_005, "认证类型不支持");
|
||||||
ErrorCode SSH_KEY_CONFIGURATION_FAIL = new ErrorCode(1_003_006_006, "SSH密钥配置失败");
|
ErrorCode CREATE_SESSION_ERROR = new ErrorCode(1_003_006_006, "创建会话失败");
|
||||||
ErrorCode NOT_SUPPORT_AUTHENTICATION_TYPE = new ErrorCode(1_003_006_007, "认证类型不支持");
|
ErrorCode WEBSOCKET_SEND_MESSAGE_ERROR = new ErrorCode(1_003_006_007, "websocket发送消息失败");
|
||||||
ErrorCode CREATE_SESSION_ERROR = new ErrorCode(1_003_006_008, "创建会话失败");
|
ErrorCode CREATE_CHANEL_ERROR = new ErrorCode(1_003_006_008, "执行通道创建失败");
|
||||||
ErrorCode WEBSOCKET_SEND_MESSAGE_ERROR = new ErrorCode(1_003_006_009, "websocket发送消息失败");
|
ErrorCode CHANEL_CONNECT_FAIL = new ErrorCode(1_003_006_009, "通道连接失败");
|
||||||
ErrorCode CREATE_CHANEL_ERROR = new ErrorCode(1_003_006_010, "执行通道创建失败");
|
ErrorCode FAILED_TO_PARSE_URL_PARAMETERS = new ErrorCode(1_003_006_010, "解析URL参数失败");
|
||||||
ErrorCode CHANEL_CONNECT_FAIL = new ErrorCode(1_003_006_011, "通道连接失败");
|
|
||||||
ErrorCode FAILED_TO_PARSE_URL_PARAMETERS = new ErrorCode(1_003_006_012, "解析URL参数失败");
|
|
||||||
|
|
||||||
//========== 远程文件树模块 1-003-007-000 ==========
|
//========== 远程文件树模块 1-003-007-000 ==========
|
||||||
ErrorCode NOT_DIRECTORY_NODE = new ErrorCode(1_003_007_001, "非目录节点不能添加子节点");
|
ErrorCode NOT_DIRECTORY_NODE = new ErrorCode(1_003_007_001, "非目录节点不能添加子节点");
|
||||||
@ -70,4 +55,10 @@ public interface MachineErrorCodeConstants {
|
|||||||
ErrorCode CONNECTION_LOST = new ErrorCode(1_003_007_003, "SFTP连接无效,无法列出文件");
|
ErrorCode CONNECTION_LOST = new ErrorCode(1_003_007_003, "SFTP连接无效,无法列出文件");
|
||||||
ErrorCode PATH_NOT_EXISTS = new ErrorCode(1_003_007_004, "路径不存在");
|
ErrorCode PATH_NOT_EXISTS = new ErrorCode(1_003_007_004, "路径不存在");
|
||||||
ErrorCode NO_PATH_PERMISSION = new ErrorCode(1_003_007_005, "无路径访问权限");
|
ErrorCode NO_PATH_PERMISSION = new ErrorCode(1_003_007_005, "无路径访问权限");
|
||||||
|
ErrorCode INVALID_FILE_NAME = new ErrorCode(1_003_007_006, "无效的文件名");
|
||||||
|
ErrorCode CREATE_TEMP_FILE_ERROR = new ErrorCode(1_003_007_007, "创建临时文件失败");
|
||||||
|
ErrorCode UPLOAD_REMOTE_FILE_ERROR = new ErrorCode(1_003_007_008, "上传文件到远程机器出错");
|
||||||
|
ErrorCode DOWNLOAD_FOLDER_NOT_ALLOWED = new ErrorCode(1_003_007_009, "无法下载文件夹");
|
||||||
|
ErrorCode REMOTE_FILE_TRANSFER_FAIL = new ErrorCode(1_003_007_010, "远程文件传输失败");
|
||||||
|
ErrorCode DELETE_REMOTE_FILE_ERROR = new ErrorCode(1_003_007_011, "删除文件时出错");
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package cd.casic.module.machine.controller;
|
|||||||
import cd.casic.framework.commons.pojo.CommonResult;
|
import cd.casic.framework.commons.pojo.CommonResult;
|
||||||
import cd.casic.framework.commons.pojo.PageResult;
|
import cd.casic.framework.commons.pojo.PageResult;
|
||||||
import cd.casic.framework.commons.util.object.BeanUtils;
|
import cd.casic.framework.commons.util.object.BeanUtils;
|
||||||
|
import cd.casic.module.machine.controller.vo.SecretKeyVO;
|
||||||
import cd.casic.module.machine.dal.dataobject.MachineInfoDO;
|
import cd.casic.module.machine.dal.dataobject.MachineInfoDO;
|
||||||
import cd.casic.module.machine.enums.ConnectionStatus;
|
import cd.casic.module.machine.enums.ConnectionStatus;
|
||||||
import cd.casic.module.machine.service.MachineInfoService;
|
import cd.casic.module.machine.service.MachineInfoService;
|
||||||
@ -11,9 +12,11 @@ import cn.hutool.core.collection.CollUtil;
|
|||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -35,7 +38,6 @@ public class MachineInfoController {
|
|||||||
return success(id);
|
return success(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@PutMapping("/update")
|
@PutMapping("/update")
|
||||||
@Operation(summary = "编辑机器信息")
|
@Operation(summary = "编辑机器信息")
|
||||||
// @PreAuthorize("@ss.hasPermission('ci:machineInfo:update')")
|
// @PreAuthorize("@ss.hasPermission('ci:machineInfo:update')")
|
||||||
@ -78,54 +80,60 @@ public class MachineInfoController {
|
|||||||
return success(true);
|
return success(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @GetMapping("/test")
|
@PutMapping("/bindingSecretKey")
|
||||||
// @Operation(summary = "测试机器连接")
|
@Operation(summary = "绑定/解绑密钥")
|
||||||
// public CommonResult<Boolean> testConnection(@RequestParam("id") Long id) {
|
public void bindingSecretKey(@RequestBody SecretKeyVO secretKeyVO) {
|
||||||
// return success(machineInfoService.testConnection(id));
|
machineInfoService.bindingSecretKey(secretKeyVO);
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// @GetMapping("/status")
|
|
||||||
// @Operation(summary = "获取机器连接状态")
|
|
||||||
// public CommonResult<ConnectionStatus> getConnectionStatus(@RequestParam Long id) {
|
|
||||||
// return success(machineInfoService.getConnectionStatus(id));
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @GetMapping("/status/all")
|
|
||||||
// @Operation(summary = "获取所有机器连接状态")
|
|
||||||
// public CommonResult<Map<Long, ConnectionStatus>> getAllConnectionStatus() {
|
|
||||||
// return success(machineInfoService.getAllConnectionStatus());
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @GetMapping("/connect")
|
|
||||||
// @Operation(summary = "建立连接")
|
|
||||||
// public CommonResult<Map<String, Object>> connect(@RequestParam Long id) {
|
|
||||||
// return success(machineInfoService.connect(id));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @GetMapping("/fileTreeNode")
|
@GetMapping("/test")
|
||||||
// @Operation(summary = "获得文件树")
|
@Operation(summary = "测试机器连接")
|
||||||
// public CommonResult<Map<String, Object>> fileTreeNode(
|
public CommonResult<Boolean> testConnection(@RequestParam("id") Long id) {
|
||||||
// @RequestParam Long machineId,
|
return success(machineInfoService.testConnection(id));
|
||||||
// @RequestParam(required = false, defaultValue = "/") String path
|
}
|
||||||
// ) {
|
|
||||||
// return CommonResult.success(machineInfoService.fileTreeNode(machineId, path));
|
@GetMapping("/status")
|
||||||
// }
|
@Operation(summary = "获取机器连接状态")
|
||||||
// @GetMapping("/upload")
|
public CommonResult<ConnectionStatus> getConnectionStatus(@RequestParam Long id) {
|
||||||
// @Operation(summary = "上传文件到远程机器")
|
return success(machineInfoService.getConnectionStatus(id));
|
||||||
// public CommonResult<Boolean> uploadFile(
|
}
|
||||||
// @RequestParam String sessionId,
|
|
||||||
// @RequestParam String localFilePath,
|
@GetMapping("/status/all")
|
||||||
// @RequestParam String remoteFilePath
|
@Operation(summary = "获取所有机器连接状态")
|
||||||
// ) {
|
public CommonResult<Map<Long, ConnectionStatus>> getAllConnectionStatus() {
|
||||||
// return success(machineInfoService.uploadFile(sessionId, localFilePath, remoteFilePath));
|
return success(machineInfoService.getAllConnectionStatus());
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// @GetMapping("/download")
|
@GetMapping("/connect")
|
||||||
// @Operation(summary = "从远程机器下载文件")
|
@Operation(summary = "建立连接")
|
||||||
// public CommonResult<Boolean> downloadFile(
|
public CommonResult<Map<String, Object>> connect(@RequestParam Long id) {
|
||||||
// @RequestParam String sessionId,
|
return success(machineInfoService.connect(id));
|
||||||
// @RequestParam String remoteFilePath,
|
}
|
||||||
// @RequestParam String localFilePath) {
|
|
||||||
// return success(machineInfoService.downloadFile(sessionId, remoteFilePath, localFilePath));
|
@GetMapping("/fileTreeNode")
|
||||||
// }
|
@Operation(summary = "获得文件树")
|
||||||
|
public CommonResult<Map<String, Object>> fileTreeNode(
|
||||||
|
@RequestParam Long machineId,
|
||||||
|
@RequestParam(required = false, defaultValue = "/") String path
|
||||||
|
) {
|
||||||
|
return success(machineInfoService.fileTreeNode(machineId, path));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/upload")
|
||||||
|
@Operation(summary = "上传文件到远程机器")
|
||||||
|
public CommonResult<Boolean> uploadFile(@RequestParam MultipartFile file, @RequestParam String remoteFilePath) {
|
||||||
|
return success(machineInfoService.uploadFile(file, remoteFilePath));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/download")
|
||||||
|
@Operation(summary = "从远程机器下载文件")
|
||||||
|
public CommonResult<Boolean> downloadFile(@RequestParam String remoteFilePath, HttpServletResponse httpServletResponse) {
|
||||||
|
return success(machineInfoService.downloadFile(remoteFilePath, httpServletResponse));
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/deleteRemoteFile")
|
||||||
|
@Operation(summary = "删除远程机器选定文件")
|
||||||
|
public CommonResult<Boolean> deleteRemoteFile(@RequestParam String remoteFilePath) {
|
||||||
|
return success(machineInfoService.deleteRemoteFile(remoteFilePath));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,9 +12,6 @@ import io.swagger.v3.oas.annotations.Operation;
|
|||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import org.springframework.core.io.InputStreamResource;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
@ -33,7 +30,7 @@ public class SecretKeyController {
|
|||||||
@PostMapping(value = "/create")
|
@PostMapping(value = "/create")
|
||||||
@Operation(summary = "新增密钥")
|
@Operation(summary = "新增密钥")
|
||||||
// @PreAuthorize("@ss.hasPermission('ci:secretKey:create')")
|
// @PreAuthorize("@ss.hasPermission('ci:secretKey:create')")
|
||||||
public CommonResult<Long> createSecretKey(@Valid @RequestBody SecretKeyVO secretKeyVO) throws Exception {
|
public CommonResult<Long> createSecretKey(@Valid @RequestBody SecretKeyVO secretKeyVO) {
|
||||||
Long secretKeyId = secretKeyService.createSecretKey(secretKeyVO);
|
Long secretKeyId = secretKeyService.createSecretKey(secretKeyVO);
|
||||||
return success(secretKeyId);
|
return success(secretKeyId);
|
||||||
}
|
}
|
||||||
@ -46,21 +43,6 @@ public class SecretKeyController {
|
|||||||
return success(true);
|
return success(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/bindingMachine")
|
|
||||||
@Operation(summary = "绑定机器")
|
|
||||||
// @PreAuthorize("@ss.hasPermission('ci:secretKey:binding')")
|
|
||||||
public CommonResult<Boolean> bindingMachine(@Valid @RequestBody SecretKeyVO secretKeyVO) {
|
|
||||||
secretKeyService.bindingMachine(secretKeyVO);
|
|
||||||
return success(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@PutMapping("/unbindMachine")
|
|
||||||
@Operation(summary = "解绑机器")
|
|
||||||
public CommonResult<Boolean> unbindMachine(@Valid @RequestBody SecretKeyVO secretKeyVO) {
|
|
||||||
secretKeyService.unbindMachine(secretKeyVO);
|
|
||||||
return success(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@GetMapping("/getBindMachine")
|
@GetMapping("/getBindMachine")
|
||||||
@Operation(summary = "获取密钥绑定的机器列表")
|
@Operation(summary = "获取密钥绑定的机器列表")
|
||||||
public CommonResult<List<MachineInfoDO>> getBindMachine(@RequestParam Long secretKeyId) {
|
public CommonResult<List<MachineInfoDO>> getBindMachine(@RequestParam Long secretKeyId) {
|
||||||
@ -74,13 +56,6 @@ public class SecretKeyController {
|
|||||||
return success(secretKeyVO);
|
return success(secretKeyVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@DeleteMapping("/delete")
|
|
||||||
@Operation(summary = "密钥信息删除")
|
|
||||||
public CommonResult<Boolean> delete(@RequestParam("id") Long id) {
|
|
||||||
secretKeyService.deleteSecretKey(id);
|
|
||||||
return success(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@DeleteMapping("/deleteList")
|
@DeleteMapping("/deleteList")
|
||||||
@Operation(summary = "批量删除密钥")
|
@Operation(summary = "批量删除密钥")
|
||||||
// @PreAuthorize("@ss.hasPermission('ci:secretKey:delete')")
|
// @PreAuthorize("@ss.hasPermission('ci:secretKey:delete')")
|
||||||
@ -92,16 +67,10 @@ public class SecretKeyController {
|
|||||||
@PostMapping("/list")
|
@PostMapping("/list")
|
||||||
@Operation(summary = "获取密钥信息列表")
|
@Operation(summary = "获取密钥信息列表")
|
||||||
public CommonResult<PageResult<SecretKeyVO>> getSecretKeyPage(@Valid @RequestBody SecretKeyVO secretKeyVO) {
|
public CommonResult<PageResult<SecretKeyVO>> getSecretKeyPage(@Valid @RequestBody SecretKeyVO secretKeyVO) {
|
||||||
PageResult<SecretKeyDO> pageResult = secretKeyService.getSecretKeypage(secretKeyVO);
|
PageResult<SecretKeyDO> pageResult = secretKeyService.getSecretKeyPage(secretKeyVO);
|
||||||
if (CollUtil.isEmpty(pageResult.getList())) {
|
if (CollUtil.isEmpty(pageResult.getList())) {
|
||||||
return success(new PageResult<>(pageResult.getTotal()));
|
return success(new PageResult<>(pageResult.getTotal()));
|
||||||
}
|
}
|
||||||
return success(BeanUtils.toBean(pageResult, SecretKeyVO.class));
|
return success(BeanUtils.toBean(pageResult, SecretKeyVO.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
// @GetMapping("/download")
|
|
||||||
// @Operation(summary = "下载密钥文件")
|
|
||||||
// public ResponseEntity<InputStreamResource> downloadSecretFile(@RequestParam("id") Long id) {
|
|
||||||
// return secretKeyService.downloadSecretFile(id);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
@ -45,4 +45,6 @@ public class SecretKeyVO extends PageParam {
|
|||||||
@Schema(description = "公钥", requiredMode = Schema.RequiredMode.REQUIRED, example = "******")
|
@Schema(description = "公钥", requiredMode = Schema.RequiredMode.REQUIRED, example = "******")
|
||||||
private String public_key;
|
private String public_key;
|
||||||
|
|
||||||
|
@Schema(description = "绑定/解绑密钥",example = "true")
|
||||||
|
private Boolean enableBind;
|
||||||
}
|
}
|
||||||
|
@ -28,10 +28,14 @@ public interface MachineInfoMapper extends BaseMapperX<MachineInfoDO> {
|
|||||||
this.update(null, set);
|
this.update(null, set);
|
||||||
}
|
}
|
||||||
|
|
||||||
default void bindingSecretKey(List<Long> machineInfoIds, Long secretKeyId) {
|
default void bindingSecretKey(List<Long> machineInfoIds, Long secretKeyId,Boolean enableBind) {
|
||||||
UpdateWrapper<MachineInfoDO> wrapper = new UpdateWrapper<>();
|
UpdateWrapper<MachineInfoDO> wrapper = new UpdateWrapper<>();
|
||||||
wrapper.in("id", machineInfoIds) // 匹配 ID 集合
|
wrapper.in("id", machineInfoIds);
|
||||||
.set("secret_key_id", secretKeyId); // 设置新的 status 值
|
if (enableBind){
|
||||||
|
wrapper.set("secret_key_id", secretKeyId);// 匹配 ID 集合
|
||||||
|
}else {
|
||||||
|
wrapper.set("secret_key_id", null);
|
||||||
|
}
|
||||||
this.update(null, wrapper);
|
this.update(null, wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,67 +1,64 @@
|
|||||||
//package cd.casic.module.machine.handler;
|
package cd.casic.module.machine.handler;
|
||||||
//
|
|
||||||
////import cd.casic.module.machine.component.WebSocketConnection;
|
import cd.casic.module.machine.component.WebSocketConnection;
|
||||||
////import cd.casic.module.machine.component.WebSocketSessionManager;
|
import cd.casic.module.machine.component.WebSocketSessionManager;
|
||||||
//import cd.casic.module.machine.enums.ConnectionStatus;
|
import cd.casic.module.machine.enums.ConnectionStatus;
|
||||||
//import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
//import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
//import org.springframework.web.socket.CloseStatus;
|
import org.springframework.web.socket.CloseStatus;
|
||||||
//import org.springframework.web.socket.TextMessage;
|
import org.springframework.web.socket.TextMessage;
|
||||||
//import org.springframework.web.socket.WebSocketSession;
|
import org.springframework.web.socket.WebSocketSession;
|
||||||
//import org.springframework.web.socket.handler.TextWebSocketHandler;
|
import org.springframework.web.socket.handler.TextWebSocketHandler;
|
||||||
//
|
|
||||||
//import java.io.IOException;
|
import java.io.IOException;
|
||||||
//
|
|
||||||
//import static cd.casic.framework.commons.exception.util.ServiceExceptionUtil.exception;
|
import static cd.casic.framework.commons.exception.util.ServiceExceptionUtil.exception;
|
||||||
//import static cd.casic.module.machine.contants.MachineErrorCodeConstants.*;
|
import static cd.casic.module.machine.contants.MachineErrorCodeConstants.*;
|
||||||
//
|
|
||||||
////WebSocket处理器
|
//WebSocket处理器
|
||||||
//@Component("machineWebSocketHandler")
|
@Component("machineWebSocketHandler")
|
||||||
//public class MachineWebSocketHandler extends TextWebSocketHandler {
|
public class MachineWebSocketHandler extends TextWebSocketHandler {
|
||||||
//
|
|
||||||
// @Override
|
@Override
|
||||||
// public void afterConnectionEstablished(@NotNull WebSocketSession webSocketSession) {
|
public void afterConnectionEstablished(@NotNull WebSocketSession webSocketSession) {
|
||||||
// Long machineId = (Long) webSocketSession.getAttributes().get("machineId");
|
Long machineId = (Long) webSocketSession.getAttributes().get("machineId");
|
||||||
// //保存webSocketSession信息
|
//保存webSocketSession信息
|
||||||
// WebSocketSessionManager.addWebSocketSession(webSocketSession.getId(), webSocketSession);
|
WebSocketSessionManager.addWebSocketConnection(webSocketSession.getId(), WebSocketSessionManager.getWebSocketConnectionByMachineId(machineId));
|
||||||
// WebSocketSessionManager.addWebSocketConnection(webSocketSession.getId(), WebSocketSessionManager.getWebSocketConnectionByMachineId(machineId));
|
try {
|
||||||
// try {
|
webSocketSession.sendMessage(new TextMessage("欢迎连接到 WebSocket 服务器!"));
|
||||||
// webSocketSession.sendMessage(new TextMessage("欢迎连接到 WebSocket 服务器!"));
|
} catch (IOException e) {
|
||||||
// } catch (IOException e) {
|
throw exception(WEBSOCKET_SEND_MESSAGE_ERROR);
|
||||||
// throw exception(WEBSOCKET_SEND_MESSAGE_ERROR);
|
}
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
//
|
// 处理文本消息
|
||||||
// // 处理文本消息
|
@Override
|
||||||
// @Override
|
protected void handleTextMessage(WebSocketSession webSocketSession, TextMessage message) {
|
||||||
// protected void handleTextMessage(WebSocketSession webSocketSession, TextMessage message) {
|
String payload = message.getPayload();
|
||||||
// String payload = message.getPayload();
|
String sessionId = webSocketSession.getId();
|
||||||
// String sessionId = webSocketSession.getId();
|
// 从管理器获取连接
|
||||||
// // 从管理器获取连接
|
WebSocketConnection webSocketConnection = WebSocketSessionManager.getWebSocketConnection(sessionId);
|
||||||
// WebSocketConnection webSocketConnection = WebSocketSessionManager.getWebSocketConnection(sessionId);
|
if (webSocketConnection != null && ConnectionStatus.CONNECTING.equals(webSocketConnection.getConnectionStatus())) {
|
||||||
//
|
// 转发消息到远程机器
|
||||||
// if (webSocketConnection != null && ConnectionStatus.CONNECTING.equals(webSocketConnection.getConnectionStatus())) {
|
webSocketConnection.executeCommand(webSocketSession, payload);
|
||||||
// // 转发消息到远程机器
|
} else if (webSocketConnection != null) {
|
||||||
// webSocketConnection.executeCommand(webSocketSession, payload);
|
webSocketConnection.sendErrorMessage(webSocketSession, "连接已断开,无法发送消息");
|
||||||
// } else if (webSocketConnection != null) {
|
} else {
|
||||||
// webSocketConnection.sendErrorMessage(webSocketSession, "连接已断开,无法发送消息");
|
throw exception(WEBSOCKET_SEND_MESSAGE_ERROR);
|
||||||
// } else {
|
}
|
||||||
// throw exception(WEBSOCKET_SEND_MESSAGE_ERROR);
|
}
|
||||||
// }
|
|
||||||
// }
|
@Override
|
||||||
//
|
public void afterConnectionClosed(WebSocketSession webSocketSession, @NotNull CloseStatus status) {
|
||||||
// @Override
|
String sessionId = webSocketSession.getId();
|
||||||
// public void afterConnectionClosed(WebSocketSession webSocketSession, @NotNull CloseStatus status) {
|
// 获取并关闭相关的 WebSocketConnection
|
||||||
// String sessionId = webSocketSession.getId();
|
WebSocketConnection webSocketConnection = WebSocketSessionManager.getWebSocketConnection(sessionId);
|
||||||
// // 获取并关闭相关的 WebSocketConnection
|
if (webSocketConnection != null) {
|
||||||
// WebSocketConnection webSocketConnection = WebSocketSessionManager.getWebSocketConnection(sessionId);
|
webSocketConnection.disconnect();
|
||||||
// if (webSocketConnection != null) {
|
}
|
||||||
// webSocketConnection.disconnect();
|
// 从管理器中移除会话和连接
|
||||||
// }
|
WebSocketSessionManager.removeWebSocketConnection(sessionId);
|
||||||
// // 从管理器中移除会话和连接
|
Long machineInfoId = (Long) webSocketSession.getAttributes().get("machineId");
|
||||||
// WebSocketSessionManager.removeWebSocketSession(sessionId);
|
WebSocketSessionManager.removeWebSocketConnectionByMachineId(machineInfoId);
|
||||||
// WebSocketSessionManager.removeWebSocketConnection(sessionId);
|
}
|
||||||
// Long machineInfoId = (Long) webSocketSession.getAttributes().get("machineId");
|
}
|
||||||
// WebSocketSessionManager.removeWebSocketConnectionByMachineId(machineInfoId);
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
@ -2,9 +2,12 @@ package cd.casic.module.machine.service;
|
|||||||
|
|
||||||
import cd.casic.framework.commons.pojo.PageResult;
|
import cd.casic.framework.commons.pojo.PageResult;
|
||||||
import cd.casic.module.machine.controller.vo.MachineInfoVO;
|
import cd.casic.module.machine.controller.vo.MachineInfoVO;
|
||||||
|
import cd.casic.module.machine.controller.vo.SecretKeyVO;
|
||||||
import cd.casic.module.machine.dal.dataobject.MachineInfoDO;
|
import cd.casic.module.machine.dal.dataobject.MachineInfoDO;
|
||||||
import cd.casic.module.machine.enums.ConnectionStatus;
|
import cd.casic.module.machine.enums.ConnectionStatus;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -18,18 +21,35 @@ public interface MachineInfoService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 查看机器列表
|
* 查看机器列表
|
||||||
* @return 分院
|
* @return 机器列表
|
||||||
*/
|
*/
|
||||||
PageResult<MachineInfoDO> listMachineInfo(@Valid MachineInfoVO MachineInfoVO);
|
PageResult<MachineInfoDO> listMachineInfo(@Valid MachineInfoVO MachineInfoVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新机器信息
|
||||||
|
*/
|
||||||
void updateMachineInfo(@Valid MachineInfoVO machineInfoVO);
|
void updateMachineInfo(@Valid MachineInfoVO machineInfoVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 变更机器状态
|
||||||
|
*/
|
||||||
Integer updateStatus(@Valid MachineInfoVO machineInfoVO);
|
Integer updateStatus(@Valid MachineInfoVO machineInfoVO);
|
||||||
|
|
||||||
void bindingSecretKey(List<Long> machineInfoIds, Long secretKeyId);
|
/**
|
||||||
|
* 绑定密钥
|
||||||
|
*/
|
||||||
|
void bindingSecretKey(SecretKeyVO secretKeyVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除机器
|
||||||
|
* @param machineInfoIds 机器id列表
|
||||||
|
*/
|
||||||
void deleteMachineInfoList(String machineInfoIds);
|
void deleteMachineInfoList(String machineInfoIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除机器信息
|
||||||
|
* @param machineInfoId 机器id
|
||||||
|
*/
|
||||||
void deleteMachineInfo(Long machineInfoId);
|
void deleteMachineInfo(Long machineInfoId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,55 +60,51 @@ public interface MachineInfoService {
|
|||||||
List<MachineInfoDO>selectBindMachineBySecretKey(Long secretKeyId);
|
List<MachineInfoDO>selectBindMachineBySecretKey(Long secretKeyId);
|
||||||
|
|
||||||
|
|
||||||
// /**
|
/**
|
||||||
// * 测试机器连接
|
* 测试机器连接
|
||||||
// *
|
* @param id 机器id
|
||||||
// * @param id 机器id
|
* @return 连接是否成功
|
||||||
// * @return 连接是否成功
|
*/
|
||||||
// */
|
boolean testConnection(Long id);
|
||||||
// boolean testConnection(Long id);
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * 连接远程机器
|
|
||||||
// *
|
|
||||||
// * @param id 机器id
|
|
||||||
// * @return 连接后端文件树
|
|
||||||
// */
|
|
||||||
// Map<String, Object> connect(Long id);
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * 获取机器连接状态
|
|
||||||
// *
|
|
||||||
// * @return 连接状态
|
|
||||||
// */
|
|
||||||
// ConnectionStatus getConnectionStatus(Long id);
|
|
||||||
//
|
|
||||||
// /**
|
|
||||||
// * 获取所有连接状态
|
|
||||||
// *
|
|
||||||
// * @return 机器名称到连接状态的映射
|
|
||||||
// */
|
|
||||||
// Map<Long, ConnectionStatus> getAllConnectionStatus();
|
|
||||||
|
|
||||||
// /**
|
/**
|
||||||
// * 上传文件到远程机器
|
* 连接远程机器
|
||||||
// *
|
*
|
||||||
// * @param sessionId 会话ID
|
* @param id 机器id
|
||||||
// * @param localFilePath 本地文件路径
|
* @return 连接后端文件树
|
||||||
// * @param remoteFilePath 远程文件路径
|
*/
|
||||||
// * @return 操作结果
|
Map<String, Object> connect(Long id);
|
||||||
// */
|
|
||||||
// boolean uploadFile(String sessionId, String localFilePath, String remoteFilePath);
|
/**
|
||||||
//
|
* 获取机器连接状态
|
||||||
// /**
|
*
|
||||||
// * 从远程机器下载文件
|
* @return 连接状态
|
||||||
// *
|
*/
|
||||||
// * @param sessionId 会话ID
|
ConnectionStatus getConnectionStatus(Long id);
|
||||||
// * @param remoteFilePath 远程文件路径
|
|
||||||
// * @param localFilePath 本地文件路径
|
/**
|
||||||
// * @return 操作结果
|
* 获取所有连接状态
|
||||||
// */
|
*
|
||||||
// boolean downloadFile(String sessionId, String remoteFilePath, String localFilePath);
|
* @return 机器名称到连接状态的映射
|
||||||
|
*/
|
||||||
|
Map<Long, ConnectionStatus> getAllConnectionStatus();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 上传文件到远程机器
|
||||||
|
*
|
||||||
|
* @param file 上传文件
|
||||||
|
* @param remoteFilePath 远程文件路径
|
||||||
|
* @return 操作结果
|
||||||
|
*/
|
||||||
|
boolean uploadFile(MultipartFile file, String remoteFilePath);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从远程机器下载文件
|
||||||
|
*
|
||||||
|
* @param remoteFilePath 远程文件路径
|
||||||
|
* @return 操作结果
|
||||||
|
*/
|
||||||
|
boolean downloadFile(String remoteFilePath, HttpServletResponse httpServletResponse);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 校验机器是否存在
|
* 校验机器是否存在
|
||||||
@ -97,12 +113,18 @@ public interface MachineInfoService {
|
|||||||
*/
|
*/
|
||||||
MachineInfoDO validateMachineInfoExists(Long id);
|
MachineInfoDO validateMachineInfoExists(Long id);
|
||||||
|
|
||||||
// /**
|
/**
|
||||||
// * 根据路径获得远程文件树
|
* 根据路径获得远程文件树
|
||||||
// *
|
*
|
||||||
// * @param machineId 机器id
|
* @param machineId 机器id
|
||||||
// * @param path 文件夹路径
|
* @param path 文件夹路径
|
||||||
// * @return 远程文件树
|
* @return 远程文件树
|
||||||
// */
|
*/
|
||||||
// Map<String, Object> fileTreeNode(Long machineId, String path);
|
Map<String, Object> fileTreeNode(Long machineId, String path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除远程文件路径
|
||||||
|
* @param remoteFilePath 远程文件路径
|
||||||
|
*/
|
||||||
|
boolean deleteRemoteFile(String remoteFilePath);
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,6 @@ public interface MachineProxyService {
|
|||||||
/**
|
/**
|
||||||
* 删除代理
|
* 删除代理
|
||||||
*
|
*
|
||||||
* @param
|
|
||||||
*/
|
*/
|
||||||
void delete(Long id);
|
void delete(Long id);
|
||||||
|
|
||||||
@ -45,5 +44,8 @@ public interface MachineProxyService {
|
|||||||
*/
|
*/
|
||||||
void deleteProxyList(String proxyIds);
|
void deleteProxyList(String proxyIds);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取代理列表(分页)
|
||||||
|
*/
|
||||||
PageResult<MachineProxyDO> getProxyPage(@Valid MachineProxyVO machineProxyVO);
|
PageResult<MachineProxyDO> getProxyPage(@Valid MachineProxyVO machineProxyVO);
|
||||||
}
|
}
|
||||||
|
@ -5,30 +5,44 @@ import cd.casic.module.machine.dal.dataobject.MachineInfoDO;
|
|||||||
import cd.casic.module.machine.dal.dataobject.SecretKeyDO;
|
import cd.casic.module.machine.dal.dataobject.SecretKeyDO;
|
||||||
import cd.casic.module.machine.controller.vo.SecretKeyVO;
|
import cd.casic.module.machine.controller.vo.SecretKeyVO;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import org.springframework.core.io.InputStreamResource;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public interface SecretKeyService {
|
public interface SecretKeyService {
|
||||||
Long createSecretKey(@Valid SecretKeyVO secretKeyVO) throws Exception;
|
/**
|
||||||
|
* 新增密钥
|
||||||
void bindingMachine(@Valid SecretKeyVO secretKeyVO);
|
*/
|
||||||
|
Long createSecretKey(@Valid SecretKeyVO secretKeyVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新密钥
|
||||||
|
*/
|
||||||
void updateSecretKey(@Valid SecretKeyVO secretKeyVO);
|
void updateSecretKey(@Valid SecretKeyVO secretKeyVO);
|
||||||
|
|
||||||
PageResult<SecretKeyDO> getSecretKeypage(@Valid SecretKeyVO secretKeyVO);
|
/**
|
||||||
|
* 获取密钥列表(分页)
|
||||||
|
*/
|
||||||
|
PageResult<SecretKeyDO> getSecretKeyPage(@Valid SecretKeyVO secretKeyVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除密钥
|
||||||
|
* @param ids 密钥id集合
|
||||||
|
*/
|
||||||
void deleteSecretKeyList(List<Long> ids);
|
void deleteSecretKeyList(List<Long> ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据id获取密钥对象
|
||||||
|
*/
|
||||||
SecretKeyVO getSecretKey(Long id);
|
SecretKeyVO getSecretKey(Long id);
|
||||||
|
|
||||||
void deleteSecretKey(Long id);
|
/**
|
||||||
|
* 获取绑定的密钥的机器列表
|
||||||
void unbindMachine(@Valid SecretKeyVO secretKeyVO);
|
*/
|
||||||
|
|
||||||
List<MachineInfoDO> getBindMachine(Long secretKeyId);
|
List<MachineInfoDO> getBindMachine(Long secretKeyId);
|
||||||
|
|
||||||
// String getKeyContent(Long secretKeyId);
|
/**
|
||||||
|
* 获取公钥内容
|
||||||
|
*/
|
||||||
|
String getPublicKeyContent(Long secretKeyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,8 @@ package cd.casic.module.machine.service.impl;
|
|||||||
|
|
||||||
import cd.casic.framework.commons.pojo.PageResult;
|
import cd.casic.framework.commons.pojo.PageResult;
|
||||||
import cd.casic.module.machine.component.FileTreeComponent;
|
import cd.casic.module.machine.component.FileTreeComponent;
|
||||||
//import cd.casic.module.machine.component.WebSocketSessionManager;
|
import cd.casic.module.machine.component.WebSocketConnection;
|
||||||
|
import cd.casic.module.machine.component.WebSocketSessionManager;
|
||||||
import cd.casic.module.machine.controller.vo.SecretKeyVO;
|
import cd.casic.module.machine.controller.vo.SecretKeyVO;
|
||||||
import cd.casic.module.machine.enums.AuthenticationType;
|
import cd.casic.module.machine.enums.AuthenticationType;
|
||||||
import cd.casic.module.machine.enums.MachineInfoType;
|
import cd.casic.module.machine.enums.MachineInfoType;
|
||||||
@ -11,17 +12,22 @@ import cd.casic.module.machine.controller.vo.MachineInfoVO;
|
|||||||
import cd.casic.module.machine.dal.dataobject.MachineInfoDO;
|
import cd.casic.module.machine.dal.dataobject.MachineInfoDO;
|
||||||
import cd.casic.module.machine.enums.ConnectionStatus;
|
import cd.casic.module.machine.enums.ConnectionStatus;
|
||||||
import cd.casic.module.machine.enums.MachineInfoStatus;
|
import cd.casic.module.machine.enums.MachineInfoStatus;
|
||||||
//import cd.casic.module.machine.component.WebSocketConnection;
|
|
||||||
import cd.casic.module.machine.service.MachineInfoService;
|
import cd.casic.module.machine.service.MachineInfoService;
|
||||||
import cd.casic.module.machine.service.SecretKeyService;
|
import cd.casic.module.machine.service.SecretKeyService;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import com.jcraft.jsch.Session;
|
import com.jcraft.jsch.Session;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import cd.casic.framework.commons.util.object.BeanUtils;
|
import cd.casic.framework.commons.util.object.BeanUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@ -44,6 +50,9 @@ public class MachineInfoServiceImpl implements MachineInfoService {
|
|||||||
@Resource
|
@Resource
|
||||||
private FileTreeComponent fileTreeComponent;
|
private FileTreeComponent fileTreeComponent;
|
||||||
|
|
||||||
|
//todo,部署后更改
|
||||||
|
private static final Path TEMP_DIR = Paths.get("D:\\桌面\\work\\ops-pro111\\temp");
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long createMachine(MachineInfoVO machineInfoVO) {
|
public Long createMachine(MachineInfoVO machineInfoVO) {
|
||||||
validateMachineEnvAdd(machineInfoVO);
|
validateMachineEnvAdd(machineInfoVO);
|
||||||
@ -85,8 +94,8 @@ public class MachineInfoServiceImpl implements MachineInfoService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bindingSecretKey(List<Long> machineInfoIds, Long secretKeyId) {
|
public void bindingSecretKey(SecretKeyVO secretKeyVO) {
|
||||||
machineInfoMapper.bindingSecretKey(machineInfoIds, secretKeyId);
|
machineInfoMapper.bindingSecretKey(secretKeyVO.getMachineInfoIds(), secretKeyVO.getId(),secretKeyVO.getEnableBind());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -109,78 +118,73 @@ public class MachineInfoServiceImpl implements MachineInfoService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<MachineInfoDO> selectBindMachineBySecretKey(Long secretKeyId) {
|
public List<MachineInfoDO> selectBindMachineBySecretKey(Long secretKeyId) {
|
||||||
return machineInfoMapper.selectBindMachineBySecretKey(secretKeyId);
|
return machineInfoMapper.selectBindMachineBySecretKey(secretKeyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// @Override
|
@Override
|
||||||
// public boolean testConnection(Long id) {
|
public boolean testConnection(Long id) {
|
||||||
// //先查询机器是否存在,在判断机器可用性
|
//先查询机器是否存在,在判断机器可用性
|
||||||
// MachineInfoDO machineInfoDO = validateMachineInfoExists(id);
|
MachineInfoDO machineInfoDO = validateMachineInfoExists(id);
|
||||||
// validateMachineUnEnable(machineInfoDO);
|
validateMachineUnEnable(machineInfoDO);
|
||||||
// log.info("测试机器连接: {}", machineInfoDO.getHostIp());
|
log.info("测试机器连接: {}", machineInfoDO.getHostIp());
|
||||||
// WebSocketConnection webSocketConnection = createWebSocketConnection(machineInfoDO);
|
WebSocketConnection webSocketConnection = createWebSocketConnection(machineInfoDO);
|
||||||
// webSocketConnection.initConnection(machineInfoDO);
|
webSocketConnection.initConnection(machineInfoDO);
|
||||||
// return true;
|
return true;
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public Map<String, Object> connect(Long id) {
|
|
||||||
// //todo使用代理机器的情况还未完成
|
|
||||||
// WebSocketConnection webSocketConnection = new WebSocketConnection(this.secretKeyService);
|
|
||||||
// MachineInfoDO machineInfoDO = validateMachineInfoExists(id);
|
|
||||||
// //初始化连接
|
|
||||||
// webSocketConnection.initConnection(machineInfoDO);
|
|
||||||
// WebSocketSessionManager.addWebSocketConnectionByMachineId(id, webSocketConnection);
|
|
||||||
// return fileTreeComponent.getRemoteFileTree(webSocketConnection.getSshSession(), "/");
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public ConnectionStatus getConnectionStatus(Long id) {
|
|
||||||
// validateMachineInfoExists(id);
|
|
||||||
// WebSocketConnection webSocketConnection = WebSocketSessionManager.getWebSocketConnectionByMachineId(id);
|
|
||||||
// return webSocketConnection == null ? ConnectionStatus.DISCONNECTED : webSocketConnection.getConnectionStatus();
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// @Override
|
|
||||||
// public Map<Long, ConnectionStatus> getAllConnectionStatus() {
|
|
||||||
// return WebSocketSessionManager.getAllWebSocketConnections().entrySet().stream()
|
|
||||||
// .collect(Collectors.toMap(
|
|
||||||
// Map.Entry::getKey,
|
|
||||||
// entry -> entry.getValue().getConnectionStatus()
|
|
||||||
// ));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @Override
|
@Override
|
||||||
// public boolean uploadFile(String sessionId, String localFilePath, String remoteFilePath) {
|
public Map<String, Object> connect(Long id) {
|
||||||
// log.info("上传文件: {} -> {}, 会话ID: {}", localFilePath, remoteFilePath, sessionId);
|
//todo使用代理机器的情况还未完成
|
||||||
// WebSocketConnection webSocketConnection = sessionConnectionMap.get(sessionId);
|
WebSocketConnection webSocketConnection = new WebSocketConnection(this.secretKeyService);
|
||||||
// if (webSocketConnection == null||webSocketConnection.getConnectionStatus() != ConnectionStatus.CONNECTED) {
|
MachineInfoDO machineInfoDO = validateMachineInfoExists(id);
|
||||||
// throw exception(SESSION_NOT_CONNECT);
|
//初始化连接
|
||||||
// }
|
webSocketConnection.initConnection(machineInfoDO);
|
||||||
// try {
|
WebSocketSessionManager.addWebSocketConnectionByMachineId(id, webSocketConnection);
|
||||||
// return webSocketConnection.uploadFile(localFilePath, remoteFilePath);
|
return fileTreeComponent.getRemoteFileTree(webSocketConnection.getSshSession(), "/");
|
||||||
// } catch (Exception e) {
|
}
|
||||||
// log.error("文件上传失败: {}", e.getMessage(), e);
|
|
||||||
// throw exception(FILE_UPLOAD_ERROR);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// @Override
|
@Override
|
||||||
// public boolean downloadFile(String sessionId, String remoteFilePath, String localFilePath) {
|
public ConnectionStatus getConnectionStatus(Long id) {
|
||||||
// log.info("下载文件: {} -> {}, 会话ID: {}", remoteFilePath, localFilePath, sessionId);
|
validateMachineInfoExists(id);
|
||||||
//
|
WebSocketConnection webSocketConnection = WebSocketSessionManager.getWebSocketConnectionByMachineId(id);
|
||||||
// WebSocketConnection webSocketConnection = sessionConnectionMap.get(sessionId);
|
return webSocketConnection == null ? ConnectionStatus.DISCONNECTED : webSocketConnection.getConnectionStatus();
|
||||||
// if (webSocketConnection == null||webSocketConnection.getConnectionStatus() != ConnectionStatus.CONNECTED) {
|
}
|
||||||
// throw new RuntimeException("会话不存在: " + sessionId);
|
|
||||||
// }
|
@Override
|
||||||
// try {
|
public Map<Long, ConnectionStatus> getAllConnectionStatus() {
|
||||||
// return webSocketConnection.downloadFile(remoteFilePath, localFilePath);
|
return WebSocketSessionManager.getAllWebSocketConnections().entrySet().stream()
|
||||||
// } catch (Exception e) {
|
.collect(Collectors.toMap(
|
||||||
// log.error("文件下载失败: {}", e.getMessage(), e);
|
Map.Entry::getKey,
|
||||||
// throw exception(FILE_DOWNLOAD_ERROR);
|
entry -> entry.getValue().getConnectionStatus()
|
||||||
// }
|
));
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean uploadFile(MultipartFile file, String remoteFilePath) {
|
||||||
|
Path tempFilePath;
|
||||||
|
// 保存上传的文件到临时位置
|
||||||
|
String originalFilename = file.getOriginalFilename();
|
||||||
|
if (originalFilename == null || originalFilename.isEmpty()) {
|
||||||
|
throw exception(INVALID_FILE_NAME);
|
||||||
|
}
|
||||||
|
// 安全过滤文件名,防止路径遍历攻击
|
||||||
|
String safeFilename = sanitizeFilename(originalFilename);
|
||||||
|
try {
|
||||||
|
tempFilePath = Files.createTempFile(TEMP_DIR, "upload-", safeFilename);
|
||||||
|
file.transferTo(tempFilePath.toFile());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw exception(CREATE_TEMP_FILE_ERROR);
|
||||||
|
}
|
||||||
|
fileTreeComponent.uploadToRemoteServer(tempFilePath, safeFilename, remoteFilePath);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean downloadFile(String remoteFilePath, HttpServletResponse httpServletResponse) {
|
||||||
|
fileTreeComponent.downloadFile(remoteFilePath, httpServletResponse);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void validateMachineEnvAdd(MachineInfoVO machineInfoVO) {
|
void validateMachineEnvAdd(MachineInfoVO machineInfoVO) {
|
||||||
@ -246,12 +250,18 @@ public class MachineInfoServiceImpl implements MachineInfoService {
|
|||||||
return machineInfoDO;
|
return machineInfoDO;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Override
|
@Override
|
||||||
// public Map<String, Object> fileTreeNode(Long machineId, String path) {
|
public Map<String, Object> fileTreeNode(Long machineId, String path) {
|
||||||
// validateMachineInfoExists(machineId);
|
validateMachineInfoExists(machineId);
|
||||||
// Session sshSession = WebSocketSessionManager.getWebSocketConnectionByMachineId(machineId).getSshSession();
|
Session sshSession = WebSocketSessionManager.getWebSocketConnectionByMachineId(machineId).getSshSession();
|
||||||
// return fileTreeComponent.getRemoteFileTree(sshSession, path);
|
return fileTreeComponent.getRemoteFileTree(sshSession, path);
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean deleteRemoteFile(String remoteFilePath) {
|
||||||
|
fileTreeComponent.deleteRemoteFile(remoteFilePath);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void validateMachineEnable(MachineInfoDO machineInfoDO) {
|
void validateMachineEnable(MachineInfoDO machineInfoDO) {
|
||||||
@ -268,12 +278,25 @@ public class MachineInfoServiceImpl implements MachineInfoService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// @VisibleForTesting
|
@VisibleForTesting
|
||||||
// WebSocketConnection createWebSocketConnection(MachineInfoDO machineInfoDO) {
|
WebSocketConnection createWebSocketConnection(MachineInfoDO machineInfoDO) {
|
||||||
// if (WebSocketSessionManager.containsMachineId(machineInfoDO.getId())) {
|
if (WebSocketSessionManager.containsMachineId(machineInfoDO.getId())) {
|
||||||
// return WebSocketSessionManager.getWebSocketConnectionByMachineId((machineInfoDO.getId()));
|
return WebSocketSessionManager.getWebSocketConnectionByMachineId((machineInfoDO.getId()));
|
||||||
// } else {
|
} else {
|
||||||
// return new WebSocketConnection(this.secretKeyService);
|
return new WebSocketConnection(this.secretKeyService);
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
// 安全过滤文件名,防止路径遍历攻击
|
||||||
|
private String sanitizeFilename(String filename) {
|
||||||
|
// 移除路径相关字符,只保留文件名和扩展名
|
||||||
|
filename = filename.replaceAll("[\\\\/:*?\"<>|]", "_");
|
||||||
|
// 限制最大长度
|
||||||
|
if (filename.length() > 255) {
|
||||||
|
filename = filename.substring(0, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,9 +7,6 @@ import cd.casic.module.machine.dal.dataobject.MachineInfoDO;
|
|||||||
import cd.casic.module.machine.dal.dataobject.SecretKeyDO;
|
import cd.casic.module.machine.dal.dataobject.SecretKeyDO;
|
||||||
import cd.casic.module.machine.dal.mysql.SecretKeyMapper;
|
import cd.casic.module.machine.dal.mysql.SecretKeyMapper;
|
||||||
import cd.casic.module.machine.service.MachineInfoService;
|
import cd.casic.module.machine.service.MachineInfoService;
|
||||||
import cn.hutool.core.io.resource.ResourceUtil;
|
|
||||||
import cn.hutool.core.util.IdUtil;
|
|
||||||
import cd.casic.module.machine.utils.AliYunOssClient;
|
|
||||||
import cd.casic.module.machine.service.SecretKeyService;
|
import cd.casic.module.machine.service.SecretKeyService;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
@ -33,36 +30,28 @@ public class SecretKeyServiceImpl implements SecretKeyService {
|
|||||||
@Resource
|
@Resource
|
||||||
private SecretKeyMapper secretKeyMapper;
|
private SecretKeyMapper secretKeyMapper;
|
||||||
|
|
||||||
@Override
|
|
||||||
public void deleteSecretKey(Long id) {
|
|
||||||
validateSecretKeyExists(id);
|
|
||||||
secretKeyMapper.deleteById(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SecretKeyVO getSecretKey(Long id) {
|
public SecretKeyVO getSecretKey(Long id) {
|
||||||
SecretKeyDO secretKeyDO = validateSecretKeyExists(id);
|
SecretKeyDO secretKeyDO = validateSecretKeyExists(id);
|
||||||
return BeanUtils.toBean(secretKeyDO, SecretKeyVO.class);
|
return BeanUtils.toBean(secretKeyDO, SecretKeyVO.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unbindMachine(SecretKeyVO secretKeyVO) {
|
|
||||||
machineInfoService.bindingSecretKey(secretKeyVO.getMachineInfoIds(),null);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<MachineInfoDO> getBindMachine(Long secretKeyId) {
|
public List<MachineInfoDO> getBindMachine(Long secretKeyId) {
|
||||||
return machineInfoService.selectBindMachineBySecretKey(secretKeyId);
|
return machineInfoService.selectBindMachineBySecretKey(secretKeyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPublicKeyContent(Long secretKeyId) {
|
||||||
|
return secretKeyMapper.selectById(secretKeyId).getPublicKey();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long createSecretKey(SecretKeyVO secretKeyVO) {
|
public Long createSecretKey(SecretKeyVO secretKeyVO) {
|
||||||
validateSecretKeyAdd(secretKeyVO);
|
validateSecretKeyAdd(secretKeyVO);
|
||||||
SecretKeyDO secretKeyDO = BeanUtils.toBean(secretKeyVO, SecretKeyDO.class);
|
SecretKeyDO secretKeyDO = BeanUtils.toBean(secretKeyVO, SecretKeyDO.class);
|
||||||
secretKeyMapper.insert(secretKeyDO);
|
secretKeyMapper.insert(secretKeyDO);
|
||||||
return secretKeyDO.getId();
|
return secretKeyDO.getId();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -72,25 +61,21 @@ public class SecretKeyServiceImpl implements SecretKeyService {
|
|||||||
secretKeyMapper.updateById(secretKeyDO);
|
secretKeyMapper.updateById(secretKeyDO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void bindingMachine(SecretKeyVO secretKeyVO) {
|
|
||||||
validateSecretKeyExists(secretKeyVO.getId());
|
|
||||||
machineInfoService.bindingSecretKey(secretKeyVO.getMachineInfoIds(), secretKeyVO.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public void deleteSecretKeyList(List<Long> ids) {
|
public void deleteSecretKeyList(List<Long> ids) {
|
||||||
machineInfoService.bindingSecretKey(ids,null);
|
SecretKeyVO secretKeyVO = new SecretKeyVO()
|
||||||
|
.setMachineInfoIds(ids)
|
||||||
|
.setEnableBind(false);
|
||||||
|
machineInfoService.bindingSecretKey(secretKeyVO);
|
||||||
secretKeyMapper.deleteBatchIds(ids);
|
secretKeyMapper.deleteBatchIds(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PageResult<SecretKeyDO> getSecretKeypage(SecretKeyVO secretKeyVO) {
|
public PageResult<SecretKeyDO> getSecretKeyPage(SecretKeyVO secretKeyVO) {
|
||||||
return secretKeyMapper.selectPage(secretKeyVO);
|
return secretKeyMapper.selectPage(secretKeyVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
void validateSecretKeyAdd(SecretKeyVO secretKeyVO) {
|
void validateSecretKeyAdd(SecretKeyVO secretKeyVO) {
|
||||||
if (secretKeyVO == null) {
|
if (secretKeyVO == null) {
|
||||||
@ -98,8 +83,6 @@ public class SecretKeyServiceImpl implements SecretKeyService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
SecretKeyDO validateSecretKeyExists(Long id) {
|
SecretKeyDO validateSecretKeyExists(Long id) {
|
||||||
if (id == null) {
|
if (id == null) {
|
||||||
@ -111,5 +94,4 @@ public class SecretKeyServiceImpl implements SecretKeyService {
|
|||||||
}
|
}
|
||||||
return secretKeyDO;
|
return secretKeyDO;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user