package captcha import ( "git.bvbej.com/bvbej/base-golang/pkg/cache" "github.com/mojocn/base64Captcha" "go.uber.org/zap" "strings" "time" ) const RedisKeyPrefixCaptcha = "captcha:base64:" var _ base64Captcha.Store = (*store)(nil) type store struct { cache cache.Repo ttl time.Duration logger *zap.Logger } func (s *store) Set(id string, value string) error { err := s.cache.Set(RedisKeyPrefixCaptcha+id, value, s.ttl) if err != nil { return err } return nil } func (s *store) Get(id string, clear bool) string { value, err := s.cache.Get(RedisKeyPrefixCaptcha + id) if err == nil && clear { s.cache.Del(RedisKeyPrefixCaptcha + id) } return value } func (s *store) Verify(id, answer string, clear bool) bool { value := s.Get(id, clear) if value == "" || answer == "" { return false } return strings.ToLower(value) == strings.ToLower(answer) } func NewStore(cache cache.Repo, ttl time.Duration) base64Captcha.Store { return &store{ cache: cache, ttl: ttl, } } var _ Captcha = (*captcha)(nil) type Captcha interface { Generate() (id, b64s string, err error) Verify(id, value string) bool } type captcha struct { driver base64Captcha.Driver store base64Captcha.Store } func NewStringCaptcha(store base64Captcha.Store, height, width, length int) Captcha { conf := &base64Captcha.DriverString{ Height: height, Width: width, NoiseCount: length, ShowLineOptions: base64Captcha.OptionShowHollowLine, Length: length, Source: "ABCDEFGHIJKMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz0123456789", } return &captcha{ driver: conf.ConvertFonts(), store: store, } } func NewDigitCaptcha(store base64Captcha.Store, height, width, length int) Captcha { conf := base64Captcha.NewDriverDigit(height, width, length, 0.7, height) return &captcha{ driver: conf, store: store, } } func (c *captcha) Generate() (id, b64s string, err error) { newCaptcha := base64Captcha.NewCaptcha(c.driver, c.store) return newCaptcha.Generate() } func (c *captcha) Verify(id, value string) bool { return c.store.Verify(id, value, true) }