2026-07-12 14:17:45 +08:00

79 lines
2.6 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package shared
import (
"hyapp-admin-server/internal/middleware"
"hyapp-admin-server/internal/model"
"github.com/gin-gonic/gin"
)
type OperationEvent struct {
RequestID string
UserID uint
Username string
Action string
Resource string
ResourceID string
Method string
Path string
IP string
UserAgent string
Status string
HTTPStatus int
RiskLevel string
LatencyMS int64
Detail string
}
type OperationLogger interface {
CreateOperationLog(log model.OperationLog) error
LogOperation(event OperationEvent) error
}
func OperationLog(c *gin.Context, logger OperationLogger, action string, resource string, status string, detail string) {
OperationLogWithResourceID(c, logger, action, resource, c.Param("id"), status, detail)
}
// OperationLogWithResourceID is the explicit audit entry point for routes whose target id
// does not use the shared ":id" path parameter name.
func OperationLogWithResourceID(c *gin.Context, logger OperationLogger, action string, resource string, resourceID string, status string, detail string) {
if logger == nil {
return
}
// MarkAuditLogged keeps middleware from creating a second generic row for this write.
middleware.MarkAuditLogged(c)
_ = logger.LogOperation(operationEvent(c, action, resource, resourceID, status, detail))
}
// OperationLogWithResourceIDStrict 是 fail-closed 版本:审计写失败时返回错误、且不抑制
// middleware 的兜底审计行。用于“操作本身在别处不留任何痕迹”的高危动作(如重签用户 token——
// 这类动作宁可失败,也不能在没有任何审计记录的情况下成功。
func OperationLogWithResourceIDStrict(c *gin.Context, logger OperationLogger, action string, resource string, resourceID string, status string, detail string) error {
if logger == nil {
return nil
}
if err := logger.LogOperation(operationEvent(c, action, resource, resourceID, status, detail)); err != nil {
return err
}
middleware.MarkAuditLogged(c)
return nil
}
func operationEvent(c *gin.Context, action string, resource string, resourceID string, status string, detail string) OperationEvent {
return OperationEvent{
RequestID: middleware.CurrentRequestID(c),
UserID: middleware.CurrentUserID(c),
Username: middleware.CurrentUsername(c),
Action: action,
Resource: resource,
ResourceID: resourceID,
Method: c.Request.Method,
Path: c.Request.URL.Path,
IP: c.ClientIP(),
UserAgent: c.Request.UserAgent(),
Status: status,
HTTPStatus: c.Writer.Status(),
Detail: detail,
}
}