mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/1Panel-dev/1Panel.git
synced 2026-09-20 08:03:55 +08:00
69 lines
1.6 KiB
Go
69 lines
1.6 KiB
Go
package captcha
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"fmt"
|
|
"math/big"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/1Panel-dev/1Panel/core/app/dto"
|
|
)
|
|
|
|
const (
|
|
captchaWidth = 160
|
|
captchaHeight = 48
|
|
captchaExpiration = 10 * time.Minute
|
|
captchaStoreLimit = 10000
|
|
)
|
|
|
|
var store = newMemoryStore(captchaStoreLimit, captchaExpiration)
|
|
|
|
func VerifyCode(codeID string, code string) string {
|
|
answer := store.consume(codeID)
|
|
code = strings.TrimSpace(code)
|
|
if codeID == "" || code == "" || answer == "" || answer != code {
|
|
return "ErrCaptchaCode"
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func CreateCaptcha() (*dto.CaptchaResponse, error) {
|
|
question, answer, err := generateQuestion()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
imagePath, err := renderQuestion(question)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
id := rand.Text()
|
|
if err := store.put(id, answer); err != nil {
|
|
return nil, err
|
|
}
|
|
return &dto.CaptchaResponse{CaptchaID: id, ImagePath: imagePath}, nil
|
|
}
|
|
|
|
func generateQuestion() (question, answer string, err error) {
|
|
limits := [...]int64{3, 80, 20, 80}
|
|
var values [4]int
|
|
for i, limit := range limits {
|
|
n, err := rand.Int(rand.Reader, big.NewInt(limit))
|
|
if err != nil {
|
|
return "", "", fmt.Errorf("generate captcha: %w", err)
|
|
}
|
|
values[i] = int(n.Int64())
|
|
}
|
|
switch values[0] {
|
|
case 0:
|
|
a, b := values[1]%20, values[2]
|
|
return fmt.Sprintf("%d+%d=?", a, b), fmt.Sprint(a + b), nil
|
|
case 1:
|
|
a, b := values[1]+values[2], values[3]
|
|
return fmt.Sprintf("%d-%d=?", a, b), fmt.Sprint(a - b), nil
|
|
default:
|
|
a, b := values[1]%10, values[2]%10
|
|
return fmt.Sprintf("%dx%d=?", a, b), fmt.Sprint(a * b), nil
|
|
}
|
|
}
|