mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2024-10-31 20:44:07 +00:00
bf0d100b84
- This is in the spirit of #5090.
- Move to a fork of gitea.com/go-chi/cache,
code.forgejo.org/go-chi/cache. It removes unused code (a lot of
adapters, that can't be used by Forgejo) and unused dependencies (see
go.sum). Also updates existing dependencies.
8c64f1a362
..main
119 lines
3.4 KiB
Go
119 lines
3.4 KiB
Go
// Copyright 2020 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package context
|
|
|
|
import (
|
|
"fmt"
|
|
"sync"
|
|
|
|
"code.gitea.io/gitea/modules/base"
|
|
"code.gitea.io/gitea/modules/cache"
|
|
"code.gitea.io/gitea/modules/hcaptcha"
|
|
"code.gitea.io/gitea/modules/log"
|
|
"code.gitea.io/gitea/modules/mcaptcha"
|
|
"code.gitea.io/gitea/modules/recaptcha"
|
|
"code.gitea.io/gitea/modules/setting"
|
|
"code.gitea.io/gitea/modules/turnstile"
|
|
|
|
mc "code.forgejo.org/go-chi/cache"
|
|
"code.forgejo.org/go-chi/captcha"
|
|
)
|
|
|
|
var (
|
|
imageCaptchaOnce sync.Once
|
|
imageCachePrefix = "captcha:"
|
|
)
|
|
|
|
type imageCaptchaStore struct {
|
|
c mc.Cache
|
|
}
|
|
|
|
func (c *imageCaptchaStore) Set(id string, digits []byte) {
|
|
if err := c.c.Put(imageCachePrefix+id, string(digits), int64(captcha.Expiration.Seconds())); err != nil {
|
|
log.Error("Couldn't store captcha cache for %q: %v", id, err)
|
|
}
|
|
}
|
|
|
|
func (c *imageCaptchaStore) Get(id string, clear bool) (digits []byte) {
|
|
val, ok := c.c.Get(imageCachePrefix + id).(string)
|
|
if !ok {
|
|
return digits
|
|
}
|
|
|
|
if clear {
|
|
if err := c.c.Delete(imageCachePrefix + id); err != nil {
|
|
log.Error("Couldn't delete captcha cache for %q: %v", id, err)
|
|
}
|
|
}
|
|
|
|
return []byte(val)
|
|
}
|
|
|
|
// GetImageCaptcha returns image captcha ID.
|
|
func GetImageCaptcha() string {
|
|
imageCaptchaOnce.Do(func() {
|
|
captcha.SetCustomStore(&imageCaptchaStore{c: cache.GetCache()})
|
|
})
|
|
return captcha.New()
|
|
}
|
|
|
|
// SetCaptchaData sets common captcha data
|
|
func SetCaptchaData(ctx *Context) {
|
|
if !setting.Service.EnableCaptcha {
|
|
return
|
|
}
|
|
ctx.Data["EnableCaptcha"] = setting.Service.EnableCaptcha
|
|
ctx.Data["RecaptchaURL"] = setting.Service.RecaptchaURL
|
|
ctx.Data["Captcha"] = GetImageCaptcha()
|
|
ctx.Data["CaptchaType"] = setting.Service.CaptchaType
|
|
ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey
|
|
ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey
|
|
ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey
|
|
ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL
|
|
ctx.Data["CfTurnstileSitekey"] = setting.Service.CfTurnstileSitekey
|
|
}
|
|
|
|
const (
|
|
imgCaptchaIDField = "img-captcha-id"
|
|
imgCaptchaResponseField = "img-captcha-response"
|
|
gRecaptchaResponseField = "g-recaptcha-response"
|
|
hCaptchaResponseField = "h-captcha-response"
|
|
mCaptchaResponseField = "m-captcha-response"
|
|
cfTurnstileResponseField = "cf-turnstile-response"
|
|
)
|
|
|
|
// VerifyCaptcha verifies Captcha data
|
|
// No-op if captchas are not enabled
|
|
func VerifyCaptcha(ctx *Context, tpl base.TplName, form any) {
|
|
if !setting.Service.EnableCaptcha {
|
|
return
|
|
}
|
|
|
|
var valid bool
|
|
var err error
|
|
switch setting.Service.CaptchaType {
|
|
case setting.ImageCaptcha:
|
|
valid = captcha.VerifyString(ctx.Req.Form.Get(imgCaptchaIDField), ctx.Req.Form.Get(imgCaptchaResponseField))
|
|
case setting.ReCaptcha:
|
|
valid, err = recaptcha.Verify(ctx, ctx.Req.Form.Get(gRecaptchaResponseField))
|
|
case setting.HCaptcha:
|
|
valid, err = hcaptcha.Verify(ctx, ctx.Req.Form.Get(hCaptchaResponseField))
|
|
case setting.MCaptcha:
|
|
valid, err = mcaptcha.Verify(ctx, ctx.Req.Form.Get(mCaptchaResponseField))
|
|
case setting.CfTurnstile:
|
|
valid, err = turnstile.Verify(ctx, ctx.Req.Form.Get(cfTurnstileResponseField))
|
|
default:
|
|
ctx.ServerError("Unknown Captcha Type", fmt.Errorf("unknown Captcha Type: %s", setting.Service.CaptchaType))
|
|
return
|
|
}
|
|
if err != nil {
|
|
log.Debug("Captcha Verify failed: %v", err)
|
|
}
|
|
|
|
if !valid {
|
|
ctx.Data["Err_Captcha"] = true
|
|
ctx.RenderWithErr(ctx.Tr("form.captcha_incorrect"), tpl, form)
|
|
}
|
|
}
|