1. 修改TaskController中的setCommandJudged方式,现在它将直接修改t_command中的IS_JUDGED字段

2. queryCommandInfos方法现在添加了筛选条件以及分页查询
This commit is contained in:
EnderByEndera
2024-01-22 20:10:54 +08:00
parent d6cf33f299
commit 095eb88eb3
11 changed files with 208 additions and 90 deletions

View File

@@ -5,7 +5,7 @@ plugins {
}
group = 'com.realtime'
version = '0.0.2-SNAPSHOT'
version = '0.0.3-SNAPSHOT'
java {
sourceCompatibility = '17'

View File

@@ -1,5 +1,6 @@
package com.realtime.protection.configuration.entity.task;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
@@ -9,51 +10,62 @@ import lombok.Data;
@Data
public class FiveTupleWithMask {
@Schema(description = "地址类型(IPv4 or IPv6)", example = "4")
@JsonProperty("addr_type")
private Integer addrType;
@Schema(description = "源IP", example = "192.168.104.14")
@Pattern(regexp = "^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$", message = "源IP无效IPv4地址")
@JsonProperty("src_ip")
private String sourceIP;
@Schema(description = "源端口", example = "114")
@Max(value = 65535, message = "源端口不可大于65535")
@Min(value = 1, message = "源端口不可小于1")
@JsonProperty("src_port")
private String sourcePort;
@Schema(description = "目的IP", example = "102.165.11.39")
@Pattern(regexp = "^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$", message = "目的IP无效IPv4地址")
@JsonProperty("dst_ip")
private String destinationIP;
@Schema(description = "目的端口", example = "514")
@Max(value = 65535, message = "目的端口不可大于65535")
@Min(value = 1, message = "目的端口不可小于1")
@JsonProperty("dst_port")
private String destinationPort;
@Schema(description = "协议名称", example = "TCP", accessMode = Schema.AccessMode.WRITE_ONLY)
private String protocol;
@Schema(description = "协议号", example = "6", accessMode = Schema.AccessMode.READ_ONLY)
@JsonProperty("protocol_num")
private Integer protocolNum;
@Schema(description = "源IP掩码", example = "255.255.255.0")
@Pattern(regexp = "^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$", message = "源IP掩码无效IPv4地址")
@JsonProperty("mask_src_ip")
private String maskSourceIP;
@Schema(description = "源端口掩码", example = "0")
@Max(value = 65535, message = "源端口掩码不可大于65535")
@Min(value = 1, message = "源端口掩码不可小于1")
@JsonProperty("mask_src_port")
private String maskSourcePort;
@Schema(description = "目的IP掩码", example = "255.255.0.0")
@Pattern(regexp = "^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$", message = "目的IP掩码无效IPv4地址")
@JsonProperty("mask_dst_ip")
private String maskDestinationIP;
@Schema(description = "目的端口掩码", example = "0")
@Max(value = 65535, message = "目的端口掩码不可大于65535")
@Min(value = 1, message = "目的端口掩码不可小于1")
@JsonProperty("mask_dst_port")
private String maskDestinationPort;
@Schema(description = "协议掩码", example = "0")
@JsonProperty("mask_protocol")
private String maskProtocol;
// 复制构造函数
@@ -70,6 +82,5 @@ public class FiveTupleWithMask {
this.maskDestinationIP = original.maskDestinationIP;
this.maskDestinationPort = original.maskDestinationPort;
this.maskProtocol = original.maskProtocol;
}
}

View File

@@ -1,5 +1,6 @@
package com.realtime.protection.configuration.entity.task;
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@@ -9,64 +10,82 @@ import java.time.LocalDateTime;
@Data
public class TaskCommandInfo {
@Schema(description = "指令UUID", accessMode = Schema.AccessMode.READ_ONLY)
@JsonProperty("uuid")
private String UUID;
@Schema(description = "任务ID", accessMode = Schema.AccessMode.READ_ONLY)
@JsonProperty("task_id")
private Long taskId;
@Schema(description = "规则ID", hidden = true)
@JsonProperty("rule_id")
private Long ruleId;
@Schema(description = "任务创建人名称", accessMode = Schema.AccessMode.READ_ONLY)
@JsonProperty("task_create_username")
private String taskCreateUsername;
@Schema(description = "任务创建人处室", accessMode = Schema.AccessMode.READ_ONLY)
@JsonProperty("task_create_depart")
private String taskCreateDepart;
@Schema(description = "任务创建人ID", accessMode = Schema.AccessMode.READ_ONLY)
@JsonProperty("task_create_userid")
private Integer taskCreateUserId;
@Schema(description = "任务名称", example = "API测试任务")
@NotNull(message = "任务名称不能为空")
@JsonProperty("task_name")
private String taskName;
@Schema(description = "任务类型", example = "1")
@NotNull(message = "任务类型不能为空")
@JsonProperty("task_type")
private Integer taskType;
@Schema(description = "任务操作", example = "阻断")
@NotNull(message = "任务操作不能为空。")
@JsonProperty("task_act")
private String taskAct;
@Schema(description = "指令下发频率", example = "30")
@NotNull(message = "指令下发频率不能为空。")
@JsonProperty("frequency")
private Integer frequency;
@Schema(description = "任务开始时间", example = "2025-10-14T10:23:33")
@NotNull(message = "任务开始时间不能为空。")
@JsonProperty("start_time")
private LocalDateTime startTime;
@Schema(description = "任务结束时间", example = "2026-10-22T10:33:22")
@NotNull(message = "指令结束时间不能为空。")
@JsonProperty("end_time")
private LocalDateTime endTime;
@Schema(description = "指令是否生效", example = "false")
@JsonProperty("is_valid")
private Boolean isValid = true;
@Schema(description = "五元组信息")
@NotNull(message = "五元组信息不能为空。")
@JsonProperty("five_tuple_with_mask")
private FiveTupleWithMask fiveTupleWithMask;
@Schema(description = "指令下发次数", accessMode = Schema.AccessMode.READ_ONLY)
@JsonProperty("command_send_times")
private Integer commandSentTimes;
@Schema(description = "指令成功次数", accessMode = Schema.AccessMode.READ_ONLY)
@JsonProperty("command_success_times")
private Integer commandSuccessTimes;
@Schema(description = "首次下发时间", accessMode = Schema.AccessMode.READ_ONLY)
@JsonProperty("earliest_send_times")
private LocalDateTime earliestSendTime;
@Schema(description = "最新下发时间", accessMode = Schema.AccessMode.READ_ONLY)
@JsonProperty("latest_send_times")
private LocalDateTime latestSendTime;
/*
@@ -74,8 +93,10 @@ public class TaskCommandInfo {
*/
@Schema(description = "防御策略模板ID", accessMode = Schema.AccessMode.READ_ONLY)
private Integer templateId;
@Schema(description = "防护等级", accessMode = Schema.AccessMode.READ_ONLY)
private Integer protectLevel;
@Schema(description = "指令所属任务的运行状态", accessMode = Schema.AccessMode.READ_ONLY)
private Integer taskStatus;

View File

@@ -32,7 +32,7 @@ public class GlobalExceptionHandler {
@Order(3)
@ExceptionHandler(value = {Exception.class})
public ResponseResult handleGlobalException(Exception e) {
log.error("遭遇全局异常:" + e.getMessage());
log.error("遭遇全局异常:" + e.getCause());
return ResponseResult.error().setMessage(e.getMessage());
}

View File

@@ -8,7 +8,7 @@ import java.util.List;
@Mapper
public interface CommandMapper {
Boolean createCommand(@Param("info") TaskCommandInfo taskCommandInfo);
void createCommand(@Param("info") TaskCommandInfo taskCommandInfo);
void createCommands(@Param("command_infos") List<TaskCommandInfo> taskCommandInfos);
@@ -18,10 +18,18 @@ public interface CommandMapper {
Boolean startCommandsByTaskId(@Param("task_id") Long taskId);
Boolean setCommandValid(@Param("command_id") String commandId,
@Param("is_valid") Boolean isValid);
Boolean setCommandJudged(@Param("command_id") String commandId,
@Param("is_judged") Boolean isJudged);
List<TaskCommandInfo> queryCommandInfoByTaskId(@Param("task_id") Long taskId);
List<TaskCommandInfo> queryCommandInfos(@Param("task_id") Long taskId,
@Param("src_ip") String sourceIP,
@Param("src_port") String sourcePort,
@Param("dst_ip") String destinationIP,
@Param("dst_port") String destinationPort,
@Param("page") Integer page,
@Param("page_num") Integer pageNum);
TaskCommandInfo queryCommandInfoByUUID(@Param("uuid") String uuid);
String queryCommandInfo(@Param("command_info") TaskCommandInfo commandInfo);
}

View File

@@ -28,6 +28,11 @@ public class CommandService {
@DSTransactional
public String createCommand(TaskCommandInfo commandInfo) {
String uuid = commandMapper.queryCommandInfo(commandInfo);
if (uuid != null) {
return uuid;
}
commandInfo.setUUID(UUID.randomUUID().toString());
commandMapper.createCommand(commandInfo);
return commandInfo.getUUID();
@@ -59,8 +64,14 @@ public class CommandService {
sqlSessionWrapper.startBatchSession(CommandMapper.class, function, taskCommandInfos);
}
public List<TaskCommandInfo> queryCommandInfoByTaskId(Long taskId) {
return commandMapper.queryCommandInfoByTaskId(taskId);
public List<TaskCommandInfo> queryCommandInfos(Long taskId,
String sourceIP, String sourcePort,
String destinationIP, String destinationPort,
Integer page, Integer pageNum) {
return commandMapper.queryCommandInfos(taskId,
sourceIP, sourcePort,
destinationIP, destinationPort,
page, pageNum);
}
public TaskCommandInfo queryCommandInfoByUUID(String uuid) {
@@ -79,9 +90,7 @@ public class CommandService {
return commandMapper.removeCommandsByTaskId(taskId);
}
public Object setCommandValid(String commandId, Boolean isValid) {
return commandMapper.setCommandValid(commandId, isValid);
public Boolean setCommandJudged(String commandId, Boolean isValid) {
return commandMapper.setCommandJudged(commandId, isValid);
}
}

View File

@@ -131,17 +131,26 @@ public class TaskController implements TaskControllerApi {
@Override
@GetMapping("/{taskId}/commands")
public ResponseResult queryCommandInfoByTaskId(@PathVariable Long taskId) {
public ResponseResult queryCommandInfos(@PathVariable Long taskId,
@RequestParam(name = "src_ip", required = false) String sourceIP,
@RequestParam(name = "src_port", required = false) String sourcePort,
@RequestParam(name = "dst_ip", required = false) String destinationIP,
@RequestParam(name = "dst_port", required = false) String destinationPort,
@RequestParam(name = "page") @Min(1) Integer page,
@RequestParam(name = "page_num") @Min(1) Integer pageNum) {
List<TaskCommandInfo> taskCommandInfos = commandService.queryCommandInfos(
taskId, sourceIP, sourcePort, destinationIP, destinationPort, page, pageNum);
return ResponseResult.ok()
.setData("success", true)
.setData("commands", commandService.queryCommandInfoByTaskId(taskId));
.setData("commands", taskCommandInfos);
}
@GetMapping("/{commandId}/valid/{isValid}")
public ResponseResult setCommandValid(@PathVariable Boolean isValid,
@GetMapping("/{commandId}/valid/{isJudged}")
public ResponseResult setCommandJudged(@PathVariable Boolean isJudged,
@PathVariable String commandId) {
return ResponseResult.ok()
.setData("success", commandService.setCommandValid(commandId, isValid))
.setData("success", commandService.setCommandJudged(commandId, isJudged))
.setData("command_id", commandId);
}
}

View File

@@ -437,30 +437,30 @@ public interface TaskControllerApi {
"success": true,
"commands": [
{
"taskAct": "篡改",
"isValid": true,
"fiveTupleWithMask": {
"uuid": "3b42ca64-282f-4040-bd8f-8f895fa82d23",
"task_act": "篡改",
"is_valid": true,
"five_tuple_with_mask": {
"sourceIP": "1.1.2.3",
"sourcePort": "80"
},
"commandSentTimes": 0,
"commandSuccessTimes": 0,
"uuid": "3b42ca64-282f-4040-bd8f-8f895fa82d23"
"command_send_times": 0,
"command_success_times": 0
}
]
}
}
""",
description = """
"taskAct": 任务行为
"task_act": 任务行为
"isValid": 指令是否生效
"is_valid": 指令是否生效
"fiveTupleWithMask": 指令五元组信息
"five_tuple_with_mask": 指令五元组信息
"commandSentTimes": 指令下发次数
"command_send_times": 指令下发次数
"commandSuccessTimes": 指令下发成功次数
"command_success_times": 指令下发成功次数
"uuid": 指令UUID
"""
@@ -469,10 +469,22 @@ public interface TaskControllerApi {
)
},
parameters = {
@Parameter(name = "taskId", description = "任务ID")
@Parameter(name = "taskId", description = "任务ID", example = "733"),
@Parameter(name = "src_ip", description = "源IP", example = "192.168.0.1"),
@Parameter(name = "dst_ip", description = "目的IP"),
@Parameter(name = "src_port", description = "源端口"),
@Parameter(name = "dst_port", description = "目的端口"),
@Parameter(name = "page", description = "页码"),
@Parameter(name = "page_num", description = "每页个数")
}
)
ResponseResult queryCommandInfoByTaskId(@PathVariable Long taskId);
ResponseResult queryCommandInfos(@PathVariable Long taskId,
@RequestParam(name = "src_ip", required = false) String sourceIP,
@RequestParam(name = "src_port", required = false) String sourcePort,
@RequestParam(name = "dst_ip", required = false) String destinationIP,
@RequestParam(name = "dst_port", required = false) String destinationPort,
@RequestParam(name = "page") @Min(1) Integer page,
@RequestParam(name = "page_num") @Min(1) Integer pageNum);
@Operation(
@@ -504,7 +516,7 @@ public interface TaskControllerApi {
)
)
)
@GetMapping("/{commandId}/valid/{isValid}")
ResponseResult setCommandValid(@PathVariable Boolean isValid,
@GetMapping("/{commandId}/valid/{isJudged}")
ResponseResult setCommandJudged(@PathVariable Boolean isJudged,
@PathVariable String commandId);
}

View File

@@ -48,6 +48,7 @@ public class StateHandler {
}
protected Boolean handleResume(CommandService commandService, Long taskId) {
commandService.startCommandsByTaskId(taskId);
return true;
}

View File

@@ -7,7 +7,7 @@
insert into t_command(COMMAND_ID, TASK_ID, TASK_ACT, FREQUENCY, ADDR_TYPE, SRC_IP, SRC_PORT, DST_IP, DST_PORT,
PROTOCOL,
MASK_SRC_IP, MASK_SRC_PORT, MASK_DST_IP, MASK_DST_PORT, MASK_PROTOCOL, VALID_TIME,
INVALID_TIME, IS_VALID,
INVALID_TIME, IS_VALID, IS_JUDGED,
SEND_TIMES, SUCCESS_TIMES, CREATE_TIME, LAST_UPDATE, IS_DELETED)
values (#{info.UUID}, #{info.taskId}, #{info.taskAct}, #{info.frequency},
DEFAULT,
@@ -17,14 +17,15 @@
#{info.fiveTupleWithMask.maskSourceIP}, #{info.fiveTupleWithMask.maskSourcePort},
#{info.fiveTupleWithMask.maskDestinationIP}, #{info.fiveTupleWithMask.maskDestinationPort},
#{info.fiveTupleWithMask.maskProtocol},
#{info.startTime}, #{info.endTime}, #{info.isValid}, 0, 0,
#{info.startTime}, #{info.endTime}, #{info.isValid}, #{info.isJudged},
0, 0,
NOW(), NOW(), FALSE)
</insert>
<insert id="createCommands" parameterType="com.realtime.protection.configuration.entity.task.TaskCommandInfo">
insert into t_command(COMMAND_ID, TASK_ID, TASK_ACT, FREQUENCY, ADDR_TYPE, SRC_IP, SRC_PORT, DST_IP, DST_PORT,
PROTOCOL,
MASK_SRC_IP, MASK_SRC_PORT, MASK_DST_IP, MASK_DST_PORT, MASK_PROTOCOL, VALID_TIME, INVALID_TIME, IS_VALID,
MASK_SRC_IP, MASK_SRC_PORT, MASK_DST_IP, MASK_DST_PORT, MASK_PROTOCOL, VALID_TIME, INVALID_TIME, IS_VALID, IS_JUDGED,
SEND_TIMES, SUCCESS_TIMES, CREATE_TIME, LAST_UPDATE, IS_DELETED)
values
<foreach collection="command_infos" item="info" separator=",">
@@ -36,7 +37,8 @@
#{info.fiveTupleWithMask.maskSourceIP}, #{info.fiveTupleWithMask.maskSourcePort},
#{info.fiveTupleWithMask.maskDestinationIP}, #{info.fiveTupleWithMask.maskDestinationPort},
#{info.fiveTupleWithMask.maskProtocol},
#{info.startTime}, #{info.endTime}, #{info.isValid}, 0, 0,
#{info.startTime}, #{info.endTime}, #{info.isValid}, DEFAULT,
0, 0,
NOW(), NOW(), FALSE
)
</foreach>
@@ -76,7 +78,7 @@
AND IS_DELETED = FALSE
</select>
<select id="queryCommandInfoByTaskId" resultMap="commandStatMap">
<select id="queryCommandInfos" resultMap="commandStatMap">
SELECT COMMAND_ID,
TASK_ACT,
SEND_TIMES,
@@ -89,8 +91,15 @@
DST_PORT,
PROTOCOL
FROM t_command
WHERE TASK_ID = #{task_id}
<where>
AND TASK_ID = #{task_id}
AND IS_DELETED = FALSE
<if test="src_ip != null">AND SRC_IP = #{src_ip}</if>
<if test="dst_ip != null">AND DST_IP = #{dst_ip}</if>
<if test="src_port != null">AND SRC_PORT = #{src_port}</if>
<if test="dst_port != null">AND DST_PORT = #{dst_port}</if>
</where>
LIMIT ${(page-1) * page_num}, #{page_num}
</select>
<update id="stopCommandsByTaskId">
@@ -117,11 +126,48 @@
AND IS_DELETED = FALSE
</update>
<update id="setCommandValid">
<update id="setCommandJudged">
UPDATE t_command
SET IS_VALID = #{is_valid},
SET IS_JUDGED = #{is_judged},
LAST_UPDATE = NOW()
WHERE COMMAND_ID = #{command_id}
AND IS_DELETED = FALSE
</update>
<select id="queryCommandInfo" resultType="java.lang.String">
SELECT COMMAND_ID FROM t_command
<where>
<if test="command_info.taskId != null">AND TASK_ID = #{command_info.taskId}</if>
<if test="command_info.fiveTupleWithMask.sourceIP != null">
AND SRC_IP = #{command_info.fiveTupleWithMask.sourceIP}
</if>
<if test="command_info.fiveTupleWithMask.destinationIP != null">
AND DST_IP = #{command_info.fiveTupleWithMask.destinationIP}
</if>
<if test="command_info.fiveTupleWithMask.sourcePort != null">
AND SRC_PORT = #{command_info.fiveTupleWithMask.sourcePort}
</if>
<if test="command_info.fiveTupleWithMask.destinationPort != null">
AND DST_PORT = #{command_info.fiveTupleWithMask.destinationPort}
</if>
<if test="command_info.fiveTupleWithMask.protocol != null">
AND PROTOCOL = #{command_info.fiveTupleWithMask.protocol}
</if>
<if test="command_info.fiveTupleWithMask.maskSourceIP != null">
AND MASK_SRC_IP = #{command_info.fiveTupleWithMask.maskSourceIP}
</if>
<if test="command_info.fiveTupleWithMask.maskSourcePort != null">
AND MASK_SOURCE_PORT = #{command_info.fiveTupleWithMask.maskSourcePort}
</if>
<if test="command_info.fiveTupleWithMask.maskDestinationIP != null">
AND MASK_DST_IP = #{command_info.fiveTupleWithMask.maskDestinationIP}
</if>
<if test="command_info.fiveTupleWithMask.maskDestinationPort != null">
AND MASK_DST_PORT = #{command_info.fiveTupleWithMask.maskDestinationPort}
</if>
<if test="command_info.fiveTupleWithMask.maskProtocol != null">
AND MASK_PROTOCOL = #{command_info.fiveTupleWithMask.maskProtocol}
</if>
</where>
</select>
</mapper>

View File

@@ -86,7 +86,8 @@ class CommandServiceTest extends ProtectionApplicationTests {
@Test
void queryCommandByUUID() {
List<TaskCommandInfo> taskCommandInfos = commandService.queryCommandInfoByTaskId(30L);
List<TaskCommandInfo> taskCommandInfos = commandService.queryCommandInfos(30L,
null, null, null, null,1, 5);
assertTrue(taskCommandInfos != null && !taskCommandInfos.isEmpty());
for (TaskCommandInfo taskCommandInfo : taskCommandInfos) {