Merge remote-tracking branch 'origin/master'

This commit is contained in:
PushM
2024-04-17 22:16:39 +08:00
32 changed files with 410 additions and 93 deletions

View File

@@ -1,6 +1,7 @@
package com.realtime.protection.configuration.entity.defense.template;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.realtime.protection.configuration.utils.NonEmptyFieldFetcher;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
@@ -40,6 +41,18 @@ public class Template {
@Schema(description = "防御策略模板紧急态字段提取选项")
private ProtectLevel protectLevelHigh;
@JsonProperty("has_protect_level_low")
@Schema(description = "日常态字段是否不空", accessMode = Schema.AccessMode.READ_ONLY)
private Boolean hasProtectLevelLow;
@JsonProperty("has_protect_level_medium")
@Schema(description = "应急态字段是否不空", accessMode = Schema.AccessMode.READ_ONLY)
private Boolean hasProtectLevelMedium;
@JsonProperty("has_protect_level_high")
@Schema(description = "紧急态字段是否不空", accessMode = Schema.AccessMode.READ_ONLY)
private Boolean hasProtectLevelHigh;
@JsonProperty("template_used_times")
@Schema(description = "防御策略模板使用次数", example = "20", accessMode = Schema.AccessMode.READ_ONLY)
private Integer usedTimes;
@@ -59,4 +72,43 @@ public class Template {
@JsonProperty("create_user_depart")
@Schema(description = "防御策略模板创建人处室", example = "xxx", accessMode = Schema.AccessMode.READ_ONLY)
private String createDepart;
/**
* 设置是否含有日常/应急/紧急防护等级态字段的字段
*/
public void setHasProtectLevel() throws IllegalAccessException {
this.hasProtectLevelHigh = hasProtectLevelFields(this.protectLevelHigh);
this.hasProtectLevelMedium = hasProtectLevelFields(this.protectLevelMedium);
this.hasProtectLevelLow = hasProtectLevelFields(this.protectLevelLow);
}
/**
*仅保留是否含有日常/应急/紧急防护等级态字段以及策略模板名称和ID
*/
public void shortenTemplate() {
this.sourceSystem = null;
this.description = null;
this.protectLevelLow = null;
this.protectLevelMedium = null;
this.protectLevelHigh = null;
this.usedTimes = null;
this.runningTasks = null;
this.createUserId = null;
this.createUsername = null;
this.createDepart = null;
}
private Boolean hasProtectLevelFields(ProtectLevel protectLevel) throws IllegalAccessException {
return NonEmptyFieldFetcher
.getNonEmptyFields(protectLevel) // 获取所有非空字段
.stream() // 流式处理
.filter(field -> field.getType().getName().contains("Boolean")) // 获取所有类型为Boolean的字段
.anyMatch(field -> {
try {
return (Boolean) field.get(protectLevel); // 返回值为true的字段
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
});
}
}

View File

@@ -32,7 +32,7 @@ public class GlobalExceptionHandler {
@Order(3)
@ExceptionHandler(value = {Exception.class})
public ResponseResult handleGlobalException(Exception e) {
log.error("遭遇全局异常:" + e.getCause());
log.error("遭遇全局异常:{}", e.getMessage());
return ResponseResult.error().setMessage(e.getMessage());
}
@@ -44,7 +44,7 @@ public class GlobalExceptionHandler {
SQLIntegrityConstraintViolationException.class
})
public ResponseResult handleSQLException(Exception e) {
log.info("遭遇数据库异常:" + e.getMessage());
log.info("遭遇数据库异常:{}", e.getMessage());
return ResponseResult.invalid().setMessage(
"请检查json字段的完整性确保json字段按照文档中要求填写。");
}
@@ -74,14 +74,14 @@ public class GlobalExceptionHandler {
IllegalStateException.class
})
public ResponseResult handleHandlerMethodValidationException(Exception e) {
log.debug("遭遇非法参数异常:" + e.getMessage());
log.debug("遭遇非法参数异常:{}", e.getMessage());
return ResponseResult.invalid().setMessage(e.getMessage());
}
@Order(2)
@ExceptionHandler(value = NotLoginException.class)
public ResponseResult handleNotLoginException(NotLoginException e) {
log.debug("遭遇Sa-Token登录异常登录类型为" + e.getLoginType());
log.debug("遭遇Sa-Token登录异常登录类型为{}", e.getLoginType());
return new ResponseResult(
401,
e.getMessage()
@@ -91,14 +91,14 @@ public class GlobalExceptionHandler {
@Order(2)
@ExceptionHandler(value = SaTokenException.class)
public ResponseResult handleSaTokenException(SaTokenException e) {
log.debug("Sa-token模块遭遇异常" + e.getMessage());
log.debug("Sa-token模块遭遇异常{}", e.getMessage());
return ResponseResult.unAuthorized().setMessage(e.getMessage());
}
@Order(2)
@ExceptionHandler(value = DorisStartException.class)
public ResponseResult handleDorisStartException(DorisStartException e) {
log.warn("Doris数据库遭遇异常" + e.getMessage());
log.warn("Doris数据库遭遇异常{}", e.getMessage());
ResponseResult responseResult = ResponseResult.error()
.setMessage("Doris数据库指令生成遭遇异常" + e.getMessage());

View File

@@ -0,0 +1,30 @@
package com.realtime.protection.configuration.utils;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
public class NonEmptyFieldFetcher {
public static List<Field> getNonEmptyFields(Object object) throws IllegalAccessException {
List<Field> nonEmptyFields = new ArrayList<>();
Class<?> clazz = object.getClass();
// 获取类中所有的字段,包括继承的字段
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
// 打开字段的访问权限
field.setAccessible(true);
// 获取字段的值
Object value = field.get(object);
// 检查字段是否非空
if (value != null) {
nonEmptyFields.add(field);
}
}
return nonEmptyFields;
}
}

View File

@@ -0,0 +1,67 @@
package com.realtime.protection.configuration.utils.enums;
import com.realtime.protection.configuration.entity.rule.staticrule.StaticRuleObject;
import com.realtime.protection.configuration.utils.NonEmptyFieldFetcher;
import java.lang.reflect.Field;
import java.util.*;
public enum RuleEnum {
// 不带掩码规则的五元组规则类型对应表
SIP_SPORT_DIP_PROTOCOL("SIP_SPORT_DIP_PROTOCOL"),
SIP_DIP_DPORT_PROTOCOL("SIP_DIP_DPORT_PROTOCOL"),
SIP_SPORT_PROTOCOL("SIP_SPORT_PROTOCOL"),
SIP_DIP_PROTOCOL("SIP_DIP_PROTOCOL"),
SIP_DPORT_PROTOCOL("SIP_DPORT_PROTOCOL"),
SPORT_DIP_PROTOCOL("SPORT_DIP_PROTOCOL"),
DIP_DPORT_PROTOCOL("DIP_DPORT_PROTOCOL"),
SIP_DIP("SIP_DIP"),
SIP_PROTOCOL("SIP_PROTOCOL"),
DIP_PROTOCOL("DIP_PROTOCOL"),
SIP("SIP"),
DIP("DIP"),
// 带掩码规则的五元组规则类型对应表
DIP_MDIP("DIP_MDIP"),
DIP_MDIP_PROTOCOL_MPROTOCOL("DIP_MDIP_PROTOCOL_MPROTOCOL"),
DIP_MDIP_DPORT_MDPORT_PROTOCOL_MPROTOCOL("DIP_MDIP_DPORT_MDPORT_PROTOCOL_MPROTOCOL"),
SPORT_MSPORT_DIP_MDIP_PROTOCOL_MPROTOCOL("SPORT_MSPORT_DIP_MDIP_PROTOCOL_MPROTOCOL"),
SPORT_MSPORT_DIP_MDIP_DPORT_MDPORT_PROTOCOL_MPROTOCOL("SPORT_MSPORT_DIP_MDIP_DPORT_MDPORT_PROTOCOL_MPROTOCOL"),
SIP_MSIP("SIP_MSIP"),
SIP_MSIP_PROTOCOL_MPROTOCOL("SIP_MSIP_PROTOCOL_MPROTOCOL"),
SIP_MSIP_DPORT_MDPORT_PROTOCOL_MPROTOCOL("SIP_MSIP_DPORT_MDPORT_PROTOCOL_MPROTOCOL"),
SIP_MSIP_SPORT_MSPORT_PROTOCOL_MPROTOCOL("SIP_MSIP_SPORT_MSPORT_PROTOCOL_MPROTOCOL"),
SIP_MSIP_SPORT_MSPORT_DPORT_MDPORT_PROTOCOL_MPROTOCOL("SIP_MSIP_SPORT_MSPORT_DPORT_MDPORT_PROTOCOL_MPROTOCOL"),
SIP_MSIP_DIP_MDIP("SIP_MSIP_DIP_MDIP"),
SIP_MSIP_DIP_MDIP_PROTOCOL_MPROTOCOL("SIP_MSIP_DIP_MDIP_PROTOCOL_MPROTOCOL"),
SIP_MSIP_DIP_MDIP_DPORT_MDPORT_PROTOCOL_MPROTOCOL("SIP_MSIP_DIP_MDIP_DPORT_MDPORT_PROTOCOL_MPROTOCOL"),
SIP_MSIP_SPORT_MSPORT_DIP_MDIP_PROTOCOL_MPROTOCOL("SIP_MSIP_SPORT_MSPORT_DIP_MDIP_PROTOCOL_MPROTOCOL"),
SIP_MSIP_SPORT_MSPORT_DIP_MDIP_DPORT_MDPORT_PROTOCOL_MPROTOCOL("SIP_MSIP_SPORT_MSPORT_DIP_MDIP_DPORT_MDPORT_PROTOCOL_MPROTOCOL")
;
private final Set<String> rule;
private static final List<Set<String>> ruleEnumList = new ArrayList<>();
static {
for (RuleEnum ruleEnum : RuleEnum.values()) {
ruleEnumList.add(ruleEnum.rule);
}
}
RuleEnum(String ruleName) {
this.rule = new HashSet<>(Arrays.stream(ruleName.split("_")).toList());
}
public static Boolean checkValidate(StaticRuleObject staticRuleObject) throws IllegalAccessException {
List<Field> nonEmptyFields = NonEmptyFieldFetcher.getNonEmptyFields(staticRuleObject);
List<String> fieldNames = new java.util.ArrayList<>(List.of());
for (Field field : nonEmptyFields) {
String fieldName = field.getName().toUpperCase().replace("STATICRULE", "");
// 将合理的非空字段加入fieldNames中
// 需要去掉STATICRULE字段仅保留后面的字段
if (fieldName.contains("IP")
|| fieldName.contains("PORT")
|| fieldName.contains("PROTOCOL")) fieldNames.add(fieldName);
}
return ruleEnumList.stream().anyMatch(rule -> rule.equals(new HashSet<>(fieldNames)));
}
}

View File

@@ -1,6 +1,5 @@
package com.realtime.protection.configuration.utils.enums;
import com.realtime.protection.configuration.utils.status.State;
import com.realtime.protection.server.task.status.states.*;
import lombok.Getter;

View File

@@ -0,0 +1,55 @@
package com.realtime.protection.configuration.utils.enums.audit;
import com.realtime.protection.configuration.utils.enums.audit.states.*;
import lombok.Getter;
import java.util.HashMap;
import java.util.Map;
@Getter
public enum AuditStatusEnum {
PENDING(0, new PendingState()), // 未审核状态
RETURNED(1, new ReturnedState()), // 退回状态
AUDITED(2, new AuditedState()), // 已审核状态
USING(3, new UsingState()); // 使用中状态
private final Integer num;
private final State state;
private static final Map<Integer, State> NumToStateMap = new HashMap<>();
private static final Map<State, Integer> StateToNumMap = new HashMap<>();
private static final Map<State, AuditStatusEnum> StateToAuditStatusEnumMap = new HashMap<>();
static {
for (AuditStatusEnum status : AuditStatusEnum.values()) {
NumToStateMap.put(status.getNum(), status.getState());
StateToNumMap.put(status.getState(), status.getNum());
StateToAuditStatusEnumMap.put(status.getState(), status);
}
}
AuditStatusEnum(int auditStatus, State state) {
this.num = auditStatus;
this.state = state;
}
public static State getStateByNum(Integer auditStatusNum) {
if (auditStatusNum == null) {
return null;
}
return NumToStateMap.get(auditStatusNum);
}
public static Integer getNumByState(State state) {
if (state == null) {
return null;
}
return StateToNumMap.get(state);
}
public static AuditStatusEnum getAuditStatusEnumByState(State state) {
if (state == null) {
return null;
}
return StateToAuditStatusEnumMap.get(state);
}
}

View File

@@ -0,0 +1,26 @@
package com.realtime.protection.configuration.utils.enums.audit;
import com.realtime.protection.configuration.utils.enums.audit.states.State;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class AuditStatusValidator {
private final State auditStatusOriginal;
public AuditStatusValidator(Integer auditStatusOriginal) {
this.auditStatusOriginal = AuditStatusEnum.getStateByNum(auditStatusOriginal);
}
public static AuditStatusValidator setOriginal(Integer auditStatusOriginal) {
return new AuditStatusValidator(auditStatusOriginal);
}
public Boolean checkValidate(Integer newAuditStatus) {
State newState = AuditStatusEnum.getStateByNum(newAuditStatus);
if (newState == null) {
return false;
}
return auditStatusOriginal.checkValidate(newState);
}
}

View File

@@ -0,0 +1,13 @@
package com.realtime.protection.configuration.utils.enums.audit.states;
import com.realtime.protection.configuration.utils.enums.audit.AuditStatusEnum;
public class AuditedState implements State {
@Override
public Boolean checkValidate(State newState) {
return switch (AuditStatusEnum.getAuditStatusEnumByState(newState)) {
case RETURNED -> false;
case PENDING, USING, AUDITED -> true;
};
}
}

View File

@@ -0,0 +1,13 @@
package com.realtime.protection.configuration.utils.enums.audit.states;
import com.realtime.protection.configuration.utils.enums.audit.AuditStatusEnum;
public class PendingState implements State {
@Override
public Boolean checkValidate(State newState) {
return switch (AuditStatusEnum.getAuditStatusEnumByState(newState)) {
case USING -> false;
case PENDING, RETURNED, AUDITED -> true;
};
}
}

View File

@@ -0,0 +1,13 @@
package com.realtime.protection.configuration.utils.enums.audit.states;
import com.realtime.protection.configuration.utils.enums.audit.AuditStatusEnum;
public class ReturnedState implements State {
@Override
public Boolean checkValidate(State newState) {
return switch (AuditStatusEnum.getAuditStatusEnumByState(newState)) {
case PENDING, RETURNED -> true;
case AUDITED, USING -> false;
};
}
}

View File

@@ -0,0 +1,5 @@
package com.realtime.protection.configuration.utils.enums.audit.states;
public interface State {
Boolean checkValidate(State newState);
}

View File

@@ -0,0 +1,13 @@
package com.realtime.protection.configuration.utils.enums.audit.states;
import com.realtime.protection.configuration.utils.enums.audit.AuditStatusEnum;
public class UsingState implements State {
@Override
public Boolean checkValidate(State newState) {
return switch (AuditStatusEnum.getAuditStatusEnumByState(newState)) {
case AUDITED, USING -> true;
case PENDING, RETURNED -> false;
};
}
}

View File

@@ -1,18 +0,0 @@
package com.realtime.protection.configuration.utils.status;
import lombok.Getter;
@Getter
public enum AuditStatus {
PENDING(0), // 未审核状态
RETURNED(1), // 退回状态
AUDITED(2), // 已审核状态
DRAFT(3); // 草稿
private final int auditStatus;
AuditStatus(int auditStatus) {
this.auditStatus = auditStatus;
}
}

View File

@@ -1,32 +0,0 @@
package com.realtime.protection.configuration.utils.status;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class AuditStatusValidator {
private final Integer auditStatusOriginal;
public AuditStatusValidator(Integer auditStatusOriginal) {
this.auditStatusOriginal = auditStatusOriginal;
}
public static AuditStatusValidator setOriginal(Integer auditStatusOriginal) {
return new AuditStatusValidator(auditStatusOriginal);
}
public Boolean checkValidate(Integer newAuditStatus) {
switch (newAuditStatus) {
case 0, 1 -> {
return auditStatusOriginal != 2;
}
case 2 -> {
return auditStatusOriginal != 1;
}
default -> {
log.debug("欲修改的审核状态不正确,需要使用正确的审核状态,当前的审核状态:{}", auditStatusOriginal);
return false;
}
}
}
}

View File

@@ -1,9 +0,0 @@
package com.realtime.protection.configuration.utils.status;
import com.realtime.protection.configuration.exception.DorisStartException;
import com.realtime.protection.server.command.CommandService;
import com.realtime.protection.server.task.TaskService;
public interface State {
Boolean handle(State newState, CommandService commandService, TaskService taskService, Long taskId) throws DorisStartException;
}

View File

@@ -1,20 +0,0 @@
package com.realtime.protection.configuration.utils.status;
import lombok.Getter;
@Getter
public enum StateNum {
PENDING(0),
RUNNING(1),
PAUSED(2),
STOPPED(3),
FAILED(4),
FINISHED(5);
private final int stateNum;
StateNum(int stateNum) {
this.stateNum = stateNum;
}
}