83 lines
2.1 KiB
Go
83 lines
2.1 KiB
Go
package handler
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"net/http"
|
|
"time"
|
|
|
|
"git.ilapage.cn/OPC/chorus/internal/core/apiaudit"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
const (
|
|
requestIDContextKey = "request_id"
|
|
responseErrorCodeContextKey = "response_error_code"
|
|
auditGenerationIDContextKey = "audit_generation_id"
|
|
auditGenerationCreatedContextKey = "audit_generation_created"
|
|
)
|
|
|
|
func (h *Handler) requestID(c *gin.Context) {
|
|
id := newOpenAPIRequestID()
|
|
c.Set(requestIDContextKey, id)
|
|
c.Header("X-Request-ID", id)
|
|
c.Next()
|
|
}
|
|
|
|
func requestID(c *gin.Context) string {
|
|
value, _ := c.Get(requestIDContextKey)
|
|
id, _ := value.(string)
|
|
return id
|
|
}
|
|
|
|
func (h *Handler) auditOpenAPISubmission(c *gin.Context) {
|
|
if c.Request.Method != http.MethodPost {
|
|
c.Next()
|
|
return
|
|
}
|
|
kind := ""
|
|
switch c.FullPath() {
|
|
case "/openapi/v1/generations/text":
|
|
kind = "text"
|
|
case "/openapi/v1/generations/image":
|
|
kind = "image"
|
|
default:
|
|
c.Next()
|
|
return
|
|
}
|
|
c.Next()
|
|
|
|
principal := currentAPIPrincipal(c)
|
|
status := c.Writer.Status()
|
|
result := apiaudit.ResultSucceeded
|
|
if status >= 500 {
|
|
result = apiaudit.ResultFailed
|
|
} else if status >= 400 {
|
|
result = apiaudit.ResultDenied
|
|
}
|
|
var generationID *uint64
|
|
if value, exists := c.Get(auditGenerationIDContextKey); exists {
|
|
if id, ok := value.(uint64); ok && id != 0 {
|
|
generationID = &id
|
|
}
|
|
}
|
|
var created *bool
|
|
if value, exists := c.Get(auditGenerationCreatedContextKey); exists {
|
|
if flag, ok := value.(bool); ok {
|
|
created = &flag
|
|
}
|
|
}
|
|
errorCode, _ := c.Get(responseErrorCodeContextKey)
|
|
code, _ := errorCode.(string)
|
|
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
|
|
defer cancel()
|
|
if err := h.service.RecordAPIAudit(ctx, apiaudit.Event{
|
|
UserID: &principal.UserID, APIKeyID: &principal.APIKeyID, GenerationID: generationID,
|
|
Action: apiaudit.ActionGenerationSubmitted, Result: result, RequestID: requestID(c),
|
|
StatusCode: status, ErrorCode: code, Summary: apiaudit.Summary{Source: "openapi", Kind: kind, Created: created},
|
|
CreatedAt: h.now(),
|
|
}); err != nil {
|
|
log.Printf("api audit write failed request_id=%s: %v", requestID(c), err)
|
|
}
|
|
}
|