diff --git a/modules/validation/email.go b/modules/validation/email.go index bef816586f..d3bc26a056 100644 --- a/modules/validation/email.go +++ b/modules/validation/email.go @@ -7,6 +7,7 @@ package validation import ( "fmt" "net/mail" + "net/url" "regexp" "strings" @@ -100,11 +101,40 @@ func validateEmailDomain(email string) error { } func IsEmailDomainAllowed(email string) bool { - if len(setting.Service.EmailDomainAllowList) == 0 { - return !isEmailDomainListed(setting.Service.EmailDomainBlockList, email) - } + return isEmailDomainAllowedInternal( + email, + setting.Service.EmailDomainAllowList, + setting.Service.EmailDomainBlockList, + setting.Federation.Enabled, + setting.AppURL) +} - return isEmailDomainListed(setting.Service.EmailDomainAllowList, email) +func isEmailDomainAllowedInternal( + email string, + emailDomainAllowList []glob.Glob, + emailDomainBlockList []glob.Glob, + isFederation bool, + fqdn string, +) bool { + var result bool + + if len(emailDomainAllowList) == 0 { + result = !isEmailDomainListed(emailDomainBlockList, email) + } else if isFederation { + localFqdn, err := url.ParseRequestURI(fqdn) + if err != nil { + return false + } + globber, err := glob.Compile(localFqdn.Hostname(), ',') + if err != nil { + return false + } + emailDomainAllowList = append(emailDomainAllowList, globber) + result = isEmailDomainListed(emailDomainAllowList, email) + } else { + result = isEmailDomainListed(emailDomainAllowList, email) + } + return result } // isEmailDomainListed checks whether the domain of an email address diff --git a/modules/validation/email_test.go b/modules/validation/email_test.go index e5125a9357..3e8f7385f1 100644 --- a/modules/validation/email_test.go +++ b/modules/validation/email_test.go @@ -6,6 +6,7 @@ package validation import ( "testing" + "github.com/gobwas/glob" "github.com/stretchr/testify/assert" ) @@ -65,3 +66,46 @@ func TestEmailAddressValidate(t *testing.T) { }) } } + +func TestEmailDomainAllowList(t *testing.T) { + res := IsEmailDomainAllowed("someuser@localhost.localdomain") + assert.True(t, res) +} + +func TestEmailDomainAllowListInternal(t *testing.T) { + domain, _ := glob.Compile("domain.de", ',') + emailDomainAllowList := []glob.Glob{domain} + emailDomainBlockList := []glob.Glob{} + + res := isEmailDomainAllowedInternal( + "user@repo.domain.de", + emailDomainAllowList, + emailDomainBlockList, + false, + "https://repo.domain.de") + assert.False(t, res) + + res = isEmailDomainAllowedInternal( + "user@repo.domain.de", + emailDomainAllowList, + emailDomainBlockList, + true, + "xttps://repo") + assert.False(t, res) + + res = isEmailDomainAllowedInternal( + "user@repo.Domain.de", + emailDomainAllowList, + emailDomainBlockList, + true, + "https://repo.domain.de") + assert.True(t, res) + + res = isEmailDomainAllowedInternal( + "user@repo.domain.de", + emailDomainAllowList, + emailDomainBlockList, + true, + "https://repo.domain.de") + assert.True(t, res) +}