-
Notifications
You must be signed in to change notification settings - Fork 2
/
factory.go
134 lines (108 loc) · 2.64 KB
/
factory.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package password // import "github.com/nathanaelle/password/v2"
import (
"encoding"
"flag"
"fmt"
)
type (
// Definition represent the public interface for a *-CRYPT
Definition interface {
String() string
CrypterFound(string) (Crypter, bool)
Options() map[string]interface{}
Default() Crypter
SetOptions(map[string]interface{}) Definition
Crypt(pwd, salt []byte, options map[string]interface{}) string
}
// Crypter is the public interface for an instancied Definition
Crypter interface {
Salt(salt []byte) Crypter
Hashed(pwd []byte) Crypter
Crypt(pwd []byte) Crypter
Verify(pwd []byte) bool
Options() map[string]interface{}
Definition() Definition
encoding.TextMarshaler
flag.Value
}
// Factory is a syntaxic sugar for finding the Definition from a password string
Factory struct {
CustomFlagHelper func([]string) string
index []Definition
deflt Crypter
found Crypter
}
)
var crypt = &Factory{}
func register(def Definition) Definition {
crypt.Register(def)
return def
}
// Register register the definition of a new crypter
func Register(def ...Definition) {
crypt.Register(def...)
}
// SetDefault define a default crypter
func SetDefault(def Definition) {
crypt.SetDefault(def)
}
// Set is a default implementation of `Crypt.Set(string) error`
func Set(pwd string) error {
return crypt.Set(pwd)
}
func CrypterFound() Crypter {
return crypt.found
}
func (c *Factory) Register(def ...Definition) {
c.index = append(c.index, def...)
}
func (c *Factory) FlagHelper() string {
a := make([]string, len(c.index))
for i, d := range c.index {
a[i] = d.String()
}
if c.CustomFlagHelper != nil {
return c.CustomFlagHelper(a)
}
return fmt.Sprintf("accepted password types : %+v", a)
}
func (c *Factory) SetDefault(def Definition) {
c.deflt = def.Default()
}
// Allow to use this type as a `flag.Value`
func (c *Factory) Set(pwd string) error {
if c.index == nil || len(c.index) == 0 {
c.index = append(c.index, crypt.index...)
}
for _, i := range c.index {
if crypter, ok := i.CrypterFound(pwd); ok {
c.found = crypter
return nil
}
}
if c.deflt != nil {
c.found = c.deflt
return nil
}
return NoMatchingDef
}
func (c *Factory) String() string {
if c.found != nil {
return c.found.String()
}
if c.deflt != nil {
return c.deflt.String()
}
return ""
}
func (c *Factory) CrypterFound() Crypter {
return c.found
}
// MarshalText implements TextMarshaler
func (c *Factory) MarshalText() ([]byte, error) {
return []byte(c.String()), nil
}
// UnmarshalText implements TextUnmarshaler
func (c *Factory) UnmarshalText(text []byte) error {
return c.Set(string(text))
}