Ctrl K
ComunidadGuías…

internal/webhooks/urlvalidation_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package webhooks

import (
	"strings"
	"testing"

	"github.com/sarathsp06/sparrow/internal/webhooks/client"
)

func TestValidateWebhookURLPolicies(t *testing.T) {
	vpn, err := client.ParseNetworks([]string{"10.20.0.0/16"})
	if err != nil {
		t.Fatal(err)
	}
	tests := []struct {
		name   string
		url    string
		policy client.NetworkPolicy
		ok     bool
	}{
		{"bad scheme", "ftp://example.com", client.NetworkPolicy{}, false},
		{"default blocks private", "http://10.20.1.1/hook", client.NetworkPolicy{}, false},
		{"default blocks localhost", "http://localhost:9000", client.NetworkPolicy{}, false},
		{"allowlist permits VPN", "http://10.20.1.1/hook", client.NetworkPolicy{AllowedNetworks: vpn}, true},
		{"allowlist blocks other private", "http://10.21.1.1/hook", client.NetworkPolicy{AllowedNetworks: vpn}, false},
		{"allow-private permits loopback", "http://127.0.0.1:9000", client.NetworkPolicy{AllowPrivate: true}, true},
		{"allow-private permits unresolved name", "http://receiver.test:9000", client.NetworkPolicy{AllowPrivate: true}, true},
		{"allow-private blocks metadata", "http://169.254.169.254/latest", client.NetworkPolicy{AllowPrivate: true}, false},
	}
	for _, tt := range tests {
		t.Run(tt.name, func(t *testing.T) {
			err := ValidateWebhookURL(tt.url, tt.policy)
			if tt.ok != (err == nil) {
				t.Fatalf("ValidateWebhookURL(%q) err = %v, want ok=%v", tt.url, err, tt.ok)
			}
		})
	}
}

func TestCanonicalHeaders(t *testing.T) {
	got, err := canonicalHeaders("secret_headers", map[string]string{"x-api-key": "k", "AUTHORIZATION": ""})
	if err != nil {
		t.Fatal(err)
	}
	if len(got) != 2 || got["X-Api-Key"] != "k" || got["Authorization"] != "" {
		t.Errorf("canonicalHeaders = %v, want X-Api-Key and Authorization", got)
	}
	in := map[string]string{"X-Api-Key": "k", "Authorization": "a"}
	if got, _ := canonicalHeaders("secret_headers", in); len(got) != 2 || got["X-Api-Key"] != "k" || got["Authorization"] != "a" {
		t.Errorf("names already canonical are kept as they are, got %v", got)
	}
	if got, _ := canonicalHeaders("secret_headers", nil); got != nil {
		t.Errorf("nil stays nil, got %v", got)
	}

	_, err = canonicalHeaders("secret_headers", map[string]string{"x-api-key": "a", "X-Api-Key": "b"})
	if err == nil || !strings.Contains(err.Error(), `"X-Api-Key" and "x-api-key" are the same header`) {
		t.Errorf("duplicate by case: err = %v", err)
	}
}

// Both origin checks (webhook URL moves and redirects) share one rule.
func TestSameOriginStrings(t *testing.T) {
	for _, c := range []struct {
		a, b string
		want bool
	}{
		{"https://a.com/x", "https://a.com:443/y", true},
		{"https://A.com/", "https://a.com/", true},
		{"https://a.com/", "https://a.com:8443/", false},
		{"https://a.com/", "http://a.com/", false},
		{"https://a.com/", "://bad", false},
	} {
		if got := sameOrigin(c.a, c.b); got != c.want {
			t.Errorf("sameOrigin(%q, %q) = %v, want %v", c.a, c.b, got, c.want)
		}
	}
}