-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Add Recaptcha functionality to Gitea #4044
Changes from 27 commits
a467186
55bbfac
76b57f1
0b12d2a
f6d9d2b
a39289d
22d6265
02ac7e3
f203c2f
7e6a60a
e787c7f
1effea1
b49c864
313e7dd
d9e4392
5039fe1
f4ddfa1
f2199d1
59cba2c
5aa9afb
628ca1b
8357eb5
7ff8e14
3239fad
795019c
6786290
d32a204
93b4909
a2b9ba2
1812cd0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
} |
Large diffs are not rendered by default.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ import ( | |
"code.gitea.io/gitea/modules/base" | ||
"code.gitea.io/gitea/modules/context" | ||
"code.gitea.io/gitea/modules/log" | ||
"code.gitea.io/gitea/modules/recaptcha" | ||
"code.gitea.io/gitea/modules/setting" | ||
"code.gitea.io/gitea/modules/util" | ||
|
||
|
@@ -641,6 +642,8 @@ func LinkAccount(ctx *context.Context) { | |
ctx.Data["Title"] = ctx.Tr("link_account") | ||
ctx.Data["LinkAccountMode"] = true | ||
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["ShowRegistrationButton"] = false | ||
|
||
|
@@ -666,6 +669,8 @@ func LinkAccountPostSignIn(ctx *context.Context, signInForm auth.SignInForm) { | |
ctx.Data["LinkAccountMode"] = true | ||
ctx.Data["LinkAccountModeSignIn"] = true | ||
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["ShowRegistrationButton"] = false | ||
|
||
|
@@ -732,6 +737,8 @@ func LinkAccountPostRegister(ctx *context.Context, cpt *captcha.Captcha, form au | |
ctx.Data["LinkAccountMode"] = true | ||
ctx.Data["LinkAccountModeRegister"] = true | ||
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["ShowRegistrationButton"] = false | ||
|
||
|
@@ -755,12 +762,21 @@ func LinkAccountPostRegister(ctx *context.Context, cpt *captcha.Captcha, form au | |
return | ||
} | ||
|
||
if setting.Service.EnableCaptcha && !cpt.VerifyReq(ctx.Req) { | ||
if setting.Service.EnableCaptcha && setting.Service.CaptchaType == "image" && !cpt.VerifyReq(ctx.Req) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you save "image" and "recaptcha" as a const strings and only reference the const variables? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok. I changed this. |
||
ctx.Data["Err_Captcha"] = true | ||
ctx.RenderWithErr(ctx.Tr("form.captcha_incorrect"), tplLinkAccount, &form) | ||
return | ||
} | ||
|
||
if setting.Service.EnableCaptcha && setting.Service.CaptchaType == "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 { | ||
ctx.Data["Err_Password"] = true | ||
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["CaptchaType"] = setting.Service.CaptchaType | ||
ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey | ||
|
||
ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration | ||
|
||
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["CaptchaType"] = setting.Service.CaptchaType | ||
ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey | ||
|
||
//Permission denied if DisableRegistration or AllowOnlyExternalRegistration options are true | ||
if !setting.Service.ShowRegistrationButton { | ||
ctx.Error(403) | ||
|
@@ -882,12 +904,21 @@ func SignUpPost(ctx *context.Context, cpt *captcha.Captcha, form auth.RegisterFo | |
return | ||
} | ||
|
||
if setting.Service.EnableCaptcha && !cpt.VerifyReq(ctx.Req) { | ||
if setting.Service.EnableCaptcha && setting.Service.CaptchaType == "image" && !cpt.VerifyReq(ctx.Req) { | ||
ctx.Data["Err_Captcha"] = true | ||
ctx.RenderWithErr(ctx.Tr("form.captcha_incorrect"), tplSignUp, &form) | ||
return | ||
} | ||
|
||
if setting.Service.EnableCaptcha && setting.Service.CaptchaType == "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 { | ||
ctx.Data["Err_Password"] = true | ||
ctx.RenderWithErr(ctx.Tr("form.password_not_match"), tplSignUp, &form) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do not change default as this way it will be breaking change
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default value is actually
false
but the documentation is wrongThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi. Yes
false
is the default, and I changed it to be correct like @JonasFranzDEV said.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like you use a captcha type and currently you have three options: disabled, image and recaptcha and default is disabled.