Merge remote-tracking branch 'origin/master' into haskafka

This commit is contained in:
PushM
2024-04-25 01:41:56 +08:00
52 changed files with 1132 additions and 84 deletions

View File

@@ -49,6 +49,7 @@ dependencies {
implementation 'com.alibaba:easyexcel:3.3.3'
implementation 'com.baomidou:dynamic-datasource-spring-boot3-starter:4.3.0'
implementation 'com.github.xiaoymin:knife4j-openapi3-jakarta-spring-boot-starter:4.4.0'
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
}
tasks.named('test') {

View File

@@ -1,7 +1,10 @@
package com.realtime.protection.configuration.entity.rule.dynamicrule;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.realtime.protection.configuration.entity.defense.object.ProtectObject;
import com.realtime.protection.configuration.utils.enums.audit.AuditStatusEnum;
import com.realtime.protection.configuration.utils.enums.audit.AuditStatusValidator;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
@@ -95,4 +98,22 @@ public class DynamicRuleObject {
@JsonProperty("log_rule_id")
@Schema(description = "筛选条件-日志规则id", example = "1", requiredMode = Schema.RequiredMode.REQUIRED)
private Long logRuleId;
@JsonProperty("dynamic_rule_audit_status")
@ExcelIgnore
@Schema(description = "动态规则审核状态0为未审核1为已退回2为审核通过", example = "2", accessMode = Schema.AccessMode.READ_ONLY)
private Integer auditStatus;
public void checkAuditStatusValidate(AuditStatusEnum newAuditStatus) {
if (!List.of(AuditStatusEnum.AUDITED.getNum(), AuditStatusEnum.USING.getNum()).contains(this.getAuditStatus())) {
throw new IllegalArgumentException("规则《" + this.getDynamicRuleName() + "》原审批状态非法");
}
if (!AuditStatusValidator
.setOriginal(this.getAuditStatus())
.checkValidate(newAuditStatus.getNum())) {
throw new IllegalArgumentException("规则《" + this.getDynamicRuleName() + "》审核状态错误");
}
}
}

View File

@@ -3,6 +3,8 @@ package com.realtime.protection.configuration.entity.rule.staticrule;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.realtime.protection.configuration.utils.enums.audit.AuditStatusEnum;
import com.realtime.protection.configuration.utils.enums.audit.AuditStatusValidator;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.Max;
import jakarta.validation.constraints.Min;
@@ -14,6 +16,7 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
import java.util.List;
@Data
@Builder
@@ -47,7 +50,7 @@ public class StaticRuleObject {
@JsonProperty("static_rule_audit_status")
@ExcelIgnore
@Schema(description = "静态规则审核状态0为未审核1为已退回2为审核通过", example = "2", accessMode = Schema.AccessMode.READ_ONLY)
private Integer staticRuleAuditStatus;
private Integer auditStatus;
@JsonProperty("static_rule_create_depart")
@ExcelIgnore
@Schema(description = "静态规则创建用户所属部门", accessMode = Schema.AccessMode.READ_ONLY)
@@ -142,4 +145,15 @@ public class StaticRuleObject {
@Schema(description = "频率最低为1", example = "1", requiredMode = Schema.RequiredMode.REQUIRED)
private Integer staticRuleFrequency;
public void checkAuditStatusValidate(AuditStatusEnum newAuditStatus) {
if (!List.of(AuditStatusEnum.AUDITED.getNum(), AuditStatusEnum.USING.getNum()).contains(this.getAuditStatus())) {
throw new IllegalArgumentException("规则《" + this.getStaticRuleName() + "》原审批状态非法");
}
if (!AuditStatusValidator
.setOriginal(this.getAuditStatus())
.checkValidate(newAuditStatus.getNum())) {
throw new IllegalArgumentException("规则《" + this.getStaticRuleName() + "》审核状态错误");
}
}
}

View File

@@ -87,7 +87,9 @@ public class FiveTupleWithMask {
public void setProtocolNum() {
ProtocolEnum protocol = ProtocolEnum.getProtocolEnumByProtocol(this.protocol);
assert protocol != null;
if (protocol == null) {
return;
}
this.protocolNum = protocol.getNumber();
}

View File

@@ -140,10 +140,16 @@ public class TaskCommandInfo {
}
public void setProtocolNum() {
if (this.fiveTupleWithMask == null) {
return;
}
this.fiveTupleWithMask.setProtocolNum();
}
public void setMask() {
if (this.fiveTupleWithMask == null) {
return;
}
this.fiveTupleWithMask.setMask();
}
}

View File

@@ -0,0 +1,17 @@
package com.realtime.protection.configuration.entity.user;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author Yixiang Zhao
**/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AccessTokenResponse {
private String access_token;
private String token_type;
private int expires_in;
}

View File

@@ -2,9 +2,11 @@ package com.realtime.protection.configuration.entity.user;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Long userId;

View File

@@ -0,0 +1,67 @@
package com.realtime.protection.configuration.entity.user;
import java.util.List;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
/**
* @author Yixiang Zhao
**/
public class UserFull {
public String ticket;
public List<Group> groups;
public List<Role> roles;
public List<Org> orgs;
public String mobile;
public String nickName;
public String email;
public String uid;
public String employeeNumber;
public String name;
public List<String> resoures;
public String getOrgCode() {
if (orgs.size() > 0) {
return orgs.get(0).orgCode;
}
return "";
}
public String getRoleKey() {
if (roles.size() > 0) {
return roles.get(0).roleKey;
}
return "";
}
}
class Group {
public int groupId;
public int applicationId;
public String groupKey;
public String groupName;
public String groupTag; // Assume it's a JSON String, otherwise it could be List<Tag> or similar
public String groupRemark;
}
class Role {
public int roleId;
public int applicationId;
public String roleKey;
public String roleName;
public String roleRemark;
public String roleTag; // Same assumption as above
public List<String> res; // Assuming a Resource class exists
public List<String> resources; // Assuming a Resource class exists
}
class Org {
public String orgName;
public String orgDescription;
public int orgParentId;
public String orgCode;
public String orgTag; // Same assumption as above
public int orgId;
public String userOrgworkType;
}

View File

@@ -3,6 +3,7 @@ package com.realtime.protection.server.defense.object;
import com.alibaba.excel.EasyExcel;
import com.realtime.protection.configuration.entity.defense.object.ProtectObject;
import com.realtime.protection.configuration.response.ResponseResult;
import com.realtime.protection.configuration.utils.enums.audit.AuditStatusEnum;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Min;
@@ -149,4 +150,22 @@ public class ProtectObjectController implements ProtectObjectControllerApi {
.addDataMap(protectObjectService.changeProtectObjectAuditStatus(protectObjectId, auditStatus))
.setData("proobj_id", protectObjectId);
}
/*
防护对象数据统计
*/
@Override
@GetMapping("/statistics")
public ResponseResult statisticsProtectObject() {
return ResponseResult.ok()
.setData("proobj_num", protectObjectService.queryProtectObjectsTotalNum(null, null, null, null,
null, null, null, null, null, null))
.setData("proobj_used_num", protectObjectService.queryUsedProtectObjectsTotalNum())
.setData("proobj_audit_num", protectObjectService.queryProtectObjectsTotalNum(null, null, null, null,
null, null, null, null, null,
AuditStatusEnum.getNumByState(AuditStatusEnum.AUDITED.getState())))
.setData("proobj_undit_num", protectObjectService.queryProtectObjectsTotalNum(null, null, null, null,
null, null, null, null, null,
AuditStatusEnum.getNumByState(AuditStatusEnum.PENDING.getState())));
}
}

View File

@@ -408,4 +408,41 @@ public interface ProtectObjectControllerApi {
)
ResponseResult changeProtectObjectAuditStatus(@PathVariable Integer protectObjectId,
@PathVariable Integer auditStatus);
/*
防护对象数据统计
*/
@Operation(
summary = "数据统计",
description = "数据统计",
responses = {
@ApiResponse(
description = "返回数据统计",
content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = ResponseResult.class),
examples = @ExampleObject(
name = "example",
value = """
{
"code": 200,
"message": "request succeed",
"data": {
"proobj_num": 2,
"proobj_used_num": 2,
"proobj_audit_num": 1,
"proobj_undit_num": 0
}
}
"""
)
)
)
},
parameters = {
}
)
@GetMapping("/statistics")
ResponseResult statisticsProtectObject();
}

View File

@@ -1,6 +1,7 @@
package com.realtime.protection.server.defense.object;
import com.realtime.protection.configuration.entity.defense.object.ProtectObject;
import com.realtime.protection.configuration.response.ResponseResult;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@@ -48,4 +49,6 @@ public interface ProtectObjectMapper {
@Param("proobj_audit_status") Integer protectObjectAuditStatus,
@Param("page") Integer page,
@Param("page_size") Integer pageSize);
Integer queryUsedProtectObjectsTotalNum();
}

