mailhole/config/config.go
2023-05-28 09:21:56 +00:00

138 lines
3.0 KiB
Go

package config
import (
"encoding/json"
"os"
"github.com/rs/zerolog/log"
)
// girc.Config can't be marshalled by JSON so we have to recreate our own
type IRCConfig struct {
Server string
ServerPass string
Port int
Nick string
User string
Name string
SSL bool
AllowFlood bool
// Not part of GIRC config
Channel string
}
type DomainConfig struct {
Domain string
IRCEnabled bool
IRC string
}
type SMTPConfig struct {
Domain string
PlainEnabled bool
PlainBind string
TLSEnabled bool
TLSBind string
TLSCert string
TLSKey string
}
type MailholeConfig struct {
IRC map[string]*IRCConfig
Domains []*DomainConfig
SMTP *SMTPConfig
WebUIBase string
}
const CONFIG_PATH = `/etc/mailhole/mailhole.json`
func LoadConfig() *MailholeConfig {
// We do the error handling inside the config loader so we don't have to
// do it for each subcommand
if _, err := os.Stat(CONFIG_PATH); os.IsNotExist(err) {
log.Error().Msg("You need to create a config file for Mailhole to read.")
log.Error().Msg("Get an example: ./mailhole firstrun > /etc/mailhole/mailhole.json")
log.Fatal().Stack().Err(err).Msg("Config file does not exist")
} else {
var configBytes []byte
if configBytes, err = os.ReadFile(CONFIG_PATH); err != nil {
log.Fatal().Stack().Err(err).Msg("Could not open config file")
}
uC := &MailholeConfig{}
if err := json.Unmarshal(configBytes, uC); err != nil {
log.Fatal().Err(err).Msg("Could not unmarshal config file")
}
// Sanity checks
// 1. Do we have any domains with IRC servers that don't exist
for _, v := range uC.Domains {
if !v.IRCEnabled {
continue
}
if _, ok := uC.IRC[v.IRC]; !ok {
log.Fatal().
Str("domain", v.Domain).
Str("irc", v.IRC).
Msg("Domain failed sanity check. Named IRC does not exist in config.")
}
}
return uC
}
return nil
}
func ExampleConfig() []byte {
t := MailholeConfig{
IRC: map[string]*IRCConfig{
"ircname": {
Server: "irc.yourirc.com",
ServerPass: "Password",
Port: 6697,
Nick: "mailhole",
User: "mailhole",
Name: "mailhole",
SSL: true,
AllowFlood: true,
Channel: "#mailhole",
},
},
Domains: []*DomainConfig{
{
Domain: "yourmaildomain.com",
IRC: "ircname",
IRCEnabled: true,
},
{
Domain: "yoursecondmaildomain.com",
IRC: "ircname",
IRCEnabled: true,
},
},
SMTP: &SMTPConfig{
Domain: "mail.yourmaildomain.com",
PlainEnabled: true,
PlainBind: "127.0.0.1:25",
TLSEnabled: true,
TLSBind: "127.0.0.1:587",
TLSCert: "/etc/letsencrypt/live/mail.yourmaildomain.com/fullchain.pem",
TLSKey: "/etc/letsencrypt/live/mail.yourmaildomain.com/privkey.pem",
},
WebUIBase: "http://127.0.0.1:8000",
}
if b, err := json.MarshalIndent(t, "", " "); err != nil {
log.Error().Stack().Err(err).Msg("Failed to marshal config")
return []byte(``)
} else {
return b
}
}