73 lines
1.4 KiB
Go
73 lines
1.4 KiB
Go
package captcha
|
|
|
|
import (
|
|
"crypto/rand"
|
|
"image"
|
|
"math/big"
|
|
"time"
|
|
)
|
|
|
|
const (
|
|
maxIntAnswer = 999999
|
|
)
|
|
|
|
type Answer string
|
|
|
|
func NewIntAnswer() Answer {
|
|
ans, _ := rand.Int(rand.Reader, big.NewInt(maxIntAnswer))
|
|
return (Answer(ans.String()))
|
|
}
|
|
|
|
// Captcha interface that should be implemented by captcha.
|
|
type Captcha interface {
|
|
// Image generates and returns an image of captcha.
|
|
Image(style string) *image.Image
|
|
// GetAnswer returns a pregenerated answer.
|
|
GetAnswer() Answer
|
|
// Solve compares a stored answer with a passed one.
|
|
// Sets field Solved to true if they are equal.
|
|
Solve(answer Answer) bool
|
|
// IsSolved returns field IsSolved.
|
|
IsSolved() bool
|
|
// Expiry returns a date after what captcha will expire.
|
|
Expiry() time.Time
|
|
}
|
|
|
|
// BaseCaptcha is a base implementation of a CAPTCHA.
|
|
//
|
|
// All derivatives that embed this struct only need to
|
|
// implement Image() method.
|
|
type BaseCaptcha struct {
|
|
Answer Answer
|
|
Solved bool
|
|
ExpireIn time.Time
|
|
}
|
|
|
|
func (c *BaseCaptcha) Image(style string) *image.Image {
|
|
return nil
|
|
}
|
|
|
|
func (c *BaseCaptcha) GetAnswer() Answer {
|
|
if c.Answer == "" {
|
|
c.Answer = NewIntAnswer()
|
|
}
|
|
return c.Answer
|
|
}
|
|
|
|
func (c *BaseCaptcha) Solve(answer Answer) bool {
|
|
c.Solved = c.Answer == answer
|
|
return c.Solved
|
|
}
|
|
|
|
func (c *BaseCaptcha) IsSolved() bool {
|
|
return c.Solved
|
|
}
|
|
|
|
func (c *BaseCaptcha) Expiry() time.Time {
|
|
return c.ExpireIn
|
|
}
|
|
|
|
func ExpiryDate(expiry time.Duration) time.Time {
|
|
return time.Now().Add(expiry)
|
|
}
|