View File

@@ -2,6 +2,7 @@ package com.realtime.protection.server.defense.object;
import com.alibaba.excel.util.ListUtils;
import com.realtime.protection.configuration.entity.defense.object.ProtectObject;
import com.realtime.protection.configuration.response.ResponseResult;
import com.realtime.protection.configuration.utils.SqlSessionWrapper;
import com.realtime.protection.configuration.utils.enums.audit.AuditStatusEnum;
import com.realtime.protection.configuration.utils.enums.audit.AuditStatusValidator;
@@ -142,4 +143,8 @@ public class ProtectObjectService {
protectObjectCreateUsername, protectObjectAuditStatus
);
}
public Integer queryUsedProtectObjectsTotalNum() {
return protectObjectMapper.queryUsedProtectObjectsTotalNum();
}
}

View File

@@ -2,6 +2,7 @@ package com.realtime.protection.server.defense.template;
import com.realtime.protection.configuration.entity.defense.template.Template;
import com.realtime.protection.configuration.response.ResponseResult;
import com.realtime.protection.configuration.utils.enums.audit.AuditStatusEnum;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Min;
import org.springframework.web.bind.annotation.*;
@@ -112,5 +113,20 @@ public class TemplateController implements TemplateControllerApi {
.setData("template_id", templateService.queryTemplateId(sourceSystem, eventName));
}
/*
策略模板数据统计
*/
@Override
@GetMapping("/statistics")
public ResponseResult statisticsTemplate() {
return ResponseResult.ok()
.setData("template_num", templateService.queryTemplateTotalNum(null, null, null))
.setData("template_used_num", templateService.queryUsedTemplateTotalNum())
.setData("template_audit_num", templateService.queryAuditTemplateTotalNum(
AuditStatusEnum.getNumByState(AuditStatusEnum.AUDITED.getState())
))
.setData("template_unaudit_num", templateService.queryAuditTemplateTotalNum(
AuditStatusEnum.getNumByState(AuditStatusEnum.PENDING.getState())
));
}
}

View File

@@ -438,4 +438,41 @@ public interface TemplateControllerApi {
}
)
ResponseResult queryTemplateId(@RequestBody Map<String, String> map);
/*
策略模板数据统计
*/
@Operation(
summary = "数据统计",
description = "数据统计",
responses = {
@ApiResponse(
description = "返回数据统计",
content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = ResponseResult.class),
examples = @ExampleObject(
name = "example",
value = """
{
"code": 200,
"message": "request succeed",
"data": {
"template_num": 1,
"template_used_num": 1,
"template_audit_num": 0,
"template_unaudit_num": 1
}
}
"""
)
)
)
},
parameters = {
}
)
@GetMapping("/statistics")
ResponseResult statisticsTemplate();
}

View File

@@ -38,4 +38,8 @@ public interface TemplateMapper {
List<String> queryEventName(String sourceSystem);
Integer queryTemplateId(String sourceSystem, String eventName);
Integer queryUsedTemplateTotalNum();
Integer queryAuditTemplateTotalNum(Integer auditState);
}

View File

@@ -79,4 +79,12 @@ public class TemplateService {
public Integer queryTemplateId(String sourceSystem, String eventName) {
return templateMapper.queryTemplateId(sourceSystem, eventName);
}
public Integer queryUsedTemplateTotalNum() {
return templateMapper.queryUsedTemplateTotalNum();
}
public Integer queryAuditTemplateTotalNum(Integer auditState) {
return templateMapper.queryAuditTemplateTotalNum(auditState);
}
}

View File

@@ -2,11 +2,14 @@ package com.realtime.protection.server.rule.dynamicrule;
import com.realtime.protection.configuration.entity.rule.dynamicrule.DynamicRuleObject;
import com.realtime.protection.configuration.response.ResponseResult;
import com.realtime.protection.configuration.utils.enums.audit.AuditStatusEnum;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("dynamicrule")
@@ -19,7 +22,7 @@ public class DynamicRuleController implements DynamicRuleControllerApi {
this.dynamicRuleService = dynamicRuleService;
}
// 新增 要关联防护对象!!!!
//
@Override
@PostMapping("/new")
public ResponseResult newDynamicRuleObject(@RequestBody @Valid DynamicRuleObject dynamicRuleObject) {
@@ -120,6 +123,65 @@ public class DynamicRuleController implements DynamicRuleControllerApi {
//详情查看?? 就是按id查询吧
//审核?不需要
/**
* 审批
*/
@GetMapping("/{id}/audit/{auditStatus}")
public ResponseResult updateDynamicRuleAuditStatus(@PathVariable Integer id, @PathVariable Integer auditStatus) {
if (id <= 0 || auditStatus < 0 || auditStatus > 2) {
return new ResponseResult(400, "id or status is invalid")
.setData("staticRule_id", id)
.setData("success", false);
}
return ResponseResult.ok()
.addDataMap(dynamicRuleService.updateAuditStatus(id, auditStatus))
.setData("dynamicRule_id", id);
}
/**
* 批量审批
*/
@PostMapping("/auditbatch")
public ResponseResult updateDynamicRuleAuditStatusBatch(@RequestBody Map<Integer, Integer> idsWithAuditStatusMap) {
List<Integer> errorIds = new ArrayList<>();
for (Map.Entry<Integer, Integer> entry: idsWithAuditStatusMap.entrySet()) {
Integer id = entry.getKey();
Integer auditStatus = entry.getValue();
if (id <= 0 || auditStatus < 0 || auditStatus > 2) {
errorIds.add(id);
}
}
if (!errorIds.isEmpty()){
return new ResponseResult(400, "id or status is invalid")
.setData("staticRule_id", errorIds)
.setData("success", false);
}
return ResponseResult.ok()
.setData("success", dynamicRuleService.updateAuditStatusBatch(idsWithAuditStatusMap));
}
/**
* 获取统计数据
*/
@Override
@GetMapping("/statistics")
public ResponseResult getStaticRuleStatisticsData(){
return ResponseResult.ok()
.setData("dynamic_rule_num", dynamicRuleService.queryDynamicRuleTotalNum(null, null,
null, null))
.setData("dynamic_rule_used_num", dynamicRuleService.queryAuditDynamicRuleTotalNum(
AuditStatusEnum.getNumByState(AuditStatusEnum.USING.getState())
))
.setData("dynamic_rule_audit_num", dynamicRuleService.queryAuditDynamicRuleTotalNum(
AuditStatusEnum.getNumByState(AuditStatusEnum.AUDITED.getState())
))
.setData("dynamic_rule_unaudit_num", dynamicRuleService.queryAuditDynamicRuleTotalNum(
AuditStatusEnum.getNumByState(AuditStatusEnum.PENDING.getState())
));
}
}

View File

@@ -358,5 +358,37 @@ public interface DynamicRuleControllerApi {
@RequestParam(value = "page", defaultValue = "1") Integer page,
@RequestParam(value = "page_size", defaultValue = "10") Integer pageSize);
@Operation(
summary = "数据统计",
description = "数据统计",
responses = {
@ApiResponse(
description = "返回数据统计",
content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = ResponseResult.class),
examples = @ExampleObject(
name = "example",
value = """
{
"code": 200,
"message": "request succeed",
"data": {
"dynamic_rule_num": 3,
"dynamic_rule_used_num": 0,
"dynamic_rule_audit_num": 2,
"dynamic_rule_unaudit_num": 0
}
}
"""
)
)
)
},
parameters = {
}
)
@GetMapping("/statistics")
ResponseResult getStaticRuleStatisticsData();
}

View File

