Files
Super-HomeworkManager/internal/service/captcha_service.go
2026-03-24 18:40:38 +09:00

76 lines
1.6 KiB
Go

package service
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"strings"
"github.com/dchest/captcha"
)
type CaptchaService struct {
captchaType string
turnstileSecretKey string
}
func NewCaptchaService(captchaType, turnstileSecretKey string) *CaptchaService {
return &CaptchaService{
captchaType: captchaType,
turnstileSecretKey: turnstileSecretKey,
}
}
func (s *CaptchaService) NewImageCaptcha() string {
return captcha.New()
}
func (s *CaptchaService) VerifyImageCaptcha(id, answer string) bool {
return captcha.VerifyString(id, answer)
}
type turnstileResponse struct {
Success bool `json:"success"`
Errors []string `json:"error-codes"`
}
func (s *CaptchaService) VerifyTurnstile(token, remoteIP string) (bool, error) {
if token == "" {
return false, nil
}
form := url.Values{}
form.Set("secret", s.turnstileSecretKey)
form.Set("response", token)
if remoteIP != "" {
form.Set("remoteip", remoteIP)
}
resp, err := http.Post(
"https://challenges.cloudflare.com/turnstile/v0/siteverify",
"application/x-www-form-urlencoded",
strings.NewReader(form.Encode()),
)
if err != nil {
return false, fmt.Errorf("turnstile request failed: %w", err)
}
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
if err != nil {
return false, fmt.Errorf("reading turnstile response: %w", err)
}
var result turnstileResponse
if err := json.Unmarshal(body, &result); err != nil {
return false, fmt.Errorf("parsing turnstile response: %w", err)
}
return result.Success, nil
}
func (s *CaptchaService) Type() string {
return s.captchaType
}