Browse Source

Add a warning for disallowed email domains (#29658)

Resolve #29660

Follow #29522 and #29609

Add a warning for disallowed email domains when admins manually add/edit
users.

Thanks @yp05327 for the
[comment](https://github.com/go-gitea/gitea/pull/29605#issuecomment-1980105119)

![image](https://github.com/go-gitea/gitea/assets/15528715/6737b221-a3a2-4180-9ef8-b846c10f96e0)
tags/v1.22.0-rc0
Zettat123 3 months ago
parent
commit
4129e0e79b
No account linked to committer's email address

+ 8
- 8
models/user/email_address.go View File



// validateEmailDomain checks whether the email domain is allowed or blocked // validateEmailDomain checks whether the email domain is allowed or blocked
func validateEmailDomain(email string) error { func validateEmailDomain(email string) error {
// if there is no allow list, then check email against block list
if len(setting.Service.EmailDomainAllowList) == 0 &&
validation.IsEmailDomainListed(setting.Service.EmailDomainBlockList, email) {
if !IsEmailDomainAllowed(email) {
return ErrEmailInvalid{email} return ErrEmailInvalid{email}
} }


// if there is an allow list, then check email against allow list
if len(setting.Service.EmailDomainAllowList) > 0 &&
!validation.IsEmailDomainListed(setting.Service.EmailDomainAllowList, email) {
return ErrEmailInvalid{email}
return nil
}

func IsEmailDomainAllowed(email string) bool {
if len(setting.Service.EmailDomainAllowList) == 0 {
return !validation.IsEmailDomainListed(setting.Service.EmailDomainBlockList, email)
} }


return nil
return validation.IsEmailDomainListed(setting.Service.EmailDomainAllowList, email)
} }

+ 1
- 0
options/locale/locale_en-US.ini View File

team_no_units_error = Allow access to at least one repository section. team_no_units_error = Allow access to at least one repository section.
email_been_used = The email address is already used. email_been_used = The email address is already used.
email_invalid = The email address is invalid. email_invalid = The email address is invalid.
email_domain_is_not_allowed = The domain of user email <b>%s</b> conflicts with EMAIL_DOMAIN_ALLOWLIST or EMAIL_DOMAIN_BLOCKLIST. Please ensure your operation is expected.
openid_been_used = The OpenID address "%s" is already used. openid_been_used = The OpenID address "%s" is already used.
username_password_incorrect = Username or password is incorrect. username_password_incorrect = Username or password is incorrect.
password_complexity = Password does not pass complexity requirements: password_complexity = Password does not pass complexity requirements:

+ 9
- 0
routers/api/v1/admin/user.go View File

} }
return return
} }

if !user_model.IsEmailDomainAllowed(u.Email) {
ctx.Resp.Header().Add("X-Gitea-Warning", fmt.Sprintf("the domain of user email %s conflicts with EMAIL_DOMAIN_ALLOWLIST or EMAIL_DOMAIN_BLOCKLIST", u.Email))
}

log.Trace("Account created by admin (%s): %s", ctx.Doer.Name, u.Name) log.Trace("Account created by admin (%s): %s", ctx.Doer.Name, u.Name)


// Send email notification. // Send email notification.
} }
return return
} }

if !user_model.IsEmailDomainAllowed(*form.Email) {
ctx.Resp.Header().Add("X-Gitea-Warning", fmt.Sprintf("the domain of user email %s conflicts with EMAIL_DOMAIN_ALLOWLIST or EMAIL_DOMAIN_BLOCKLIST", *form.Email))
}
} }


opts := &user_service.UpdateOptions{ opts := &user_service.UpdateOptions{

+ 8
- 0
routers/web/admin/users.go View File

} }
return return
} }

if !user_model.IsEmailDomainAllowed(u.Email) {
ctx.Flash.Warning(ctx.Tr("form.email_domain_is_not_allowed", u.Email))
}

log.Trace("Account created by admin (%s): %s", ctx.Doer.Name, u.Name) log.Trace("Account created by admin (%s): %s", ctx.Doer.Name, u.Name)


// Send email notification. // Send email notification.
} }
return return
} }
if !user_model.IsEmailDomainAllowed(form.Email) {
ctx.Flash.Warning(ctx.Tr("form.email_domain_is_not_allowed", form.Email))
}
} }


opts := &user_service.UpdateOptions{ opts := &user_service.UpdateOptions{

+ 2
- 6
services/forms/user_form.go View File

"strings" "strings"


auth_model "code.gitea.io/gitea/models/auth" auth_model "code.gitea.io/gitea/models/auth"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/validation"
"code.gitea.io/gitea/modules/web/middleware" "code.gitea.io/gitea/modules/web/middleware"
"code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/context"


// domains in the whitelist or if it doesn't match any of // domains in the whitelist or if it doesn't match any of
// domains in the blocklist, if any such list is not empty. // domains in the blocklist, if any such list is not empty.
func (f *RegisterForm) IsEmailDomainAllowed() bool { func (f *RegisterForm) IsEmailDomainAllowed() bool {
if len(setting.Service.EmailDomainAllowList) == 0 {
return !validation.IsEmailDomainListed(setting.Service.EmailDomainBlockList, f.Email)
}

return validation.IsEmailDomainListed(setting.Service.EmailDomainAllowList, f.Email)
return user_model.IsEmailDomainAllowed(f.Email)
} }


// MustChangePasswordForm form for updating your password after account creation // MustChangePasswordForm form for updating your password after account creation

+ 4
- 2
tests/integration/api_admin_test.go View File

"password": "allowedUser1_pass", "password": "allowedUser1_pass",
"must_change_password": "true", "must_change_password": "true",
}).AddTokenAuth(token) }).AddTokenAuth(token)
MakeRequest(t, req, http.StatusCreated)
resp := MakeRequest(t, req, http.StatusCreated)
assert.Equal(t, "the domain of user email allowedUser1@example1.org conflicts with EMAIL_DOMAIN_ALLOWLIST or EMAIL_DOMAIN_BLOCKLIST", resp.Header().Get("X-Gitea-Warning"))


req = NewRequest(t, "DELETE", "/api/v1/admin/users/allowedUser1").AddTokenAuth(token) req = NewRequest(t, "DELETE", "/api/v1/admin/users/allowedUser1").AddTokenAuth(token)
MakeRequest(t, req, http.StatusNoContent) MakeRequest(t, req, http.StatusNoContent)
SourceID: 0, SourceID: 0,
Email: &newEmail, Email: &newEmail,
}).AddTokenAuth(token) }).AddTokenAuth(token)
MakeRequest(t, req, http.StatusOK)
resp := MakeRequest(t, req, http.StatusOK)
assert.Equal(t, "the domain of user email user2@example1.com conflicts with EMAIL_DOMAIN_ALLOWLIST or EMAIL_DOMAIN_BLOCKLIST", resp.Header().Get("X-Gitea-Warning"))


originalEmail := "user2@example.com" originalEmail := "user2@example.com"
req = NewRequestWithJSON(t, "PATCH", urlStr, api.EditUserOption{ req = NewRequestWithJSON(t, "PATCH", urlStr, api.EditUserOption{

Loading…
Cancel
Save