🔨 优化传输模块日志逻辑.

This commit is contained in:
lijiahangmax
2025-06-30 21:59:24 +08:00
parent 700b6d221d
commit 5dcd8cbad2
13 changed files with 96 additions and 47 deletions

View File

@@ -22,10 +22,8 @@
*/
package org.dromara.visor.module.common.utils;
import cn.orionsec.kit.lang.constant.Letters;
import cn.orionsec.kit.lang.utils.Booleans;
import cn.orionsec.kit.lang.utils.Strings;
import cn.orionsec.kit.lang.utils.io.Files1;
import cn.orionsec.kit.net.host.sftp.SftpExecutor;
import cn.orionsec.kit.net.host.sftp.SftpFile;
import cn.orionsec.kit.spring.SpringHolder;
@@ -69,21 +67,4 @@ public class SftpUtils {
}
}
/**
* 获取移动目标路径
*
* @param source source
* @param target target
* @return absolute target
*/
public static String getAbsoluteTargetPath(String source, String target) {
if (target.charAt(0) == Letters.SLASH) {
// 绝对路径
return Files1.getPath(Files1.normalize(target));
} else {
// 相对路径
return Files1.getPath(Files1.normalize(Files1.getPath(source + "/../" + target)));
}
}
}

View File

@@ -74,15 +74,15 @@ public class TerminalOperatorType extends InitializingOperatorTypes {
new OperatorType(OperatorRiskLevel.L, SFTP_MKDIR, "创建文件夹 ${hostName} <sb>${path}</sb>"),
new OperatorType(OperatorRiskLevel.L, SFTP_TOUCH, "创建文件 ${hostName} <sb>${path}</sb>"),
new OperatorType(OperatorRiskLevel.M, SFTP_MOVE, "移动文件 ${hostName} <sb>${path}</sb> 至 <sb>${target}</sb>"),
new OperatorType(OperatorRiskLevel.H, SFTP_REMOVE, "删除文件 ${hostName} <sb>${path}</sb>"),
new OperatorType(OperatorRiskLevel.H, SFTP_REMOVE, "删除文件 ${hostName} ${count}个\n<sb>${path}</sb>"),
new OperatorType(OperatorRiskLevel.H, SFTP_TRUNCATE, "截断文件 ${hostName} <sb>${path}</sb>"),
new OperatorType(OperatorRiskLevel.M, SFTP_CHMOD, "文件提权 ${hostName} <sb>${path}</sb> <sb>${mod}</sb>"),
new OperatorType(OperatorRiskLevel.M, SFTP_CHOWN, "修改文件归属 ${hostName} <sb>${path}</sb> <sb>${id}</sb>"),
new OperatorType(OperatorRiskLevel.M, SFTP_CHGRP, "修改文件分组 ${hostName} <sb>${path}</sb> <sb>${id}</sb>"),
new OperatorType(OperatorRiskLevel.L, SFTP_GET_CONTENT, "获取文件内容 ${hostName} <sb>${path}</sb>"),
new OperatorType(OperatorRiskLevel.M, SFTP_SET_CONTENT, "修改文件内容 ${hostName} <sb>${path}</sb>"),
new OperatorType(OperatorRiskLevel.M, SFTP_UPLOAD, "上传文件 ${hostName} <sb>${path}</sb>"),
new OperatorType(OperatorRiskLevel.M, SFTP_DOWNLOAD, "下载文件 ${hostName} <sb>${path}</sb>"),
new OperatorType(OperatorRiskLevel.M, SFTP_UPLOAD, "上传文件 ${hostName} (${count}个)\n<sb>${path}</sb>"),
new OperatorType(OperatorRiskLevel.M, SFTP_DOWNLOAD, "下载文件 ${hostName} (${count}个)\n<sb>${path}</sb>"),
new OperatorType(OperatorRiskLevel.M, RDP_UPLOAD, "上传文件 ${hostName} <sb>${path}</sb>"),
new OperatorType(OperatorRiskLevel.M, RDP_DOWNLOAD, "下载文件 ${hostName} <sb>${path}</sb>"),
};

View File

