From 2cb8a3ba7634d45950328d8f77aea0d050a9748a Mon Sep 17 00:00:00 2001 From: tsmethurst Date: Sat, 16 Oct 2021 17:14:58 +0200 Subject: [PATCH] add smtp configuration --- cmd/gotosocial/flags.go | 1 + cmd/gotosocial/smtpflags.go | 59 +++++++++++++++++++++++++++++++++++++ example/config.yaml | 32 ++++++++++++++++++++ internal/config/config.go | 47 +++++++++++++++++++++++++++++ internal/config/default.go | 26 ++++++++++++++++ internal/config/smtp.go | 33 +++++++++++++++++++++ 6 files changed, 198 insertions(+) create mode 100644 cmd/gotosocial/smtpflags.go create mode 100644 internal/config/smtp.go diff --git a/cmd/gotosocial/flags.go b/cmd/gotosocial/flags.go index 355ec0b81..8e162f6c7 100644 --- a/cmd/gotosocial/flags.go +++ b/cmd/gotosocial/flags.go @@ -39,6 +39,7 @@ func getFlags() []cli.Flag { statusesFlags(flagNames, envNames, defaults), letsEncryptFlags(flagNames, envNames, defaults), oidcFlags(flagNames, envNames, defaults), + smtpFlags(flagNames, envNames, defaults), } for _, fs := range flagSets { flags = append(flags, fs...) diff --git a/cmd/gotosocial/smtpflags.go b/cmd/gotosocial/smtpflags.go new file mode 100644 index 000000000..84556ca00 --- /dev/null +++ b/cmd/gotosocial/smtpflags.go @@ -0,0 +1,59 @@ +/* + GoToSocial + Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +package main + +import ( + "github.com/superseriousbusiness/gotosocial/internal/config" + "github.com/urfave/cli/v2" +) + +func smtpFlags(flagNames, envNames config.Flags, defaults config.Defaults) []cli.Flag { + return []cli.Flag{ + &cli.StringFlag{ + Name: flagNames.SMTPHost, + Usage: "Host of the smtp server. Eg., 'smtp.eu.mailgun.org'", + Value: defaults.SMTPHost, + EnvVars: []string{envNames.SMTPHost}, + }, + &cli.IntFlag{ + Name: flagNames.SMTPPort, + Usage: "Port of the smtp server. Eg., 587", + Value: defaults.SMTPPort, + EnvVars: []string{envNames.SMTPPort}, + }, + &cli.StringFlag{ + Name: flagNames.SMTPUsername, + Usage: "Username to authenticate with the smtp server as. Eg., 'postmaster@mail.example.org'", + Value: defaults.SMTPUsername, + EnvVars: []string{envNames.SMTPUsername}, + }, + &cli.StringFlag{ + Name: flagNames.SMTPPassword, + Usage: "Password to pass to the smtp server.", + Value: defaults.SMTPPassword, + EnvVars: []string{envNames.SMTPPassword}, + }, + &cli.StringFlag{ + Name: flagNames.SMTPFrom, + Usage: "String to use as the 'from' field of the email. Eg., 'gotosocial@example.org'", + Value: defaults.SMTPFrom, + EnvVars: []string{envNames.SMTPFrom}, + }, + } +} diff --git a/example/config.yaml b/example/config.yaml index 50b863725..81e6e7c06 100644 --- a/example/config.yaml +++ b/example/config.yaml @@ -360,3 +360,35 @@ oidc: - "email" - "profile" - "groups" + +####################### +##### SMTP CONFIG ##### +####################### + +# Config for sending emails via an smtp server. See https://en.wikipedia.org/wiki/Simple_Mail_Transfer_Protocol +smtp: + + # String. The hostname of the smtp server you want to use. + # If this is not set, smtp will not be used to send emails, and you can ignore the other settings. + # Examples: ["mail.example.org", "localhost"] + # Default: "" + host: "" + # Int. Port to use to connect to the smtp server. + # Examples: [] + # Default: 0 + port: 0 + # String. Username to use when authenticating with the smtp server. + # This should have been provided to you by your smtp host. + # This is often, but not always, an email address. + # Examples: ["maillord@example.org"] + # Default: "" + username: + # String. Password to use when authenticating with the smtp server. + # This should have been provided to you by your smtp host. + # Examples: ["1234", "password"] + # Default: "" + password: + # String. 'From' field for sent emails. + # Examples: ["mail@example.org", "GoToSocial"] + # Default: "GoToSocial" + from: "GoToSocial" diff --git a/internal/config/config.go b/internal/config/config.go index bb789b7d2..7a3a92af9 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -63,6 +63,7 @@ type Config struct { StatusesConfig *StatusesConfig `yaml:"statuses"` LetsEncryptConfig *LetsEncryptConfig `yaml:"letsEncrypt"` OIDCConfig *OIDCConfig `yaml:"oidc"` + SMTPConfig *SMTPConfig `yaml:"smtp"` /* Not parsed from .yaml configuration file. @@ -95,6 +96,7 @@ func Empty() *Config { StatusesConfig: &StatusesConfig{}, LetsEncryptConfig: &LetsEncryptConfig{}, OIDCConfig: &OIDCConfig{}, + SMTPConfig: &SMTPConfig{}, AccountCLIFlags: make(map[string]string), ExportCLIFlags: make(map[string]string), } @@ -318,6 +320,27 @@ func (c *Config) ParseCLIFlags(f KeyedFlags, version string) error { c.OIDCConfig.Scopes = f.StringSlice(fn.OIDCScopes) } + // smtp flags + if c.SMTPConfig.Host == "" || f.IsSet(fn.SMTPHost) { + c.SMTPConfig.Host = f.String(fn.SMTPHost) + } + + if c.SMTPConfig.Port == 0 || f.IsSet(fn.SMTPPort) { + c.SMTPConfig.Port = f.Int(fn.SMTPPort) + } + + if c.SMTPConfig.Username == "" || f.IsSet(fn.SMTPUsername) { + c.SMTPConfig.Username = f.String(fn.SMTPUsername) + } + + if c.SMTPConfig.Password == "" || f.IsSet(fn.SMTPPassword) { + c.SMTPConfig.Password = f.String(fn.SMTPPassword) + } + + if c.SMTPConfig.From == "" || f.IsSet(fn.SMTPFrom) { + c.SMTPConfig.From = f.String(fn.SMTPFrom) + } + // command-specific flags // admin account CLI flags @@ -399,6 +422,12 @@ type Flags struct { OIDCClientID string OIDCClientSecret string OIDCScopes string + + SMTPHost string + SMTPPort string + SMTPUsername string + SMTPPassword string + SMTPFrom string } // Defaults contains all the default values for a gotosocial config @@ -458,6 +487,12 @@ type Defaults struct { OIDCClientID string OIDCClientSecret string OIDCScopes []string + + SMTPHost string + SMTPPort int + SMTPUsername string + SMTPPassword string + SMTPFrom string } // GetFlagNames returns a struct containing the names of the various flags used for @@ -518,6 +553,12 @@ func GetFlagNames() Flags { OIDCClientID: "oidc-client-id", OIDCClientSecret: "oidc-client-secret", OIDCScopes: "oidc-scopes", + + SMTPHost: "smtp-host", + SMTPPort: "smtp-port", + SMTPUsername: "smtp-username", + SMTPPassword: "smtp-password", + SMTPFrom: "smtp-from", } } @@ -579,5 +620,11 @@ func GetEnvNames() Flags { OIDCClientID: "GTS_OIDC_CLIENT_ID", OIDCClientSecret: "GTS_OIDC_CLIENT_SECRET", OIDCScopes: "GTS_OIDC_SCOPES", + + SMTPHost: "SMTP_HOST", + SMTPPort: "SMTP_PORT", + SMTPUsername: "SMTP_USERNAME", + SMTPPassword: "SMTP_PASSWORD", + SMTPFrom: "SMTP_FROM", } } diff --git a/internal/config/default.go b/internal/config/default.go index ad171a376..a04a5899b 100644 --- a/internal/config/default.go +++ b/internal/config/default.go @@ -67,6 +67,13 @@ func TestDefault() *Config { ClientSecret: defaults.OIDCClientSecret, Scopes: defaults.OIDCScopes, }, + SMTPConfig: &SMTPConfig{ + Host: defaults.SMTPHost, + Port: defaults.SMTPPort, + Username: defaults.SMTPUsername, + Password: defaults.SMTPPassword, + From: defaults.SMTPFrom, + }, } } @@ -134,6 +141,13 @@ func Default() *Config { ClientSecret: defaults.OIDCClientSecret, Scopes: defaults.OIDCScopes, }, + SMTPConfig: &SMTPConfig{ + Host: defaults.SMTPHost, + Port: defaults.SMTPPort, + Username: defaults.SMTPUsername, + Password: defaults.SMTPPassword, + From: defaults.SMTPFrom, + }, } } @@ -195,6 +209,12 @@ func GetDefaults() Defaults { OIDCClientID: "", OIDCClientSecret: "", OIDCScopes: []string{oidc.ScopeOpenID, "profile", "email", "groups"}, + + SMTPHost: "", + SMTPPort: 0, + SMTPUsername: "", + SMTPPassword: "", + SMTPFrom: "GoToSocial", } } @@ -253,5 +273,11 @@ func GetTestDefaults() Defaults { OIDCClientID: "", OIDCClientSecret: "", OIDCScopes: []string{oidc.ScopeOpenID, "profile", "email", "groups"}, + + SMTPHost: "", + SMTPPort: 0, + SMTPUsername: "", + SMTPPassword: "", + SMTPFrom: "GoToSocial", } } diff --git a/internal/config/smtp.go b/internal/config/smtp.go new file mode 100644 index 000000000..daa4967bf --- /dev/null +++ b/internal/config/smtp.go @@ -0,0 +1,33 @@ +/* + GoToSocial + Copyright (C) 2021 GoToSocial Authors admin@gotosocial.org + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +*/ + +package config + +// SMTPConfig holds configuration for sending emails using the smtp protocol. +type SMTPConfig struct { + // Host of the smtp server. + Host string `yaml:"host"` + // Port of the smtp server. + Port int `yaml:"port"` + // Username to use when authenticating with the smtp server. + Username string `yaml:"username"` + // Password to use when authenticating with the smtp server. + Password string `yaml:"password"` + // From address to use when sending emails. + From string `yaml:"from"` +}