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

@@ -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,16 +76,21 @@ public class DynamicRuleService {
public void deleteDynamicRuleObject(Integer dynamicRuleId) {
//根据任务状态判断能否删除
Integer taskStatus = dynamicRuleMapper.queryTaskStatusBydynamicRuleId(dynamicRuleId);
switch (StateEnum.getStateEnumByNum(taskStatus)){
case RUNNING:
throw new IllegalArgumentException("使用该动态规则的任务处于运行状态");
case PAUSED:
throw new IllegalArgumentException("使用该动态规则的任务处于暂停状态");
default:
break;
if (taskStatus == null){
dynamicRuleMapper.deleteDynamicRuleObject(dynamicRuleId);
}else{
switch (StateEnum.getStateEnumByNum(taskStatus)){
case RUNNING:
throw new IllegalArgumentException("使用该动态规则的任务处于运行状态");
case PAUSED:
throw new IllegalArgumentException("使用该动态规则的任务处于暂停状态");
default:
break;
}
//不需要使用 join,在数据库中设置了级联删除 ON DELETE CASCADE在删除在从父表中删除数据时自动删除子表中的数据
dynamicRuleMapper.deleteDynamicRuleObject(dynamicRuleId);
}
//不需要使用 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<>();
@@ -172,7 +175,7 @@ public class TaskController implements TaskControllerApi {
errorIds.add(id);
}
}
if (!errorIds.isEmpty()){
if (!errorIds.isEmpty()) {
return new ResponseResult(400, "id or status is invalid")
.setData("tasks_id", errorIds)
.setData("success", false);
@@ -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) {
return ResponseResult.ok().setMessage("success")
.setData("success", true);
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("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);
}
}