@@ -29,6 +29,7 @@ import org.dromara.visor.module.terminal.handler.terminal.model.request.SftpDown
import org.dromara.visor.module.terminal.handler.terminal.model.response.SftpFileVO;
import org.dromara.visor.module.terminal.handler.terminal.sender.ISftpTerminalSender;
import org.dromara.visor.module.terminal.handler.terminal.session.ISftpSession;
import org.dromara.visor.module.terminal.utils.SftpFileUtils;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@@ -50,7 +51,7 @@ public class SftpDownloadFlatDirectoryHandler extends AbstractTerminalHandler<IS
// 获取会话
String sessionId = props.getId();
ISftpSession session = terminalManager.getSession(props.getId());
String[] paths = payload.getPath().split("\\|");
String[] paths = SftpFileUtils.fromMultiPaths(payload.getPath());
log.info("SftpDownloadFlatDirectoryHandler-handle start sessionId: {}, paths: {}", sessionId, Arrays.toString(paths));
Exception ex = null;
List<SftpFileVO> files = Lists.empty();

View File

@@ -24,12 +24,14 @@ package org.dromara.visor.module.terminal.handler.terminal.handler;
import cn.orionsec.kit.lang.utils.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.dromara.visor.common.constant.Const;
import org.dromara.visor.framework.biz.operator.log.core.utils.OperatorLogs;
import org.dromara.visor.module.terminal.define.operator.TerminalOperatorType;
import org.dromara.visor.module.terminal.handler.terminal.model.TerminalChannelProps;
import org.dromara.visor.module.terminal.handler.terminal.model.request.SftpBaseRequest;
import org.dromara.visor.module.terminal.handler.terminal.sender.ISftpTerminalSender;
import org.dromara.visor.module.terminal.handler.terminal.session.ISftpSession;
import org.dromara.visor.module.terminal.utils.SftpFileUtils;
import org.springframework.stereotype.Component;
import java.util.Arrays;
@@ -49,11 +51,11 @@ public class SftpRemoveHandler extends AbstractTerminalHandler<ISftpTerminalSend
@Override
public void handle(TerminalChannelProps props, ISftpTerminalSender sender, SftpBaseRequest payload) {
long startTime = System.currentTimeMillis();
String path = payload.getPath();
String[] paths = SftpFileUtils.fromMultiPaths(payload.getPath());
String path = String.join(Const.LF, paths);
String sessionId = props.getId();
// 获取会话
ISftpSession session = terminalManager.getSession(sessionId);
String[] paths = path.split("\\|");
log.info("SftpRemoveHandler-handle start sessionId: {}, path: {}", sessionId, Arrays.toString(paths));
Exception ex = null;
// 删除
@@ -69,6 +71,7 @@ public class SftpRemoveHandler extends AbstractTerminalHandler<ISftpTerminalSend
// 保存操作日志
Map<String, Object> extra = Maps.newMap();
extra.put(OperatorLogs.PATH, path);
extra.put(OperatorLogs.COUNT, paths.length);
this.saveOperatorLog(props,
extra, TerminalOperatorType.SFTP_REMOVE,
startTime, ex);

View File

@@ -129,6 +129,7 @@ public class TerminalConnectHandler extends AbstractTerminalHandler<ITerminalSen
this.updateTerminalConnectLog(logId, null, null);
// 发送设置信息
sender.sendSetInfo(TerminalSetInfo.builder()
.logId(logId)
.address(connectConfig.getHostAddress())
.port(connectConfig.getHostPort())
.username(connectConfig.getUsername())

View File

@@ -41,6 +41,11 @@ import lombok.experimental.SuperBuilder;
@AllArgsConstructor
public class TerminalSetInfo implements IJsonObject {
/**
* logId
*/
private Long logId;
/**
* 地址
*/

View File

@@ -34,7 +34,6 @@ import lombok.extern.slf4j.Slf4j;
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.common.utils.SftpUtils;
import org.dromara.visor.module.terminal.handler.terminal.model.TerminalChannelProps;
import org.dromara.visor.module.terminal.handler.terminal.model.config.TerminalSessionSftpConfig;
import org.dromara.visor.module.terminal.handler.terminal.model.response.SftpFileVO;
@@ -117,7 +116,7 @@ public class SftpSession extends AbstractTerminalSession<ISftpTerminalSender, Te
public void move(String source, String target) {
// 计算路径
source = Valid.checkNormalize(source);
target = SftpUtils.getAbsoluteTargetPath(source, target);
target = SftpFileUtils.getAbsoluteTargetPath(source, target);
// 移动
executor.move(source, target);
}

View File

@@ -40,6 +40,11 @@ import lombok.NoArgsConstructor;
@AllArgsConstructor
public class TransferOperatorRequest {
/**
* 日志id
*/
private Long logId;
/**
* 文件路径
*/

View File

@@ -25,6 +25,7 @@ package org.dromara.visor.module.terminal.handler.transfer.session;
import cn.orionsec.kit.lang.define.wrapper.Ref;
import cn.orionsec.kit.lang.utils.Threads;
import cn.orionsec.kit.lang.utils.Valid;
import cn.orionsec.kit.lang.utils.collect.Lists;
import cn.orionsec.kit.lang.utils.io.Streams;
import cn.orionsec.kit.net.host.SessionStore;
import cn.orionsec.kit.net.host.sftp.SftpFile;
@@ -72,7 +73,7 @@ public class DownloadSession extends TransferSession implements StreamingRespons
super.onStart(request);
log.info("DownloadSession.startDownload open start channelId: {}, path: {}", channelId, path);
// 保存操作日志
this.saveOperatorLog(TerminalOperatorType.SFTP_DOWNLOAD, path);
this.saveOperatorLog(request.getLogId(), TerminalOperatorType.SFTP_DOWNLOAD, Lists.singleton(path));
// 检查连接
this.init();
// 检查文件是否存在

View File

@@ -23,27 +23,24 @@
package org.dromara.visor.module.terminal.handler.transfer.session;
import cn.orionsec.kit.lang.exception.argument.InvalidArgumentException;
import cn.orionsec.kit.lang.utils.collect.Maps;
import cn.orionsec.kit.lang.utils.io.Streams;
import cn.orionsec.kit.net.host.SessionStore;
import cn.orionsec.kit.net.host.sftp.SftpExecutor;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.dromara.visor.common.constant.Const;
import org.dromara.visor.common.constant.FieldConst;
import org.dromara.visor.common.session.config.SshConnectConfig;
import org.dromara.visor.framework.biz.operator.log.core.model.OperatorLogModel;
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.terminal.handler.terminal.model.TerminalChannelProps;
import org.dromara.visor.module.terminal.handler.terminal.record.TerminalAsyncSaver;
import org.dromara.visor.module.terminal.handler.terminal.utils.TerminalUtils;
import org.dromara.visor.module.terminal.handler.transfer.enums.TransferReceiver;
import org.dromara.visor.module.terminal.handler.transfer.model.TransferOperatorRequest;
import org.dromara.visor.module.terminal.handler.transfer.utils.TransferUtils;
import org.springframework.web.socket.WebSocketSession;
import java.util.Map;
import java.util.List;
/**
* 主机传输会话实现
@@ -147,20 +144,16 @@ public abstract class TransferSession implements ITransferSession {
/**
* 保存操作日志
*
* @param logId logId
* @param type type
* @param path path
* @param paths paths
*/
protected void saveOperatorLog(String type, String path) {
// 设置参数
Map<String, Object> extra = Maps.newMap();
extra.put(OperatorLogs.PATH, path);
extra.put(OperatorLogs.HOST_ID, connectConfig.getHostId());
extra.put(OperatorLogs.HOST_NAME, connectConfig.getHostName());
extra.put(OperatorLogs.ADDRESS, connectConfig.getHostAddress());
// 获取日志
TerminalChannelProps props = WebSockets.getAttr(channel, FieldConst.PROPS);
OperatorLogModel model = TerminalUtils.getOperatorLogModel(props, extra, type, System.currentTimeMillis(), null);
// 保存
protected void saveOperatorLog(Long logId, String type, List<String> paths) {
String path = String.join(Const.LF, paths);
int count = paths.size();
// 获取操作日志
OperatorLogModel model = TransferUtils.getOperatorLogModel(type, path, count, connectConfig, WebSockets.getAttr(channel, FieldConst.PROPS));
// 保存操作日志
TerminalAsyncSaver.saveOperatorLog(model);
}

View File

@@ -22,6 +22,7 @@
*/
package org.dromara.visor.module.terminal.handler.transfer.session;
import cn.orionsec.kit.lang.utils.collect.Lists;
import cn.orionsec.kit.lang.utils.io.Streams;
import cn.orionsec.kit.net.host.SessionStore;
import lombok.extern.slf4j.Slf4j;
@@ -58,7 +59,7 @@ public class UploadSession extends TransferSession {
try {
log.info("UploadSession.startUpload start channelId: {}, path: {}", channelId, path);
// 保存操作日志
this.saveOperatorLog(TerminalOperatorType.SFTP_UPLOAD, path);
this.saveOperatorLog(request.getLogId(), TerminalOperatorType.SFTP_UPLOAD, Lists.singleton(path));
// 检查连接
this.init();
// 检查文件是否存在

View File

@@ -23,14 +23,21 @@
package org.dromara.visor.module.terminal.handler.transfer.utils;
import cn.orionsec.kit.lang.utils.Strings;
import cn.orionsec.kit.lang.utils.collect.Maps;
import com.alibaba.fastjson.JSON;
import org.apache.catalina.connector.ClientAbortException;
import org.dromara.visor.common.constant.ErrorMessage;
import org.dromara.visor.common.session.config.BaseConnectConfig;
import org.dromara.visor.framework.biz.operator.log.core.model.OperatorLogModel;
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.terminal.handler.terminal.model.TerminalChannelProps;
import org.dromara.visor.module.terminal.handler.terminal.utils.TerminalUtils;
import org.dromara.visor.module.terminal.handler.transfer.enums.TransferReceiver;
import org.dromara.visor.module.terminal.handler.transfer.model.TransferOperatorResponse;
import org.springframework.web.socket.WebSocketSession;
import java.util.Map;
import java.util.function.Consumer;
/**
@@ -45,6 +52,30 @@ public class TransferUtils {
private TransferUtils() {
}
/**
* 获取传输操作日志
*
* @param type type
* @param path path
* @param count count
* @param config config
* @param props props
*/
public static OperatorLogModel getOperatorLogModel(String type,
String path, Integer count,
BaseConnectConfig config,
TerminalChannelProps props) {
// 设置参数
Map<String, Object> extra = Maps.newMap();
extra.put(OperatorLogs.PATH, path);
extra.put(OperatorLogs.COUNT, count);
extra.put(OperatorLogs.HOST_ID, config.getHostId());
extra.put(OperatorLogs.HOST_NAME, config.getHostName());
extra.put(OperatorLogs.ADDRESS, config.getHostAddress());
// 获取操作日志
return TerminalUtils.getOperatorLogModel(props, extra, type, System.currentTimeMillis(), null);
}
/**
* 发送消息
*

View File

@@ -22,6 +22,7 @@
*/
package org.dromara.visor.module.terminal.utils;
import cn.orionsec.kit.lang.constant.Letters;
import cn.orionsec.kit.lang.utils.io.FileType;
import cn.orionsec.kit.lang.utils.io.Files1;
import cn.orionsec.kit.net.host.sftp.SftpFile;
@@ -41,6 +42,33 @@ public class SftpFileUtils {
private SftpFileUtils() {
}
/**
* 获取移动目标路径
*
* @param source source
* @param target target
* @return absolute target
*/
public static String getAbsoluteTargetPath(String source, String target) {
if (target.charAt(0) == Letters.SLASH) {
// 绝对路径
return Files1.getPath(Files1.normalize(target));
} else {
// 相对路径
return Files1.getPath(Files1.normalize(Files1.getPath(source + "/../" + target)));
}
}
/**
* 分割文件路径
*
* @param path path
* @return paths
*/
public static String[] fromMultiPaths(String path) {
return path.split("\\|");
}
/**
* 转为文件
*