79 lines
2.6 KiB
Go
79 lines
2.6 KiB
Go
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,
|
||
}
|
||
}
|