Add Cap Captcha support (#2511)
* Add Cap Captcha support - Add CaptchaCap type constant in types.go - Add Cap struct with InstanceURL, KeyID, and KeySecret fields - Add CapCaptcha method in provider.go to return Cap settings - Add default settings for Cap captcha in setting.go - Implement Cap captcha verification logic in middleware - Expose Cap captcha settings in site API This adds support for Cap captcha service as an alternative captcha option alongside existing reCAPTCHA, Turnstile and built-in captcha options. * update cap json tags
This commit is contained in:
@@ -38,6 +38,9 @@ type (
|
||||
turnstileResponse struct {
|
||||
Success bool `json:"success"`
|
||||
}
|
||||
capResponse struct {
|
||||
Success bool `json:"success"`
|
||||
}
|
||||
)
|
||||
|
||||
// CaptchaRequired 验证请求签名
|
||||
@@ -127,6 +130,61 @@ func CaptchaRequired(enabled func(c *gin.Context) bool) gin.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
break
|
||||
case setting.CaptchaCap:
|
||||
captchaSetting := settings.CapCaptcha(c)
|
||||
if captchaSetting.InstanceURL == "" || captchaSetting.KeyID == "" || captchaSetting.KeySecret == "" {
|
||||
l.Warning("Cap verification failed: missing configuration")
|
||||
c.JSON(200, serializer.ErrWithDetails(c, serializer.CodeCaptchaError, "Captcha configuration error", nil))
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
r := dep.RequestClient(
|
||||
request2.WithContext(c),
|
||||
request2.WithLogger(logging.FromContext(c)),
|
||||
request2.WithHeader(http.Header{"Content-Type": []string{"application/json"}}),
|
||||
)
|
||||
|
||||
capEndpoint := strings.TrimSuffix(captchaSetting.InstanceURL, "/") + "/" + captchaSetting.KeyID + "/siteverify"
|
||||
requestBody := map[string]string{
|
||||
"secret": captchaSetting.KeySecret,
|
||||
"response": service.Ticket,
|
||||
}
|
||||
requestData, err := json.Marshal(requestBody)
|
||||
if err != nil {
|
||||
l.Warning("Cap verification failed: %s", err)
|
||||
c.JSON(200, serializer.ErrWithDetails(c, serializer.CodeCaptchaError, "Captcha validation failed", err))
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
res, err := r.Request("POST", capEndpoint, strings.NewReader(string(requestData))).
|
||||
CheckHTTPResponse(http.StatusOK).
|
||||
GetResponse()
|
||||
if err != nil {
|
||||
l.Warning("Cap verification failed: %s", err)
|
||||
c.JSON(200, serializer.ErrWithDetails(c, serializer.CodeCaptchaError, "Captcha validation failed", err))
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
var capRes capResponse
|
||||
err = json.Unmarshal([]byte(res), &capRes)
|
||||
if err != nil {
|
||||
l.Warning("Cap verification failed: %s", err)
|
||||
c.JSON(200, serializer.ErrWithDetails(c, serializer.CodeCaptchaError, "Captcha validation failed", err))
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
if !capRes.Success {
|
||||
l.Warning("Cap verification failed: validation returned false")
|
||||
c.JSON(200, serializer.ErrWithDetails(c, serializer.CodeCaptchaError, "Captcha validation failed", nil))
|
||||
c.Abort()
|
||||
return
|
||||
}
|
||||
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user