/
factory.go
136 lines (103 loc) · 2.28 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
135
136
package password // import "github.com/nathanaelle/password"
import (
"encoding"
"flag"
"fmt"
)
type (
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 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 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 the definition of a new crypter
func Register(def ...Definition) {
crypt.Register(def...)
}
// define a default crypter
func SetDefault(def Definition) {
crypt.SetDefault(def)
}
// see `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
}
func (p *Factory) MarshalText() ([]byte, error) {
return []byte(p.String()), nil
}
func (p *Factory) UnmarshalText(text []byte) error {
return p.Set(string(text))
}