package main import ( "context" "io" "net/http" "os" "path/filepath" "strings" "testing" ) func TestAgentEndpointValidation(t *testing.T) { for _, endpoint := range []string{"http://127.0.0.1:9105", "https://10.10.0.2:9105", "http://[fd00::1]:9105"} { if err := validateAgentEndpoint(endpoint); err != nil { t.Fatalf("%s: %v", endpoint, err) } } for _, endpoint := range []string{"http://0.0.0.0:9105", "http://8.8.8.8:9105", "https://agent.example:9105", "file:///etc/passwd", "http://127.0.0.1:9105/path"} { if validateAgentEndpoint(endpoint) == nil { t.Fatalf("unsafe endpoint accepted: %s", endpoint) } } } func TestCredentialReferences(t *testing.T) { if !validCredentialRef("agent_primary.token") { t.Fatal("valid ref rejected") } for _, value := range []string{"", "../secret", "path/name", ".", "bad ref"} { if validCredentialRef(value) { t.Fatalf("invalid ref accepted: %q", value) } } } func TestAgentClientAuthenticatesAndBoundsPath(t *testing.T) { token := strings.Repeat("a", 32) dir := t.TempDir() if err := os.WriteFile(filepath.Join(dir, "agent"), []byte(token), 0o600); err != nil { t.Fatal(err) } client := NewAgentClient(dir) client.http.Transport = roundTripFunc(func(request *http.Request) (*http.Response, error) { if request.Header.Get("Authorization") != "Bearer "+token { t.Error("missing token") } return &http.Response{StatusCode: 200, Header: make(http.Header), Body: io.NopCloser(strings.NewReader(`{"ok":true}`))}, nil }) server := Server{AgentEndpoint: "http://127.0.0.1:9105", CredentialRef: "agent"} status, _, err := client.Do(context.Background(), server, http.MethodGet, "/v1/version", nil) if err != nil || status != 200 { t.Fatalf("agent request failed: status=%d err=%v", status, err) } if _, _, err = client.Do(context.Background(), server, http.MethodGet, "/private", nil); err == nil { t.Fatal("out-of-contract path accepted") } } type roundTripFunc func(*http.Request) (*http.Response, error) func (function roundTripFunc) RoundTrip(request *http.Request) (*http.Response, error) { return function(request) }