-
Notifications
You must be signed in to change notification settings - Fork 0
/
config.go
108 lines (94 loc) · 2.49 KB
/
config.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
package main
import (
"crypto/tls"
"crypto/x509"
"encoding/json"
"log"
"net/url"
"os"
"strings"
"time"
)
type Account struct {
Filter string
TLSConfig *tls.Config
URL *url.URL
}
type Config struct {
Listen string
Timeout time.Duration
Accounts []Account
}
type internalAccount struct {
Filter string `json:"filter"`
SkipTLSValidation bool `json:"skip_tls_validation"`
Pem string `json:"pem"`
URL string `json:"url"`
}
type internalConfig struct {
Listen string `json:"listen"`
TimeoutSeconds float64 `json:"timeout"`
Accounts []internalAccount `json:"accounts"`
}
func NewConfig(filename string) Config {
fd, err := os.Open(filename)
if err != nil {
log.Fatalln(err)
}
defer fd.Close()
internalConfig := internalConfig{
Listen: ":9091",
TimeoutSeconds: 5,
}
if err := json.NewDecoder(fd).Decode(&internalConfig); err != nil {
log.Fatalln(err)
}
config := Config{
Listen: internalConfig.Listen,
Timeout: time.Duration(internalConfig.TimeoutSeconds * float64(time.Second)),
}
for _, internalAccount := range internalConfig.Accounts {
config.Accounts = append(config.Accounts, Account{
Filter: internalAccount.Filter,
})
account := &config.Accounts[len(config.Accounts)-1]
if account.Filter == "" {
account.Filter = "*"
}
parsedURL, err := url.Parse(internalAccount.URL)
if err != nil {
log.Fatalf("Cannot parse URL %s: %s", account.URL, err)
}
if parsedURL.Scheme != "imap" && parsedURL.Scheme != "imaps" {
log.Fatalf("Unknown scheme: %s", parsedURL.Scheme)
}
if !strings.Contains(parsedURL.Host, ":") {
if parsedURL.Scheme == "imaps" {
parsedURL.Host += ":993"
} else {
parsedURL.Host += ":143"
}
}
if parsedURL.User == nil {
log.Fatalln("No user/password")
}
if parsedURL.Opaque != "" || parsedURL.Path != "" || parsedURL.RawQuery != "" || parsedURL.Fragment != "" {
log.Fatalf("Wrong URL: %s", account.URL)
}
if internalAccount.SkipTLSValidation || internalAccount.Pem != "" {
account.TLSConfig = &tls.Config{}
if internalAccount.SkipTLSValidation {
account.TLSConfig.InsecureSkipVerify = true
} else if internalAccount.Pem != "" {
roots := x509.NewCertPool()
ok := roots.AppendCertsFromPEM([]byte(internalAccount.Pem))
if !ok {
log.Fatalf("failed to parse root certificate %s", internalAccount.Pem)
}
account.TLSConfig.RootCAs = roots
}
}
account.URL = parsedURL
}
return config
}