| new file mode 100644 |
| index 000000000..749a02770 |
| --- /dev/null |
| +++ b/internal/mail/dnsrecords_test.go |
| @@ -0,0 +1,107 @@ |
| +package mail |
| + |
| +import ( |
| + "strings" |
| + "testing" |
| + |
| + "github.com/carlosframework/platform/internal/dnsrec" |
| +) |
| + |
| +// The MAIL FROM subdomain carries its region from the FIRST domain ever |
| +// verified. For a custom domain this record lives in the CUSTOMER's zone, |
| +// so it is the one thing we cannot republish for them — and the MX target |
| +// is region-specific, so an unqualified "mail." could never hold a second |
| +// region without ambiguity (spec §7, §8). |
| +func TestMailFromDomainCarriesTheRegion(t *testing.T) { |
| + got := MailFromDomain("seapointish.bag.oncarlos.com", "eu-west-1") |
| + want := "mail-eu-west-1.seapointish.bag.oncarlos.com" |
| + if got != want { |
| + t.Fatalf("MailFromDomain = %q, want %q", got, want) |
| + } |
| + if MailFromDomain("x.com", "eu-west-1") == MailFromDomain("x.com", "us-east-1") { |
| + t.Fatal("two regions collided on one MAIL FROM subdomain") |
| + } |
| +} |
| + |
| +// Nothing is EVER written at the app host itself. The edge owns an A record |
| +// there, and an email record sharing that name could fight it — this is a |
| +// permanent invariant, not an implementation detail (spec §7). |
| +func TestNoRecordSitsAtTheDomainApex(t *testing.T) { |
| + const domain = "seapointish.bag.oncarlos.com" |
| + for _, r := range RecordSet(domain, "eu-west-1", []string{"t1", "t2", "t3"}, "") { |
| + if r.Name == domain { |
| + t.Fatalf("record %s %s sits at the apex — it would fight the edge's A record", r.Type, r.Name) |
| + } |
| + } |
| +} |
| + |
| +func TestRecordSetGolden(t *testing.T) { |
| + got := RecordSet("seapointish.bag.oncarlos.com", "eu-west-1", |
| + []string{"tok1", "tok2", "tok3"}, "") |
| + want := []dnsrec.Record{ |
| + {Name: "tok1._domainkey.seapointish.bag.oncarlos.com", Type: dnsrec.TypeCNAME, |
| + Values: []string{"tok1.dkim.amazonses.com"}, TTL: 300}, |
| + {Name: "tok2._domainkey.seapointish.bag.oncarlos.com", Type: dnsrec.TypeCNAME, |
| + Values: []string{"tok2.dkim.amazonses.com"}, TTL: 300}, |
| + {Name: "tok3._domainkey.seapointish.bag.oncarlos.com", Type: dnsrec.TypeCNAME, |
| + Values: []string{"tok3.dkim.amazonses.com"}, TTL: 300}, |
| + {Name: "mail-eu-west-1.seapointish.bag.oncarlos.com", Type: dnsrec.TypeMX, |
| + Values: []string{"10 feedback-smtp.eu-west-1.amazonses.com"}, TTL: 300}, |
| + {Name: "mail-eu-west-1.seapointish.bag.oncarlos.com", Type: dnsrec.TypeTXT, |
| + Values: []string{"v=spf1 include:amazonses.com ~all"}, TTL: 300}, |
| + {Name: "_dmarc.seapointish.bag.oncarlos.com", Type: dnsrec.TypeTXT, |
| + Values: []string{"v=DMARC1; p=none; adkim=s; aspf=s"}, TTL: 300}, |
| + } |
| + if len(got) != len(want) { |
| + t.Fatalf("got %d records, want %d:\n%+v", len(got), len(want), got) |
| + } |
| + for i := range want { |
| + if got[i].Name != want[i].Name || got[i].Type != want[i].Type || |
| + got[i].TTL != want[i].TTL || len(got[i].Values) != len(want[i].Values) || |
| + got[i].Values[0] != want[i].Values[0] { |
| + t.Fatalf("record %d:\n got %+v\nwant %+v", i, got[i], want[i]) |
| + } |
| + } |
| +} |
| + |
| +// adkim=s is the TENANT BOUNDARY on a shared registrable domain, not |
| +// hygiene. DMARC's default relaxed alignment compares ORGANIZATIONAL |
| +// domains, so without it tenant bag's DKIM signature authenticates a From |
| +// address at bae.oncarlos.com (spec §7). |
| +func TestDMARCIsStrictlyAligned(t *testing.T) { |
| + var dmarc string |
| + for _, r := range RecordSet("x.bag.oncarlos.com", "eu-west-1", []string{"t"}, "") { |
| + if r.Name == "_dmarc.x.bag.oncarlos.com" { |
| + dmarc = r.Values[0] |
| + } |
| + } |
| + if dmarc == "" { |
| + t.Fatal("no _dmarc record emitted") |
| + } |
| + for _, want := range []string{"adkim=s", "aspf=s"} { |
| + if !contains(dmarc, want) { |
| + t.Fatalf("DMARC %q is missing %q — tenants are not isolated", dmarc, want) |
| + } |
| + } |
| +} |
| + |
| +// rua is CONFIGURATION. Unset means publish no rua at all: a reporting |
| +// address is only honoured by receivers when the destination authorises it |
| +// (RFC 7489 §7.1), so emitting one by default would publish a record that |
| +// looks right and yields nothing. |
| +func TestRUAIsOmittedWhenUnset(t *testing.T) { |
| + for _, r := range RecordSet("x.com", "eu-west-1", []string{"t"}, "") { |
| + if r.Name == "_dmarc.x.com" && contains(r.Values[0], "rua=") { |
| + t.Fatalf("unset rua still emitted: %q", r.Values[0]) |
| + } |
| + } |
| + for _, r := range RecordSet("x.com", "eu-west-1", []string{"t"}, "reports@cribado.report") { |
| + if r.Name == "_dmarc.x.com" { |
| + if !contains(r.Values[0], "rua=mailto:reports@cribado.report") { |
| + t.Fatalf("rua not rendered: %q", r.Values[0]) |
| + } |
| + } |
| + } |
| +} |
| + |
| +func contains(h, n string) bool { return len(n) > 0 && len(h) >= len(n) && strings.Contains(h, n) } |