mirror of
https://blitiri.com.ar/repos/chasquid
synced 2025-12-17 14:37:02 +00:00
aliases: Skip resolution logic for non-local addresses
This patch skips the resolution logic if the address is not local. Today, the resolution logic handles that case transparently, and returns the original email address, so this should be a no-op. However, having an explicit early check makes the resolution logic more robust, and will simplify future patches. Note this also means that the `alias-resolve` hook is no longer run for non-local aliases, which should also help simplify their implementation.
This commit is contained in:
@@ -145,7 +145,7 @@ func (v *Resolver) Resolve(addr string) ([]Recipient, error) {
|
|||||||
// Exists check that the address exists in the database.
|
// Exists check that the address exists in the database.
|
||||||
// It returns the cleaned address, and a boolean indicating the result.
|
// It returns the cleaned address, and a boolean indicating the result.
|
||||||
// The clean address can be used to look it up in other databases, even if it
|
// The clean address can be used to look it up in other databases, even if it
|
||||||
// doesn't exist.
|
// doesn't exist. It must only be called for local addresses.
|
||||||
func (v *Resolver) Exists(addr string) (string, bool) {
|
func (v *Resolver) Exists(addr string) (string, bool) {
|
||||||
addr = v.cleanIfLocal(addr)
|
addr = v.cleanIfLocal(addr)
|
||||||
|
|
||||||
@@ -171,6 +171,13 @@ func (v *Resolver) resolve(rcount int, addr string) ([]Recipient, error) {
|
|||||||
return nil, ErrRecursionLimitExceeded
|
return nil, ErrRecursionLimitExceeded
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the address is not local, we return it as-is, so delivery is
|
||||||
|
// attempted against it.
|
||||||
|
// Example: an alias that resolves to a non-local address.
|
||||||
|
if _, ok := v.domains[envelope.DomainOf(addr)]; !ok {
|
||||||
|
return []Recipient{{addr, EMAIL}}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Drop suffixes and chars to get the "clean" address before resolving.
|
// Drop suffixes and chars to get the "clean" address before resolving.
|
||||||
// This also means that we will return the clean version if there's no
|
// This also means that we will return the clean version if there's no
|
||||||
// match, which our callers can rely upon.
|
// match, which our callers can rely upon.
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ type Cases []struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cases Cases) check(t *testing.T, r *Resolver) {
|
func (cases Cases) check(t *testing.T, r *Resolver) {
|
||||||
|
t.Helper()
|
||||||
for _, c := range cases {
|
for _, c := range cases {
|
||||||
got, err := r.Resolve(c.addr)
|
got, err := r.Resolve(c.addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -26,6 +27,7 @@ func (cases Cases) check(t *testing.T, r *Resolver) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func mustExist(t *testing.T, r *Resolver, addrs ...string) {
|
func mustExist(t *testing.T, r *Resolver, addrs ...string) {
|
||||||
|
t.Helper()
|
||||||
for _, addr := range addrs {
|
for _, addr := range addrs {
|
||||||
if _, ok := r.Exists(addr); !ok {
|
if _, ok := r.Exists(addr); !ok {
|
||||||
t.Errorf("address %q does not exist, it should", addr)
|
t.Errorf("address %q does not exist, it should", addr)
|
||||||
@@ -34,6 +36,7 @@ func mustExist(t *testing.T, r *Resolver, addrs ...string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func mustNotExist(t *testing.T, r *Resolver, addrs ...string) {
|
func mustNotExist(t *testing.T, r *Resolver, addrs ...string) {
|
||||||
|
t.Helper()
|
||||||
for _, addr := range addrs {
|
for _, addr := range addrs {
|
||||||
if _, ok := r.Exists(addr); ok {
|
if _, ok := r.Exists(addr); ok {
|
||||||
t.Errorf("address %q exists, it should not", addr)
|
t.Errorf("address %q exists, it should not", addr)
|
||||||
@@ -43,20 +46,22 @@ func mustNotExist(t *testing.T, r *Resolver, addrs ...string) {
|
|||||||
|
|
||||||
func TestBasic(t *testing.T) {
|
func TestBasic(t *testing.T) {
|
||||||
resolver := NewResolver()
|
resolver := NewResolver()
|
||||||
|
resolver.AddDomain("localA")
|
||||||
|
resolver.AddDomain("localB")
|
||||||
resolver.aliases = map[string][]Recipient{
|
resolver.aliases = map[string][]Recipient{
|
||||||
"a@b": {{"c@d", EMAIL}, {"e@f", EMAIL}},
|
"a@localA": {{"c@d", EMAIL}, {"e@localB", EMAIL}},
|
||||||
"e@f": {{"cmd", PIPE}},
|
"e@localB": {{"cmd", PIPE}},
|
||||||
"cmd": {{"x@y", EMAIL}}, // it's a trap!
|
"cmd": {{"x@y", EMAIL}}, // it's a trap!
|
||||||
}
|
}
|
||||||
|
|
||||||
cases := Cases{
|
cases := Cases{
|
||||||
{"a@b", []Recipient{{"c@d", EMAIL}, {"cmd", PIPE}}},
|
{"a@localA", []Recipient{{"c@d", EMAIL}, {"cmd", PIPE}}},
|
||||||
{"e@f", []Recipient{{"cmd", PIPE}}},
|
{"e@localB", []Recipient{{"cmd", PIPE}}},
|
||||||
{"x@y", []Recipient{{"x@y", EMAIL}}},
|
{"x@y", []Recipient{{"x@y", EMAIL}}},
|
||||||
}
|
}
|
||||||
cases.check(t, resolver)
|
cases.check(t, resolver)
|
||||||
|
|
||||||
mustExist(t, resolver, "a@b", "e@f", "cmd")
|
mustExist(t, resolver, "a@localA", "e@localB", "cmd")
|
||||||
mustNotExist(t, resolver, "x@y")
|
mustNotExist(t, resolver, "x@y")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,6 +73,7 @@ func TestAddrRewrite(t *testing.T) {
|
|||||||
"abc@def": {{"x@y", EMAIL}},
|
"abc@def": {{"x@y", EMAIL}},
|
||||||
"ñoño@def": {{"x@y", EMAIL}},
|
"ñoño@def": {{"x@y", EMAIL}},
|
||||||
"recu@def": {{"ab+cd@p-q.com", EMAIL}},
|
"recu@def": {{"ab+cd@p-q.com", EMAIL}},
|
||||||
|
"remo@def": {{"x-@y-z.com", EMAIL}},
|
||||||
}
|
}
|
||||||
resolver.DropChars = ".~"
|
resolver.DropChars = ".~"
|
||||||
resolver.SuffixSep = "-+"
|
resolver.SuffixSep = "-+"
|
||||||
@@ -96,6 +102,7 @@ func TestAddrRewrite(t *testing.T) {
|
|||||||
{"x.y@z.com", []Recipient{{"x.y@z.com", EMAIL}}},
|
{"x.y@z.com", []Recipient{{"x.y@z.com", EMAIL}}},
|
||||||
{"x-@y-z.com", []Recipient{{"x-@y-z.com", EMAIL}}},
|
{"x-@y-z.com", []Recipient{{"x-@y-z.com", EMAIL}}},
|
||||||
{"x+blah@y", []Recipient{{"x+blah@y", EMAIL}}},
|
{"x+blah@y", []Recipient{{"x+blah@y", EMAIL}}},
|
||||||
|
{"remo@def", []Recipient{{"x-@y-z.com", EMAIL}}},
|
||||||
}
|
}
|
||||||
cases.check(t, resolver)
|
cases.check(t, resolver)
|
||||||
}
|
}
|
||||||
@@ -143,7 +150,9 @@ func TestExistsRewrite(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestTooMuchRecursion(t *testing.T) {
|
func TestTooMuchRecursion(t *testing.T) {
|
||||||
resolver := Resolver{}
|
resolver := NewResolver()
|
||||||
|
resolver.AddDomain("b")
|
||||||
|
resolver.AddDomain("d")
|
||||||
resolver.aliases = map[string][]Recipient{
|
resolver.aliases = map[string][]Recipient{
|
||||||
"a@b": {{"c@d", EMAIL}},
|
"a@b": {{"c@d", EMAIL}},
|
||||||
"c@d": {{"a@b", EMAIL}},
|
"c@d": {{"a@b", EMAIL}},
|
||||||
|
|||||||
Reference in New Issue
Block a user