Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Block registration based on email domain #5157

Merged
Next Next commit
implement email domain whitelist
  • Loading branch information
adelowo committed Oct 23, 2018
commit e672015264722841c0e8a24590546dad2b59c0bf
3 changes: 3 additions & 0 deletions custom/conf/app.ini.sample
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,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=
adelowo marked this conversation as resolved.
Show resolved Hide resolved
; 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
Expand Down
2 changes: 2 additions & 0 deletions docs/content/doc/advanced/config-cheat-sheet.en-us.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`)

Expand Down
28 changes: 28 additions & 0 deletions modules/auth/user_form.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ package auth

import (
"mime/multipart"
"strings"
adelowo marked this conversation as resolved.
Show resolved Hide resolved

"code.gitea.io/gitea/modules/setting"

"github.com/go-macaron/binding"
"gopkg.in/macaron.v1"
Expand Down Expand Up @@ -84,6 +87,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 {
adelowo marked this conversation as resolved.
Show resolved Hide resolved
if len(setting.Service.EmailDomainWhitelist) == 0 {
return true
}

n := strings.LastIndex(f.Email, "@")
if n <= 0 {
return false
}

domain := f.Email[n+1:]
adelowo marked this conversation as resolved.
Show resolved Hide resolved

for _, v := range setting.Service.EmailDomainWhitelist {
if v == domain {
adelowo marked this conversation as resolved.
Show resolved Hide resolved
return true
}
}

return false
}

// MustChangePasswordForm form for updating your password after account creation
// by an admin
type MustChangePasswordForm struct {
Expand Down
63 changes: 63 additions & 0 deletions modules/auth/user_form_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// 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
}{
{"[email protected]", true},
{"hdudhdd", false},
{"[email protected]", false},
}

for _, v := range tt {
form := RegisterForm{Email: v.email}

assert.Equal(t, v.valid, form.IsEmailDomainWhitelisted())
}
}
3 changes: 2 additions & 1 deletion modules/setting/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import (
"code.gitea.io/gitea/modules/log"
_ "code.gitea.io/gitea/modules/minwinsvc" // import minwinsvc for windows services
"code.gitea.io/gitea/modules/user"

adelowo marked this conversation as resolved.
Show resolved Hide resolved
"github.com/Unknwon/com"
_ "github.com/go-macaron/cache/memcache" // memcache plugin for cache
_ "github.com/go-macaron/cache/redis"
Expand Down Expand Up @@ -1200,6 +1199,7 @@ var Service struct {
ActiveCodeLives int
ResetPwdCodeLives int
RegisterEmailConfirm bool
EmailDomainWhitelist []string
DisableRegistration bool
AllowOnlyExternalRegistration bool
ShowRegistrationButton bool
Expand Down Expand Up @@ -1233,6 +1233,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()
Expand Down
1 change: 1 addition & 0 deletions options/locale/locale_en-US.ini
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,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
Expand Down
6 changes: 5 additions & 1 deletion routers/user/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"code.gitea.io/gitea/modules/recaptcha"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"

adelowo marked this conversation as resolved.
Show resolved Hide resolved
"github.com/go-macaron/captcha"
"github.com/markbates/goth"
"github.com/tstranex/u2f"
Expand Down Expand Up @@ -926,6 +925,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)
Expand Down