@@ -7,6 +7,7 @@ import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
@Mapper
public interface DynamicRuleMapper {
@@ -47,4 +48,14 @@ public interface DynamicRuleMapper {
List<DynamicRuleObject> queryDynamicRuleByIds(List<Integer> ids);
Integer queryTaskStatusBydynamicRuleId(Integer dynamicRuleId);
Integer queryUsedDynamicRuleTotalNum();
Integer queryAuditDynamicRuleTotalNum(int auditStatus);
Integer queryAuditStatusById(Integer dynamicRuleId);
Boolean updateAuditStatusById(Integer dynamicRuleId, Integer auditStatus);
void updateAuditStatusByIdBatch(@Param("idWithAuditStatusBatch") Map<Integer, Integer> idWithAuditStatusBatch);
}

View File

@@ -5,11 +5,14 @@ import com.realtime.protection.configuration.entity.defense.template.Template;
import com.realtime.protection.configuration.entity.rule.dynamicrule.DynamicRuleObject;
import com.realtime.protection.configuration.utils.SqlSessionWrapper;
import com.realtime.protection.configuration.utils.enums.StateEnum;
import com.realtime.protection.configuration.utils.enums.audit.AuditStatusValidator;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
@Service
@@ -73,6 +76,9 @@ public class DynamicRuleService {
public void deleteDynamicRuleObject(Integer dynamicRuleId) {
//根据任务状态判断能否删除
Integer taskStatus = dynamicRuleMapper.queryTaskStatusBydynamicRuleId(dynamicRuleId);
if (taskStatus == null){
dynamicRuleMapper.deleteDynamicRuleObject(dynamicRuleId);
}else{
switch (StateEnum.getStateEnumByNum(taskStatus)){
case RUNNING:
throw new IllegalArgumentException("使用该动态规则的任务处于运行状态");
@@ -83,6 +89,8 @@ public class DynamicRuleService {
}
//不需要使用 join,在数据库中设置了级联删除 ON DELETE CASCADE在删除在从父表中删除数据时自动删除子表中的数据
dynamicRuleMapper.deleteDynamicRuleObject(dynamicRuleId);
}
}
@@ -177,4 +185,55 @@ public class DynamicRuleService {
public List<DynamicRuleObject> queryDynamicRuleByIds(List<Integer> ids) {
return dynamicRuleMapper.queryDynamicRuleByIds(ids);
}
public Integer queryUsedDynamicRuleTotalNum() {
return dynamicRuleMapper.queryUsedDynamicRuleTotalNum();
}
public Integer queryAuditDynamicRuleTotalNum(int auditStatus) {
return dynamicRuleMapper.queryAuditDynamicRuleTotalNum(auditStatus);
}
public Map<String, Object> updateAuditStatus(Integer id, Integer auditStatus) {
Integer originalAuditStatus = dynamicRuleMapper.queryAuditStatusById(id);
if (originalAuditStatus == null) {
throw new IllegalArgumentException("cannot find audit status of static rule " + id + ", maybe static rule doesn't exist?");
}
if (!AuditStatusValidator.setOriginal(originalAuditStatus).checkValidate(auditStatus)) {
throw new IllegalArgumentException("invalid audit status");
}
Boolean success = dynamicRuleMapper.updateAuditStatusById(id, auditStatus);
Map<String, Object> resultMap = new HashMap<>();
resultMap.put("success", success);
resultMap.put("audit_status", auditStatus);
return resultMap;
}
public Object updateAuditStatusBatch(Map<Integer, Integer> idsWithAuditStatusMap) {
Function<DynamicRuleMapper, Function<Map<Integer, Integer>, Boolean>> updateDynamicRuleAuditStatusFunction =
mapper -> map -> {
if (map == null || map.isEmpty()) {
return false;
}
Map<Integer, Integer> idWithAuditStatusBatch = new HashMap<>();
for (Map.Entry<Integer, Integer> item : map.entrySet()) {
idWithAuditStatusBatch.put(item.getKey(), item.getValue());
if (idWithAuditStatusBatch.size() < 100) {
continue;
}
//mapper指的就是外层函数输入的参数也就是WhiteListMapper
mapper.updateAuditStatusByIdBatch(idWithAuditStatusBatch);
idWithAuditStatusBatch.clear();
}
if (!idWithAuditStatusBatch.isEmpty()) {
mapper.updateAuditStatusByIdBatch(idWithAuditStatusBatch);
}
return true;
};
//实现事务操作
return sqlSessionWrapper.startBatchSession(DynamicRuleMapper.class, updateDynamicRuleAuditStatusFunction, idsWithAuditStatusMap);
}
}

View File

@@ -4,6 +4,7 @@ package com.realtime.protection.server.rule.staticrule;
import com.alibaba.excel.EasyExcel;
import com.realtime.protection.configuration.entity.rule.staticrule.StaticRuleObject;
import com.realtime.protection.configuration.response.ResponseResult;
import com.realtime.protection.configuration.utils.enums.audit.AuditStatusEnum;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
@@ -178,6 +179,7 @@ public class StaticRuleController implements StaticRuleControllerApi {
/**
* 批量修改审核状态
*/
@Override
@PostMapping("/auditbatch")
public ResponseResult updateStaticRuleAuditStatusBatch(@RequestBody Map<Integer, Integer> idsWithAuditStatusMap) {
List<Integer> errorIds = new ArrayList<>();
@@ -198,6 +200,26 @@ public class StaticRuleController implements StaticRuleControllerApi {
.setData("success", staticRuleService.updateAuditStatusBatch(idsWithAuditStatusMap));
}
/**
* 获取统计数据
*/
@Override
@GetMapping("/statistics")
public ResponseResult getStaticRuleStatisticsData(){
return ResponseResult.ok()
.setData("static_rule_num", staticRuleService.queryStaticRuleTotalNum(null, null, null, null))
.setData("static_rule_used_num", staticRuleService.queryAuditStaticRuleTotalNum(
AuditStatusEnum.getNumByState(AuditStatusEnum.USING.getState())
))
.setData("static_rule_audit_num", staticRuleService.queryAuditStaticRuleTotalNum(
AuditStatusEnum.getNumByState(AuditStatusEnum.AUDITED.getState())
))
.setData("static_rule_unaudit_num", staticRuleService.queryAuditStaticRuleTotalNum(
AuditStatusEnum.getNumByState(AuditStatusEnum.PENDING.getState())));
}
}

View File

@@ -7,18 +7,17 @@ import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.util.List;
import java.util.Map;
@Tag(name = "静态规则API", description = "静态规则模块所有接口")
public interface StaticRuleControllerApi {
@@ -281,4 +280,62 @@ public interface StaticRuleControllerApi {
}
)
ResponseResult updateStaticRuleAuditStatus(@PathVariable Integer id, @PathVariable Integer auditStatus);
@PostMapping("/auditbatch")
@Operation(
summary = "批量更新静态规则审批状态",
description = "批量更新静态规则审批状态0未审核、1审核不通过、2审核通过",
responses = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(
description = "返回静态规则审核结果",
content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = ResponseResult.class)
)
)
},
requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "字典key是静态规则idvalue是静态规则审核状态id",
content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = Map.class)
)
)
)
ResponseResult updateStaticRuleAuditStatusBatch(@RequestBody Map<Integer, Integer> idsWithAuditStatusMap);
@Operation(
summary = "数据统计",
description = "数据统计",
responses = {
@ApiResponse(
description = "返回数据统计",
content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = ResponseResult.class),
examples = @ExampleObject(
name = "example",
value = """
{
"code": 200,
"message": "request succeed",
"data": {
"static_rule_num": 7,
"static_rule_used_num": 2,
"static_rule_audit_num": 3,
"static_rule_unaudit_num": 1
}
}
"""
)
)
)
},
parameters = {
}
)
@GetMapping("/statistics")
ResponseResult getStaticRuleStatisticsData();
}

View File

@@ -46,4 +46,8 @@ public interface StaticRuleMapper {
List<StaticRuleObject> queryStaticRuleByIds(List<Integer> ids);
void updateAuditStatusByIdBatch(@Param("idWithAuditStatusBatch")Map<Integer, Integer> idWithAuditStatusBatch);
Integer queryUsedStaticRuleTotalNum();
Integer queryAuditStaticRuleTotalNum(@Param("auditStatus")Integer auditStatus);
}

View File

@@ -57,7 +57,7 @@ public class StaticRuleService {
public Integer newStaticRuleObject(StaticRuleObject object) {
object.setStaticRuleCreateTime(LocalDateTime.now());
object.setStaticRuleAuditStatus(0);
object.setAuditStatus(0);
/*
待开发:设置静态规则对象的创建用户、用户所属部门等属性
*/
@@ -114,7 +114,7 @@ public class StaticRuleService {
throw new IllegalArgumentException("未知的静态规则ID");
}
if (!staticRuleObject.getStaticRuleAuditStatus().equals(AuditStatusEnum.AUDITED.getNum())) {
if (!staticRuleObject.getAuditStatus().equals(AuditStatusEnum.AUDITED.getNum())) {
throw new IllegalStateException("无法修改该静态规则,因为其审核状态未处于" + AuditStatusEnum.AUDITED);
}
@@ -125,7 +125,7 @@ public class StaticRuleService {
//判断当前静态规则是否能够修改---是否存在任务选择的静态规则??
//按id查询该静态规则的used_task_id字段如果不为空则不能修改
object.setStaticRuleModifyTime(LocalDateTime.now());
object.setStaticRuleAuditStatus(AuditStatusEnum.PENDING.getNum());
object.setAuditStatus(AuditStatusEnum.PENDING.getNum());
//修改静态规则
return staticRuleMapper.updateStaticRule(id, object);
}
@@ -193,14 +193,14 @@ public class StaticRuleService {
return resultMap;
}
@Transactional
public void deleteStaticRuleById(Integer id) {
StaticRuleObject staticRuleObject = staticRuleMapper.queryStaticRuleById(id);
if (staticRuleObject == null) {
return;
}
if (Objects.equals(staticRuleObject.getStaticRuleAuditStatus(), AuditStatusEnum.USING.getNum())) {
if (Objects.equals(staticRuleObject.getAuditStatus(), AuditStatusEnum.USING.getNum())) {
throw new IllegalArgumentException("当前静态规则正在使用,无法删除");
}
staticRuleMapper.deleteStaticRuleById(id);
@@ -242,4 +242,12 @@ public class StaticRuleService {
//实现事务操作
return sqlSessionWrapper.startBatchSession(StaticRuleMapper.class, updateStaticRuleAuditStatusFunction, idsWithAuditStatusMap);
}
public Integer queryUsedStaticRuleTotalNum() {
return staticRuleMapper.queryUsedStaticRuleTotalNum();
}
public Integer queryAuditStaticRuleTotalNum(Integer auditStatus) {
return staticRuleMapper.queryAuditStaticRuleTotalNum(auditStatus);
}
}

View File

@@ -4,6 +4,8 @@ import com.realtime.protection.configuration.entity.task.Task;
import com.realtime.protection.configuration.entity.task.TaskCommandInfo;
import com.realtime.protection.configuration.exception.DorisStartException;
import com.realtime.protection.configuration.response.ResponseResult;
import com.realtime.protection.configuration.utils.enums.StateEnum;
import com.realtime.protection.configuration.utils.enums.audit.AuditStatusEnum;
import com.realtime.protection.server.command.CommandService;
import com.realtime.protection.server.task.status.StateChangeService;
import jakarta.validation.Valid;
@@ -162,6 +164,7 @@ public class TaskController implements TaskControllerApi {
/**
* 批量修改审核状态
*/
@Override
@PostMapping("/auditbatch")
public ResponseResult updateTaskAuditStatusBatch(@RequestBody Map<Integer, Integer> idsWithAuditStatusMap) {
List<Integer> errorIds = new ArrayList<>();
@@ -181,4 +184,20 @@ public class TaskController implements TaskControllerApi {
return ResponseResult.ok()
.setData("success", taskService.updateAuditStatusBatch(idsWithAuditStatusMap));
}
/**
* 统计
*/
@Override
@GetMapping("/statistics")
public ResponseResult statistics() {
return ResponseResult.ok()
.setData("total_num", taskService.queryTaskTotalNum(null, null, null, null))
.setData("running_num", taskService.queryTaskTotalNum(StateEnum.RUNNING.getStateNum(), null, null, null))
.setData("finished_num", taskService.queryTaskTotalNum(StateEnum.FINISHED.getStateNum(), null, null, null))
.setData("unaudit_num", taskService.queryAuditTaskTotalNum(
AuditStatusEnum.PENDING.getNum()
));
}
}

View File

@@ -17,6 +17,8 @@ import jakarta.validation.constraints.Min;
import jakarta.validation.constraints.NotNull;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@Tag(name = "任务控制器API", description = "任务管理模块相关的所有接口")
public interface TaskControllerApi {
@PostMapping("/new")
@@ -521,4 +523,71 @@ public interface TaskControllerApi {
@GetMapping("/{commandId}/valid/{isJudged}")
ResponseResult setCommandJudged(@PathVariable Boolean isJudged,
@PathVariable String commandId);
@Operation(
summary = "批量更新任务审批状态",
description = "批量更新任务审批状态0未审核、1审核不通过、2审核通过",
responses = {
@io.swagger.v3.oas.annotations.responses.ApiResponse(
description = "返回任务审核结果",
content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = ResponseResult.class)
)
)
},
requestBody = @io.swagger.v3.oas.annotations.parameters.RequestBody(
description = "字典key是任务idvalue是任务审核状态id",
content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = Map.class)
)
)
)
@PostMapping("/auditbatch")
ResponseResult updateTaskAuditStatusBatch(@RequestBody Map<Integer, Integer> idsWithAuditStatusMap);
@Operation(
summary = "数据统计",
description = "数据统计",
responses = {
@ApiResponse(
description = "返回数据统计",
content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = ResponseResult.class),
examples = @ExampleObject(
name = "example",
value = """
{
"code": 200,
"message": "request succeed",
"data": {
"total_num": 11,
"running_num": 2,
"finished_num": 5,
"unaudit_num": 5
}
}
""",
description = """
"total_num": 总数
"running_num": 运行任务数
"finished_num": 结束任务数
"unaudit_num": 未审核数
"""
)
)
)
},
parameters = {
}
)
@GetMapping("/statistics")
ResponseResult statistics();
}

View File

@@ -61,4 +61,6 @@ public interface TaskMapper {
@Param("task_name") String taskName, @Param("task_creator") String taskCreator);
void updateAuditStatusByIdBatch(@Param("idWithAuditStatusBatch") Map<Integer, Integer> idWithAuditStatusBatch);
Integer queryAuditTaskTotalNum(Integer auditState);
}

View File

