Files
new-api/service/task_plugin_audit.go

99 lines
2.9 KiB
Go

package service
import (
"github.com/QuantumNous/new-api/common"
"github.com/QuantumNous/new-api/model"
pluginruntime "github.com/QuantumNous/new-api/pkg/jsplugin"
"github.com/gin-gonic/gin"
)
// TaskExecutionSnapshotFromContext captures immutable request and plugin
// provenance at submission time. It never copies plugin source or payloads.
func TaskExecutionSnapshotFromContext(ctx *gin.Context) *model.TaskExecutionSnapshot {
if ctx == nil {
return nil
}
snapshot := &model.TaskExecutionSnapshot{
RequestID: ctx.GetString(common.RequestIdKey),
}
if ctx.Request != nil && ctx.Request.URL != nil {
snapshot.RequestPath = ctx.Request.URL.Path
}
pinnedValue, exists := ctx.Get(pluginruntime.ContextKeyPinnedPlugin)
if exists {
pinned, ok := pinnedValue.(pluginruntime.PinnedPlugin)
if ok && pinned.Plugin != nil {
generation := uint64(0)
if pinned.Generation != nil {
generation = pinned.Generation.Number
}
meta := pinned.Plugin.Meta
snapshot.TaskPlugin = &model.TaskPluginSnapshot{
Key: meta.Key,
Name: meta.Name,
Version: meta.Version,
Author: &model.TaskPluginAuthorSnapshot{
Name: meta.Author.Name,
URL: meta.Author.URL,
},
APIVersion: meta.APIVersion,
Generation: generation,
}
}
}
if snapshot.RequestID == "" && snapshot.RequestPath == "" && snapshot.TaskPlugin == nil {
return nil
}
return snapshot
}
// AppendTaskPluginAuditInfo writes role-separated, credential-free plugin
// provenance into a usage log.
func AppendTaskPluginAuditInfo(other map[string]interface{}, snapshot *model.TaskPluginSnapshot) {
if other == nil || snapshot == nil || snapshot.Key == "" {
return
}
adminInfo, ok := other["admin_info"].(map[string]interface{})
if !ok || adminInfo == nil {
adminInfo = map[string]interface{}{}
other["admin_info"] = adminInfo
}
taskPlugin := map[string]interface{}{
"key": snapshot.Key,
"name": snapshot.Name,
"version": snapshot.Version,
}
if snapshot.Author != nil && snapshot.Author.Name != "" {
author := map[string]interface{}{"name": snapshot.Author.Name}
if snapshot.Author.URL != "" {
author["url"] = snapshot.Author.URL
}
taskPlugin["author"] = author
}
adminInfo["task_plugin"] = taskPlugin
rootInfo, ok := other["root_info"].(map[string]interface{})
if !ok || rootInfo == nil {
rootInfo = map[string]interface{}{}
other["root_info"] = rootInfo
}
rootInfo["task_plugin"] = map[string]interface{}{
"key": snapshot.Key,
"version": snapshot.Version,
"api_version": snapshot.APIVersion,
"generation": snapshot.Generation,
}
}
// AppendTaskPluginContextAuditInfo is used before a task row exists, such as
// an upstream submission error log.
func AppendTaskPluginContextAuditInfo(ctx *gin.Context, other map[string]interface{}) {
execution := TaskExecutionSnapshotFromContext(ctx)
if execution == nil {
return
}
AppendTaskPluginAuditInfo(other, execution.TaskPlugin)
}