generated from clevergo/pkg-template
-
Notifications
You must be signed in to change notification settings - Fork 6
/
manager.go
94 lines (76 loc) · 2.01 KB
/
manager.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// Copyright 2020 CleverGo. All rights reserved.
// Use of this source code is governed by a MIT style license that can be found
// in the LICENSE file.
package captchas
import (
"context"
"errors"
"strings"
)
// Option is a function that receives a pointer of manager.
type Option func(*Manager)
// CaseSensitive is an option that enable or disable case sensitive.
func CaseSensitive(v bool) Option {
return func(m *Manager) {
m.caseSensitive = v
}
}
// Manager is a captchas manager.
type Manager struct {
store Store
driver Driver
caseSensitive bool
}
// New returns a manager instance with the given store and driver.
func New(store Store, driver Driver, opts ...Option) *Manager {
m := &Manager{
store: store,
driver: driver,
caseSensitive: true,
}
for _, f := range opts {
f(m)
}
return m
}
// Generate generates a new captcha and save it to store, returns an error if failed.
func (m *Manager) Generate(ctx context.Context) (Captcha, error) {
captcha, err := m.driver.Generate()
if err != nil {
return nil, err
}
if err = m.store.Set(ctx, captcha.ID(), captcha.Answer()); err != nil {
return nil, err
}
return captcha, nil
}
// Get is a shortcut of Store.Get.
func (m *Manager) Get(ctx context.Context, id string, clear bool) (string, error) {
return m.store.Get(ctx, id, clear)
}
// Errors
var (
ErrCaptchaIncorrect = errors.New("captcha is incorrect")
ErrCaptchaExpired = errors.New("captcha is expired")
)
// Verify verifies whether the given actual value is equal to the
// answer of captcha, returns an error if failed.
func (m *Manager) Verify(ctx context.Context, id, actual string, clear bool) error {
answer, err := m.store.Get(ctx, id, clear)
if err != nil {
return err
}
if m.isEqual(actual, answer) {
return nil
}
return ErrCaptchaIncorrect
}
func (m *Manager) isEqual(actual, answer string) bool {
if answer == "" || actual == "" {
return false
}
if !m.caseSensitive {
return strings.EqualFold(actual, answer)
}
return actual == answer
}