mirror of
https://github.com/jhillyerd/inbucket.git
synced 2025-12-17 17:47:03 +00:00
Handle IP address domains (#285)
* Add basic TestRecipientAddress tests * Handle forward-path route spec * Validate IP addr "domains" * Forward-path test cases * Add integration test * Add IPv4 recip swaks test * Special case domain mailbox extraction * add IPv6 swaks test * Formatting Signed-off-by: James Hillyerd <james@hillyerd.com> * Update changelog
This commit is contained in:
@@ -259,6 +259,30 @@ func TestExtractMailboxValid(t *testing.T) {
|
||||
full: "chars|}~@example.co.uk",
|
||||
domain: "example.co.uk",
|
||||
},
|
||||
{
|
||||
input: "@host:user+label@domain.com",
|
||||
local: "user",
|
||||
full: "user@domain.com",
|
||||
domain: "domain.com",
|
||||
},
|
||||
{
|
||||
input: "@a.com,@b.com:user+label@domain.com",
|
||||
local: "user",
|
||||
full: "user@domain.com",
|
||||
domain: "domain.com",
|
||||
},
|
||||
{
|
||||
input: "u@[127.0.0.1]",
|
||||
local: "u",
|
||||
full: "u@[127.0.0.1]",
|
||||
domain: "[127.0.0.1]",
|
||||
},
|
||||
{
|
||||
input: "u@[IPv6:2001:db8:aaaa:1::100]",
|
||||
local: "u",
|
||||
full: "u@[IPv6:2001:db8:aaaa:1::100]",
|
||||
domain: "[IPv6:2001:db8:aaaa:1::100]",
|
||||
},
|
||||
}
|
||||
for _, tc := range testTable {
|
||||
if result, err := localPolicy.ExtractMailbox(tc.input); err != nil {
|
||||
@@ -285,10 +309,42 @@ func TestExtractMailboxValid(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// Test special cases with domain addressing mode.
|
||||
func TestExtractDomainMailboxValid(t *testing.T) {
|
||||
domainPolicy := policy.Addressing{Config: &config.Root{MailboxNaming: config.DomainNaming}}
|
||||
|
||||
tests := map[string]struct {
|
||||
input string // Input to test
|
||||
domain string // Expected output when mailbox naming = domain
|
||||
}{
|
||||
"ipv4": {
|
||||
input: "[127.0.0.1]",
|
||||
domain: "[127.0.0.1]",
|
||||
},
|
||||
"medium ipv6": {
|
||||
input: "[IPv6:2001:db8:aaaa:1::100]",
|
||||
domain: "[IPv6:2001:db8:aaaa:1::100]",
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
if result, err := domainPolicy.ExtractMailbox(tc.input); tc.domain != "" && err != nil {
|
||||
t.Errorf("Error while parsing with domain naming %q: %v", tc.input, err)
|
||||
} else {
|
||||
if result != tc.domain {
|
||||
t.Errorf("Parsing %q, expected %q, got %q", tc.input, tc.domain, result)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractMailboxInvalid(t *testing.T) {
|
||||
localPolicy := policy.Addressing{Config: &config.Root{MailboxNaming: config.LocalNaming}}
|
||||
fullPolicy := policy.Addressing{Config: &config.Root{MailboxNaming: config.FullNaming}}
|
||||
domainPolicy := policy.Addressing{Config: &config.Root{MailboxNaming: config.DomainNaming}}
|
||||
|
||||
// Test local mailbox naming policy.
|
||||
localInvalidTable := []struct {
|
||||
input, msg string
|
||||
@@ -303,6 +359,7 @@ func TestExtractMailboxInvalid(t *testing.T) {
|
||||
t.Errorf("Didn't get an error while parsing in local mode %q: %v", tt.input, tt.msg)
|
||||
}
|
||||
}
|
||||
|
||||
// Test full mailbox naming policy.
|
||||
fullInvalidTable := []struct {
|
||||
input, msg string
|
||||
@@ -318,6 +375,7 @@ func TestExtractMailboxInvalid(t *testing.T) {
|
||||
t.Errorf("Didn't get an error while parsing in full mode %q: %v", tt.input, tt.msg)
|
||||
}
|
||||
}
|
||||
|
||||
// Test domain mailbox naming policy.
|
||||
domainInvalidTable := []struct {
|
||||
input, msg string
|
||||
@@ -365,6 +423,10 @@ func TestValidateDomain(t *testing.T) {
|
||||
{strings.Repeat("a", 256), false, "Max domain length is 255"},
|
||||
{strings.Repeat("a", 63) + ".com", true, "Should allow 63 char domain label"},
|
||||
{strings.Repeat("a", 64) + ".com", false, "Max domain label length is 63"},
|
||||
{"[0.0.0.0]", true, "Single digit octet IP addr is valid"},
|
||||
{"[123.123.123.123]", true, "Multiple digit octet IP addr is valid"},
|
||||
{"[IPv6:2001:0db8:aaaa:0001:0000:0000:0000:0200]", true, "Full IPv6 addr is valid"},
|
||||
{"[IPv6:::1]", true, "Abbr IPv6 addr is valid"},
|
||||
}
|
||||
for _, tt := range testTable {
|
||||
if policy.ValidateDomainPart(tt.input) != tt.expect {
|
||||
@@ -419,6 +481,9 @@ func TestValidateLocal(t *testing.T) {
|
||||
{"$A12345", true, "RFC3696 test case should be valid"},
|
||||
{"!def!xyz%abc", true, "RFC3696 test case should be valid"},
|
||||
{"_somename", true, "RFC3696 test case should be valid"},
|
||||
{"@host:mailbox", true, "Forward-path routes are valid"},
|
||||
{"@a.com,@b.com:mailbox", true, "Multi-hop forward-path routes are valid"},
|
||||
{"@a.com,mailbox", false, "Unterminated forward-path routes are invalid"},
|
||||
}
|
||||
for _, tt := range testTable {
|
||||
_, _, err := policy.ParseEmailAddress(tt.input + "@domain.com")
|
||||
@@ -430,3 +495,33 @@ func TestValidateLocal(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestRecipientAddress verifies the Recipient.Address values returned by Addressing.NewRecipient.
|
||||
// This function parses a RCPT TO path, not a To header. See rfc5321#section-4.1.2
|
||||
func TestRecipientAddress(t *testing.T) {
|
||||
localPolicy := policy.Addressing{Config: &config.Root{MailboxNaming: config.LocalNaming}}
|
||||
|
||||
tests := map[string]string{
|
||||
"common": "user@example.com",
|
||||
"with label": "user+mailbox@example.com",
|
||||
"special chars": "a!#$%&'*+-/=?^_`{|}~@example.com",
|
||||
"ipv4": "user@[127.0.0.1]",
|
||||
"ipv6": "user@[IPv6:::1]",
|
||||
"route host": "@host:user@example.com",
|
||||
"route domain": "@route.com:user@example.com",
|
||||
"multi-hop route": "@first.com,@second.com:user@example.com",
|
||||
}
|
||||
|
||||
for name, tc := range tests {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
r, err := localPolicy.NewRecipient(tc)
|
||||
if err != nil {
|
||||
t.Fatalf("Parse of %q failed: %v", tc, err)
|
||||
}
|
||||
|
||||
if got, want := r.Address.Address, tc; got != want {
|
||||
t.Errorf("Got Address: %q, want: %q", got, want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user