Files
ttstd-infinite-canvas/backend/internal/service/desktop_local_channel_dispatch_test.go

134 lines
4.6 KiB
Go

package service
import (
"context"
"net"
"net/url"
"strings"
"testing"
"infinite-canvas/backend/internal/model"
)
func TestDesktopLocalChannelModeRejectsPublicAcrossProductionDispatch(t *testing.T) {
open := &Service{runtimeCapabilities: RuntimeCapabilities{desktopLocalChannels: true}}
requested := true
const publicBaseURL = "https://8.8.8.8"
if _, err := open.channelFromRequest(ChannelRequest{Name: "Public", BaseURL: publicBaseURL, AllowLocalChannel: &requested}, model.ModelChannel{Scope: model.ChannelScopeSystem}); err == nil {
t.Fatal("saving allowLocalChannel=true with a public Base URL must fail")
}
if _, err := ValidateCustomRelayChannelURL(publicBaseURL+"/v1/models", publicBaseURL, true, true); err == nil {
t.Fatal("custom relay allowLocalChannel=true must not fall back to the public relay policy")
}
if _, err := open.resolveProviderConfig(providerConfig{BaseURL: publicBaseURL, AllowLocalChannel: true}); err == nil {
t.Fatal("generation provider allowLocalChannel=true must reject a public Base URL before dispatch")
}
}
func TestDesktopLocalChannelModeOwnsOutboundPolicy(t *testing.T) {
t.Setenv("CANVAS_ALLOW_PRIVATE_UPSTREAMS", "true")
t.Setenv("CANVAS_ALLOWED_PRIVATE_UPSTREAM_HOSTS", "127.0.0.1,localhost,192.168.1.20,169.254.169.254")
open := &Service{runtimeCapabilities: RuntimeCapabilities{desktopLocalChannels: true}}
closed := &Service{}
for _, rawURL := range []string{
"https://8.8.8.8/v1/models",
"http://192.168.1.20:8000/v1/models",
"http://169.254.169.254/latest/meta-data",
"http://127.0.0.2:8000/v1/models",
"http://localhost.:8000/v1/models",
"http://[::1]:8000/v1/models",
} {
if _, err := open.validateChannelOutboundURL(rawURL, true, false); err == nil {
t.Fatalf("allowLocalChannel=true must reject non-exact-loopback URL %q", rawURL)
}
}
for _, rawURL := range []string{
"http://127.0.0.1:8000/v1/models",
"http://localhost:8000/v1/models",
} {
for _, customRelay := range []bool{false, true} {
_, err := open.validateChannelOutboundURL(rawURL, false, customRelay)
if err == nil || !strings.Contains(err.Error(), "不允许访问本机、内网或链路本地地址") {
t.Fatalf("allowLocalChannel=false must reject exact loopback %q with canonical error, customRelay=%v: %v", rawURL, customRelay, err)
}
}
}
for _, customRelay := range []bool{false, true} {
if _, err := open.validateChannelOutboundURL("https://8.8.8.8/v1/models", false, customRelay); err != nil {
t.Fatalf("ordinary public channel must keep the existing outbound policy, customRelay=%v: %v", customRelay, err)
}
}
for _, rawURL := range []string{
"http://127.0.0.1:8000/v1/models",
"https://8.8.8.8/v1/models",
} {
if _, err := closed.validateChannelOutboundURL(rawURL, true, false); err == nil {
t.Fatalf("server capability=false must reject requested local mode for %q", rawURL)
}
}
}
func TestGoURLParserDesktopLoopbackPortBoundary(t *testing.T) {
tests := []struct {
rawURL string
wantErr bool
wantHost string
wantPort string
}{
{rawURL: "http://localhost:", wantHost: "localhost", wantPort: ""},
{rawURL: "http://localhost:0", wantHost: "localhost", wantPort: "0"},
{rawURL: "http://localhost:65536", wantHost: "localhost", wantPort: "65536"},
{rawURL: "http://localhost:abc", wantErr: true},
}
for _, test := range tests {
parsed, err := url.Parse(test.rawURL)
if test.wantErr {
if err == nil {
t.Fatalf("url.Parse(%q) error=nil, want parser error", test.rawURL)
}
continue
}
if err != nil {
t.Fatalf("url.Parse(%q) error=%v", test.rawURL, err)
}
if parsed.Hostname() != test.wantHost || parsed.Port() != test.wantPort {
t.Fatalf("url.Parse(%q) hostname=%q port=%q", test.rawURL, parsed.Hostname(), parsed.Port())
}
}
}
func TestDesktopLoopbackPolicyValidatesPortSyntaxAndRange(t *testing.T) {
policy := desktopLoopbackOutboundPolicy(func(context.Context, string) ([]net.IP, error) {
return []net.IP{net.ParseIP("127.0.0.1")}, nil
})
for _, rawURL := range []string{
"http://localhost",
"http://localhost:1/v1/models",
"http://127.0.0.1:65535/v1/models",
} {
if _, err := validateOutboundURLWithPolicy(rawURL, policy); err != nil {
t.Fatalf("strict local URL %q must be accepted: %v", rawURL, err)
}
}
for _, rawURL := range []string{
"http://localhost:/v1/models",
"http://localhost:0/v1/models",
"http://localhost:65536/v1/models",
"http://localhost:abc/v1/models",
"http://localhost:+1/v1/models",
"http://localhost:-1/v1/models",
"http://localhost:0x50/v1/models",
} {
if _, err := validateOutboundURLWithPolicy(rawURL, policy); err == nil {
t.Fatalf("strict local URL %q must reject invalid port syntax/range", rawURL)
}
}
}