Block registration based on email domain (#5157)
* implement email domain whitelist
This commit is contained in:
parent
4c1f1f9646
commit
b97af15de6
7 changed files with 106 additions and 0 deletions
|
@ -311,6 +311,9 @@ ACTIVE_CODE_LIVE_MINUTES = 180
|
||||||
RESET_PASSWD_CODE_LIVE_MINUTES = 180
|
RESET_PASSWD_CODE_LIVE_MINUTES = 180
|
||||||
; Whether a new user needs to confirm their email when registering.
|
; Whether a new user needs to confirm their email when registering.
|
||||||
REGISTER_EMAIL_CONFIRM = false
|
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.
|
; Disallow registration, only allow admins to create accounts.
|
||||||
DISABLE_REGISTRATION = false
|
DISABLE_REGISTRATION = false
|
||||||
; Allow registration only using third part services, it works only when DISABLE_REGISTRATION is 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.
|
- `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.
|
- `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.
|
- `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`)
|
## Webhook (`webhook`)
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// Copyright 2014 The Gogs Authors. All rights reserved.
|
// 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
|
// Use of this source code is governed by a MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
@ -6,6 +7,9 @@ package auth
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"mime/multipart"
|
"mime/multipart"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
|
||||||
"github.com/go-macaron/binding"
|
"github.com/go-macaron/binding"
|
||||||
"gopkg.in/macaron.v1"
|
"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)
|
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
|
// MustChangePasswordForm form for updating your password after account creation
|
||||||
// by an admin
|
// by an admin
|
||||||
type MustChangePasswordForm struct {
|
type MustChangePasswordForm struct {
|
||||||
|
|
64
modules/auth/user_form_test.go
Normal file
64
modules/auth/user_form_test.go
Normal file
|
@ -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
|
ActiveCodeLives int
|
||||||
ResetPwdCodeLives int
|
ResetPwdCodeLives int
|
||||||
RegisterEmailConfirm bool
|
RegisterEmailConfirm bool
|
||||||
|
EmailDomainWhitelist []string
|
||||||
DisableRegistration bool
|
DisableRegistration bool
|
||||||
AllowOnlyExternalRegistration bool
|
AllowOnlyExternalRegistration bool
|
||||||
ShowRegistrationButton bool
|
ShowRegistrationButton bool
|
||||||
|
@ -1248,6 +1249,7 @@ func newService() {
|
||||||
Service.ResetPwdCodeLives = sec.Key("RESET_PASSWD_CODE_LIVE_MINUTES").MustInt(180)
|
Service.ResetPwdCodeLives = sec.Key("RESET_PASSWD_CODE_LIVE_MINUTES").MustInt(180)
|
||||||
Service.DisableRegistration = sec.Key("DISABLE_REGISTRATION").MustBool()
|
Service.DisableRegistration = sec.Key("DISABLE_REGISTRATION").MustBool()
|
||||||
Service.AllowOnlyExternalRegistration = sec.Key("ALLOW_ONLY_EXTERNAL_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.ShowRegistrationButton = sec.Key("SHOW_REGISTRATION_BUTTON").MustBool(!(Service.DisableRegistration || Service.AllowOnlyExternalRegistration))
|
||||||
Service.RequireSignInView = sec.Key("REQUIRE_SIGNIN_VIEW").MustBool()
|
Service.RequireSignInView = sec.Key("REQUIRE_SIGNIN_VIEW").MustBool()
|
||||||
Service.EnableReverseProxyAuth = sec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION").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_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.
|
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.
|
disable_forgot_password_mail = Password reset is disabled. Please contact your site administrator.
|
||||||
|
email_domain_blacklisted = You cannot register with your email address.
|
||||||
|
|
||||||
[mail]
|
[mail]
|
||||||
activate_account = Please activate your account
|
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 {
|
if form.Password != form.Retype {
|
||||||
ctx.Data["Err_Password"] = true
|
ctx.Data["Err_Password"] = true
|
||||||
ctx.RenderWithErr(ctx.Tr("form.password_not_match"), tplSignUp, &form)
|
ctx.RenderWithErr(ctx.Tr("form.password_not_match"), tplSignUp, &form)
|
||||||
|
|
Reference in a new issue