-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconfig.go
148 lines (121 loc) · 4.5 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
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
137
138
139
140
141
142
143
144
145
146
147
148
package main
import (
"log"
"strings"
"github.com/go-playground/validator/v10"
"github.com/spf13/viper"
)
// Global config variable
var Config config
// Struct for config validation using go-playground/validator
type config struct {
Paperless Paperless `validate:"required"`
Email struct {
SMTPAddress string `validate:"required,email"`
SMTPServer string `validate:"required,hostname"`
SMTPPort string `validate:"required,min=1,max=65535"`
SMTPConnectionType string `validate:"required,oneof=starttls tls"`
SMTPUser string `validate:"required"`
SMTPPassword string `validate:"required"`
MailBody string
MailHeader string
}
RunEveryXMinute int `validate:"required,min=-1,max=65535"`
}
type Paperless struct {
InstanceURL string `validate:"required,url"`
InstanceToken string `validate:"required"`
AddQueueTagName string `validate:"required"`
ProcessedTagName string `validate:"required"`
Rules []rule `validate:"required,dive,required"`
}
type rule struct {
Name string `validate:"required"`
ReceiverAddresses []string `validate:"required,dive,required,email"`
BCCAddresses []string `validate:"dive,required,email"`
MailBody string
MailHeader string
Tags []string
Type string
Correspondent string
}
// Validate config using go-playground/validator
func validateWithPlayground(config config) error {
validate := validator.New()
//custom validator to check if rule or paperless has at least a mailbody or header
validate.RegisterStructValidation(RuleValidation, rule{})
err := validate.Struct(config)
if err != nil {
// If validation fails, print errors
for _, err := range err.(validator.ValidationErrors) {
log.Printf("Validation failed on field '%s', condition: '%s'\n", err.StructField(), err.Tag())
}
return err
}
return nil
}
// ruleValidation custom validator to check details of rule
func RuleValidation(sl validator.StructLevel) {
// rule to validate
r := sl.Current().Interface().(rule)
// entire config struct
p := sl.Top().Interface().(config)
// email body and header must be set in rule or config
if len(r.MailBody) == 0 && len(p.Email.MailBody) == 0 {
sl.ReportError(r.MailBody, "MailBody", "MailBody", "`MailBody` of rule or at least `Mailbody` of `Config.Email `must be set", "")
}
if len(r.MailHeader) == 0 && len(p.Email.MailHeader) == 0 {
sl.ReportError(r.MailHeader, "MailHeader", "MailHeader", "`MailHeader` of rule or at least `MailHeader` of `Config.Email` must be set", "")
}
// atleast tags, correspondent or type must be set in the rule
if len(r.Tags) == 0 && len(r.Correspondent) == 0 && len(r.Type) == 0 {
sl.ReportError(r, "", "rule", "At least one of `Tags`, `Correspondent` or `Type` must be set in the rule", "")
}
}
// LoadConfig function to initialize config
func LoadConfig() {
viper.SetConfigName("config")
viper.SetConfigType("yaml")
viper.AddConfigPath("config/")
// Attempt to read the config file
if err := viper.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
log.Fatalf("Error loading Config: %s", err)
} else {
log.Fatalf("Error reading Config: %s", err)
}
}
// Populate struct for validator use
err := viper.Unmarshal(&Config)
if err != nil {
log.Fatalf("Unable to unmarshal into struct, %v", err)
}
// Validate the struct using go-playground/validator
if err := validateWithPlayground(Config); err != nil {
log.Fatalf("Struct validation failed: %v", err)
}
}
// PrintRules prints the current config to stdout
func PrintRules() {
log.Printf("Documents with Tag %s at paperless will be marked for queuing", Config.Paperless.AddQueueTagName)
for _, rule := range Config.Paperless.Rules {
var l string
var details []string
if len(rule.Tags) > 0 {
details = append(details, "Tag(s): \""+strings.Join(rule.Tags, ",")+"\"")
}
if len(rule.Correspondent) > 0 {
details = append(details, "Correspondent: \""+rule.Correspondent+"\"")
}
if len(rule.Type) > 0 {
details = append(details, "Type: \""+rule.Type+"\"")
}
l += strings.Join(details, ", ")
l += " to Address(es): \"" + strings.Join(rule.ReceiverAddresses, ",") + "\" "
if len(rule.BCCAddresses) > 0 {
l += "and Bcc to: \"" + strings.Join(rule.BCCAddresses, ",") + "\""
}
log.Printf("Found Rule \"%s\": Send Documents with %s", rule.Name, l)
}
log.Printf("All processed documents will be marked with Tag: %s at paperless", Config.Paperless.ProcessedTagName)
}