mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-07-31 18:20:25 +00:00
- Update go.mod and Dockerfile to Go 1.26 - Apply `go fix ./...` stdlib modernizations across 170+ files - Add `go fix` to post-implementation checklist in CLAUDE.md - Fix go fix misapplied rewrite in loop_history.go
125 lines
3.6 KiB
Go
125 lines
3.6 KiB
Go
package methods
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
|
|
"github.com/nextlevelbuilder/goclaw/internal/gateway"
|
|
"github.com/nextlevelbuilder/goclaw/internal/i18n"
|
|
"github.com/nextlevelbuilder/goclaw/internal/store"
|
|
"github.com/nextlevelbuilder/goclaw/internal/tools"
|
|
"github.com/nextlevelbuilder/goclaw/pkg/protocol"
|
|
)
|
|
|
|
// ExecApprovalMethods handles exec.approval.list, exec.approval.approve, exec.approval.deny.
|
|
type ExecApprovalMethods struct {
|
|
manager *tools.ExecApprovalManager
|
|
}
|
|
|
|
func NewExecApprovalMethods(manager *tools.ExecApprovalManager) *ExecApprovalMethods {
|
|
return &ExecApprovalMethods{manager: manager}
|
|
}
|
|
|
|
func (m *ExecApprovalMethods) Register(router *gateway.MethodRouter) {
|
|
router.Register(protocol.MethodApprovalsList, m.handleList)
|
|
router.Register(protocol.MethodApprovalsApprove, m.handleApprove)
|
|
router.Register(protocol.MethodApprovalsDeny, m.handleDeny)
|
|
}
|
|
|
|
func (m *ExecApprovalMethods) handleList(_ context.Context, client *gateway.Client, req *protocol.RequestFrame) {
|
|
if m.manager == nil {
|
|
client.SendResponse(protocol.NewOKResponse(req.ID, map[string]any{
|
|
"pending": []any{},
|
|
}))
|
|
return
|
|
}
|
|
pending := m.manager.ListPending()
|
|
|
|
type pendingInfo struct {
|
|
ID string `json:"id"`
|
|
Command string `json:"command"`
|
|
AgentID string `json:"agentId"`
|
|
CreatedAt int64 `json:"createdAt"`
|
|
}
|
|
|
|
items := make([]pendingInfo, 0, len(pending))
|
|
for _, pa := range pending {
|
|
items = append(items, pendingInfo{
|
|
ID: pa.ID,
|
|
Command: pa.Command,
|
|
AgentID: pa.AgentID,
|
|
CreatedAt: pa.CreatedAt.UnixMilli(),
|
|
})
|
|
}
|
|
|
|
client.SendResponse(protocol.NewOKResponse(req.ID, map[string]any{
|
|
"pending": items,
|
|
}))
|
|
}
|
|
|
|
func (m *ExecApprovalMethods) handleApprove(ctx context.Context, client *gateway.Client, req *protocol.RequestFrame) {
|
|
locale := store.LocaleFromContext(ctx)
|
|
if m.manager == nil {
|
|
client.SendResponse(protocol.NewErrorResponse(req.ID, protocol.ErrInvalidRequest, i18n.T(locale, i18n.MsgExecApprovalDisabled)))
|
|
return
|
|
}
|
|
|
|
var params struct {
|
|
ID string `json:"id"`
|
|
Always bool `json:"always"` // true = allow-always, false = allow-once
|
|
}
|
|
if req.Params != nil {
|
|
json.Unmarshal(req.Params, ¶ms)
|
|
}
|
|
|
|
if params.ID == "" {
|
|
client.SendResponse(protocol.NewErrorResponse(req.ID, protocol.ErrInvalidRequest, i18n.T(locale, i18n.MsgRequired, "id")))
|
|
return
|
|
}
|
|
|
|
decision := tools.ApprovalAllowOnce
|
|
if params.Always {
|
|
decision = tools.ApprovalAllowAlways
|
|
}
|
|
|
|
if err := m.manager.Resolve(params.ID, decision); err != nil {
|
|
client.SendResponse(protocol.NewErrorResponse(req.ID, protocol.ErrNotFound, err.Error()))
|
|
return
|
|
}
|
|
|
|
client.SendResponse(protocol.NewOKResponse(req.ID, map[string]any{
|
|
"resolved": true,
|
|
"decision": string(decision),
|
|
}))
|
|
}
|
|
|
|
func (m *ExecApprovalMethods) handleDeny(ctx context.Context, client *gateway.Client, req *protocol.RequestFrame) {
|
|
locale := store.LocaleFromContext(ctx)
|
|
if m.manager == nil {
|
|
client.SendResponse(protocol.NewErrorResponse(req.ID, protocol.ErrInvalidRequest, i18n.T(locale, i18n.MsgExecApprovalDisabled)))
|
|
return
|
|
}
|
|
|
|
var params struct {
|
|
ID string `json:"id"`
|
|
}
|
|
if req.Params != nil {
|
|
json.Unmarshal(req.Params, ¶ms)
|
|
}
|
|
|
|
if params.ID == "" {
|
|
client.SendResponse(protocol.NewErrorResponse(req.ID, protocol.ErrInvalidRequest, i18n.T(locale, i18n.MsgRequired, "id")))
|
|
return
|
|
}
|
|
|
|
if err := m.manager.Resolve(params.ID, tools.ApprovalDeny); err != nil {
|
|
client.SendResponse(protocol.NewErrorResponse(req.ID, protocol.ErrNotFound, err.Error()))
|
|
return
|
|
}
|
|
|
|
client.SendResponse(protocol.NewOKResponse(req.ID, map[string]any{
|
|
"resolved": true,
|
|
"decision": "deny",
|
|
}))
|
|
}
|