accounts/api/admin_sandbox.go

98 lines
2.4 KiB
Go

package api
import (
"errors"
"net/http"
"strings"
"github.com/gin-gonic/gin"
"gorm.io/gorm"
"account/internal/model"
)
func (h *handler) getSandboxBinding(c *gin.Context) {
if _, ok := h.requireAdminPermission(c, permissionAdminSettingsRead); !ok {
return
}
if h.db == nil {
c.JSON(http.StatusServiceUnavailable, gin.H{"error": "database_not_configured"})
return
}
var binding model.SandboxBinding
if err := h.db.WithContext(c.Request.Context()).First(&binding).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
c.JSON(http.StatusOK, gin.H{"address": "", "name": ""})
return
}
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed_to_query_binding", "message": err.Error()})
return
}
c.JSON(http.StatusOK, gin.H{
"address": binding.AgentID,
"updatedAt": binding.UpdatedAt.UnixMilli(),
})
}
func (h *handler) bindSandboxNode(c *gin.Context) {
adminUser, ok := h.requireAdminPermission(c, permissionAdminSettingsWrite)
if !ok {
return
}
if h.isReadOnlyAccount(adminUser) {
respondError(c, http.StatusForbidden, "read_only_account", "demo account is read-only")
return
}
if h.db == nil {
c.JSON(http.StatusServiceUnavailable, gin.H{"error": "database_not_configured"})
return
}
var req struct {
Address string `json:"address"`
}
if err := c.ShouldBindJSON(&req); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": "invalid_request", "message": err.Error()})
return
}
agentID := strings.TrimSpace(req.Address)
err := h.db.WithContext(c.Request.Context()).Transaction(func(tx *gorm.DB) error {
// Clear existing bindings (enforce 1-to-1 for now as per frontend)
if err := tx.Session(&gorm.Session{AllowGlobalUpdate: true}).Delete(&model.SandboxBinding{}).Error; err != nil {
return err
}
if agentID != "" {
newBinding := model.SandboxBinding{
AgentID: agentID,
}
if err := tx.Create(&newBinding).Error; err != nil {
return err
}
}
return nil
})
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": "failed_to_save_binding", "message": err.Error()})
return
}
// Update the in-memory registry if available
if h.agentRegistry != nil {
// Enforce 1-to-1 binding: clear then set.
h.agentRegistry.ClearSandboxAgents()
if agentID != "" {
h.agentRegistry.SetSandboxAgent(agentID, true)
}
}
c.JSON(http.StatusOK, gin.H{"message": "sandbox node bound successfully", "address": agentID})
}