allways set a message-id on mails (#17900)
* allways set a message-id on mails * Add unit tests for mailer & Message-ID Co-authored-by: wxiaoguang <wxiaoguang@gmail.com> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
parent
0ff18a808c
commit
b59875aa12
3 changed files with 66 additions and 5 deletions
|
@ -548,17 +548,17 @@ func SetCustomPathAndConf(providedCustom, providedConf, providedWorkPath string)
|
||||||
|
|
||||||
// LoadFromExisting initializes setting options from an existing config file (app.ini)
|
// LoadFromExisting initializes setting options from an existing config file (app.ini)
|
||||||
func LoadFromExisting() {
|
func LoadFromExisting() {
|
||||||
loadFromConf(false)
|
loadFromConf(false, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadAllowEmpty initializes setting options, it's also fine that if the config file (app.ini) doesn't exist
|
// LoadAllowEmpty initializes setting options, it's also fine that if the config file (app.ini) doesn't exist
|
||||||
func LoadAllowEmpty() {
|
func LoadAllowEmpty() {
|
||||||
loadFromConf(true)
|
loadFromConf(true, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadForTest initializes setting options for tests
|
// LoadForTest initializes setting options for tests
|
||||||
func LoadForTest() {
|
func LoadForTest(extraConfigs ...string) {
|
||||||
loadFromConf(true)
|
loadFromConf(true, strings.Join(extraConfigs, "\n"))
|
||||||
if err := PrepareAppDataPath(); err != nil {
|
if err := PrepareAppDataPath(); err != nil {
|
||||||
log.Fatal("Can not prepare APP_DATA_PATH: %v", err)
|
log.Fatal("Can not prepare APP_DATA_PATH: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -566,7 +566,7 @@ func LoadForTest() {
|
||||||
|
|
||||||
// loadFromConf initializes configuration context.
|
// loadFromConf initializes configuration context.
|
||||||
// NOTE: do not print any log except error.
|
// NOTE: do not print any log except error.
|
||||||
func loadFromConf(allowEmpty bool) {
|
func loadFromConf(allowEmpty bool, extraConfig string) {
|
||||||
Cfg = ini.Empty()
|
Cfg = ini.Empty()
|
||||||
|
|
||||||
if WritePIDFile && len(PIDFile) > 0 {
|
if WritePIDFile && len(PIDFile) > 0 {
|
||||||
|
@ -585,6 +585,12 @@ func loadFromConf(allowEmpty bool) {
|
||||||
log.Fatal("Unable to find configuration file: %q.\nEnsure you are running in the correct environment or set the correct configuration file with -c.", CustomConf)
|
log.Fatal("Unable to find configuration file: %q.\nEnsure you are running in the correct environment or set the correct configuration file with -c.", CustomConf)
|
||||||
} // else: no config file, a config file might be created at CustomConf later (might not)
|
} // else: no config file, a config file might be created at CustomConf later (might not)
|
||||||
|
|
||||||
|
if extraConfig != "" {
|
||||||
|
if err = Cfg.Append([]byte(extraConfig)); err != nil {
|
||||||
|
log.Fatal("Unable to append more config: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Cfg.NameMapper = ini.SnackCase
|
Cfg.NameMapper = ini.SnackCase
|
||||||
|
|
||||||
homeDir, err := com.HomeDir()
|
homeDir, err := com.HomeDir()
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"hash/fnv"
|
||||||
"io"
|
"io"
|
||||||
"net"
|
"net"
|
||||||
"net/smtp"
|
"net/smtp"
|
||||||
|
@ -67,6 +68,10 @@ func (m *Message) ToMessage() *gomail.Message {
|
||||||
msg.SetBody("text/plain", plainBody)
|
msg.SetBody("text/plain", plainBody)
|
||||||
msg.AddAlternative("text/html", m.Body)
|
msg.AddAlternative("text/html", m.Body)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if len(msg.GetHeader("Message-ID")) == 0 {
|
||||||
|
msg.SetHeader("Message-ID", m.generateAutoMessageID())
|
||||||
|
}
|
||||||
return msg
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,6 +80,17 @@ func (m *Message) SetHeader(field string, value ...string) {
|
||||||
m.Headers[field] = value
|
m.Headers[field] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Message) generateAutoMessageID() string {
|
||||||
|
dateMs := m.Date.UnixNano() / 1e6
|
||||||
|
h := fnv.New64()
|
||||||
|
if len(m.To) > 0 {
|
||||||
|
_, _ = h.Write([]byte(m.To[0]))
|
||||||
|
}
|
||||||
|
_, _ = h.Write([]byte(m.Subject))
|
||||||
|
_, _ = h.Write([]byte(m.Body))
|
||||||
|
return fmt.Sprintf("<autogen-%d-%016x@%s>", dateMs, h.Sum64(), setting.Domain)
|
||||||
|
}
|
||||||
|
|
||||||
// NewMessageFrom creates new mail message object with custom From header.
|
// NewMessageFrom creates new mail message object with custom From header.
|
||||||
func NewMessageFrom(to []string, fromDisplayName, fromAddress, subject, body string) *Message {
|
func NewMessageFrom(to []string, fromDisplayName, fromAddress, subject, body string) *Message {
|
||||||
log.Trace("NewMessageFrom (body):\n%s", body)
|
log.Trace("NewMessageFrom (body):\n%s", body)
|
||||||
|
|
39
services/mailer/mailer_test.go
Normal file
39
services/mailer/mailer_test.go
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
// Copyright 2021 The Gogs Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package mailer
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"code.gitea.io/gitea/modules/setting"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGenerateMessageID(t *testing.T) {
|
||||||
|
setting.LoadForTest(`
|
||||||
|
[mailer]
|
||||||
|
ENABLED = true
|
||||||
|
FROM = test@domain.com
|
||||||
|
`)
|
||||||
|
setting.NewServices()
|
||||||
|
|
||||||
|
date := time.Date(2000, 01, 02, 03, 04, 05, 06, time.UTC)
|
||||||
|
m := NewMessageFrom(nil, "display-name", "from-address", "subject", "body")
|
||||||
|
m.Date = date
|
||||||
|
gm := m.ToMessage()
|
||||||
|
assert.Equal(t, "<autogen-946782245000-41e8fc54a8ad3a3f@localhost>", gm.GetHeader("Message-ID")[0])
|
||||||
|
|
||||||
|
m = NewMessageFrom([]string{"a@b.com"}, "display-name", "from-address", "subject", "body")
|
||||||
|
m.Date = date
|
||||||
|
gm = m.ToMessage()
|
||||||
|
assert.Equal(t, "<autogen-946782245000-cc88ce3cfe9bd04f@localhost>", gm.GetHeader("Message-ID")[0])
|
||||||
|
|
||||||
|
m = NewMessageFrom([]string{"a@b.com"}, "display-name", "from-address", "subject", "body")
|
||||||
|
m.SetHeader("Message-ID", "<msg-d@domain.com>")
|
||||||
|
gm = m.ToMessage()
|
||||||
|
assert.Equal(t, "<msg-d@domain.com>", gm.GetHeader("Message-ID")[0])
|
||||||
|
}
|
Reference in a new issue