justcaptcha/pkg/captcha/db.go

46 lines
1.1 KiB
Go
Raw Normal View History

package captcha
import (
"crypto/rand"
"crypto/sha256"
"encoding/base64"
"errors"
"image"
"strconv"
"time"
)
var ErrorNotFound = errors.New("captcha not found")
const DefaultExpiredScanInterval = 60 * time.Second
// ID is a CAPTCHA identifier.
type ID string
// NewID generates an ID as a sha256 hash of additionalData (usually IP-address),
// current time, answer and more, it adds a set of random bytes and encodes all
// of it with base64 in raw URL variant.
func NewID(additionalData string, answer Answer) ID {
idHash := sha256.New()
idHash.Write([]byte(additionalData))
idHash.Write([]byte(strconv.FormatInt(time.Now().UnixMicro(), 16)))
idHash.Write([]byte(answer))
randData := make([]byte, 32)
rand.Read(randData)
idHash.Write(randData)
return ID(base64.RawURLEncoding.EncodeToString(idHash.Sum(nil)))
}
// CaptchaDB interface with all necessary methods.
type CaptchaDB interface {
New(data string, captcha Captcha) (Captcha, ID)
GetExpiry() time.Duration
SetExpiry(expiry time.Duration)
Image(id ID, style string) *image.Image
Solve(id ID, answer Answer) bool
IsSolved(id ID) bool
Remove(id ID)
}