借鉴 DBX:安装检测(Node/npm/包/Go 二进制)、只读与 allow_dangerous、 连接白名单、多客户端配置片段;GET/PUT /api/ai/mcp-policy、/mcp-install; 文档 /docs/mcp 与落地页 AI/MCP 块;对照 docs/16 勾选设置项、列仍未完清单。
69 lines
1.8 KiB
Go
69 lines
1.8 KiB
Go
package aitools
|
|
|
|
import (
|
|
"context"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestSaveLoadPolicyRoundTrip(t *testing.T) {
|
|
dir := t.TempDir()
|
|
t.Setenv("HOME", dir)
|
|
// PolicyPath uses UserHomeDir → ~/.opsxdb/mcp.json
|
|
p := Policy{
|
|
AllowedConnectionIDs: []string{" a ", "b", "a", ""},
|
|
Mode: "READ_WRITE",
|
|
AllowDangerous: true,
|
|
DefaultLimit: 50,
|
|
MaxLimit: 200,
|
|
}
|
|
if err := SavePolicy(p); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
path := filepath.Join(dir, ".opsxdb", "mcp.json")
|
|
if _, err := os.Stat(path); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
got, err := LoadPolicy()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if got.Mode != ModeReadWrite {
|
|
t.Fatalf("mode=%s", got.Mode)
|
|
}
|
|
if !got.AllowDangerous {
|
|
t.Fatal("want allow_dangerous")
|
|
}
|
|
if len(got.AllowedConnectionIDs) != 2 || got.AllowedConnectionIDs[0] != "a" || got.AllowedConnectionIDs[1] != "b" {
|
|
t.Fatalf("ids=%v", got.AllowedConnectionIDs)
|
|
}
|
|
if got.DefaultLimit != 50 || got.MaxLimit != 200 {
|
|
t.Fatalf("limits %d/%d", got.DefaultLimit, got.MaxLimit)
|
|
}
|
|
}
|
|
|
|
func TestDangerousSQLRequiresAllowFlag(t *testing.T) {
|
|
rt := NewRuntime(Policy{
|
|
AllowedConnectionIDs: []string{"c1"},
|
|
Mode: ModeReadWrite,
|
|
AllowDangerous: false,
|
|
})
|
|
rt.FindConn = func(id string) (*SavedConnection, error) {
|
|
return &SavedConnection{ID: id, Name: "c1", Driver: "mysql", Host: "127.0.0.1", Port: 3306}, nil
|
|
}
|
|
rt.Audit = func(AuditEntry) {}
|
|
rt.AllowConfirmedWrite = true
|
|
_, err := rt.Call(context.Background(), ToolExecuteQuery, map[string]any{
|
|
"connection_id": "c1",
|
|
"sql": "DROP TABLE users",
|
|
"confirm_danger": true,
|
|
})
|
|
if err == nil || !contains(err.Error(), "dangerous sql disabled") {
|
|
t.Fatalf("want dangerous disabled, got %v", err)
|
|
}
|
|
}
|
|
|
|
func contains(s, sub string) bool { return strings.Contains(s, sub) }
|