/
conf.go
103 lines (84 loc) · 2.78 KB
/
conf.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
package authn
import (
"fmt"
"github.com/alexedwards/argon2id"
"github.com/pkg/errors"
"github.com/sargassum-world/godest/env"
)
const envPrefix = "AUTHN_"
type Config struct {
NoAuth bool
Argon2idParams argon2id.Params
AdminUsername string
AdminPasswordHash string
}
func GetConfig() (c Config, err error) {
c.NoAuth, err = getNoAuth()
if err != nil {
return Config{}, errors.Wrap(err, "couldn't make authentication config")
}
c.Argon2idParams, err = getArgon2idParams()
if err != nil {
return Config{}, errors.Wrap(err, "couldn't make password hashing config")
}
c.AdminUsername = getAdminUsername()
c.AdminPasswordHash, err = getAdminPasswordHash(c.Argon2idParams, c.NoAuth)
if err != nil {
return Config{}, errors.Wrap(err, "couldn't make admin password hash config")
}
return c, nil
}
func getNoAuth() (bool, error) {
return env.GetBool(envPrefix + "NOAUTH")
}
func getArgon2idParams() (argon2id.Params, error) {
var defaultMemorySize uint64 = 64 // default: 64 MiB
memorySize, err := env.GetUint64(envPrefix+"ARGON2ID_M", defaultMemorySize)
if err != nil {
return argon2id.Params{}, errors.Wrap(err, "couldn't make memorySize config")
}
memorySize *= 1024
var defaultIterations uint64 = 1 // default: 1 iteration over the memory
iterations, err := env.GetUint64(envPrefix+"ARGON2ID_T", defaultIterations)
if err != nil {
return argon2id.Params{}, errors.Wrap(err, "couldn't make iterations config")
}
var defaultParallelism uint64 = 2 // default: 2 threads/lanes
parallelism, err := env.GetUint64(envPrefix+"ARGON2ID_P", defaultParallelism)
if err != nil {
return argon2id.Params{}, errors.Wrap(err, "couldn't make parallelism config")
}
var defaultSaltLength uint32 = 16 // default: 16 bytes
var defaultKeyLength uint32 = 32 // default: 32 bytes
return argon2id.Params{
Memory: uint32(memorySize),
Iterations: uint32(iterations),
Parallelism: uint8(parallelism),
SaltLength: defaultSaltLength,
KeyLength: defaultKeyLength,
}, nil
}
func getAdminUsername() string {
return env.GetString(envPrefix+"ADMIN_USERNAME", "admin")
}
func getAdminPasswordHash(argon2idParams argon2id.Params, noAuth bool) (hash string, err error) {
hash = env.GetString(envPrefix+"ADMIN_PW_HASH", "")
if len(hash) == 0 && !noAuth {
password := env.GetString(envPrefix+"ADMIN_PW", "")
if len(password) == 0 {
return "", errors.Errorf(
"must provide a password for the admin account with %sADMIN_PW", envPrefix,
)
}
hash, err = argon2id.CreateHash(password, &argon2idParams)
if err != nil {
return "", err
}
fmt.Printf(
"Record this admin password hash for future use as %sADMIN_PW_HASH "+
"(use single-quotes from shell to avoid string substitution with dollar-signs): %s\n",
envPrefix, hash,
)
}
return hash, nil
}