Skip to content

Commit b59875a

Browse files
Garionionwxiaoguanglunny
authored
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 <[email protected]> Co-authored-by: Lunny Xiao <[email protected]>
1 parent 0ff18a8 commit b59875a

File tree

3 files changed

+66
-5
lines changed

3 files changed

+66
-5
lines changed

modules/setting/setting.go

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -548,25 +548,25 @@ func SetCustomPathAndConf(providedCustom, providedConf, providedWorkPath string)
548548

549549
// LoadFromExisting initializes setting options from an existing config file (app.ini)
550550
func LoadFromExisting() {
551-
loadFromConf(false)
551+
loadFromConf(false, "")
552552
}
553553

554554
// LoadAllowEmpty initializes setting options, it's also fine that if the config file (app.ini) doesn't exist
555555
func LoadAllowEmpty() {
556-
loadFromConf(true)
556+
loadFromConf(true, "")
557557
}
558558

559559
// LoadForTest initializes setting options for tests
560-
func LoadForTest() {
561-
loadFromConf(true)
560+
func LoadForTest(extraConfigs ...string) {
561+
loadFromConf(true, strings.Join(extraConfigs, "\n"))
562562
if err := PrepareAppDataPath(); err != nil {
563563
log.Fatal("Can not prepare APP_DATA_PATH: %v", err)
564564
}
565565
}
566566

567567
// loadFromConf initializes configuration context.
568568
// NOTE: do not print any log except error.
569-
func loadFromConf(allowEmpty bool) {
569+
func loadFromConf(allowEmpty bool, extraConfig string) {
570570
Cfg = ini.Empty()
571571

572572
if WritePIDFile && len(PIDFile) > 0 {
@@ -585,6 +585,12 @@ func loadFromConf(allowEmpty bool) {
585585
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)
586586
} // else: no config file, a config file might be created at CustomConf later (might not)
587587

588+
if extraConfig != "" {
589+
if err = Cfg.Append([]byte(extraConfig)); err != nil {
590+
log.Fatal("Unable to append more config: %v", err)
591+
}
592+
}
593+
588594
Cfg.NameMapper = ini.SnackCase
589595

590596
homeDir, err := com.HomeDir()

services/mailer/mailer.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"bytes"
1010
"crypto/tls"
1111
"fmt"
12+
"hash/fnv"
1213
"io"
1314
"net"
1415
"net/smtp"
@@ -67,6 +68,10 @@ func (m *Message) ToMessage() *gomail.Message {
6768
msg.SetBody("text/plain", plainBody)
6869
msg.AddAlternative("text/html", m.Body)
6970
}
71+
72+
if len(msg.GetHeader("Message-ID")) == 0 {
73+
msg.SetHeader("Message-ID", m.generateAutoMessageID())
74+
}
7075
return msg
7176
}
7277

@@ -75,6 +80,17 @@ func (m *Message) SetHeader(field string, value ...string) {
7580
m.Headers[field] = value
7681
}
7782

83+
func (m *Message) generateAutoMessageID() string {
84+
dateMs := m.Date.UnixNano() / 1e6
85+
h := fnv.New64()
86+
if len(m.To) > 0 {
87+
_, _ = h.Write([]byte(m.To[0]))
88+
}
89+
_, _ = h.Write([]byte(m.Subject))
90+
_, _ = h.Write([]byte(m.Body))
91+
return fmt.Sprintf("<autogen-%d-%016x@%s>", dateMs, h.Sum64(), setting.Domain)
92+
}
93+
7894
// NewMessageFrom creates new mail message object with custom From header.
7995
func NewMessageFrom(to []string, fromDisplayName, fromAddress, subject, body string) *Message {
8096
log.Trace("NewMessageFrom (body):\n%s", body)

services/mailer/mailer_test.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// Copyright 2021 The Gogs Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package mailer
6+
7+
import (
8+
"testing"
9+
"time"
10+
11+
"code.gitea.io/gitea/modules/setting"
12+
13+
"github.com/stretchr/testify/assert"
14+
)
15+
16+
func TestGenerateMessageID(t *testing.T) {
17+
setting.LoadForTest(`
18+
[mailer]
19+
ENABLED = true
20+
21+
`)
22+
setting.NewServices()
23+
24+
date := time.Date(2000, 01, 02, 03, 04, 05, 06, time.UTC)
25+
m := NewMessageFrom(nil, "display-name", "from-address", "subject", "body")
26+
m.Date = date
27+
gm := m.ToMessage()
28+
assert.Equal(t, "<autogen-946782245000-41e8fc54a8ad3a3f@localhost>", gm.GetHeader("Message-ID")[0])
29+
30+
m = NewMessageFrom([]string{"[email protected]"}, "display-name", "from-address", "subject", "body")
31+
m.Date = date
32+
gm = m.ToMessage()
33+
assert.Equal(t, "<autogen-946782245000-cc88ce3cfe9bd04f@localhost>", gm.GetHeader("Message-ID")[0])
34+
35+
m = NewMessageFrom([]string{"[email protected]"}, "display-name", "from-address", "subject", "body")
36+
m.SetHeader("Message-ID", "<[email protected]>")
37+
gm = m.ToMessage()
38+
assert.Equal(t, "<[email protected]>", gm.GetHeader("Message-ID")[0])
39+
}

0 commit comments

Comments
 (0)