Add Recaptcha functionality to Gitea (#4044)
This commit is contained in:
		
							parent
							
								
									54fedd4070
								
							
						
					
					
						commit
						f035dcd4f2
					
				
					 13 changed files with 163 additions and 15 deletions
				
			
		|  | @ -301,7 +301,13 @@ ENABLE_NOTIFY_MAIL = false | ||||||
| ENABLE_REVERSE_PROXY_AUTHENTICATION = false | ENABLE_REVERSE_PROXY_AUTHENTICATION = false | ||||||
| ENABLE_REVERSE_PROXY_AUTO_REGISTRATION = false | ENABLE_REVERSE_PROXY_AUTO_REGISTRATION = false | ||||||
| ; Enable captcha validation for registration | ; Enable captcha validation for registration | ||||||
| ENABLE_CAPTCHA = true | ENABLE_CAPTCHA = false | ||||||
|  | ; Type of captcha you want to use. Options: image, recaptcha | ||||||
|  | CAPTCHA_TYPE = image | ||||||
|  | ; Enable recaptcha to use Google's recaptcha service | ||||||
|  | ; Go to https://www.google.com/recaptcha/admin to sign up for a key | ||||||
|  | RECAPTCHA_SECRET  =  | ||||||
|  | RECAPTCHA_SITEKEY =  | ||||||
| ; Default value for KeepEmailPrivate | ; Default value for KeepEmailPrivate | ||||||
| ; Each new user will get the value of this setting copied into their profile | ; Each new user will get the value of this setting copied into their profile | ||||||
| DEFAULT_KEEP_EMAIL_PRIVATE = false | DEFAULT_KEEP_EMAIL_PRIVATE = false | ||||||
|  |  | ||||||
|  | @ -177,7 +177,10 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`. | ||||||
| - `ENABLE_REVERSE_PROXY_AUTHENTICATION`: **false**: Enable this to allow reverse proxy authentication. | - `ENABLE_REVERSE_PROXY_AUTHENTICATION`: **false**: Enable this to allow reverse proxy authentication. | ||||||
| - `ENABLE_REVERSE_PROXY_AUTO_REGISTRATION`: **false**: Enable this to allow auto-registration | - `ENABLE_REVERSE_PROXY_AUTO_REGISTRATION`: **false**: Enable this to allow auto-registration | ||||||
|    for reverse authentication. |    for reverse authentication. | ||||||
| - `ENABLE_CAPTCHA`: **true**: Enable this to use captcha validation for registration. | - `ENABLE_CAPTCHA`: **false**: Enable this to use captcha validation for registration. | ||||||
|  | - `CAPTCHA_TYPE`: **image**: \[image, recaptcha\] | ||||||
|  | - `RECAPTCHA_SECRET`: **""**: Go to https://www.google.com/recaptcha/admin to get a secret for recaptcha  | ||||||
|  | - `RECAPTCHA_SITEKEY`: **""**: Go to https://www.google.com/recaptcha/admin to get a sitekey for recaptcha | ||||||
| 
 | 
 | ||||||
| ## Webhook (`webhook`) | ## Webhook (`webhook`) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -72,10 +72,11 @@ func (f *InstallForm) Validate(ctx *macaron.Context, errs binding.Errors) bindin | ||||||
| 
 | 
 | ||||||
| // RegisterForm form for registering
 | // RegisterForm form for registering
 | ||||||
| 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:"Required;MaxSize(255)"` | ||||||
| 	Retype   string | 	Retype             string | ||||||
|  | 	GRecaptchaResponse string `form:"g-recaptcha-response"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Validate valideates the fields
 | // Validate valideates the fields
 | ||||||
|  |  | ||||||
|  | @ -22,8 +22,9 @@ func (f *SignInOpenIDForm) Validate(ctx *macaron.Context, errs binding.Errors) b | ||||||
| 
 | 
 | ||||||
| // SignUpOpenIDForm form for signin up with OpenID
 | // SignUpOpenIDForm form for signin up with OpenID
 | ||||||
| type SignUpOpenIDForm struct { | type SignUpOpenIDForm 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)"` | ||||||
|  | 	GRecaptchaResponse string `form:"g-recaptcha-response"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Validate valideates the fields
 | // Validate valideates the fields
 | ||||||
|  |  | ||||||
							
								
								
									
										47
									
								
								modules/recaptcha/recaptcha.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								modules/recaptcha/recaptcha.go
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,47 @@ | ||||||
|  | // 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.
 | ||||||
|  | 
 | ||||||
|  | package recaptcha | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"encoding/json" | ||||||
|  | 	"fmt" | ||||||
|  | 	"io/ioutil" | ||||||
|  | 	"net/http" | ||||||
|  | 	"net/url" | ||||||
|  | 	"time" | ||||||
|  | 
 | ||||||
|  | 	"code.gitea.io/gitea/modules/setting" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // Response is the structure of JSON returned from API
 | ||||||
|  | type Response struct { | ||||||
|  | 	Success     bool      `json:"success"` | ||||||
|  | 	ChallengeTS time.Time `json:"challenge_ts"` | ||||||
|  | 	Hostname    string    `json:"hostname"` | ||||||
|  | 	ErrorCodes  []string  `json:"error-codes"` | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const apiURL = "https://www.google.com/recaptcha/api/siteverify" | ||||||
|  | 
 | ||||||
|  | // Verify calls Google Recaptcha API to verify token
 | ||||||
|  | func Verify(response string) (bool, error) { | ||||||
|  | 	resp, err := http.PostForm(apiURL, | ||||||
|  | 		url.Values{"secret": {setting.Service.RecaptchaSecret}, "response": {response}}) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return false, fmt.Errorf("Failed to send CAPTCHA response: %s", err) | ||||||
|  | 	} | ||||||
|  | 	defer resp.Body.Close() | ||||||
|  | 	body, err := ioutil.ReadAll(resp.Body) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return false, fmt.Errorf("Failed to read CAPTCHA response: %s", err) | ||||||
|  | 	} | ||||||
|  | 	var jsonResponse Response | ||||||
|  | 	err = json.Unmarshal(body, &jsonResponse) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return false, fmt.Errorf("Failed to parse CAPTCHA response: %s", err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return jsonResponse.Success, nil | ||||||
|  | } | ||||||
|  | @ -75,6 +75,12 @@ const ( | ||||||
| 	RepoCreatingPublic             = "public" | 	RepoCreatingPublic             = "public" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | // enumerates all the types of captchas
 | ||||||
|  | const ( | ||||||
|  | 	ImageCaptcha = "image" | ||||||
|  | 	ReCaptcha    = "recaptcha" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
| // settings
 | // settings
 | ||||||
| var ( | var ( | ||||||
| 	// AppVer settings
 | 	// AppVer settings
 | ||||||
|  | @ -1165,6 +1171,9 @@ var Service struct { | ||||||
| 	EnableReverseProxyAuth                  bool | 	EnableReverseProxyAuth                  bool | ||||||
| 	EnableReverseProxyAutoRegister          bool | 	EnableReverseProxyAutoRegister          bool | ||||||
| 	EnableCaptcha                           bool | 	EnableCaptcha                           bool | ||||||
|  | 	CaptchaType                             string | ||||||
|  | 	RecaptchaSecret                         string | ||||||
|  | 	RecaptchaSitekey                        string | ||||||
| 	DefaultKeepEmailPrivate                 bool | 	DefaultKeepEmailPrivate                 bool | ||||||
| 	DefaultAllowCreateOrganization          bool | 	DefaultAllowCreateOrganization          bool | ||||||
| 	EnableTimetracking                      bool | 	EnableTimetracking                      bool | ||||||
|  | @ -1189,7 +1198,10 @@ func newService() { | ||||||
| 	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() | ||||||
| 	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(false) | ||||||
|  | 	Service.CaptchaType = sec.Key("CAPTCHA_TYPE").MustString(ImageCaptcha) | ||||||
|  | 	Service.RecaptchaSecret = sec.Key("RECAPTCHA_SECRET").MustString("") | ||||||
|  | 	Service.RecaptchaSitekey = sec.Key("RECAPTCHA_SITEKEY").MustString("") | ||||||
| 	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) | ||||||
|  |  | ||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							|  | @ -80,6 +80,23 @@ | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | @media only screen and (min-width: 768px) { | ||||||
|  |     .g-recaptcha { | ||||||
|  |         margin: 0 auto !important; | ||||||
|  |         width: 304px; | ||||||
|  |         padding-left: 30px; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | @media screen and (max-height: 575px){ | ||||||
|  |     #rc-imageselect, .g-recaptcha { | ||||||
|  |         transform:scale(0.77); | ||||||
|  |         -webkit-transform:scale(0.77); | ||||||
|  |         transform-origin:0 0; | ||||||
|  |         -webkit-transform-origin:0 0; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .user.activate, | .user.activate, | ||||||
| .user.forgot.password, | .user.forgot.password, | ||||||
| .user.reset.password, | .user.reset.password, | ||||||
|  |  | ||||||
|  | @ -17,6 +17,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/base" | 	"code.gitea.io/gitea/modules/base" | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
|  | 	"code.gitea.io/gitea/modules/recaptcha" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 	"code.gitea.io/gitea/modules/util" | 	"code.gitea.io/gitea/modules/util" | ||||||
| 
 | 
 | ||||||
|  | @ -641,6 +642,8 @@ 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.EnableCaptcha | ||||||
|  | 	ctx.Data["CaptchaType"] = setting.Service.CaptchaType | ||||||
|  | 	ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey | ||||||
| 	ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration | 	ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration | ||||||
| 	ctx.Data["ShowRegistrationButton"] = false | 	ctx.Data["ShowRegistrationButton"] = false | ||||||
| 
 | 
 | ||||||
|  | @ -666,6 +669,8 @@ func LinkAccountPostSignIn(ctx *context.Context, signInForm auth.SignInForm) { | ||||||
| 	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.EnableCaptcha | ||||||
|  | 	ctx.Data["CaptchaType"] = setting.Service.CaptchaType | ||||||
|  | 	ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey | ||||||
| 	ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration | 	ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration | ||||||
| 	ctx.Data["ShowRegistrationButton"] = false | 	ctx.Data["ShowRegistrationButton"] = false | ||||||
| 
 | 
 | ||||||
|  | @ -732,6 +737,8 @@ func LinkAccountPostRegister(ctx *context.Context, cpt *captcha.Captcha, form au | ||||||
| 	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.EnableCaptcha | ||||||
|  | 	ctx.Data["CaptchaType"] = setting.Service.CaptchaType | ||||||
|  | 	ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey | ||||||
| 	ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration | 	ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration | ||||||
| 	ctx.Data["ShowRegistrationButton"] = false | 	ctx.Data["ShowRegistrationButton"] = false | ||||||
| 
 | 
 | ||||||
|  | @ -755,12 +762,21 @@ func LinkAccountPostRegister(ctx *context.Context, cpt *captcha.Captcha, form au | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if setting.Service.EnableCaptcha && !cpt.VerifyReq(ctx.Req) { | 	if setting.Service.EnableCaptcha && setting.Service.CaptchaType == setting.ImageCaptcha && !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 setting.Service.EnableCaptcha && setting.Service.CaptchaType == setting.ReCaptcha { | ||||||
|  | 		valid, _ := recaptcha.Verify(form.GRecaptchaResponse) | ||||||
|  | 		if !valid { | ||||||
|  | 			ctx.Data["Err_Captcha"] = true | ||||||
|  | 			ctx.RenderWithErr(ctx.Tr("form.captcha_incorrect"), tplLinkAccount, &form) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	if (len(strings.TrimSpace(form.Password)) > 0 || len(strings.TrimSpace(form.Retype)) > 0) && form.Password != form.Retype { | 	if (len(strings.TrimSpace(form.Password)) > 0 || len(strings.TrimSpace(form.Retype)) > 0) && form.Password != form.Retype { | ||||||
| 		ctx.Data["Err_Password"] = true | 		ctx.Data["Err_Password"] = true | ||||||
| 		ctx.RenderWithErr(ctx.Tr("form.password_not_match"), tplLinkAccount, &form) | 		ctx.RenderWithErr(ctx.Tr("form.password_not_match"), tplLinkAccount, &form) | ||||||
|  | @ -858,6 +874,9 @@ func SignUp(ctx *context.Context) { | ||||||
| 
 | 
 | ||||||
| 	ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha | 	ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha | ||||||
| 
 | 
 | ||||||
|  | 	ctx.Data["CaptchaType"] = setting.Service.CaptchaType | ||||||
|  | 	ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey | ||||||
|  | 
 | ||||||
| 	ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration | 	ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration | ||||||
| 
 | 
 | ||||||
| 	ctx.HTML(200, tplSignUp) | 	ctx.HTML(200, tplSignUp) | ||||||
|  | @ -871,6 +890,9 @@ 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["CaptchaType"] = setting.Service.CaptchaType | ||||||
|  | 	ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey | ||||||
|  | 
 | ||||||
| 	//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) | ||||||
|  | @ -882,12 +904,21 @@ func SignUpPost(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterFo | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	if setting.Service.EnableCaptcha && !cpt.VerifyReq(ctx.Req) { | 	if setting.Service.EnableCaptcha && setting.Service.CaptchaType == setting.ImageCaptcha && !cpt.VerifyReq(ctx.Req) { | ||||||
| 		ctx.Data["Err_Captcha"] = true | 		ctx.Data["Err_Captcha"] = true | ||||||
| 		ctx.RenderWithErr(ctx.Tr("form.captcha_incorrect"), tplSignUp, &form) | 		ctx.RenderWithErr(ctx.Tr("form.captcha_incorrect"), tplSignUp, &form) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	if setting.Service.EnableCaptcha && setting.Service.CaptchaType == setting.ReCaptcha { | ||||||
|  | 		valid, _ := recaptcha.Verify(form.GRecaptchaResponse) | ||||||
|  | 		if !valid { | ||||||
|  | 			ctx.Data["Err_Captcha"] = true | ||||||
|  | 			ctx.RenderWithErr(ctx.Tr("form.captcha_incorrect"), 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) | ||||||
|  |  | ||||||
|  | @ -15,6 +15,7 @@ import ( | ||||||
| 	"code.gitea.io/gitea/modules/context" | 	"code.gitea.io/gitea/modules/context" | ||||||
| 	"code.gitea.io/gitea/modules/generate" | 	"code.gitea.io/gitea/modules/generate" | ||||||
| 	"code.gitea.io/gitea/modules/log" | 	"code.gitea.io/gitea/modules/log" | ||||||
|  | 	"code.gitea.io/gitea/modules/recaptcha" | ||||||
| 	"code.gitea.io/gitea/modules/setting" | 	"code.gitea.io/gitea/modules/setting" | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-macaron/captcha" | 	"github.com/go-macaron/captcha" | ||||||
|  | @ -308,6 +309,8 @@ func RegisterOpenID(ctx *context.Context) { | ||||||
| 	ctx.Data["PageIsOpenIDRegister"] = true | 	ctx.Data["PageIsOpenIDRegister"] = true | ||||||
| 	ctx.Data["EnableOpenIDSignUp"] = setting.Service.EnableOpenIDSignUp | 	ctx.Data["EnableOpenIDSignUp"] = setting.Service.EnableOpenIDSignUp | ||||||
| 	ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha | 	ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha | ||||||
|  | 	ctx.Data["CaptchaType"] = setting.Service.CaptchaType | ||||||
|  | 	ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey | ||||||
| 	ctx.Data["OpenID"] = oid | 	ctx.Data["OpenID"] = oid | ||||||
| 	userName, _ := ctx.Session.Get("openid_determined_username").(string) | 	userName, _ := ctx.Session.Get("openid_determined_username").(string) | ||||||
| 	if userName != "" { | 	if userName != "" { | ||||||
|  | @ -333,14 +336,26 @@ func RegisterOpenIDPost(ctx *context.Context, cpt *captcha.Captcha, form auth.Si | ||||||
| 	ctx.Data["PageIsOpenIDRegister"] = true | 	ctx.Data["PageIsOpenIDRegister"] = true | ||||||
| 	ctx.Data["EnableOpenIDSignUp"] = setting.Service.EnableOpenIDSignUp | 	ctx.Data["EnableOpenIDSignUp"] = setting.Service.EnableOpenIDSignUp | ||||||
| 	ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha | 	ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha | ||||||
|  | 	ctx.Data["CaptchaType"] = setting.Service.CaptchaType | ||||||
|  | 	ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey | ||||||
| 	ctx.Data["OpenID"] = oid | 	ctx.Data["OpenID"] = oid | ||||||
| 
 | 
 | ||||||
| 	if setting.Service.EnableCaptcha && !cpt.VerifyReq(ctx.Req) { | 	if setting.Service.EnableCaptcha && setting.Service.CaptchaType == setting.ImageCaptcha && !cpt.VerifyReq(ctx.Req) { | ||||||
| 		ctx.Data["Err_Captcha"] = true | 		ctx.Data["Err_Captcha"] = true | ||||||
| 		ctx.RenderWithErr(ctx.Tr("form.captcha_incorrect"), tplSignUpOID, &form) | 		ctx.RenderWithErr(ctx.Tr("form.captcha_incorrect"), tplSignUpOID, &form) | ||||||
| 		return | 		return | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	if setting.Service.EnableCaptcha && setting.Service.CaptchaType == setting.ReCaptcha { | ||||||
|  | 		ctx.Req.ParseForm() | ||||||
|  | 		valid, _ := recaptcha.Verify(form.GRecaptchaResponse) | ||||||
|  | 		if !valid { | ||||||
|  | 			ctx.Data["Err_Captcha"] = true | ||||||
|  | 			ctx.RenderWithErr(ctx.Tr("form.captcha_incorrect"), tplSignUpOID, &form) | ||||||
|  | 			return | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	len := setting.MinPasswordLength | 	len := setting.MinPasswordLength | ||||||
| 	if len < 256 { | 	if len < 256 { | ||||||
| 		len = 256 | 		len = 256 | ||||||
|  |  | ||||||
|  | @ -67,6 +67,11 @@ | ||||||
| {{if .RequireU2F}} | {{if .RequireU2F}} | ||||||
| 	<script src="{{AppSubUrl}}/vendor/plugins/u2f/index.js"></script> | 	<script src="{{AppSubUrl}}/vendor/plugins/u2f/index.js"></script> | ||||||
| {{end}} | {{end}} | ||||||
|  | {{if .EnableCaptcha}} | ||||||
|  | 	{{if eq .CaptchaType "recaptcha"}} | ||||||
|  | 		<script src="https://www.google.com/recaptcha/api.js" async></script> | ||||||
|  | 	{{end}} | ||||||
|  | {{end}} | ||||||
| {{if .RequireTribute}} | {{if .RequireTribute}} | ||||||
| 	<script src="{{AppSubUrl}}/vendor/plugins/tribute/tribute.min.js"></script> | 	<script src="{{AppSubUrl}}/vendor/plugins/tribute/tribute.min.js"></script> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -29,7 +29,7 @@ | ||||||
| 							<label for="retype">{{.i18n.Tr "re_type"}}</label> | 							<label for="retype">{{.i18n.Tr "re_type"}}</label> | ||||||
| 							<input id="retype" name="retype" type="password" value="{{.retype}}" autocomplete="off" required> | 							<input id="retype" name="retype" type="password" value="{{.retype}}" autocomplete="off" required> | ||||||
| 						</div> | 						</div> | ||||||
| 						{{if .EnableCaptcha}} | 						{{if and .EnableCaptcha (eq .CaptchaType "image")}} | ||||||
| 							<div class="inline field"> | 							<div class="inline field"> | ||||||
| 								<label></label> | 								<label></label> | ||||||
| 								{{.Captcha.CreateHtml}} | 								{{.Captcha.CreateHtml}} | ||||||
|  | @ -39,6 +39,11 @@ | ||||||
| 								<input id="captcha" name="captcha" value="{{.captcha}}" autocomplete="off"> | 								<input id="captcha" name="captcha" value="{{.captcha}}" autocomplete="off"> | ||||||
| 							</div> | 							</div> | ||||||
| 						{{end}} | 						{{end}} | ||||||
|  | 						{{if and .EnableCaptcha (eq .CaptchaType "recaptcha")}} | ||||||
|  | 							<div class="inline field required"> | ||||||
|  | 								<div class="g-recaptcha" data-sitekey="{{ .RecaptchaSitekey }}"></div> | ||||||
|  | 							</div> | ||||||
|  | 						{{end}} | ||||||
| 
 | 
 | ||||||
| 						<div class="inline field"> | 						<div class="inline field"> | ||||||
| 							<label></label> | 							<label></label> | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ | ||||||
| 						<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> | ||||||
| 					{{if .EnableCaptcha}} | 					{{if and .EnableCaptcha (eq .CaptchaType "image")}} | ||||||
| 						<div class="inline field"> | 						<div class="inline field"> | ||||||
| 							<label></label> | 							<label></label> | ||||||
| 							{{.Captcha.CreateHtml}} | 							{{.Captcha.CreateHtml}} | ||||||
|  | @ -30,6 +30,11 @@ | ||||||
| 							<input id="captcha" name="captcha" value="{{.captcha}}" autocomplete="off"> | 							<input id="captcha" name="captcha" value="{{.captcha}}" autocomplete="off"> | ||||||
| 						</div> | 						</div> | ||||||
| 					{{end}} | 					{{end}} | ||||||
|  | 					{{if and .EnableCaptcha (eq .CaptchaType "recaptcha")}} | ||||||
|  | 						<div class="inline field required"> | ||||||
|  | 							<div class="g-recaptcha" data-sitekey="{{ .RecaptchaSitekey }}"></div> | ||||||
|  | 						</div> | ||||||
|  | 					{{end}} | ||||||
| 					<div class="inline field"> | 					<div class="inline field"> | ||||||
| 						<label for="openid">OpenID URI</label> | 						<label for="openid">OpenID URI</label> | ||||||
| 						<input id="openid" value="{{ .OpenID }}" readonly> | 						<input id="openid" value="{{ .OpenID }}" readonly> | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue