feat(policy): add ValidWhitelistAddress
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3,6 +3,8 @@
|
||||
package policy
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/mail"
|
||||
"strings"
|
||||
)
|
||||
@@ -42,3 +44,31 @@ func MatchAddress(entries []string, addr string) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ValidWhitelistAddress reports an error if s is not a usable whitelist entry.
|
||||
// Accepted forms: a bare address "local@domain", or a domain wildcard "@domain".
|
||||
// The domain must contain at least one dot. Display-name forms ("Bob <b@x>")
|
||||
// are rejected because the store keeps the raw string, which would never match.
|
||||
func ValidWhitelistAddress(s string) error {
|
||||
s = strings.TrimSpace(s)
|
||||
if s == "" {
|
||||
return errors.New("address must not be empty")
|
||||
}
|
||||
bad := fmt.Errorf("invalid address %q: expected local@domain or @domain", s)
|
||||
if strings.HasPrefix(s, "@") {
|
||||
domain := s[1:]
|
||||
if domain == "" || strings.Contains(domain, "@") || !strings.Contains(domain, ".") {
|
||||
return bad
|
||||
}
|
||||
return nil
|
||||
}
|
||||
addr, err := mail.ParseAddress(s)
|
||||
if err != nil || !strings.EqualFold(addr.Address, s) {
|
||||
return bad // parse failure or a display-name/extra-token form
|
||||
}
|
||||
at := strings.LastIndex(addr.Address, "@")
|
||||
if at < 1 || !strings.Contains(addr.Address[at+1:], ".") {
|
||||
return bad
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package policy
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestValidWhitelistAddress(t *testing.T) {
|
||||
good := []string{"tk555@protonmail.com", "a.b@sub.example.co.uk", "@example.com", "@sub.example.com"}
|
||||
for _, s := range good {
|
||||
if err := ValidWhitelistAddress(s); err != nil {
|
||||
t.Errorf("ValidWhitelistAddress(%q) = %v, want nil", s, err)
|
||||
}
|
||||
}
|
||||
bad := []string{"", " ", "notanaddress", "@", "@nodot", "a@nodot", "Bob <b@x.com>", "a@b@c.com"}
|
||||
for _, s := range bad {
|
||||
if err := ValidWhitelistAddress(s); err == nil {
|
||||
t.Errorf("ValidWhitelistAddress(%q) = nil, want error", s)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user