]> source.dussan.org Git - gitea.git/commitdiff
Block registration based on email domain (#5157)
authorLanre Adelowo <adelowomailbox@gmail.com>
Thu, 15 Nov 2018 01:00:04 +0000 (02:00 +0100)
committertechknowlogick <hello@techknowlogick.com>
Thu, 15 Nov 2018 01:00:04 +0000 (20:00 -0500)
* implement email domain whitelist

custom/conf/app.ini.sample
docs/content/doc/advanced/config-cheat-sheet.en-us.md
modules/auth/user_form.go
modules/auth/user_form_test.go [new file with mode: 0644]
modules/setting/setting.go
options/locale/locale_en-US.ini
routers/user/auth.go

index f42fa122b8175379dfb8bad14d650745ed779dd4..92d72e8c9bbee3854f6614be6773c92e26ac7672 100644 (file)
@@ -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
index b0ab78d2f14af0225cbbbf4ed71d9b46ff89fb94..a3bded679df18faed0e110f9bdf55e0eac6e8b28 100644 (file)
@@ -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`)
 
index 43ddb29c76e6893bff316f0a6c979ad586a1bdd4..c281672fe12118f439a31f2377eea7b14224c3cf 100644 (file)
@@ -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 {
diff --git a/modules/auth/user_form_test.go b/modules/auth/user_form_test.go
new file mode 100644 (file)
index 0000000..0841746
--- /dev/null
@@ -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())
+       }
+}
index b31162c140bf42a9516bdd54a1c92142bc6558b0..b0bcd2ead854949536e080c837eb10bc4227e995 100644 (file)
@@ -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()
index a82acc3dd10f4e8542fd826c3847f23324aeb098..f806d631ea87142da080bf4ec5dec81ae348e225 100644 (file)
@@ -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
index 25aa437efdbbd4647b1f8914952cf0e36d06c0cc..24b35e6f62274450c9b7d7ef59f3a4b5f9c02e78 100644 (file)
@@ -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)