Unify SMTP settings in separate section (#536)
* move SMTP settings to separate group * move deprecated options in separate section in readme * adjust variables in docker-compose * add description to SmtpGroup * remove SMTP option setting which is already set to same value * remove smtp port default for consistency * add server deprecated functions handling * satisfy linter * add missing bracket in description * add test for handleDeprecatedFlags * add HandleDeprecatedFlags function to CommonOptionsCommander * improve HandleDeprecatedFlags behavior * add missing result check to ServerCommand.HandleDeprecatedFlags
This commit is contained in:
committed by
Umputun
parent
17be003652
commit
d0ddd8aa80
@@ -144,29 +144,23 @@ _this is the recommended way to run remark42_
|
||||
| auth.dev | AUTH_DEV | `false` | local oauth2 server, development mode only |
|
||||
| auth.anon | AUTH_ANON | `false` | enable anonymous login |
|
||||
| auth.email.enable | AUTH_EMAIL_ENABLE | `false` | enable auth via email |
|
||||
| auth.email.host | AUTH_EMAIL_HOST | | smtp host |
|
||||
| auth.email.port | AUTH_EMAIL_PORT | `25` | smtp port |
|
||||
| auth.email.from | AUTH_EMAIL_FROM | | email from |
|
||||
| auth.email.subj | AUTH_EMAIL_SUBJ | `remark42 confirmation` | email subject |
|
||||
| auth.email.content-type | AUTH_EMAIL_CONTENT_TYPE | `text/html` | email content type |
|
||||
| auth.email.tls | AUTH_EMAIL_TLS | `false` | enable TLS |
|
||||
| auth.email.user | AUTH_EMAIL_USER | | smtp user name |
|
||||
| auth.email.passwd | AUTH_EMAIL_PASSWD | | smtp password |
|
||||
| auth.email.timeout | AUTH_EMAIL_TIMEOUT | `10s` | smtp timeout |
|
||||
| auth.email.template | AUTH_EMAIL_TEMPLATE | none (predefined) | custom email message template file |
|
||||
| notify.type | NOTIFY_TYPE | none | type of notification (telegram and/or email) |
|
||||
| notify.queue | NOTIFY_QUEUE | `100` | size of notification queue |
|
||||
| notify.telegram.token | NOTIFY_TELEGRAM_TOKEN | | telegram token |
|
||||
| notify.telegram.chan | NOTIFY_TELEGRAM_CHAN | | telegram channel |
|
||||
| notify.telegram.timeout | NOTIFY_TELEGRAM_TIMEOUT | `5s` | telegram timeout |
|
||||
| notify.email.host | NOTIFY_EMAIL_HOST | | SMTP host |
|
||||
| notify.email.port | NOTIFY_EMAIL_PORT | `587` | SMTP port |
|
||||
| notify.email.tls | NOTIFY_EMAIL_TLS | | enable TLS for SMTP |
|
||||
| notify.email.fromAddress | NOTIFY_EMAIL_FROM | | from email address |
|
||||
| notify.email.username | NOTIFY_EMAIL_USERNAME | | SMTP user name |
|
||||
| notify.email.password | NOTIFY_EMAIL_PASSWORD | | SMTP password |
|
||||
| notify.email.timeout | NOTIFY_EMAIL_TIMEOUT | `10s` | SMTP TCP connection timeout |
|
||||
| notify.email.verification_subj | NOTIFY_EMAIL_VERIFICATION_SUBJ | `Email verification` | verification message subject |
|
||||
| smtp.host | SMTP_HOST | | SMTP host |
|
||||
| smtp.port | SMTP_PORT | | SMTP port |
|
||||
| smtp.username | SMTP_USERNAME | | SMTP user name |
|
||||
| smtp.password | SMTP_PASSWORD | | SMTP password |
|
||||
| smtp.tls | SMTP_TLS | | enable TLS for SMTP |
|
||||
| smtp.timeout | SMTP_TIMEOUT | `10s` | SMTP TCP connection timeout |
|
||||
| ssl.type | SSL_TYPE | none | `none`-http, `static`-https, `auto`-https + le |
|
||||
| ssl.port | SSL_PORT | `8443` | port for https server |
|
||||
| ssl.cert | SSL_CERT | | path to cert.pem file |
|
||||
@@ -197,6 +191,19 @@ _this is the recommended way to run remark42_
|
||||
* _multi_ parameters separated by `,` in the environment or repeated with command line key, like `--site=s1 --site=s2 ...`
|
||||
* _required_ parameters have to be presented in the environment or provided in command line
|
||||
|
||||
##### Deprecated
|
||||
|
||||
<details><summary>deprecated options</summary>
|
||||
| Command line | Replacement | Environment | Replacement | Default | Description | Deprecation version |
|
||||
| ------------------ | ------------- | ------------------ | ------------- | ------- | -------------- | ------------------- |
|
||||
| auth.email.host | smtp.host | AUTH_EMAIL_HOST | SMTP_HOST | | smtp host | 1.5.0 |
|
||||
| auth.email.port | smtp.port | AUTH_EMAIL_PORT | SMTP_PORT | | smtp port | 1.5.0 |
|
||||
| auth.email.user | smtp.username | AUTH_EMAIL_USER | SMTP_USERNAME | | smtp user name | 1.5.0 |
|
||||
| auth.email.passwd | smtp.password | AUTH_EMAIL_PASSWD | SMTP_PASSWORD | | smtp password | 1.5.0 |
|
||||
| auth.email.tls | smtp.tls | AUTH_EMAIL_TLS | SMTP_TLS | `false` | enable TLS | 1.5.0 |
|
||||
| auth.email.timeout | smtp.timeout | AUTH_EMAIL_TIMEOUT | SMTP_TIMEOUT | `10s` | smtp timeout | 1.5.0 |
|
||||
</details>
|
||||
|
||||
##### Required parameters
|
||||
|
||||
Most of the parameters have sane defaults and don't require customization. There are only a few parameters user has to define:
|
||||
|
||||
@@ -21,6 +21,7 @@ import (
|
||||
type CommonOptionsCommander interface {
|
||||
SetCommon(commonOpts CommonOpts)
|
||||
Execute(args []string) error
|
||||
HandleDeprecatedFlags() []DeprecatedFlag
|
||||
}
|
||||
|
||||
// CommonOpts sets externally from main, shared across all commands
|
||||
@@ -30,6 +31,13 @@ type CommonOpts struct {
|
||||
Revision string
|
||||
}
|
||||
|
||||
// DeprecatedFlag contains information about deprecated option
|
||||
type DeprecatedFlag struct {
|
||||
Old string
|
||||
New string
|
||||
RemoveVersion string
|
||||
}
|
||||
|
||||
// SetCommon satisfies CommonOptionsCommander interface and sets common option fields
|
||||
// The method called by main for each command
|
||||
func (c *CommonOpts) SetCommon(commonOpts CommonOpts) {
|
||||
@@ -38,6 +46,9 @@ func (c *CommonOpts) SetCommon(commonOpts CommonOpts) {
|
||||
c.Revision = commonOpts.Revision
|
||||
}
|
||||
|
||||
// HandleDeprecatedFlags sets new flags from deprecated and returns their list
|
||||
func (c *CommonOpts) HandleDeprecatedFlags() []DeprecatedFlag { return nil }
|
||||
|
||||
// fileParser used to convert template strings like blah-{{.SITE}}-{{.YYYYMMDD}} the final format
|
||||
type fileParser struct {
|
||||
site string
|
||||
|
||||
+62
-27
@@ -47,6 +47,7 @@ type ServerCommand struct {
|
||||
Cache CacheGroup `group:"cache" namespace:"cache" env-namespace:"CACHE"`
|
||||
Admin AdminGroup `group:"admin" namespace:"admin" env-namespace:"ADMIN"`
|
||||
Notify NotifyGroup `group:"notify" namespace:"notify" env-namespace:"NOTIFY"`
|
||||
SMTP SmtpGroup `group:"smtp" namespace:"smtp" env-namespace:"SMTP"`
|
||||
Image ImageGroup `group:"image" namespace:"image" env-namespace:"IMAGE"`
|
||||
SSL SSLGroup `group:"ssl" namespace:"ssl" env-namespace:"SSL"`
|
||||
Stream StreamGroup `group:"stream" namespace:"stream" env-namespace:"STREAM"`
|
||||
@@ -87,15 +88,15 @@ type ServerCommand struct {
|
||||
Anonymous bool `long:"anon" env:"ANON" description:"enable anonymous login"`
|
||||
Email struct {
|
||||
Enable bool `long:"enable" env:"ENABLE" description:"enable auth via email"`
|
||||
Host string `long:"host" env:"HOST" description:"smtp host"`
|
||||
Port int `long:"port" env:"PORT" description:"smtp port"`
|
||||
From string `long:"from" env:"FROM" description:"email's from"`
|
||||
From string `long:"from" env:"FROM" description:"from email address"`
|
||||
Subject string `long:"subj" env:"SUBJ" default:"remark42 confirmation" description:"email's subject"`
|
||||
ContentType string `long:"content-type" env:"CONTENT_TYPE" default:"text/html" description:"content type"`
|
||||
TLS bool `long:"tls" env:"TLS" description:"enable TLS"`
|
||||
SMTPUserName string `long:"user" env:"USER" description:"smtp user name"`
|
||||
SMTPPassword string `long:"passwd" env:"PASSWD" description:"smtp password"`
|
||||
TimeOut time.Duration `long:"timeout" env:"TIMEOUT" default:"10s" description:"smtp timeout"`
|
||||
Host string `long:"host" env:"HOST" description:"[deprecated, use --smtp.host] SMTP host"`
|
||||
Port int `long:"port" env:"PORT" description:"[deprecated, use --smtp.port] SMTP password"`
|
||||
SMTPPassword string `long:"passwd" env:"PASSWD" description:"[deprecated, use --smtp.password] SMTP port"`
|
||||
SMTPUserName string `long:"user" env:"USER" description:"[deprecated, use --smtp.username] enable TLS"`
|
||||
TLS bool `long:"tls" env:"TLS" description:"[deprecated, use --smtp.tls] SMTP TCP connection timeout"`
|
||||
TimeOut time.Duration `long:"timeout" env:"TIMEOUT" default:"10s" description:"[deprecated, use --smtp.timeout] SMTP TCP connection timeout"`
|
||||
MsgTemplate string `long:"template" env:"TEMPLATE" description:"message template file"`
|
||||
} `group:"email" namespace:"email" env-namespace:"EMAIL"`
|
||||
} `group:"auth" namespace:"auth" env-namespace:"AUTH"`
|
||||
@@ -168,6 +169,16 @@ type AdminGroup struct {
|
||||
RPC RPCGroup `group:"rpc" namespace:"rpc" env-namespace:"RPC"`
|
||||
}
|
||||
|
||||
// SmtpGroup defines options for SMTP server connection, used in auth and notify modules
|
||||
type SmtpGroup struct {
|
||||
Host string `long:"host" env:"HOST" description:"SMTP host"`
|
||||
Port int `long:"port" env:"PORT" description:"SMTP port"`
|
||||
Username string `long:"username" env:"USERNAME" description:"SMTP user name"`
|
||||
Password string `long:"password" env:"PASSWORD" description:"SMTP password"`
|
||||
TLS bool `long:"tls" env:"TLS" description:"enable TLS"`
|
||||
TimeOut time.Duration `long:"timeout" env:"TIMEOUT" default:"10s" description:"SMTP TCP connection timeout"`
|
||||
}
|
||||
|
||||
// NotifyGroup defines options for notification
|
||||
type NotifyGroup struct {
|
||||
Type []string `long:"type" env:"TYPE" description:"type of notification" choice:"none" choice:"telegram" choice:"email" default:"none" env-delim:","` //nolint
|
||||
@@ -179,14 +190,8 @@ type NotifyGroup struct {
|
||||
API string `long:"api" env:"API" default:"https://api.telegram.org/bot" description:"telegram api prefix"`
|
||||
} `group:"telegram" namespace:"telegram" env-namespace:"TELEGRAM"`
|
||||
Email struct {
|
||||
Host string `long:"host" env:"HOST" description:"SMTP host"`
|
||||
Port int `long:"port" env:"PORT" default:"587" description:"SMTP port"`
|
||||
TLS bool `long:"tls" env:"TLS" description:"enable TLS for SMTP"`
|
||||
From string `long:"fromAddress" env:"FROM" description:"from email address"`
|
||||
Username string `long:"username" env:"USERNAME" description:"SMTP user name"`
|
||||
Password string `long:"password" env:"PASSWORD" description:"SMTP password"`
|
||||
TimeOut time.Duration `long:"timeout" env:"TIMEOUT" default:"10s" description:"SMTP TCP connection timeout"`
|
||||
VerificationSubject string `long:"verification_subj" env:"VERIFICATION_SUBJ" description:"verification message subject"`
|
||||
From string `long:"fromAddress" env:"FROM" description:"from email address"`
|
||||
VerificationSubject string `long:"verification_subj" env:"VERIFICATION_SUBJ" description:"verification message subject"`
|
||||
} `group:"email" namespace:"email" env-namespace:"EMAIL"`
|
||||
}
|
||||
|
||||
@@ -262,6 +267,36 @@ func (s *ServerCommand) Execute(args []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// HandleDeprecatedFlags sets new flags from deprecated returns their list
|
||||
func (s *ServerCommand) HandleDeprecatedFlags() (result []DeprecatedFlag) {
|
||||
// 1.5.0
|
||||
if s.Auth.Email.Host != "" && s.SMTP.Host == "" {
|
||||
s.SMTP.Host = s.Auth.Email.Host
|
||||
result = append(result, DeprecatedFlag{Old: "auth.email.host", New: "smtp.host", RemoveVersion: "1.7.0"})
|
||||
}
|
||||
if s.Auth.Email.Port != 0 && s.SMTP.Port == 0 {
|
||||
s.SMTP.Port = s.Auth.Email.Port
|
||||
result = append(result, DeprecatedFlag{Old: "auth.email.port", New: "smtp.port", RemoveVersion: "1.7.0"})
|
||||
}
|
||||
if s.Auth.Email.TLS && !s.SMTP.TLS {
|
||||
s.SMTP.TLS = s.Auth.Email.TLS
|
||||
result = append(result, DeprecatedFlag{Old: "auth.email.tls", New: "smtp.tls", RemoveVersion: "1.7.0"})
|
||||
}
|
||||
if s.Auth.Email.SMTPUserName != "" && s.SMTP.Username == "" {
|
||||
s.SMTP.Username = s.Auth.Email.SMTPUserName
|
||||
result = append(result, DeprecatedFlag{Old: "auth.email.user", New: "smtp.username", RemoveVersion: "1.7.0"})
|
||||
}
|
||||
if s.Auth.Email.SMTPPassword != "" && s.SMTP.Password == "" {
|
||||
s.SMTP.Password = s.Auth.Email.SMTPPassword
|
||||
result = append(result, DeprecatedFlag{Old: "auth.email.passwd", New: "smtp.password", RemoveVersion: "1.7.0"})
|
||||
}
|
||||
if s.Auth.Email.TimeOut != 10*time.Second && s.SMTP.TimeOut == 10*time.Second {
|
||||
s.SMTP.TimeOut = s.Auth.Email.TimeOut
|
||||
result = append(result, DeprecatedFlag{Old: "auth.email.timeout", New: "smtp.timeout", RemoveVersion: "1.7.0"})
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// newServerApp prepares application and return it with all active parts
|
||||
// doesn't start anything
|
||||
func (s *ServerCommand) newServerApp() (*serverApp, error) {
|
||||
@@ -644,15 +679,15 @@ func (s *ServerCommand) addAuthProviders(authenticator *auth.Service) {
|
||||
|
||||
if s.Auth.Email.Enable {
|
||||
params := sender.EmailParams{
|
||||
Host: s.Auth.Email.Host,
|
||||
Port: s.Auth.Email.Port,
|
||||
Host: s.SMTP.Host,
|
||||
Port: s.SMTP.Port,
|
||||
SMTPUserName: s.SMTP.Username,
|
||||
SMTPPassword: s.SMTP.Password,
|
||||
TimeOut: s.SMTP.TimeOut,
|
||||
TLS: s.SMTP.TLS,
|
||||
From: s.Auth.Email.From,
|
||||
Subject: s.Auth.Email.Subject,
|
||||
ContentType: s.Auth.Email.ContentType,
|
||||
TLS: s.Auth.Email.TLS,
|
||||
SMTPUserName: s.Auth.Email.SMTPUserName,
|
||||
SMTPPassword: s.Auth.Email.SMTPPassword,
|
||||
TimeOut: s.Auth.Email.TimeOut,
|
||||
}
|
||||
sndr := sender.NewEmailClient(params, log.Default())
|
||||
authenticator.AddVerifProvider("email", s.loadEmailTemplate(), sndr)
|
||||
@@ -732,12 +767,12 @@ func (s *ServerCommand) makeNotify(dataStore *service.DataStore, authenticator *
|
||||
},
|
||||
}
|
||||
smtpParams := notify.SmtpParams{
|
||||
Host: s.Notify.Email.Host,
|
||||
Port: s.Notify.Email.Port,
|
||||
TLS: s.Notify.Email.TLS,
|
||||
Username: s.Notify.Email.Username,
|
||||
Password: s.Notify.Email.Password,
|
||||
TimeOut: s.Notify.Email.TimeOut,
|
||||
Host: s.SMTP.Host,
|
||||
Port: s.SMTP.Port,
|
||||
TLS: s.SMTP.TLS,
|
||||
Username: s.SMTP.Username,
|
||||
Password: s.SMTP.Password,
|
||||
TimeOut: s.SMTP.TimeOut,
|
||||
}
|
||||
emailService, err := notify.NewEmail(emailParams, smtpParams)
|
||||
if err != nil {
|
||||
|
||||
@@ -312,6 +312,47 @@ func TestServerApp_MainSignal(t *testing.T) {
|
||||
assert.True(t, time.Since(st).Seconds() < 5, "should take under five sec", time.Since(st).Seconds())
|
||||
}
|
||||
|
||||
func TestServerApp_DeprecatedArgs(t *testing.T) {
|
||||
s := ServerCommand{}
|
||||
s.SetCommon(CommonOpts{RemarkURL: "https://demo.remark42.com", SharedSecret: "123456"})
|
||||
|
||||
p := flags.NewParser(&s, flags.Default)
|
||||
args := []string{
|
||||
"test",
|
||||
"--auth.email.host=smtp.example.org",
|
||||
"--auth.email.port=666",
|
||||
"--auth.email.tls",
|
||||
"--auth.email.user=test_user",
|
||||
"--auth.email.passwd=test_password",
|
||||
"--auth.email.timeout=15s",
|
||||
}
|
||||
assert.Empty(t, s.SMTP.Host)
|
||||
assert.Empty(t, s.SMTP.Port)
|
||||
assert.Empty(t, s.SMTP.TLS)
|
||||
assert.Empty(t, s.SMTP.Username)
|
||||
assert.Empty(t, s.SMTP.Password)
|
||||
assert.Empty(t, s.SMTP.TimeOut)
|
||||
_, err := p.ParseArgs(args)
|
||||
require.NoError(t, err)
|
||||
deprecatedFlags := s.HandleDeprecatedFlags()
|
||||
assert.ElementsMatch(t,
|
||||
[]DeprecatedFlag{
|
||||
{Old: "auth.email.host", New: "smtp.host", RemoveVersion: "1.7.0"},
|
||||
{Old: "auth.email.port", New: "smtp.port", RemoveVersion: "1.7.0"},
|
||||
{Old: "auth.email.tls", New: "smtp.tls", RemoveVersion: "1.7.0"},
|
||||
{Old: "auth.email.user", New: "smtp.username", RemoveVersion: "1.7.0"},
|
||||
{Old: "auth.email.passwd", New: "smtp.password", RemoveVersion: "1.7.0"},
|
||||
{Old: "auth.email.timeout", New: "smtp.timeout", RemoveVersion: "1.7.0"},
|
||||
},
|
||||
deprecatedFlags)
|
||||
assert.Equal(t, "smtp.example.org", s.SMTP.Host)
|
||||
assert.Equal(t, 666, s.SMTP.Port)
|
||||
assert.Equal(t, true, s.SMTP.TLS)
|
||||
assert.Equal(t, "test_user", s.SMTP.Username)
|
||||
assert.Equal(t, "test_password", s.SMTP.Password)
|
||||
assert.Equal(t, 15*time.Second, s.SMTP.TimeOut)
|
||||
}
|
||||
|
||||
func Test_ACMEEmail(t *testing.T) {
|
||||
cmd := ServerCommand{}
|
||||
cmd.SetCommon(CommonOpts{RemarkURL: "https://remark.com:443", SharedSecret: "123456"})
|
||||
@@ -512,14 +553,13 @@ func prepServerApp(t *testing.T, fn func(o ServerCommand) ServerCommand) (*serve
|
||||
cmd.Auth.Email.MsgTemplate = "testdata/email.tmpl"
|
||||
cmd.BackupLocation = "/tmp"
|
||||
cmd.Notify.Type = []string{"email"}
|
||||
cmd.Notify.Email.Host = "127.0.0.1"
|
||||
cmd.Notify.Email.Port = 25
|
||||
cmd.Notify.Email.TLS = false
|
||||
cmd.Notify.Email.From = "from@example.org"
|
||||
cmd.Notify.Email.Username = "test_user"
|
||||
cmd.Notify.Email.Password = "test_password"
|
||||
cmd.Notify.Email.TimeOut = time.Second
|
||||
cmd.Notify.Email.VerificationSubject = "test verification email subject"
|
||||
cmd.SMTP.Host = "127.0.0.1"
|
||||
cmd.SMTP.Port = 25
|
||||
cmd.SMTP.Username = "test_user"
|
||||
cmd.SMTP.Password = "test_password"
|
||||
cmd.SMTP.TimeOut = time.Second
|
||||
cmd.UpdateLimit = 10
|
||||
cmd = fn(cmd)
|
||||
|
||||
|
||||
@@ -45,6 +45,10 @@ func main() {
|
||||
SharedSecret: opts.SharedSecret,
|
||||
Revision: revision,
|
||||
})
|
||||
for _, entry := range c.HandleDeprecatedFlags() {
|
||||
log.Printf("[WARN] --%s is deprecated and will be removed in v%s, please use --%s instead",
|
||||
entry.Old, entry.RemoveVersion, entry.New)
|
||||
}
|
||||
err := c.Execute(args)
|
||||
if err != nil {
|
||||
log.Printf("[ERROR] failed with %+v", err)
|
||||
|
||||
@@ -44,12 +44,12 @@ services:
|
||||
- NOTIFY_TYPE
|
||||
- NOTIFY_TELEGRAM_TOKEN
|
||||
- NOTIFY_TELEGRAM_CHAN
|
||||
- NOTIFY_EMAIL_HOST
|
||||
- NOTIFY_EMAIL_USERNAME
|
||||
- NOTIFY_EMAIL_PASSWORD
|
||||
- NOTIFY_EMAIL_FROM
|
||||
- NOTIFY_EMAIL_PORT
|
||||
- NOTIFY_EMAIL_TLS
|
||||
- SMTP_HOST
|
||||
- SMTP_USERNAME
|
||||
- SMTP_PASSWORD
|
||||
- SMTP_PORT
|
||||
- SMTP_TLS
|
||||
- EMOJI=true
|
||||
- ANON_VOTE=true
|
||||
- VOTES_IP=true
|
||||
|
||||
Reference in New Issue
Block a user