Block registration based on email domain (#5157)
* implement email domain whitelist
This commit is contained in:
		
							parent
							
								
									4c1f1f9646
								
							
						
					
					
						commit
						b97af15de6
					
				|  | @ -311,6 +311,9 @@ ACTIVE_CODE_LIVE_MINUTES = 180 | |||
| RESET_PASSWD_CODE_LIVE_MINUTES = 180 | ||||
| ; Whether a new user needs to confirm their email when registering. | ||||
| REGISTER_EMAIL_CONFIRM = false | ||||
| ; List of domain names that are allowed to be used to register on a Gitea instance | ||||
| ; gitea.io,example.com | ||||
| EMAIL_DOMAIN_WHITELIST= | ||||
| ; Disallow registration, only allow admins to create accounts. | ||||
| DISABLE_REGISTRATION = false | ||||
| ; Allow registration only using third part services, it works only when DISABLE_REGISTRATION is false | ||||
|  |  | |||
|  | @ -194,6 +194,8 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`. | |||
| - `RECAPTCHA_SITEKEY`: **""**: Go to https://www.google.com/recaptcha/admin to get a sitekey for recaptcha. | ||||
| - `DEFAULT_ENABLE_DEPENDENCIES`: **true** Enable this to have dependencies enabled by default. | ||||
| - `ENABLE_USER_HEATMAP`: **true** Enable this to display the heatmap on users profiles. | ||||
| - `EMAIL_DOMAIN_WHITELIST`: **\<empty\>**: If non-empty, list of domain names that can only be used to register | ||||
|   on this instance. | ||||
| 
 | ||||
| ## Webhook (`webhook`) | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,4 +1,5 @@ | |||
| // Copyright 2014 The Gogs Authors. All rights reserved.
 | ||||
| // Copyright 2018 The Gitea Authors. All rights reserved.
 | ||||
| // Use of this source code is governed by a MIT-style
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
|  | @ -6,6 +7,9 @@ package auth | |||
| 
 | ||||
| import ( | ||||
| 	"mime/multipart" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 
 | ||||
| 	"github.com/go-macaron/binding" | ||||
| 	"gopkg.in/macaron.v1" | ||||
|  | @ -84,6 +88,31 @@ func (f *RegisterForm) Validate(ctx *macaron.Context, errs binding.Errors) bindi | |||
| 	return validate(errs, ctx.Data, f, ctx.Locale) | ||||
| } | ||||
| 
 | ||||
| // IsEmailDomainWhitelisted validates that the email address
 | ||||
| // provided by the user matches what has been configured .
 | ||||
| // If the domain whitelist from the config is empty, it marks the
 | ||||
| // email as whitelisted
 | ||||
| func (f RegisterForm) IsEmailDomainWhitelisted() bool { | ||||
| 	if len(setting.Service.EmailDomainWhitelist) == 0 { | ||||
| 		return true | ||||
| 	} | ||||
| 
 | ||||
| 	n := strings.LastIndex(f.Email, "@") | ||||
| 	if n <= 0 { | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	domain := strings.ToLower(f.Email[n+1:]) | ||||
| 
 | ||||
| 	for _, v := range setting.Service.EmailDomainWhitelist { | ||||
| 		if strings.ToLower(v) == domain { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| // MustChangePasswordForm form for updating your password after account creation
 | ||||
| // by an admin
 | ||||
| type MustChangePasswordForm struct { | ||||
|  |  | |||
|  | @ -0,0 +1,64 @@ | |||
| // Copyright 2018 The Gogs Authors. All rights reserved.
 | ||||
| // Use of this source code is governed by a MIT-style
 | ||||
| // license that can be found in the LICENSE file.
 | ||||
| 
 | ||||
| package auth | ||||
| 
 | ||||
| import ( | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
| 
 | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
| 
 | ||||
| func TestRegisterForm_IsDomainWhiteList_Empty(t *testing.T) { | ||||
| 	_ = setting.Service | ||||
| 
 | ||||
| 	setting.Service.EmailDomainWhitelist = []string{} | ||||
| 
 | ||||
| 	form := RegisterForm{} | ||||
| 
 | ||||
| 	assert.True(t, form.IsEmailDomainWhitelisted()) | ||||
| } | ||||
| 
 | ||||
| func TestRegisterForm_IsDomainWhiteList_InvalidEmail(t *testing.T) { | ||||
| 	_ = setting.Service | ||||
| 
 | ||||
| 	setting.Service.EmailDomainWhitelist = []string{"gitea.io"} | ||||
| 
 | ||||
| 	tt := []struct { | ||||
| 		email string | ||||
| 	}{ | ||||
| 		{"securitygieqqq"}, | ||||
| 		{"hdudhdd"}, | ||||
| 	} | ||||
| 
 | ||||
| 	for _, v := range tt { | ||||
| 		form := RegisterForm{Email: v.email} | ||||
| 
 | ||||
| 		assert.False(t, form.IsEmailDomainWhitelisted()) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func TestRegisterForm_IsDomainWhiteList_ValidEmail(t *testing.T) { | ||||
| 	_ = setting.Service | ||||
| 
 | ||||
| 	setting.Service.EmailDomainWhitelist = []string{"gitea.io"} | ||||
| 
 | ||||
| 	tt := []struct { | ||||
| 		email string | ||||
| 		valid bool | ||||
| 	}{ | ||||
| 		{"security@gitea.io", true}, | ||||
| 		{"security@gITea.io", true}, | ||||
| 		{"hdudhdd", false}, | ||||
| 		{"seee@example.com", false}, | ||||
| 	} | ||||
| 
 | ||||
| 	for _, v := range tt { | ||||
| 		form := RegisterForm{Email: v.email} | ||||
| 
 | ||||
| 		assert.Equal(t, v.valid, form.IsEmailDomainWhitelisted()) | ||||
| 	} | ||||
| } | ||||
|  | @ -1215,6 +1215,7 @@ var Service struct { | |||
| 	ActiveCodeLives                         int | ||||
| 	ResetPwdCodeLives                       int | ||||
| 	RegisterEmailConfirm                    bool | ||||
| 	EmailDomainWhitelist                    []string | ||||
| 	DisableRegistration                     bool | ||||
| 	AllowOnlyExternalRegistration           bool | ||||
| 	ShowRegistrationButton                  bool | ||||
|  | @ -1248,6 +1249,7 @@ func newService() { | |||
| 	Service.ResetPwdCodeLives = sec.Key("RESET_PASSWD_CODE_LIVE_MINUTES").MustInt(180) | ||||
| 	Service.DisableRegistration = sec.Key("DISABLE_REGISTRATION").MustBool() | ||||
| 	Service.AllowOnlyExternalRegistration = sec.Key("ALLOW_ONLY_EXTERNAL_REGISTRATION").MustBool() | ||||
| 	Service.EmailDomainWhitelist = sec.Key("EMAIL_DOMAIN_WHITELIST").Strings(",") | ||||
| 	Service.ShowRegistrationButton = sec.Key("SHOW_REGISTRATION_BUTTON").MustBool(!(Service.DisableRegistration || Service.AllowOnlyExternalRegistration)) | ||||
| 	Service.RequireSignInView = sec.Key("REQUIRE_SIGNIN_VIEW").MustBool() | ||||
| 	Service.EnableReverseProxyAuth = sec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION").MustBool() | ||||
|  |  | |||
|  | @ -242,6 +242,7 @@ openid_register_title = Create new account | |||
| openid_register_desc = The chosen OpenID URI is unknown. Associate it with a new account here. | ||||
| openid_signin_desc = Enter your OpenID URI. For example: https://anne.me, bob.openid.org.cn or gnusocial.net/carry. | ||||
| disable_forgot_password_mail = Password reset is disabled. Please contact your site administrator. | ||||
| email_domain_blacklisted = You cannot register with your email address. | ||||
| 
 | ||||
| [mail] | ||||
| activate_account = Please activate your account | ||||
|  |  | |||
|  | @ -948,6 +948,11 @@ func SignUpPost(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterFo | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if !form.IsEmailDomainWhitelisted() { | ||||
| 		ctx.RenderWithErr(ctx.Tr("auth.email_domain_blacklisted"), tplSignUp, &form) | ||||
| 		return | ||||
| 	} | ||||
| 
 | ||||
| 	if form.Password != form.Retype { | ||||
| 		ctx.Data["Err_Password"] = true | ||||
| 		ctx.RenderWithErr(ctx.Tr("form.password_not_match"), tplSignUp, &form) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue