1
0
mirror of https://blitiri.com.ar/repos/chasquid synced 2025-12-17 14:37:02 +00:00

aliases: Support '*' as the destination user

This patch implements support for aliases that contain '*' as the
destination user.

In that case, we replace it with the original user.

For example, `*: *@pond` will redirect `lilly@domain` to `lilly@pond`.

This is experimental for now, and marked as such in the documentation.
The semantics can be subtle, so we may need to adjust them later.
This commit is contained in:
Alberto Bertogli
2025-03-24 10:38:11 +00:00
parent 8e4d31c74c
commit 2ee64deec0
4 changed files with 104 additions and 0 deletions

View File

@@ -62,6 +62,10 @@ func allUsersExist(tr *trace.Trace, user, domain string) (bool, error) {
return true, nil
}
func noUsersExist(tr *trace.Trace, user, domain string) (bool, error) {
return false, nil
}
func usersWithXDontExist(tr *trace.Trace, user, domain string) (bool, error) {
if strings.HasPrefix(user, "x") {
return false, nil
@@ -104,6 +108,8 @@ func TestBasic(t *testing.T) {
func TestCatchAll(t *testing.T) {
resolver := NewResolver(usersWithXDontExist)
resolver.DropChars = "."
resolver.SuffixSep = "+"
resolver.AddDomain("dom")
resolver.aliases = map[string][]Recipient{
"a@dom": {{"a@remote", EMAIL}},
@@ -114,6 +120,8 @@ func TestCatchAll(t *testing.T) {
cases := Cases{
{"a@dom", []Recipient{{"a@remote", EMAIL}}, nil},
{"a+z@dom", []Recipient{{"a@remote", EMAIL}}, nil},
{"a.@dom", []Recipient{{"a@remote", EMAIL}}, nil},
{"b@dom", []Recipient{{"cmd", PIPE}}, nil},
{"c@dom", []Recipient{{"cmd", PIPE}}, nil},
{"x@dom", []Recipient{{"cmd", PIPE}}, nil},
@@ -132,6 +140,80 @@ func TestCatchAll(t *testing.T) {
"x@dom", "x1@dom")
}
func TestRightSideAsterisk(t *testing.T) {
resolver := NewResolver(noUsersExist)
resolver.DropChars = "."
resolver.SuffixSep = "+"
resolver.AddDomain("dom1")
resolver.AddDomain("dom2")
resolver.AddDomain("dom3")
resolver.AddDomain("dom4")
resolver.AddDomain("dom5")
resolver.aliases = map[string][]Recipient{
"a@dom1": {{"aaa@remote", EMAIL}},
// Note this goes to dom2 which is local too, and will be resolved
// recursively.
"*@dom1": {{"*@dom2", EMAIL}},
"b@dom2": {{"bbb@remote", EMAIL}},
"*@dom2": {{"*@remote", EMAIL}},
// A right hand asterisk on a specific address isn't very useful, but
// it is supported.
"z@dom1": {{"*@remote", EMAIL}},
// Asterisk to asterisk creates an infinite loop.
"*@dom3": {{"*@dom3", EMAIL}},
// A right-side asterisk as part of multiple addresses, some of which
// are fixed.
"*@dom4": {{"*@remote1", EMAIL}, {"*@remote2", EMAIL},
{"fixed@remote3", EMAIL}},
// A chain of a -> b -> * -> *@remote.
// This checks which one is used as the "original" user.
"a@dom5": {{"b@dom5", EMAIL}},
"*@dom5": {{"*@remote", EMAIL}},
}
cases := Cases{
{"a@dom1", []Recipient{{"aaa@remote", EMAIL}}, nil},
{"b@dom1", []Recipient{{"bbb@remote", EMAIL}}, nil},
{"xyz@dom1", []Recipient{{"xyz@remote", EMAIL}}, nil},
{"xyz@dom2", []Recipient{{"xyz@remote", EMAIL}}, nil},
{"z@dom1", []Recipient{{"z@remote", EMAIL}}, nil},
// Check that we match after dropping the characters as needed.
// This is not specific to the right side asterisk, but serve to
// confirm we're not matching against it by accident.
{"a+lala@dom1", []Recipient{{"aaa@remote", EMAIL}}, nil},
{"a..@dom1", []Recipient{{"aaa@remote", EMAIL}}, nil},
// Check we don't remove drop characters or suffixes when doing the
// rewrite: we expect to pass addresses as they come if they didn't
// match previously.
{"xyz+abcd@dom1", []Recipient{{"xyz+abcd@remote", EMAIL}}, nil},
{"x.y.z@dom1", []Recipient{{"x.y.z@remote", EMAIL}}, nil},
// This one should fail because it creates an infinite loop.
{"x@dom3", nil, ErrRecursionLimitExceeded},
// Check the multiple addresses case.
{"abc@dom4", []Recipient{
{"abc@remote1", EMAIL},
{"abc@remote2", EMAIL},
{"fixed@remote3", EMAIL},
}, nil},
// Check the chain case: a -> b -> * -> remote.
{"a@dom5", []Recipient{{"b@remote", EMAIL}}, nil},
{"b@dom5", []Recipient{{"b@remote", EMAIL}}, nil},
{"c@dom5", []Recipient{{"c@remote", EMAIL}}, nil},
}
cases.check(t, resolver)
}
func TestUserLookupErrors(t *testing.T) {
resolver := NewResolver(usersWithXErrorYDontExist)
resolver.AddDomain("dom")