do not require password for external registration
This commit is contained in:
parent
ee0fa3e58f
commit
e64ff60c13
|
@ -74,7 +74,7 @@ func (f *InstallForm) Validate(ctx *macaron.Context, errs binding.Errors) bindin
|
||||||
type RegisterForm struct {
|
type RegisterForm struct {
|
||||||
UserName string `binding:"Required;AlphaDashDot;MaxSize(35)"`
|
UserName string `binding:"Required;AlphaDashDot;MaxSize(35)"`
|
||||||
Email string `binding:"Required;Email;MaxSize(254)"`
|
Email string `binding:"Required;Email;MaxSize(254)"`
|
||||||
Password string `binding:"Required;MaxSize(255)"`
|
Password string `binding:"MaxSize(255)"`
|
||||||
Retype string
|
Retype string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,6 +86,7 @@ func (f *RegisterForm) Validate(ctx *macaron.Context, errs binding.Errors) bindi
|
||||||
// SignInForm form for signing in with user/password
|
// SignInForm form for signing in with user/password
|
||||||
type SignInForm struct {
|
type SignInForm struct {
|
||||||
UserName string `binding:"Required;MaxSize(254)"`
|
UserName string `binding:"Required;MaxSize(254)"`
|
||||||
|
// TODO remove required from password for SecondFactorAuthentication
|
||||||
Password string `binding:"Required;MaxSize(255)"`
|
Password string `binding:"Required;MaxSize(255)"`
|
||||||
Remember bool
|
Remember bool
|
||||||
}
|
}
|
||||||
|
|
|
@ -1165,6 +1165,8 @@ var Service struct {
|
||||||
EnableReverseProxyAuth bool
|
EnableReverseProxyAuth bool
|
||||||
EnableReverseProxyAutoRegister bool
|
EnableReverseProxyAutoRegister bool
|
||||||
EnableCaptcha bool
|
EnableCaptcha bool
|
||||||
|
RequireExternalRegistrationCaptcha bool
|
||||||
|
RequireExternalRegistrationPassword bool
|
||||||
DefaultKeepEmailPrivate bool
|
DefaultKeepEmailPrivate bool
|
||||||
DefaultAllowCreateOrganization bool
|
DefaultAllowCreateOrganization bool
|
||||||
EnableTimetracking bool
|
EnableTimetracking bool
|
||||||
|
@ -1190,6 +1192,8 @@ func newService() {
|
||||||
Service.EnableReverseProxyAuth = sec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION").MustBool()
|
Service.EnableReverseProxyAuth = sec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION").MustBool()
|
||||||
Service.EnableReverseProxyAutoRegister = sec.Key("ENABLE_REVERSE_PROXY_AUTO_REGISTRATION").MustBool()
|
Service.EnableReverseProxyAutoRegister = sec.Key("ENABLE_REVERSE_PROXY_AUTO_REGISTRATION").MustBool()
|
||||||
Service.EnableCaptcha = sec.Key("ENABLE_CAPTCHA").MustBool()
|
Service.EnableCaptcha = sec.Key("ENABLE_CAPTCHA").MustBool()
|
||||||
|
Service.RequireExternalRegistrationCaptcha = sec.Key("REQUIRE_EXTERNAL_REGISTRATION_CAPTCHA").MustBool()
|
||||||
|
Service.RequireExternalRegistrationPassword = sec.Key("REQUIRE_EXTERNAL_REGISTRATION_PASSWORD").MustBool()
|
||||||
Service.DefaultKeepEmailPrivate = sec.Key("DEFAULT_KEEP_EMAIL_PRIVATE").MustBool()
|
Service.DefaultKeepEmailPrivate = sec.Key("DEFAULT_KEEP_EMAIL_PRIVATE").MustBool()
|
||||||
Service.DefaultAllowCreateOrganization = sec.Key("DEFAULT_ALLOW_CREATE_ORGANIZATION").MustBool(true)
|
Service.DefaultAllowCreateOrganization = sec.Key("DEFAULT_ALLOW_CREATE_ORGANIZATION").MustBool(true)
|
||||||
Service.EnableTimetracking = sec.Key("ENABLE_TIMETRACKING").MustBool(true)
|
Service.EnableTimetracking = sec.Key("ENABLE_TIMETRACKING").MustBool(true)
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
package user
|
package user
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -123,6 +125,7 @@ func SignIn(ctx *context.Context) {
|
||||||
ctx.Data["OAuth2Providers"] = oauth2Providers
|
ctx.Data["OAuth2Providers"] = oauth2Providers
|
||||||
ctx.Data["Title"] = ctx.Tr("sign_in")
|
ctx.Data["Title"] = ctx.Tr("sign_in")
|
||||||
ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login"
|
ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login"
|
||||||
|
ctx.Data["AllowPassword"] = true
|
||||||
ctx.Data["PageIsSignIn"] = true
|
ctx.Data["PageIsSignIn"] = true
|
||||||
ctx.Data["PageIsLogin"] = true
|
ctx.Data["PageIsLogin"] = true
|
||||||
|
|
||||||
|
@ -142,6 +145,7 @@ func SignInPost(ctx *context.Context, form auth.SignInForm) {
|
||||||
ctx.Data["OAuth2Providers"] = oauth2Providers
|
ctx.Data["OAuth2Providers"] = oauth2Providers
|
||||||
ctx.Data["Title"] = ctx.Tr("sign_in")
|
ctx.Data["Title"] = ctx.Tr("sign_in")
|
||||||
ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login"
|
ctx.Data["SignInLink"] = setting.AppSubURL + "/user/login"
|
||||||
|
ctx.Data["AllowPassword"] = true
|
||||||
ctx.Data["PageIsSignIn"] = true
|
ctx.Data["PageIsSignIn"] = true
|
||||||
ctx.Data["PageIsLogin"] = true
|
ctx.Data["PageIsLogin"] = true
|
||||||
|
|
||||||
|
@ -641,7 +645,8 @@ func oAuth2UserLoginCallback(loginSource *models.LoginSource, request *http.Requ
|
||||||
func LinkAccount(ctx *context.Context) {
|
func LinkAccount(ctx *context.Context) {
|
||||||
ctx.Data["Title"] = ctx.Tr("link_account")
|
ctx.Data["Title"] = ctx.Tr("link_account")
|
||||||
ctx.Data["LinkAccountMode"] = true
|
ctx.Data["LinkAccountMode"] = true
|
||||||
ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha
|
ctx.Data["EnableCaptcha"] = setting.Service.RequireExternalRegistrationCaptcha //&& setting.Service.EnableCaptcha
|
||||||
|
ctx.Data["AllowPassword"] = setting.Service.RequireExternalRegistrationPassword && !setting.Service.AllowOnlyExternalRegistration
|
||||||
ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration
|
ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration
|
||||||
ctx.Data["ShowRegistrationButton"] = false
|
ctx.Data["ShowRegistrationButton"] = false
|
||||||
|
|
||||||
|
@ -688,7 +693,9 @@ func LinkAccountPostSignIn(ctx *context.Context, signInForm auth.SignInForm) {
|
||||||
ctx.Data["Title"] = ctx.Tr("link_account")
|
ctx.Data["Title"] = ctx.Tr("link_account")
|
||||||
ctx.Data["LinkAccountMode"] = true
|
ctx.Data["LinkAccountMode"] = true
|
||||||
ctx.Data["LinkAccountModeSignIn"] = true
|
ctx.Data["LinkAccountModeSignIn"] = true
|
||||||
ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha
|
ctx.Data["EnableCaptcha"] = setting.Service.RequireExternalRegistrationCaptcha //&& setting.Service.EnableCaptcha
|
||||||
|
// Only allow a password if local login is enabled (TODO) except if SecondFactorAuthentication is enabled
|
||||||
|
ctx.Data["AllowPassword"] = !setting.Service.AllowOnlyExternalRegistration
|
||||||
ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration
|
ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration
|
||||||
ctx.Data["ShowRegistrationButton"] = false
|
ctx.Data["ShowRegistrationButton"] = false
|
||||||
|
|
||||||
|
@ -754,7 +761,9 @@ func LinkAccountPostRegister(ctx *context.Context, cpt *captcha.Captcha, form au
|
||||||
ctx.Data["Title"] = ctx.Tr("link_account")
|
ctx.Data["Title"] = ctx.Tr("link_account")
|
||||||
ctx.Data["LinkAccountMode"] = true
|
ctx.Data["LinkAccountMode"] = true
|
||||||
ctx.Data["LinkAccountModeRegister"] = true
|
ctx.Data["LinkAccountModeRegister"] = true
|
||||||
ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha
|
ctx.Data["EnableCaptcha"] = setting.Service.RequireExternalRegistrationCaptcha //&& setting.Service.EnableCaptcha
|
||||||
|
// TODO implement the same for local accounts, once email-based Second Factor Auth is available
|
||||||
|
ctx.Data["AllowPassword"] = setting.Service.RequireExternalRegistrationPassword && !setting.Service.AllowOnlyExternalRegistration
|
||||||
ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration
|
ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration
|
||||||
ctx.Data["ShowRegistrationButton"] = false
|
ctx.Data["ShowRegistrationButton"] = false
|
||||||
|
|
||||||
|
@ -778,21 +787,35 @@ func LinkAccountPostRegister(ctx *context.Context, cpt *captcha.Captcha, form au
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if setting.Service.EnableCaptcha && !cpt.VerifyReq(ctx.Req) {
|
if setting.Service.RequireExternalRegistrationCaptcha && !cpt.VerifyReq(ctx.Req) {
|
||||||
ctx.Data["Err_Captcha"] = true
|
ctx.Data["Err_Captcha"] = true
|
||||||
ctx.RenderWithErr(ctx.Tr("form.captcha_incorrect"), tplLinkAccount, &form)
|
ctx.RenderWithErr(ctx.Tr("form.captcha_incorrect"), tplLinkAccount, &form)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len(strings.TrimSpace(form.Password)) > 0 || len(strings.TrimSpace(form.Retype)) > 0) && form.Password != form.Retype {
|
if setting.Service.AllowOnlyExternalRegistration || !setting.Service.RequireExternalRegistrationPassword {
|
||||||
ctx.Data["Err_Password"] = true
|
// Generating a random password a stop-gap shim to get around the password requirement
|
||||||
ctx.RenderWithErr(ctx.Tr("form.password_not_match"), tplLinkAccount, &form)
|
// Eventually the database should be changed to indicate "Second Factor" enabled accounts
|
||||||
return
|
// that do not introduce the security vulnerabilities of a password
|
||||||
}
|
bytes := make([]byte, 16)
|
||||||
if len(strings.TrimSpace(form.Password)) > 0 && len(form.Password) < setting.MinPasswordLength {
|
_, err := rand.Read(bytes)
|
||||||
ctx.Data["Err_Password"] = true
|
if nil != err {
|
||||||
ctx.RenderWithErr(ctx.Tr("auth.password_too_short", setting.MinPasswordLength), tplLinkAccount, &form)
|
ctx.ServerError("CreateUser", err)
|
||||||
return
|
return
|
||||||
|
}
|
||||||
|
form.Password = hex.EncodeToString(bytes)
|
||||||
|
} else {
|
||||||
|
// TODO Retype password should move to frontend JavaScript, not be required by server
|
||||||
|
if (len(strings.TrimSpace(form.Password)) > 0 || len(strings.TrimSpace(form.Retype)) > 0) && form.Password != form.Retype {
|
||||||
|
ctx.Data["Err_Password"] = true
|
||||||
|
ctx.RenderWithErr(ctx.Tr("form.password_not_match"), tplLinkAccount, &form)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if len(strings.TrimSpace(form.Password)) > 0 && len(form.Password) < setting.MinPasswordLength {
|
||||||
|
ctx.Data["Err_Password"] = true
|
||||||
|
ctx.RenderWithErr(ctx.Tr("auth.password_too_short", setting.MinPasswordLength), tplLinkAccount, &form)
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loginSource, err := models.GetActiveOAuth2LoginSourceByName(gothUser.(goth.User).Provider)
|
loginSource, err := models.GetActiveOAuth2LoginSourceByName(gothUser.(goth.User).Provider)
|
||||||
|
@ -881,6 +904,8 @@ func SignUp(ctx *context.Context) {
|
||||||
|
|
||||||
ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha
|
ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha
|
||||||
|
|
||||||
|
ctx.Data["AllowPassword"] = true
|
||||||
|
|
||||||
ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration
|
ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration
|
||||||
|
|
||||||
ctx.HTML(200, tplSignUp)
|
ctx.HTML(200, tplSignUp)
|
||||||
|
@ -894,6 +919,8 @@ func SignUpPost(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterFo
|
||||||
|
|
||||||
ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha
|
ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha
|
||||||
|
|
||||||
|
ctx.Data["AllowPassword"] = true
|
||||||
|
|
||||||
//Permission denied if DisableRegistration or AllowOnlyExternalRegistration options are true
|
//Permission denied if DisableRegistration or AllowOnlyExternalRegistration options are true
|
||||||
if !setting.Service.ShowRegistrationButton {
|
if !setting.Service.ShowRegistrationButton {
|
||||||
ctx.Error(403)
|
ctx.Error(403)
|
||||||
|
|
|
@ -15,10 +15,12 @@
|
||||||
<label for="user_name">{{.i18n.Tr "home.uname_holder"}}</label>
|
<label for="user_name">{{.i18n.Tr "home.uname_holder"}}</label>
|
||||||
<input id="user_name" name="user_name" value="{{.user_name}}" autofocus required>
|
<input id="user_name" name="user_name" value="{{.user_name}}" autofocus required>
|
||||||
</div>
|
</div>
|
||||||
|
{{if .AllowPassword}}
|
||||||
<div class="required inline field {{if and (.Err_Password) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeSignIn))}}error{{end}}">
|
<div class="required inline field {{if and (.Err_Password) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeSignIn))}}error{{end}}">
|
||||||
<label for="password">{{.i18n.Tr "password"}}</label>
|
<label for="password">{{.i18n.Tr "password"}}</label>
|
||||||
<input id="password" name="password" type="password" value="{{.password}}" autocomplete="off" required>
|
<input id="password" name="password" type="password" value="{{.password}}" autocomplete="off" required>
|
||||||
</div>
|
</div>
|
||||||
|
{{end}}
|
||||||
{{if not .LinkAccountMode}}
|
{{if not .LinkAccountMode}}
|
||||||
<div class="inline field">
|
<div class="inline field">
|
||||||
<label></label>
|
<label></label>
|
||||||
|
|
|
@ -25,14 +25,16 @@
|
||||||
<label for="email">{{.i18n.Tr "email"}}</label>
|
<label for="email">{{.i18n.Tr "email"}}</label>
|
||||||
<input id="email" name="email" type="email" value="{{.email}}" required>
|
<input id="email" name="email" type="email" value="{{.email}}" required>
|
||||||
</div>
|
</div>
|
||||||
<div class="required inline field {{if and (.Err_Password) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeRegister))}}error{{end}}">
|
{{if .AllowPassword}}
|
||||||
<label for="password">{{.i18n.Tr "password"}}</label>
|
<div class="required inline field {{if and (.Err_Password) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeRegister))}}error{{end}}">
|
||||||
<input id="password" name="password" type="password" value="{{.password}}" autocomplete="off" required>
|
<label for="password">{{.i18n.Tr "password"}}</label>
|
||||||
</div>
|
<input id="password" name="password" type="password" value="{{.password}}" autocomplete="off" required>
|
||||||
<div class="required inline field {{if and (.Err_Password) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeRegister))}}error{{end}}">
|
</div>
|
||||||
<label for="retype">{{.i18n.Tr "re_type"}}</label>
|
<div class="required inline field {{if and (.Err_Password) (or (not .LinkAccountMode) (and .LinkAccountMode .LinkAccountModeRegister))}}error{{end}}">
|
||||||
<input id="retype" name="retype" type="password" value="{{.retype}}" autocomplete="off" required>
|
<label for="retype">{{.i18n.Tr "re_type"}}</label>
|
||||||
</div>
|
<input id="retype" name="retype" type="password" value="{{.retype}}" autocomplete="off" required>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
{{if .EnableCaptcha}}
|
{{if .EnableCaptcha}}
|
||||||
<div class="inline field">
|
<div class="inline field">
|
||||||
<label></label>
|
<label></label>
|
||||||
|
|
Loading…
Reference in New Issue