138 lines
3.0 KiB
Go
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
|
|
}
|
|
}
|