ICaptchaDB interface renamed to CaptchaDB. And implementation was renamed to InMemoryCaptchaDB. Composition of sync.Mutex was moved to the top of struct. Methods was rearranged to resemble order from CaptchaDB interface.

This commit is contained in:
Alexander Andreev 2022-07-30 15:39:19 +04:00
parent c14f9b0149
commit 925d48c10d
Signed by: Arav
GPG Key ID: 0388CC8FAA51063F

View File

@ -25,8 +25,8 @@ func NewID(additionalData string, answer Answer) ID {
return ID(base64.RawURLEncoding.EncodeToString(idHash.Sum(nil))) return ID(base64.RawURLEncoding.EncodeToString(idHash.Sum(nil)))
} }
type ICaptchaDB interface { type CaptchaDB interface {
New(data string) (ICaptcha, ID) New(data string) (Captcha, ID)
SetExpiry(expiry time.Duration) SetExpiry(expiry time.Duration)
GetExpiry() time.Duration GetExpiry() time.Duration
Image(id ID) (*image.Image, error) Image(id ID) (*image.Image, error)
@ -34,15 +34,29 @@ type ICaptchaDB interface {
IsSolved(id ID) bool IsSolved(id ID) bool
} }
type CaptchaDB struct { type InMemoryCaptchaDB struct {
DB map[ID]ICaptcha
ExpireIn time.Duration
sync.Mutex sync.Mutex
DB map[ID]Captcha
ExpireIn time.Duration
}
// New accepts an Captcha instance, generates an ID and store it in a database.
// `data` string is an additional random data used to generate an ID,
// e.g. IP-address.
func (cdb *InMemoryCaptchaDB) New(data string, captcha Captcha) (Captcha, ID) {
id := NewID(data, captcha.GetAnswer())
cdb.Lock()
cdb.DB[id] = captcha
cdb.Unlock()
return captcha, id
} }
// SetExpiry stores expire value and starts a goroutine // SetExpiry stores expire value and starts a goroutine
// that checks for expired CAPTCHAs every minute. // that checks for expired CAPTCHAs.
func (cdb *CaptchaDB) SetExpiry(expire time.Duration) { func (cdb *InMemoryCaptchaDB) SetExpiry(expire time.Duration) {
cdb.ExpireIn = expire cdb.ExpireIn = expire
if expire < expiredScanInterval { if expire < expiredScanInterval {
expiredScanInterval = expire expiredScanInterval = expire
@ -64,32 +78,24 @@ func (cdb *CaptchaDB) SetExpiry(expire time.Duration) {
}() }()
} }
// New accepts an ICaptcha instance, generates an ID and store it in a database. // GetExpiry returns time for how long captcha will last.
// `data` string is an additional random data used to generate an ID, func (cdb *InMemoryCaptchaDB) GetExpiry() time.Duration {
// e.g. IP-address. return cdb.ExpireIn
func (cdb *CaptchaDB) New(data string, captcha ICaptcha) (ICaptcha, ID) {
id := NewID(data, captcha.GetAnswer())
cdb.Lock()
cdb.DB[id] = captcha
cdb.Unlock()
return captcha, id
} }
// Image returns image for a captcha. // Image returns image for a captcha.
func (cdb *CaptchaDB) Image(id ID, style string) (*image.Image, error) { func (cdb *InMemoryCaptchaDB) Image(id ID, style string) (image.Image, error) {
cdb.Lock() cdb.Lock()
defer cdb.Unlock() defer cdb.Unlock()
if c, ok := cdb.DB[id]; ok { if c, ok := cdb.DB[id]; ok {
return c.GetImage(style), nil return c.Image(style), nil
} }
return nil, errorNotFound return nil, errorNotFound
} }
// Solve compares given answer with a stored one and if failed // Solve compares given answer with a stored one and if failed
// deletes a captcha from database. // deletes a captcha from database.
func (cdb *CaptchaDB) Solve(id ID, answer Answer) (bool, error) { func (cdb *InMemoryCaptchaDB) Solve(id ID, answer Answer) (bool, error) {
cdb.Lock() cdb.Lock()
defer cdb.Unlock() defer cdb.Unlock()
if c, ok := cdb.DB[id]; ok { if c, ok := cdb.DB[id]; ok {
@ -104,7 +110,7 @@ func (cdb *CaptchaDB) Solve(id ID, answer Answer) (bool, error) {
// IsSolved checks if captcha was solved and removes it // IsSolved checks if captcha was solved and removes it
// from a database. // from a database.
func (cdb *CaptchaDB) IsSolved(id ID) (bool, error) { func (cdb *InMemoryCaptchaDB) IsSolved(id ID) (bool, error) {
cdb.Lock() cdb.Lock()
defer cdb.Unlock() defer cdb.Unlock()
if c, ok := cdb.DB[id]; ok { if c, ok := cdb.DB[id]; ok {
@ -114,8 +120,3 @@ func (cdb *CaptchaDB) IsSolved(id ID) (bool, error) {
} }
return false, errorNotFound return false, errorNotFound
} }
// GetExpiry returns time for how long captcha will last.
func (cdb *CaptchaDB) GetExpiry() time.Duration {
return cdb.ExpireIn
}