69 lines
3.1 KiB
Java
69 lines
3.1 KiB
Java
package com.baiyue.audit.controller;
|
|
|
|
import com.baiyue.audit.dto.AuditIngestRequest;
|
|
import com.baiyue.audit.service.AuditIngestService;
|
|
import com.baiyue.common.core.api.ApiResponse;
|
|
import io.swagger.v3.oas.annotations.Operation;
|
|
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
|
import jakarta.annotation.Resource;
|
|
import jakarta.validation.Valid;
|
|
import java.nio.charset.StandardCharsets;
|
|
import java.security.MessageDigest;
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
import org.springframework.http.HttpStatus;
|
|
import org.springframework.http.ResponseEntity;
|
|
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.RequestHeader;
|
|
import org.springframework.web.bind.annotation.RestController;
|
|
|
|
/**
|
|
* 内部审计事件接收接口,校验服务间提交的审计数据并交由审计服务持久化。
|
|
*/
|
|
@Tag(
|
|
name = "Internal audit ingestion / 内部审计写入",
|
|
description = "Internal service-to-service API for immutable business audit events. / 服务间写入不可变业务审计事件的内部接口。"
|
|
)
|
|
@RestController
|
|
@RequestMapping("/internal/audit/events")
|
|
public class AuditIngestController {
|
|
private static final String INTERNAL_SERVICE_TOKEN_HEADER = "X-Internal-Service-Token";
|
|
|
|
@Resource
|
|
private AuditIngestService service;
|
|
|
|
@Value("${baiyue.security.internal-service-token:}")
|
|
private String internalServiceToken;
|
|
@Operation(
|
|
summary = "Ingest business audit event / 写入业务审计事件",
|
|
description = "Validates and stores one sanitized event in baiyue_audit.sys_audit_log. / 校验并将一条脱敏事件写入 baiyue_audit.sys_audit_log。"
|
|
)
|
|
@ApiResponses({
|
|
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "202", description = "Event accepted and stored / 事件已接收并存储"),
|
|
})
|
|
@PostMapping
|
|
public ResponseEntity<ApiResponse<Void>> ingest(
|
|
@RequestHeader(value = INTERNAL_SERVICE_TOKEN_HEADER, required = false) String providedToken,
|
|
@Valid @RequestBody AuditIngestRequest event) {
|
|
if (!tokenMatches(providedToken)) {
|
|
return ResponseEntity.status(HttpStatus.FORBIDDEN)
|
|
.body(ApiResponse.failure(com.baiyue.common.core.api.ResultCode.FORBIDDEN,
|
|
"Internal service token is invalid", null, null));
|
|
}
|
|
service.ingest(event);
|
|
return ResponseEntity.status(HttpStatus.ACCEPTED).body(ApiResponse.success(null));
|
|
}
|
|
|
|
private boolean tokenMatches(String providedToken) {
|
|
if (providedToken == null || providedToken.isBlank()
|
|
|| internalServiceToken == null || internalServiceToken.isBlank()) {
|
|
return false;
|
|
}
|
|
return MessageDigest.isEqual(
|
|
internalServiceToken.getBytes(StandardCharsets.UTF_8),
|
|
providedToken.getBytes(StandardCharsets.UTF_8));
|
|
}
|
|
}
|