sendmail/config.go

141 lines
3.6 KiB
Go

package main
import (
"errors"
"fmt"
"os"
toml "github.com/pelletier/go-toml"
)
type Validation struct {
Param string
CmdFlag string
ConfFlag string
}
type ServerConfig struct {
Address string `toml:address,omitempty`
Port int64 `toml:port,omitempty`
Encryption bool `toml:encryption,omitempty`
User string `toml:user,omitempty`
Password string `toml:password,omitempty`
}
func (s ServerConfig) String() string {
return fmt.Sprintf(
"\tAddress: %s\n\tPort: %d\n\tEncryption: %t\n\tUser: %s\n\tPassword: %s\n",
s.Address,
s.Port,
s.Encryption,
s.User,
s.Password,
)
}
type Config struct {
Server *ServerConfig `toml:server,omitempty`
From string `toml:from,omitempty`
To []string `toml:to,omitempty`
Cc []string `toml:cc,omitempty`
Bcc []string `toml:bcc,omitempty`
Subject string `toml:subject,omitempty`
Text string `toml:text,omitempty`
Attachments []string `toml:attachments,omitempty`
}
func (c Config) String() string {
msg := fmt.Sprintf(
"From: %s\nTo: %s\nCc: %s\nBcc: %s\nSubject: %s\nText:\n%s\nServer:\n%s\n",
c.From,
c.To,
c.Cc,
c.Bcc,
c.Subject,
c.Text,
c.Server,
)
msg += "Attachments:"
for _, attachment := range c.Attachments {
msg += fmt.Sprintf(" - %s\n", attachment)
}
return msg
}
func NewConfig() *Config {
server := &ServerConfig{}
config := &Config{}
config.Server = server
return config
}
func (s *ServerConfig) Merge(key string, value interface{}) {
Merge(key, value, s)
}
func (c *Config) Merge(key string, value interface{}) {
Merge(key, value, c)
}
func readConfig(configPath, section string) (*Config, error) {
config := NewConfig()
tree, err := toml.LoadFile(configPath)
if err != nil {
return config, err
}
keys := tree.Keys()
if !IsPresent(keys, section) {
return config, errors.New("missing section")
}
sub := tree.Get(section).(*toml.Tree)
err = sub.Unmarshal(config)
return config, err
}
func checkValidity(validations *[]Validation, obj interface{}, name, cmd, param string) {
if IsEmpty(obj) {
*validations = append(*validations, Validation{name, cmd, param})
}
}
func (c *Config) Validate() error {
var validations = []Validation{}
var msg string
checkValidity(&validations, c.Server.Address, "server address", "server-address", "server.address")
checkValidity(&validations, c.Server.Port, "server port", "server-port", "server.port")
if !c.Server.Encryption {
Warning.Ln("Warning: not using encryption!")
}
checkValidity(&validations, c.Server.User, "username", "user", "server.user")
checkValidity(&validations, c.Server.Password, "password", "password", "server.password")
checkValidity(&validations, c.From, "from", "from", "from")
checkValidity(&validations, c.To, "to", "to", "to")
checkValidity(&validations, c.Subject, "subject", "sub", "subject")
checkValidity(&validations, c.Text, "body", "", "text")
Debug.F("Lengths:\n\tTo: %d\n\tCc: %d\n\tBcc: %d", len(c.To), len(c.Cc), len(c.Bcc))
if len(validations) > 0 {
for _, v := range validations {
if v.CmdFlag == "" {
msg += fmt.Sprintf("%s: pass a value either via stdin or in configuration file section (%s)\n", v.Param, v.ConfFlag)
} else {
msg += fmt.Sprintf("%s: pass a value either via command line (-%s) or in configuration file section (%s)\n", v.Param, v.CmdFlag, v.ConfFlag)
}
}
}
if len(c.Attachments) > 0 {
for _, file := range c.Attachments {
if _, err := os.Lstat(file); err != nil {
msg += fmt.Sprintf("Error with attachment: %s -> %s\n", file, err)
}
}
}
if msg != "" {
return errors.New(msg)
}
return nil
}