code.gitea.io/gitea@v1.19.3/modules/context/captcha.go (about) 1 // Copyright 2020 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package context 5 6 import ( 7 "fmt" 8 "sync" 9 10 "code.gitea.io/gitea/modules/base" 11 "code.gitea.io/gitea/modules/cache" 12 "code.gitea.io/gitea/modules/hcaptcha" 13 "code.gitea.io/gitea/modules/log" 14 "code.gitea.io/gitea/modules/mcaptcha" 15 "code.gitea.io/gitea/modules/recaptcha" 16 "code.gitea.io/gitea/modules/setting" 17 "code.gitea.io/gitea/modules/turnstile" 18 19 "gitea.com/go-chi/captcha" 20 ) 21 22 var ( 23 imageCaptchaOnce sync.Once 24 cpt *captcha.Captcha 25 ) 26 27 // GetImageCaptcha returns global image captcha 28 func GetImageCaptcha() *captcha.Captcha { 29 imageCaptchaOnce.Do(func() { 30 cpt = captcha.NewCaptcha(captcha.Options{ 31 SubURL: setting.AppSubURL, 32 }) 33 cpt.Store = cache.GetCache() 34 }) 35 return cpt 36 } 37 38 // SetCaptchaData sets common captcha data 39 func SetCaptchaData(ctx *Context) { 40 if !setting.Service.EnableCaptcha { 41 return 42 } 43 ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha 44 ctx.Data["RecaptchaURL"] = setting.Service.RecaptchaURL 45 ctx.Data["Captcha"] = GetImageCaptcha() 46 ctx.Data["CaptchaType"] = setting.Service.CaptchaType 47 ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey 48 ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey 49 ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey 50 ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL 51 ctx.Data["CfTurnstileSitekey"] = setting.Service.CfTurnstileSitekey 52 } 53 54 const ( 55 gRecaptchaResponseField = "g-recaptcha-response" 56 hCaptchaResponseField = "h-captcha-response" 57 mCaptchaResponseField = "m-captcha-response" 58 cfTurnstileResponseField = "cf-turnstile-response" 59 ) 60 61 // VerifyCaptcha verifies Captcha data 62 // No-op if captchas are not enabled 63 func VerifyCaptcha(ctx *Context, tpl base.TplName, form interface{}) { 64 if !setting.Service.EnableCaptcha { 65 return 66 } 67 68 var valid bool 69 var err error 70 switch setting.Service.CaptchaType { 71 case setting.ImageCaptcha: 72 valid = GetImageCaptcha().VerifyReq(ctx.Req) 73 case setting.ReCaptcha: 74 valid, err = recaptcha.Verify(ctx, ctx.Req.Form.Get(gRecaptchaResponseField)) 75 case setting.HCaptcha: 76 valid, err = hcaptcha.Verify(ctx, ctx.Req.Form.Get(hCaptchaResponseField)) 77 case setting.MCaptcha: 78 valid, err = mcaptcha.Verify(ctx, ctx.Req.Form.Get(mCaptchaResponseField)) 79 case setting.CfTurnstile: 80 valid, err = turnstile.Verify(ctx, ctx.Req.Form.Get(cfTurnstileResponseField)) 81 default: 82 ctx.ServerError("Unknown Captcha Type", fmt.Errorf("Unknown Captcha Type: %s", setting.Service.CaptchaType)) 83 return 84 } 85 if err != nil { 86 log.Debug("%v", err) 87 } 88 89 if !valid { 90 ctx.Data["Err_Captcha"] = true 91 ctx.RenderWithErr(ctx.Tr("form.captcha_incorrect"), tpl, form) 92 } 93 }