@@ -1,6 +1,9 @@
package com.realtime.protection.server.task;
import com.alibaba.excel.util.MapUtils;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.realtime.protection.configuration.entity.rule.dynamicrule.DynamicRuleObject;
import com.realtime.protection.configuration.entity.rule.staticrule.StaticRuleObject;
import com.realtime.protection.configuration.entity.task.DynamicTaskInfo;
import com.realtime.protection.configuration.entity.task.Task;
import com.realtime.protection.configuration.entity.task.TaskCommandInfo;
@@ -8,6 +11,8 @@ import com.realtime.protection.configuration.utils.SqlSessionWrapper;
import com.realtime.protection.configuration.utils.enums.StateEnum;
import com.realtime.protection.configuration.utils.enums.audit.AuditStatusEnum;
import com.realtime.protection.configuration.utils.enums.audit.AuditStatusValidator;
import com.realtime.protection.server.rule.dynamicrule.DynamicRuleMapper;
import com.realtime.protection.server.rule.staticrule.StaticRuleMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -17,17 +22,23 @@ import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
@Service
@Slf4j
@DS("mysql")
public class TaskService {
private final TaskMapper taskMapper;
private final StaticRuleMapper staticRuleMapper;
private final SqlSessionWrapper sqlSessionWrapper;
private static final int BATCH_SIZE = 100;
private final DynamicRuleMapper dynamicRuleMapper;
public TaskService(TaskMapper taskMapper,SqlSessionWrapper sqlSessionWrapper) {
public TaskService(TaskMapper taskMapper, StaticRuleMapper staticRuleMapper, SqlSessionWrapper sqlSessionWrapper, DynamicRuleMapper dynamicRuleMapper) {
this.taskMapper = taskMapper;
this.staticRuleMapper = staticRuleMapper;
this.sqlSessionWrapper = sqlSessionWrapper;
this.dynamicRuleMapper = dynamicRuleMapper;
}
@Transactional
@@ -36,19 +47,146 @@ public class TaskService {
task.setTaskCreateUsername("xxx");
task.setTaskCreateDepart("xxx");
// todo: 添加新建任务时,将动态/静态规则从“已审核”修改为“使用中”
taskMapper.newTask(task);
if (task.getStaticRuleIds() != null && !task.getStaticRuleIds().isEmpty())
if (task.getStaticRuleIds() != null && !task.getStaticRuleIds().isEmpty()) {
staticRuleMapper.queryStaticRuleByIds(task.getStaticRuleIds()).forEach(staticRuleObject -> {
if (!staticRuleObject.getAuditStatus().equals(AuditStatusEnum.AUDITED.getNum())) {
throw new IllegalArgumentException("部分规则审批状态错误");
}
if (staticRuleObject.getStaticRuleUsedTaskId() != null) {
throw new IllegalArgumentException("部分静态规则已被其他任务使用");
}
});
taskMapper.newTaskStaticRuleConcat(task.getTaskId(), task.getStaticRuleIds());
}
if (task.getDynamicRuleIds() != null && !task.getDynamicRuleIds().isEmpty())
if (task.getDynamicRuleIds() != null && !task.getDynamicRuleIds().isEmpty()) {
dynamicRuleMapper.queryDynamicRuleByIds(task.getDynamicRuleIds()).forEach(dynamicRuleObject -> {
if (!dynamicRuleObject.getAuditStatus().equals(AuditStatusEnum.AUDITED.getNum())) {
throw new IllegalArgumentException("部分规则审批状态错误");
}
if (dynamicRuleObject.getDynamicRuleUsedTaskId() != null) {
throw new IllegalArgumentException("部分动态规则已被其他任务使用");
}
});
taskMapper.newTaskDynamicRuleConcat(task.getTaskId(), task.getDynamicRuleIds());
}
return task.getTaskId();
}
/**
* 更新任务关联的静态规则审批状态,用于任务新建/停止时候,修改审批状态为已使用/已审批,不能用于其他审批状态修改
* @param taskId 与静态规则关联的任务ID
* @param newAuditStatus 需要修改的审批状态
*/
public void updateStaticRuleAuditStatusInTask(Long taskId, AuditStatusEnum newAuditStatus) {
if (taskId == null) {
return;
}
// 限制该函数仅能用于将规则修改为已审批/使用中
if (!List.of(AuditStatusEnum.AUDITED, AuditStatusEnum.USING).contains(newAuditStatus)) {
return;
}
List<StaticRuleObject> staticRuleObjects = staticRuleMapper.queryStaticRuleByIds(taskMapper.queryDynamicRuleIdsFromTaskId(taskId));
if (staticRuleObjects == null || staticRuleObjects.isEmpty()) {
throw new IllegalArgumentException("静态规则列表中的ID不存在请检查静态规则是否真实存在");
}
// 检查所有的静态规则审批状态是否正确,如果不正确则报错
staticRuleObjects.forEach(staticRuleObject -> staticRuleObject.checkAuditStatusValidate(newAuditStatus));
Map<Integer, Integer> staticRuleAuditStatusBatch = staticRuleObjects
.stream()
.collect(Collectors.toMap(
StaticRuleObject::getStaticRuleId,
k -> newAuditStatus.getNum(), // 将审核状态全部修改为使用中状态
(existing, replacement) -> existing)); // 如果有重复字段,默认使用先前值
sqlSessionWrapper.startBatchSession(
StaticRuleMapper.class,
(Function<StaticRuleMapper, Function<Map<Integer, Integer>, Void>>) mapper -> staticRuleBatch -> {
Map<Integer, Integer> batchMap = MapUtils.newHashMapWithExpectedSize(BATCH_SIZE);
for (Map.Entry<Integer, Integer> auditStatusEntry : staticRuleBatch.entrySet()) {
batchMap.put(auditStatusEntry.getKey(), auditStatusEntry.getValue());
if (batchMap.size() < BATCH_SIZE) {
continue;
}
mapper.updateAuditStatusByIdBatch(batchMap);
batchMap.clear();
}
mapper.updateAuditStatusByIdBatch(batchMap);
batchMap.clear();
return null;
},
staticRuleAuditStatusBatch
);
}
/**
* 更新任务关联的动态规则审批状态,用于任务新建/停止时候,修改审批状态为已使用/已审批,不能用于其他审批状态修改
* @param taskId 与动态规则关联的任务ID
* @param newAuditStatus 需要修改的审批状态
*/
public void updateDynamicRuleAuditStatusInTask(Long taskId, AuditStatusEnum newAuditStatus) {
if (taskId == null) {
return;
}
// 限制该函数仅能用于将规则修改为已审批/使用中
if (!List.of(AuditStatusEnum.AUDITED, AuditStatusEnum.USING).contains(newAuditStatus)) {
return;
}
List<DynamicRuleObject> dynamicRuleObjects = dynamicRuleMapper.queryDynamicRuleByIds(taskMapper.queryDynamicRuleIdsFromTaskId(taskId));
if (dynamicRuleObjects == null || dynamicRuleObjects.isEmpty()) {
throw new IllegalArgumentException("静态规则列表中的ID不存在请检查静态规则是否真实存在");
}
// 检查所有的动态规则列表的审批状态是否正确,如不正确则报错
dynamicRuleObjects.forEach(dynamicRuleObject -> dynamicRuleObject.checkAuditStatusValidate(newAuditStatus));
Map<Integer, Integer> dynamicRuleAuditStatusBatch = dynamicRuleObjects
.stream()
.collect(Collectors.toMap(
DynamicRuleObject::getDynamicRuleId,
k -> newAuditStatus.getNum(),
(existing, replacement) -> existing));
sqlSessionWrapper.startBatchSession(
DynamicRuleMapper.class,
(Function<DynamicRuleMapper, Function<Map<Integer, Integer>, Void>>) mapper -> batch -> {
Map<Integer, Integer> batchMap = MapUtils.newHashMapWithExpectedSize(BATCH_SIZE);
for (Map.Entry<Integer, Integer> auditStatusEntry : batch.entrySet()) {
batchMap.put(auditStatusEntry.getKey(), auditStatusEntry.getValue());
if (batchMap.size() < BATCH_SIZE) {
continue;
}
mapper.updateAuditStatusByIdBatch(batchMap);
batchMap.clear();
}
mapper.updateAuditStatusByIdBatch(batchMap);
batchMap.clear();
return null;
},
dynamicRuleAuditStatusBatch
);
}
@Transactional
public List<Task> queryTasks(Integer taskStatus,
Integer taskType, String taskName, String taskCreator,
@@ -116,6 +254,15 @@ public class TaskService {
}
public Boolean deleteTask(Long taskId) {
Task task = taskMapper.queryTask(taskId);
if (task == null) {
return true;
}
updateStaticRuleAuditStatusInTask(taskId, AuditStatusEnum.AUDITED);
updateDynamicRuleAuditStatusInTask(taskId, AuditStatusEnum.AUDITED);
taskMapper.clearTaskConnectedStaticRule(task.getTaskId());
taskMapper.clearTaskConnectedDynamicRule(task.getTaskId());
return taskMapper.deleteTask(taskId);
}
@@ -187,4 +334,8 @@ public class TaskService {
}
public Integer queryAuditTaskTotalNum(Integer auditState) {
return taskMapper.queryAuditTaskTotalNum(auditState);
}
}

View File

@@ -36,14 +36,14 @@ public class StateHandler {
}
// 如果审核状态不为已通过审核,则报错
if (taskAuditStatus != AuditStatusEnum.AUDITED.getNum()) {
if (!taskAuditStatus.equals(AuditStatusEnum.AUDITED.getNum())) {
throw new IllegalArgumentException("无效的task_id因为未通过审核");
}
return switch (TaskTypeEnum.getTaskTypeByNum(task.getTaskType())) {
case STATIC -> handleStaticTaskStart(commandService, taskService, taskId);
case DYNAMIC -> handleDynamicTaskStart(taskService, taskId);
case JUDGED -> handleJudgedTaskStart(taskService, taskId);
case STATIC -> handleStaticTaskStart(commandService, taskService, task);
case DYNAMIC -> handleDynamicTaskStart(taskService, task);
case JUDGED -> handleJudgedTaskStart(taskService, task);
};
}
@@ -57,49 +57,61 @@ public class StateHandler {
return true;
}
protected Boolean handleStop(CommandService commandService, Long taskId) {
protected Boolean handleStop(CommandService commandService, TaskService taskService, Long taskId) {
commandService.removeCommandsByTaskId(taskId);
taskService.updateDynamicRuleAuditStatusInTask(taskId, AuditStatusEnum.AUDITED);
taskService.updateStaticRuleAuditStatusInTask(taskId, AuditStatusEnum.AUDITED);
return true;
}
protected Boolean handleFinish(CommandService commandService, Long taskId) {
protected Boolean handleFinish(CommandService commandService, TaskService taskService, Long taskId) {
commandService.removeCommandsByTaskId(taskId);
taskService.updateDynamicRuleAuditStatusInTask(taskId, AuditStatusEnum.AUDITED);
taskService.updateStaticRuleAuditStatusInTask(taskId, AuditStatusEnum.AUDITED);
return true;
}
protected Boolean handleFailed(CommandService commandService, Long taskId) {
protected Boolean handleFailed(CommandService commandService, TaskService taskService, Long taskId) {
commandService.removeCommandsByTaskId(taskId);
taskService.updateDynamicRuleAuditStatusInTask(taskId, AuditStatusEnum.AUDITED);
taskService.updateStaticRuleAuditStatusInTask(taskId, AuditStatusEnum.AUDITED);
return true;
}
// todo: 如果是实时任务或者研判后处置任务,那么就需要在任务启动之后,立刻向动态规则中指定的系统发送日志筛选请求。
// 筛选完成后,系统返回日志,需要由接收端点提取字段,并且合成一条静态规则,再按照任务开始时间、结束时间和任务类型进行指令创建
private Boolean handleJudgedTaskStart(TaskService taskService, Long taskId) {
return sendFilters(taskService, taskId);
private Boolean handleJudgedTaskStart(TaskService taskService, Task task) {
return sendFilters(taskService, task);
}
private Boolean handleDynamicTaskStart(TaskService taskService, Long taskId) {
return sendFilters(taskService, taskId);
private Boolean handleDynamicTaskStart(TaskService taskService, Task task) {
return sendFilters(taskService, task);
}
private Boolean handleStaticTaskStart(CommandService commandService, TaskService taskService, Long taskId) {
private Boolean handleStaticTaskStart(CommandService commandService, TaskService taskService, Task task) {
// 如果未能获取staticTaskCommandInfos需要报错
List<TaskCommandInfo> staticTaskCommandInfos = taskService.getStaticCommandInfos(taskId);
List<TaskCommandInfo> staticTaskCommandInfos = taskService.getStaticCommandInfos(task.getTaskId());
if (staticTaskCommandInfos == null || staticTaskCommandInfos.isEmpty()) {
throw new IllegalArgumentException("静态规则列表为空,请至少选择一个静态规则以启动任务");
}
// 将所有关联的静态规则全部设置为已使用状态
taskService.updateStaticRuleAuditStatusInTask(task.getTaskId(), AuditStatusEnum.USING);
commandService.createCommands(staticTaskCommandInfos);
return true;
}
private Boolean sendFilters(TaskService taskService, Long taskId) {
List<DynamicTaskInfo> dynamicTaskInfos = taskService.getDynamicTaskInfos(taskId);
private Boolean sendFilters(TaskService taskService, Task task) {
List<DynamicTaskInfo> dynamicTaskInfos = taskService.getDynamicTaskInfos(task.getTaskId());
if (dynamicTaskInfos == null || dynamicTaskInfos.isEmpty()) {
throw new IllegalArgumentException("动态规则列表为空,请至少选择一个动态规则以启动动态/研判后类型任务");
}
taskService.updateDynamicRuleAuditStatusInTask(task.getTaskId(), AuditStatusEnum.AUDITED);
AtomicReference<Boolean> success = new AtomicReference<>(false);
Mono<SimpleResponse> mono = client.post()

View File

@@ -11,8 +11,8 @@ public class FailedState extends StateHandler implements State {
public Boolean handle(State newState, CommandService commandService, TaskService taskService, Long taskId) throws DorisStartException {
return switch (StateEnum.getStateEnumByState(newState)) {
case RUNNING -> handleStart(taskService, commandService, taskId);
case STOP -> handleStop(commandService, taskId);
case FINISHED -> handleFinish(commandService, taskId);
case STOP -> handleStop(commandService, taskService, taskId);
case FINISHED -> handleFinish(commandService, taskService, taskId);
default -> throw new IllegalStateException("Unexpected value: " + StateEnum.getStateEnumByState(newState));
};
}

View File

@@ -1,11 +1,16 @@
package com.realtime.protection.server.task.status.states;
import com.realtime.protection.configuration.utils.enums.StateEnum;
import com.realtime.protection.server.command.CommandService;
import com.realtime.protection.server.task.TaskService;
import com.realtime.protection.server.task.status.StateHandler;
public class FinishedState implements State {
public class FinishedState extends StateHandler implements State {
@Override
public Boolean handle(State newState, CommandService commandService, TaskService taskService, Long taskId) {
return newState instanceof FinishedState;
return switch (StateEnum.getStateEnumByState(newState)) {
case PENDING, FINISHED -> true;
default -> throw new IllegalStateException("Unexpected value: " + StateEnum.getStateEnumByState(newState));
};
}
}

View File

@@ -10,8 +10,8 @@ public class GeneratingState extends StateHandler implements State {
public Boolean handle(State newState, CommandService commandService, TaskService taskService, Long taskId) {
return switch (StateEnum.getStateEnumByState(newState)) {
case RUNNING -> true;
case FAILED -> handleFailed(commandService, taskId);
case FINISHED -> handleFinish(commandService, taskId);
case FAILED -> handleFailed(commandService, taskService, taskId);
case FINISHED -> handleFinish(commandService, taskService, taskId);
default -> throw new IllegalStateException("Unexpected value: " + StateEnum.getStateEnumByState(newState));
};
}

View File

@@ -10,9 +10,9 @@ public class PauseState extends StateHandler implements State {
public Boolean handle(State newState, CommandService commandService, TaskService taskService, Long taskId) {
return switch (StateEnum.getStateEnumByState(newState)) {
case RUNNING -> handleResume(commandService, taskId);
case STOP -> handleStop(commandService, taskId);
case FINISHED -> handleFinish(commandService, taskId);
case FAILED -> handleFailed(commandService, taskId);
case STOP -> handleStop(commandService, taskService, taskId);
case FINISHED -> handleFinish(commandService, taskService, taskId);
case FAILED -> handleFailed(commandService, taskService, taskId);
default -> throw new IllegalStateException("Unexpected value: " + StateEnum.getStateEnumByState(newState));
};
}

View File

@@ -10,9 +10,9 @@ public class PendingState extends StateHandler implements State {
@Override
public Boolean handle(State newState, CommandService commandService, TaskService taskService, Long taskId) throws DorisStartException {
return switch (StateEnum.getStateEnumByState(newState)) {
case FAILED -> handleFailed(commandService, taskId);
case FAILED -> handleFailed(commandService, taskService, taskId);
case RUNNING -> handleStart(taskService, commandService, taskId);
case FINISHED -> handleFinish(commandService, taskId);
case FINISHED -> handleFinish(commandService, taskService, taskId);
default -> throw new IllegalStateException(taskId + " meets unexpected value: "
+ StateEnum.getStateEnumByState(newState));
};

View File

@@ -10,9 +10,9 @@ public class RunningState extends StateHandler implements State {
public Boolean handle(State newState, CommandService commandService, TaskService taskService, Long taskId) {
return switch (StateEnum.getStateEnumByState(newState)) {
case PAUSED -> handlePause(commandService, taskId);
case STOP -> handleStop(commandService, taskId);
case FINISHED -> handleFinish(commandService, taskId);
case FAILED -> handleFailed(commandService, taskId);
case STOP -> handleStop(commandService, taskService, taskId);
case FINISHED -> handleFinish(commandService, taskService, taskId);
case FAILED -> handleFailed(commandService, taskService, taskId);
default -> throw new IllegalStateException("Unexpected value: " + StateEnum.getStateEnumByState(newState));
};
}

View File

@@ -12,8 +12,8 @@ public class StopState extends StateHandler implements State {
public Boolean handle(State newState, CommandService commandService, TaskService taskService, Long taskId) throws DorisStartException {
return switch (StateEnum.getStateEnumByState(newState)) {
case RUNNING -> handleStart(taskService, commandService, taskId);
case FAILED -> handleFailed(commandService, taskId);
case FINISHED -> handleFinish(commandService, taskId);
case FAILED -> handleFailed(commandService, taskService, taskId);
case FINISHED -> handleFinish(commandService, taskService, taskId);
default -> throw new IllegalStateException("Unexpected value: " + StateEnum.getStateEnumByState(newState));
};
}

View File

@@ -1,11 +1,22 @@
package com.realtime.protection.server.user.login;
import com.realtime.protection.configuration.entity.user.User;
import com.realtime.protection.configuration.response.ResponseResult;
import org.springframework.web.bind.annotation.*;
import javax.security.auth.login.LoginException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.realtime.protection.configuration.entity.user.User;
import com.realtime.protection.configuration.entity.user.UserFull;
import com.realtime.protection.configuration.response.ResponseResult;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
// Just for example, not in production environment
@RestController
@RequestMapping("/user")
@@ -36,10 +47,29 @@ public class LoginController {
@PostMapping("/auth")
public ResponseResult auth(@RequestParam("sessionData") String sessionData,
@RequestParam("accessToken") String accessToken,
@Autowired HttpServletRequest request,
@RequestParam(value = "scopes", required = false) String scopes) {
try {
UserFull userFull = loginService.loginWithSSO(sessionData);
if (userFull == null) {
throw new LoginException("登录失败,无法获取用户信息");
}
// 设置 session
HttpSession session = request.getSession();
session.setAttribute("user", userFull);
// 返回结果
return ResponseResult.ok().setMessage("success")
.setData("success", true);
.setData("userId", userFull.uid)
.setData("userName", userFull.name)
.setData("userRole", userFull.getRoleKey());
} catch (Exception e) {
return ResponseResult.error(e.getMessage());
}
}
@GetMapping("/auth_redirect")
public String authRedirect(@RequestParam(value = "SESSION_DATA", required = false) String sessionData) {
System.out.println("SESSION_DATA: " + sessionData);
return "";
}
}

View File

@@ -1,11 +1,26 @@
package com.realtime.protection.server.user.login;
import cn.dev33.satoken.stp.StpUtil;
import com.realtime.protection.configuration.entity.user.User;
import org.springframework.stereotype.Service;
import org.apache.logging.log4j.util.Strings;
import javax.security.auth.login.LoginException;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.realtime.protection.configuration.entity.user.AccessTokenResponse;
import com.realtime.protection.configuration.entity.user.User;
import com.realtime.protection.configuration.entity.user.UserFull;
import cn.dev33.satoken.stp.StpUtil;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import io.micrometer.common.util.StringUtils;
@Service
// just for example, not for production environment
public class LoginService {
@@ -28,4 +43,59 @@ public class LoginService {
StpUtil.login(userId);
return userId;
}
public UserFull loginWithSSO(String sessionData) throws LoginException {
String accessToken = "";
// 获取 ACCESS_TOKEN
ObjectMapper objectMapper = new ObjectMapper();
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://114.243.134.122:9217/passport/accessToken?grant_type=client_credentials")
.header("Authorization", "Basic TlNBRERAWlguT1JHOk14a1hHZ1ltOUNROUE3TCRSOCNLRW02R1pSeEhwd1c2")
.post(okhttp3.internal.Util.EMPTY_REQUEST)
.build();
try {
Response response = client.newCall(request).execute();
String rsp = response.body().string();
try {
AccessTokenResponse atr = objectMapper.readValue(rsp, AccessTokenResponse.class);
accessToken = atr.getAccess_token();
} catch (Exception e) {
throw new LoginException("解析 ACCESS_TOKEN 失败");
}
} catch (Exception e) {
e.printStackTrace();
throw new LoginException("获取 ACCESS_TOKEN 失败,网络请求错误");
}
if (Strings.isBlank(accessToken)) {
throw new LoginException("获取 ACCESS_TOKEN 失败");
}
// 校验 SESSION_DATA
RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("sessionData", sessionData).build();
request = new Request.Builder()
.url("http://114.243.134.122:9217/passport/accessApplication")
.header("Authorization", "Bearer " + accessToken)
.header("Content-Type", "application/x-www-form-urlencoded")
.post(body)
.build();
try {
Response response = client.newCall(request).execute();
String rsp = response.body().string();
// System.out.println("user: " + rsp);
if (StringUtils.isBlank(rsp)) {
throw new LoginException("解析用户数据为空");
}
try {
UserFull userFull = objectMapper.readValue(rsp, UserFull.class);
return userFull;
} catch (Exception e) {
e.printStackTrace();
throw new LoginException("解析 ACCESS_TOKEN 失败");
}
} catch (Exception e) {
e.printStackTrace();
throw new LoginException("校验 SESSION_DATA 失败");
}
}
}

View File

@@ -3,6 +3,7 @@ package com.realtime.protection.server.whitelist;
import com.alibaba.excel.EasyExcel;
import com.realtime.protection.configuration.entity.whitelist.WhiteListObject;
import com.realtime.protection.configuration.response.ResponseResult;
import com.realtime.protection.configuration.utils.enums.audit.AuditStatusEnum;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.*;
@@ -194,5 +195,21 @@ public class WhiteListController implements WhiteListControllerApi {
.setData("whiteobj_list", whiteListService.whiteListStaticRulesCheck(staticRuleIds));
}
/*
白名单数据统计
*/
@Override
@GetMapping("/statistics")
public ResponseResult getWhiteListStatisticsData() {
return ResponseResult.ok()
.setData("whiteobj_num", whiteListService.queryWhiteListTotalNum(null, null))
.setData("whiteobj_audit_num", whiteListService.queryAuditWhiteListTotalNum(
AuditStatusEnum.getNumByState(AuditStatusEnum.AUDITED.getState())
))
.setData("whiteobj_unaudit_num", whiteListService.queryAuditWhiteListTotalNum(
AuditStatusEnum.getNumByState(AuditStatusEnum.PENDING.getState())
));
}
}

View File

@@ -7,8 +7,10 @@ import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.ExampleObject;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
@@ -240,4 +242,51 @@ public interface WhiteListControllerApi {
}
)
ResponseResult whiteListStaticRulesCheck(@PathVariable List<Integer> staticRuleIds);
/*
白名单数据统计
*/
@Operation(
summary = "白名单数据统计",
description = "白名单数据统计",
responses = {
@ApiResponse(
description = "返回白名单数据统计",
content = @Content(
mediaType = "application/json",
schema = @Schema(implementation = ResponseResult.class),
examples = @ExampleObject(
name = "example",
value = """
{
"code": 200,
"message": "request succeed",
"data": {
"proobj_num": 2,
"proobj_used_num": 2,
"proobj_audit_num": 1,
"proobj_undit_num": 0
}
}
""",
description = """
"proobj_num": 白名单总数
"template_name": 白名单使用数
"proobj_audit_num": 审核通过数
"proobj_undit_num": 未审核数
"""
)
)
)
},
parameters = {
}
)
@GetMapping("/statistics")
ResponseResult getWhiteListStatisticsData();
}

View File

@@ -45,4 +45,6 @@ public interface WhiteListMapper {
List<WhiteListObject> whiteListCommandsCheck(List<TaskCommandInfo> taskCommandInfos);
List<WhiteListObject> whiteListCStaticRulesCheck(@Param("staticRuleObjects") List<StaticRuleObject> staticRuleObjects);
Integer queryAuditWhiteListTotalNum(@Param("auditStatus") Integer auditStatus);
}

View File

@@ -185,4 +185,7 @@ public class WhiteListService {
}
public Integer queryAuditWhiteListTotalNum(Integer auditStatus) {
return whiteListMapper.queryAuditWhiteListTotalNum(auditStatus);
}
}

View File

@@ -101,6 +101,26 @@
where
dynamic_rule_id = #{dynamicRuleId}
</update>
<update id="updateAuditStatusById">
update t_dynamic_rule
set audit_status = #{auditStatus}
where dynamic_rule_id = #{dynamicRuleId}
</update>
<!-- 用于批量更新审核状态 -->
<update id="updateAuditStatusByIdBatch">
update t_dynamic_rule
set audit_status = CASE dynamic_rule_id
<foreach collection="idWithAuditStatusBatch" index="id" item="auditStatus" separator=" ">
WHEN #{id} THEN #{auditStatus}
</foreach>
ELSE audit_status
END
WHERE dynamic_rule_id IN
<foreach collection="idWithAuditStatusBatch" index="id" open="(" separator="," close=")">
#{id}
</foreach>
</update>
<resultMap id="dynamicRuleMap"
@@ -133,6 +153,7 @@
<!-- <result column="protect_object_id" property="protectObjectIds"/>-->
<result column="strategy_template_name" property="dynamicRuleEventType"/>
<result column="strategy_template_source_system" property="dynamicRuleSourceSystem"/>
<result column="audit_status" property="auditStatus"/>
</resultMap>
<select id="queryDynamicRuleById" resultMap="dynamicRuleMap">
@@ -248,5 +269,19 @@
where dynamic_rule_id = #{dynamicRuleId}
</select>
<select id="queryUsedDynamicRuleTotalNum" resultType="java.lang.Integer">
</select>
<select id="queryAuditDynamicRuleTotalNum" resultType="java.lang.Integer">
select count(*)
from t_dynamic_rule
where audit_status = #{auditStatus}
</select>
<select id="queryAuditStatusById" resultType="java.lang.Integer">
select audit_status
from t_dynamic_rule
where dynamic_rule_id = #{dynamicRuleId}
</select>
</mapper>

View File

@@ -132,6 +132,11 @@
</if>
</where>
</select>
<select id="queryUsedProtectObjectsTotalNum"
resultType="java.lang.Integer">
SELECT COUNT(DISTINCT protect_object_id)
FROM t_protect_object_dynamic_rule_conn
</select>
<update id="updateProtectObject">
UPDATE t_protect_object

View File

@@ -22,7 +22,7 @@
#{object.staticRuleMdport}, #{object.staticRuleProtocol}, #{object.staticRuleMprotocol},
#{object.staticRuleDns}, #{object.staticRuleURL}, #{object.staticRulePriority},
#{object.staticRuleRange}, #{object.staticRuleFrequency},
#{object.staticRuleAuditStatus})
#{object.auditStatus})
</insert>
<insert id="newStaticRules">
insert into t_static_rule(static_rule_name, static_rule_create_time,
@@ -86,7 +86,8 @@
</update>
<update id="updateAuditStatusByIdBatch">
update t_static_rule
set static_rule_audit_status = CASE static_rule_id
set static_rule_modify_time = NOW(),
static_rule_audit_status = CASE static_rule_id
<foreach collection="idWithAuditStatusBatch" index="id" item="auditStatus" separator=" ">
WHEN #{id} THEN #{auditStatus}
</foreach>
@@ -114,7 +115,7 @@
<result column="static_rule_create_depart" property="staticRuleCreateDepart"/>
<result column="static_rule_used_task_id" property="staticRuleUsedTaskId"/>
<result column="task_status" property="usedTaskStatus"/>
<result column="static_rule_audit_status" property="staticRuleAuditStatus"/>
<result column="static_rule_audit_status" property="auditStatus"/>
<result column="static_rule_create_user_id" property="staticRuleCreateUserId"/>
<result column="static_rule_modify_time" property="staticRuleModifyTime"/>
@@ -205,5 +206,15 @@
#{id}
</foreach>
</select>
<select id="queryUsedStaticRuleTotalNum" resultType="java.lang.Integer">
SELECT COUNT(*)
FROM t_static_rule
WHERE static_rule_used_task_id IS NOT NULL;
</select>
<select id="queryAuditStaticRuleTotalNum" resultType="java.lang.Integer">
SELECT COUNT(*)
FROM t_static_rule
WHERE static_rule_audit_status = #{auditStatus}
</select>
</mapper>

View File

@@ -81,13 +81,13 @@
<select id="queryStaticRuleIdsFromTaskId" resultType="java.lang.Integer">
SELECT static_rule_id
FROM t_static_rule
WHERE static_rule_used_task_id = #{task_id} AND static_rule_audit_status = true
WHERE static_rule_used_task_id = #{task_id} AND static_rule_audit_status = 2
</select>
<select id="queryDynamicRuleIdsFromTaskId" resultType="java.lang.Integer">
SELECT dynamic_rule_id
FROM t_dynamic_rule
WHERE dynamic_rule_used_task_id = #{task_id}
WHERE dynamic_rule_used_task_id = #{task_id} AND audit_status = 2
</select>
<select id="queryTask" resultMap="taskMap">
@@ -130,7 +130,8 @@
<update id="clearTaskConnectedDynamicRule">
UPDATE t_dynamic_rule
SET dynamic_rule_used_task_id = null
SET dynamic_rule_used_task_id = null,
modify_time = NOW()
WHERE dynamic_rule_used_task_id = #{task_id}
</update>
@@ -151,7 +152,8 @@
<!-- 批量审核 -->
<update id="updateAuditStatusByIdBatch">
update t_task
set task_audit_status = CASE task_id
set task_modify_time = NOW(),
task_audit_status = CASE task_id
<foreach collection="idWithAuditStatusBatch" index="id" item="auditStatus" separator=" ">
WHEN #{id} THEN #{auditStatus}
</foreach>
@@ -255,7 +257,7 @@
<result column="log_rule_id" property="logRuleId"/>
<result column="source_system" property="sourceSystem"/>
<result column="event_type" property="eventType"/>
<collection property="protectObjects">
<collection property="protectObjects" ofType="com.realtime.protection.configuration.entity.task.DynamicTaskInfo$SimpleProtectObject">
<result column="protect_object_ip" property="IP"/>
<result column="protect_object_port" property="port"/>
<result column="protect_object_url" property="URL"/>
@@ -264,7 +266,7 @@
</resultMap>
<select id="getDynamicTaskInfos"
resultType="com.realtime.protection.configuration.entity.task.DynamicTaskInfo">
resultMap="dynamicTaskInfoMap">
SELECT task_id,
task_start_time,
task_end_time,
@@ -272,7 +274,7 @@
strategy_template_source_system as source_system,
strategy_template_name as event_type,
tdr.log_rule_id,
INET_NTOA(protect_object_ip),
INET_NTOA(protect_object_ip) as protect_object_ip,
protect_object_port,
protect_object_url,
protect_object_protocol
@@ -302,4 +304,9 @@
</where>
</select>
<select id="queryAuditTaskTotalNum" resultType="java.lang.Integer">
SELECT COUNT(*) FROM t_task
WHERE task_audit_status = #{auditStatus}
</select>
</mapper>

View File

@@ -146,6 +146,17 @@
WHERE strategy_template_name = #{eventName} AND strategy_template_source_system = #{sourceSystem}
</select>
<select id="queryUsedTemplateTotalNum" resultType="java.lang.Integer">
SELECT COUNT(DISTINCT template_id)
FROM t_dynamic_rule
</select>
<select id="queryAuditTemplateTotalNum" resultType="java.lang.Integer">
SELECT COUNT(*)
FROM t_strategy_template
WHERE audit_state = #{auditState}
</select>
<update id="updateTemplateInformation">
UPDATE t_strategy_template
<set>

View File

@@ -284,5 +284,10 @@
</foreach>
</where>
</select>
<select id="queryAuditWhiteListTotalNum" resultType="java.lang.Integer">
select COUNT(*)
from t_white_list
where white_list_audit_status = #{auditStatus}
</select>
</mapper>

View File

@@ -14,7 +14,9 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@SpringBootTest
public class DynamicRuleServiceTest extends ProtectionApplicationTests {
@@ -136,4 +138,16 @@ public class DynamicRuleServiceTest extends ProtectionApplicationTests {
null,null,null,null);
System.out.println(num);
}
@Test
void testUpdateDynamicRuleAuditStatusBatch(){
Map<Integer, Integer> map = new HashMap<>();
map.put(101, 1);
map.put(102, 2);
map.put(103, 2);
System.out.println(dynamicRuleService.updateAuditStatusBatch(map));
}
}

View File

@@ -30,7 +30,7 @@ public class StaticRuleServiceTest extends ProtectionApplicationTests {
staticRuleTest.setStaticRuleCreateUsername("mh");
staticRuleTest.setStaticRuleCreateDepart("mmeess");
staticRuleTest.setStaticRuleCreateUserId(2);
staticRuleTest.setStaticRuleAuditStatus(0);
staticRuleTest.setAuditStatus(0);
staticRuleTest.setStaticRuleSip("1.1.2.0");
staticRuleTest.setStaticRuleMsip("255.255.255.0");
@@ -114,4 +114,6 @@ public class StaticRuleServiceTest extends ProtectionApplicationTests {
System.out.println(staticRuleService.updateAuditStatusBatch(map));
}
}

View File

@@ -3,8 +3,10 @@ package com.realtime.protection.server.task;
import com.realtime.protection.ProtectionApplicationTests;
import com.realtime.protection.configuration.entity.rule.dynamicrule.DynamicRuleObject;
import com.realtime.protection.configuration.entity.rule.staticrule.StaticRuleObject;
import com.realtime.protection.configuration.entity.task.DynamicTaskInfo;
import com.realtime.protection.configuration.entity.task.Task;
import com.realtime.protection.configuration.entity.task.TaskCommandInfo;
import com.realtime.protection.configuration.exception.DorisStartException;
import com.realtime.protection.server.rule.dynamicrule.DynamicRuleService;
import com.realtime.protection.server.rule.staticrule.StaticRuleService;
import com.realtime.protection.server.task.status.StateChangeService;
@@ -27,13 +29,15 @@ class TaskServiceTest extends ProtectionApplicationTests {
private final TaskService taskService;
private final StaticRuleService staticRuleService;
private final DynamicRuleService dynamicRuleService;
private final StateChangeService stateChangeService;
private Task task;
@Autowired
TaskServiceTest(TaskService taskService, StaticRuleService staticRuleService, DynamicRuleService dynamicRuleService) {
TaskServiceTest(TaskService taskService, StaticRuleService staticRuleService, DynamicRuleService dynamicRuleService, StateChangeService stateChangeService) {
this.taskService = taskService;
this.staticRuleService = staticRuleService;
this.dynamicRuleService = dynamicRuleService;
this.stateChangeService = stateChangeService;
}
@BeforeEach
@@ -189,4 +193,15 @@ class TaskServiceTest extends ProtectionApplicationTests {
System.out.println(taskService.updateAuditStatusBatch(map));
}
@Test
void testGetDynamicTaskInfos(){
List<DynamicTaskInfo> dynamicTaskInfos = taskService.getDynamicTaskInfos(43844L);
System.out.println(dynamicTaskInfos);
}
@Test
void changeTaskstatus() throws DorisStartException {
stateChangeService.changeState(2, 43844L, false);
}
}

View File

@@ -103,7 +103,7 @@ class WhiteListServiceTest extends ProtectionApplicationTests {
staticRuleTest.setStaticRuleCreateUsername("mh");
staticRuleTest.setStaticRuleCreateDepart("mmeess");
staticRuleTest.setStaticRuleCreateUserId(2);
staticRuleTest.setStaticRuleAuditStatus(0);
staticRuleTest.setAuditStatus(0);
staticRuleTest.setStaticRuleSip("1.1.2.3");
staticRuleTest.setStaticRuleSport(80);