From d97b9c3b98ed88e05299ddef88c0dd79ae867540 Mon Sep 17 00:00:00 2001 From: garionion Date: Fri, 3 Dec 2021 17:00:49 +0100 Subject: [PATCH 1/3] allways set a message-id on mails --- services/mailer/mailer.go | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/services/mailer/mailer.go b/services/mailer/mailer.go index 4b1492df0b89..2aa236a1159e 100644 --- a/services/mailer/mailer.go +++ b/services/mailer/mailer.go @@ -67,6 +67,10 @@ func (m *Message) ToMessage() *gomail.Message { msg.SetBody("text/plain", plainBody) msg.AddAlternative("text/html", m.Body) } + + if len(msg.GetHeader("Message-ID")) == 0 { + msg.SetHeader("Message-ID", "") + } return msg } @@ -75,6 +79,11 @@ func (m *Message) SetHeader(field string, value ...string) { m.Headers[field] = value } +func (m *Message) generateMessageID() string { + now := time.Now().Unix() + return fmt.Sprintf("%d.%x@%s", now, len(m.To[0])^len(m.Subject)^len(m.Body), setting.Domain) +} + // NewMessageFrom creates new mail message object with custom From header. func NewMessageFrom(to []string, fromDisplayName, fromAddress, subject, body string) *Message { log.Trace("NewMessageFrom (body):\n%s", body) From 6581eb33a0b5b776260a89e7721a5038c153ae13 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Mon, 6 Dec 2021 11:41:54 +0800 Subject: [PATCH 2/3] Add unit tests for mailer & Message-ID --- modules/setting/setting.go | 16 +++++++++----- services/mailer/mailer.go | 15 +++++++++---- services/mailer/mailer_test.go | 39 ++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 9 deletions(-) create mode 100644 services/mailer/mailer_test.go diff --git a/modules/setting/setting.go b/modules/setting/setting.go index d219dbaafd79..b94856502213 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -548,17 +548,17 @@ func SetCustomPathAndConf(providedCustom, providedConf, providedWorkPath string) // LoadFromExisting initializes setting options from an existing config file (app.ini) func LoadFromExisting() { - loadFromConf(false) + loadFromConf(false, "") } // LoadAllowEmpty initializes setting options, it's also fine that if the config file (app.ini) doesn't exist func LoadAllowEmpty() { - loadFromConf(true) + loadFromConf(true, "") } // LoadForTest initializes setting options for tests -func LoadForTest() { - loadFromConf(true) +func LoadForTest(extraConfigs ...string) { + loadFromConf(true, strings.Join(extraConfigs, "\n")) if err := PrepareAppDataPath(); err != nil { log.Fatal("Can not prepare APP_DATA_PATH: %v", err) } @@ -566,7 +566,7 @@ func LoadForTest() { // loadFromConf initializes configuration context. // NOTE: do not print any log except error. -func loadFromConf(allowEmpty bool) { +func loadFromConf(allowEmpty bool, extraConfig string) { Cfg = ini.Empty() 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) } // 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 homeDir, err := com.HomeDir() diff --git a/services/mailer/mailer.go b/services/mailer/mailer.go index 2aa236a1159e..cbe545bdfcba 100644 --- a/services/mailer/mailer.go +++ b/services/mailer/mailer.go @@ -9,6 +9,7 @@ import ( "bytes" "crypto/tls" "fmt" + "hash/fnv" "io" "net" "net/smtp" @@ -69,7 +70,7 @@ func (m *Message) ToMessage() *gomail.Message { } if len(msg.GetHeader("Message-ID")) == 0 { - msg.SetHeader("Message-ID", "") + msg.SetHeader("Message-ID", "<"+m.generateAutoMessageID()+">") } return msg } @@ -79,9 +80,15 @@ func (m *Message) SetHeader(field string, value ...string) { m.Headers[field] = value } -func (m *Message) generateMessageID() string { - now := time.Now().Unix() - return fmt.Sprintf("%d.%x@%s", now, len(m.To[0])^len(m.Subject)^len(m.Body), setting.Domain) +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. diff --git a/services/mailer/mailer_test.go b/services/mailer/mailer_test.go new file mode 100644 index 000000000000..8505803d22a2 --- /dev/null +++ b/services/mailer/mailer_test.go @@ -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, "", 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, "", gm.GetHeader("Message-ID")[0]) + + m = NewMessageFrom([]string{"a@b.com"}, "display-name", "from-address", "subject", "body") + m.SetHeader("Message-ID", "") + gm = m.ToMessage() + assert.Equal(t, "", gm.GetHeader("Message-ID")[0]) +} From 2f35d9bf8e5056dc2395cb2db1465d0448cc0a03 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Mon, 6 Dec 2021 11:47:31 +0800 Subject: [PATCH 3/3] fix string --- services/mailer/mailer.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/services/mailer/mailer.go b/services/mailer/mailer.go index cbe545bdfcba..eac2b15c3c2c 100644 --- a/services/mailer/mailer.go +++ b/services/mailer/mailer.go @@ -70,7 +70,7 @@ func (m *Message) ToMessage() *gomail.Message { } if len(msg.GetHeader("Message-ID")) == 0 { - msg.SetHeader("Message-ID", "<"+m.generateAutoMessageID()+">") + msg.SetHeader("Message-ID", m.generateAutoMessageID()) } return msg } @@ -88,7 +88,7 @@ func (m *Message) generateAutoMessageID() string { } _, _ = h.Write([]byte(m.Subject)) _, _ = h.Write([]byte(m.Body)) - return fmt.Sprintf("autogen-%d-%016x@%s", dateMs, h.Sum64(), setting.Domain) + return fmt.Sprintf("", dateMs, h.Sum64(), setting.Domain) } // NewMessageFrom creates new mail message object with custom From header.