package policy import ( "net" "net/http" "net/url" "testing" "git.maze.io/maze/styx/internal/netutil" "git.maze.io/maze/styx/proxy/match" "github.com/miekg/dns" ) type testInDomainList struct { t *testing.T list []string } func (testInDomainList) Name() string { return "testInDomainList" } func (l testInDomainList) MatchesRequest(r *http.Request) bool { for _, domain := range l.list { if dns.IsSubDomain(domain, netutil.Host(r.URL.Host)) { l.t.Logf("domain %s contains %s", domain, r.URL.Host) return true } l.t.Logf("domain %s does not contain %s", domain, r.URL.Host) } return false } func testInDomain(t *testing.T, domains ...string) match.Matcher { return &testInDomainList{t: t, list: domains} } type testInNetworkList struct { t *testing.T list []*net.IPNet } func (testInNetworkList) Name() string { return "testInNetworkList" } func (l testInNetworkList) MatchesIP(ip net.IP) bool { for _, ipnet := range l.list { if ipnet.Contains(ip) { l.t.Logf("network %s contains %s", ipnet, ip) return true } l.t.Logf("network %s does not contain %s", ipnet, ip) } return false } func testInNetwork(t *testing.T, cidr string) match.Matcher { t.Helper() _, ipnet, err := net.ParseCIDR(cidr) if err != nil { panic(err) } return testInNetworkList{t: t, list: []*net.IPNet{ipnet}} } func TestPolicy(t *testing.T) { var ( yes = true nope = false ) p := &Policy{ Rules: []*rawRule{ { Rule: &requestRule{ domainOrNetworkRule: domainOrNetworkRule{ matchers: []match.Matcher{testInNetwork(t, "127.0.0.0/8")}, isSource: []bool{true}, }, }, }, { Rule: &requestRule{ domainOrNetworkRule: domainOrNetworkRule{ matchers: []match.Matcher{testInNetwork(t, "127.0.0.0/8")}, isSource: []bool{false}, }, Permit: &yes, }, }, { Rule: &requestRule{ domainOrNetworkRule: domainOrNetworkRule{ matchers: []match.Matcher{testInDomain(t, "maze.io", "maze.engineering")}, }, Permit: &yes, }, }, { Rule: &requestRule{ domainOrNetworkRule: domainOrNetworkRule{ matchers: []match.Matcher{testInDomain(t, "google.com")}, }, Permit: &nope, }, }, }, } r := &http.Request{ URL: &url.URL{Scheme: "http", Host: "golang.org:80"}, RemoteAddr: "127.0.0.1:1234", } if v := p.PermitRequest(r); v != nil { t.Errorf("expected request to return no verdict, got %t", *v) } p.Rules[0].Rule.(*requestRule).Permit = &yes if v := p.PermitRequest(r); v == nil || *v != yes { t.Errorf("expected request to return %t, %v", yes, v) } r.RemoteAddr = "192.168.1.2:3456" if v := p.PermitRequest(r); v != nil { t.Errorf("expected request to return no verdict, got %t", *v) } if v := p.PermitIntercept(r); v != nil { t.Errorf("expected request to return no verdict, got %t", *v) } r.URL.Host = "maze.io" if v := p.PermitRequest(r); v == nil || *v != yes { t.Errorf("expected request to return %t, %v", yes, v) } r.URL.Host = "google.com" if v := p.PermitRequest(r); v == nil || *v != nope { t.Errorf("expected request to return %t, %v", nope, v) } r.URL.Host = "localhost:80" if v := p.PermitRequest(r); v == nil || *v != yes { t.Errorf("expected request to return %t, %v", yes, v) } }