package policy import ( "errors" "reflect" "testing" ) func TestHostsFromRule(t *testing.T) { tests := map[string][]string{ "Host(`a.de`)": {"a.de"}, "Host(\"a.de\")": {"a.de"}, "Host(`a.de`) || Host(`b.de`)": {"a.de", "b.de"}, "Host(`a.de`, `b.de`)": {"a.de", "b.de"}, // v2-Syntax "Host(`a.de`) && PathPrefix(`/api`)": {"a.de"}, "(Host(`a.de`) || Host(`b.de`)) && Method(`GET`)": {"a.de", "b.de"}, "Host(`a.de`) && !Host(`b.de`)": {"a.de"}, // ausgeschlossene Hosts zählen nicht "host(`a.de`)": {"a.de"}, " Host( `a.de` ) ": {"a.de"}, "Host(`a.de`) && (PathPrefix(`/x`) || Path(`/y`))": {"a.de"}, "PathPrefix(`/x`) && Host(`a.de`)": {"a.de"}, "Host(`a.de`) || (Host(`b.de`) && Header(`X`, `1`))": {"a.de", "b.de"}, } for rule, want := range tests { got, err := HostsFromRule(rule) if err != nil { t.Errorf("%s: unerwarteter Fehler %v", rule, err) continue } if !reflect.DeepEqual(got, want) { t.Errorf("%s: Hosts = %v, erwartet %v", rule, got, want) } } } // Regeln, die nicht auf eigene Hosts beschränkt sind, würden fremden // Verkehr abgreifen (Catch-all). func TestHostsFromRule_Unconstrained(t *testing.T) { for _, rule := range []string{ "PathPrefix(`/`)", "Host(`a.de`) || PathPrefix(`/`)", "!Host(`a.de`)", "Method(`GET`)", "ClientIP(`10.0.0.0/8`)", "!(Host(`a.de`) && Path(`/`))", "(Host(`a.de`) && Path(`/`)) || Header(`X`, `1`)", } { if _, err := HostsFromRule(rule); !errors.Is(err, ErrUnconstrained) { t.Errorf("%s: erwartet ErrUnconstrained, bekommen %v", rule, err) } } } func TestHostsFromRule_HostRegexp(t *testing.T) { for _, rule := range []string{ "HostRegexp(`.+`)", "Host(`a.de`) && HostRegexp(`^x`)", "hostregexp(`.+`)", } { if _, err := HostsFromRule(rule); !errors.Is(err, ErrHostRegexp) { t.Errorf("%s: erwartet ErrHostRegexp, bekommen %v", rule, err) } } } func TestHostsFromRule_SyntaxErrors(t *testing.T) { for _, rule := range []string{ "", "Host(", "Host(`a.de`", "Host(`a.de`) &&", "Host(a.de)", "Host(`a.de`) Host(`b.de`)", ")(", "Host()", "Host(`a.de)", "&& Host(`a.de`)", "Host(`a.de`) | Host(`b.de`)", "Host(`a.de`,)", "(Host(`a.de`)", "Host(\"a.de)", } { if _, err := HostsFromRule(rule); !errors.Is(err, ErrSyntax) { t.Errorf("%q: erwartet ErrSyntax, bekommen %v", rule, err) } } }