mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-16 15:26:40 +00:00
382 lines
8.4 KiB
Go
382 lines
8.4 KiB
Go
package domain
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestValidateDomains(t *testing.T) {
|
|
label63 := strings.Repeat("a", 63)
|
|
label64 := strings.Repeat("a", 64)
|
|
|
|
tests := []struct {
|
|
name string
|
|
domains []string
|
|
expected List
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "Empty list",
|
|
domains: nil,
|
|
expected: nil,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Valid ASCII domain",
|
|
domains: []string{"sub.ex-ample.com"},
|
|
expected: List{"sub.ex-ample.com"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Valid uppercase domain normalized to lowercase",
|
|
domains: []string{"EXAMPLE.COM"},
|
|
expected: List{"example.com"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Valid mixed case domain",
|
|
domains: []string{"ExAmPlE.CoM"},
|
|
expected: List{"example.com"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Single letter TLD",
|
|
domains: []string{"example.x"},
|
|
expected: List{"example.x"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Two letter domain labels",
|
|
domains: []string{"a.b"},
|
|
expected: List{"a.b"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Single character domain",
|
|
domains: []string{"x"},
|
|
expected: List{"x"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Wildcard with single letter TLD",
|
|
domains: []string{"*.x"},
|
|
expected: List{"*.x"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Multi-level with single letter labels",
|
|
domains: []string{"a.b.c"},
|
|
expected: List{"a.b.c"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Valid Unicode domain",
|
|
domains: []string{"münchen.de"},
|
|
expected: List{"xn--mnchen-3ya.de"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Valid Unicode, all labels",
|
|
domains: []string{"中国.中国.中国"},
|
|
expected: List{"xn--fiqs8s.xn--fiqs8s.xn--fiqs8s"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "With underscores",
|
|
domains: []string{"_jabber._tcp.gmail.com"},
|
|
expected: List{"_jabber._tcp.gmail.com"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Valid domain starting with digit",
|
|
domains: []string{"123.example.com"},
|
|
expected: List{"123.example.com"},
|
|
wantErr: false,
|
|
},
|
|
// Numeric TLDs are allowed for internal/private DNS use cases.
|
|
// While ICANN doesn't issue all-numeric gTLDs, the DNS protocol permits them
|
|
// and resolvers like systemd-resolved handle them correctly.
|
|
{
|
|
name: "Numeric TLD allowed",
|
|
domains: []string{"example.123"},
|
|
expected: List{"example.123"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Single digit TLD allowed",
|
|
domains: []string{"example.1"},
|
|
expected: List{"example.1"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "All numeric labels allowed",
|
|
domains: []string{"123.456"},
|
|
expected: List{"123.456"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Single numeric label allowed",
|
|
domains: []string{"123"},
|
|
expected: List{"123"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Valid domain with double hyphen",
|
|
domains: []string{"test--example.com"},
|
|
expected: List{"test--example.com"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Invalid leading hyphen",
|
|
domains: []string{"-example.com"},
|
|
expected: nil,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Invalid trailing hyphen",
|
|
domains: []string{"example.com-"},
|
|
expected: nil,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Invalid leading dot",
|
|
domains: []string{".com"},
|
|
expected: nil,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Invalid dot only",
|
|
domains: []string{"."},
|
|
expected: nil,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Invalid double dot",
|
|
domains: []string{"example..com"},
|
|
expected: nil,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Invalid special characters",
|
|
domains: []string{"example?,.com"},
|
|
expected: nil,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Invalid space in domain",
|
|
domains: []string{"space .example.com"},
|
|
expected: nil,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Invalid trailing space",
|
|
domains: []string{"example.com "},
|
|
expected: nil,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Multiple domains valid and invalid",
|
|
domains: []string{"google.com", "invalid,nbdomain.com", "münchen.de"},
|
|
expected: List{"google.com"},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Valid wildcard domain",
|
|
domains: []string{"*.example.com"},
|
|
expected: List{"*.example.com"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Wildcard with dot domain",
|
|
domains: []string{".*.example.com"},
|
|
expected: nil,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Wildcard with dot domain",
|
|
domains: []string{".*.example.com"},
|
|
expected: nil,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Invalid wildcard domain",
|
|
domains: []string{"a.*.example.com"},
|
|
expected: nil,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Valid 63 char label (max)",
|
|
domains: []string{label63 + ".com"},
|
|
expected: List{Domain(label63 + ".com")},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Invalid 64 char label (exceeds max)",
|
|
domains: []string{label64 + ".com"},
|
|
expected: nil,
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Valid 253 char domain (max)",
|
|
domains: []string{strings.Repeat("a.", 126) + "a"},
|
|
expected: List{Domain(strings.Repeat("a.", 126) + "a")},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Invalid 254+ char domain (exceeds max)",
|
|
domains: []string{strings.Repeat("ab.", 85)},
|
|
expected: nil,
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got, err := ValidateDomains(tt.domains)
|
|
assert.Equal(t, tt.wantErr, err != nil)
|
|
assert.Equal(t, got, tt.expected)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidateDomainsList(t *testing.T) {
|
|
validDomains := make([]string, maxDomains)
|
|
for i := range maxDomains {
|
|
validDomains[i] = fmt.Sprintf("example%d.com", i)
|
|
}
|
|
|
|
tests := []struct {
|
|
name string
|
|
domains []string
|
|
wantErr bool
|
|
}{
|
|
{
|
|
name: "Empty list",
|
|
domains: nil,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Single valid ASCII domain",
|
|
domains: []string{"sub.ex-ample.com"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Uppercase domain accepted",
|
|
domains: []string{"EXAMPLE.COM"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Single letter TLD",
|
|
domains: []string{"example.x"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Two letter domain labels",
|
|
domains: []string{"a.b"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Single character domain",
|
|
domains: []string{"x"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Wildcard with single letter TLD",
|
|
domains: []string{"*.x"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Multi-level with single letter labels",
|
|
domains: []string{"a.b.c"},
|
|
wantErr: false,
|
|
},
|
|
// Numeric TLDs are allowed for internal/private DNS use cases.
|
|
{
|
|
name: "Numeric TLD allowed",
|
|
domains: []string{"example.123"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Single digit TLD allowed",
|
|
domains: []string{"example.1"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "All numeric labels allowed",
|
|
domains: []string{"123.456"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Single numeric label allowed",
|
|
domains: []string{"123"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Underscores in labels",
|
|
domains: []string{"_jabber._tcp.gmail.com"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
// Unlike ValidateDomains (which converts to punycode),
|
|
// ValidateDomainsStrSlice will fail on non-ASCII domain chars.
|
|
name: "Unicode domain fails (no punycode conversion)",
|
|
domains: []string{"münchen.de"},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Invalid domain format - leading dash",
|
|
domains: []string{"-example.com"},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Invalid domain format - trailing dash",
|
|
domains: []string{"example-.com"},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Multiple domains with a valid one, then invalid",
|
|
domains: []string{"google.com", "invalid_domain.com-"},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Valid wildcard domain",
|
|
domains: []string{"*.example.com"},
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Wildcard with leading dot - invalid",
|
|
domains: []string{".*.example.com"},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Invalid wildcard with multiple asterisks",
|
|
domains: []string{"a.*.example.com"},
|
|
wantErr: true,
|
|
},
|
|
{
|
|
name: "Exactly maxDomains items (valid)",
|
|
domains: validDomains,
|
|
wantErr: false,
|
|
},
|
|
{
|
|
name: "Exceeds maxDomains items",
|
|
domains: append(validDomains, "extra.com"),
|
|
wantErr: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
err := ValidateDomainsList(tt.domains)
|
|
if tt.wantErr {
|
|
assert.Error(t, err)
|
|
} else {
|
|
assert.NoError(t, err)
|
|
}
|
|
})
|
|
}
|
|
}
|