From 932928ddc897cba9e3e0c9bdf681569b969feaf1 Mon Sep 17 00:00:00 2001 From: Michal Horejsek Date: Mon, 5 Oct 2020 15:28:11 +0200 Subject: [PATCH] Allow to send calendar update multiple times --- Changelog.md | 2 ++ internal/smtp/send_recorder.go | 14 ++++++++++++++ internal/smtp/send_recorder_test.go | 29 ++++++++++++++++++++++++++++- 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 4dee7824..6e8d1ce9 100644 --- a/Changelog.md +++ b/Changelog.md @@ -11,6 +11,8 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) * Bump crypto version to v0.0.0-20200818122824-ed5d25e28db8 * GODT-785 Clear separation of different message IDs in integration tests. +* Bump crypto version to v0.0.0-20200818122824-ed5d25e28db8. +* GODT-374 Allow to send calendar update multiple times. ## [IE 1.1.1] Danube (beta 2020-09-xx) [Bridge 1.4.1] Forth (beta 2020-09-xx) diff --git a/internal/smtp/send_recorder.go b/internal/smtp/send_recorder.go index 20abfdcc..61855b98 100644 --- a/internal/smtp/send_recorder.go +++ b/internal/smtp/send_recorder.go @@ -20,6 +20,7 @@ package smtp import ( "crypto/sha256" "fmt" + "strings" "sync" "time" @@ -48,6 +49,15 @@ func newSendRecorder() *sendRecorder { } func (q *sendRecorder) getMessageHash(message *pmapi.Message) string { + // Outlook Calendar updates has only headers (no body) and thus have always + // the same hash. If the message is type of calendar, the "is sending" + // check to avoid potential duplicates is skipped. Duplicates should not + // be a problem in this case as calendar updates are small. + contentType := message.Header.Get("Content-Type") + if strings.HasPrefix(contentType, "text/calendar") { + return "" + } + h := sha256.New() _, _ = h.Write([]byte(message.AddressID + message.Subject)) if message.Sender != nil { @@ -101,6 +111,10 @@ func (q *sendRecorder) isSendingOrSent(client messageGetter, hash string) (isSen q.lock.Lock() defer q.lock.Unlock() + if hash == "" { + return false, false + } + q.deleteExpiredKeys() value, ok := q.hashes[hash] if !ok { diff --git a/internal/smtp/send_recorder_test.go b/internal/smtp/send_recorder_test.go index 1c4f272b..06f07701 100644 --- a/internal/smtp/send_recorder_test.go +++ b/internal/smtp/send_recorder_test.go @@ -349,6 +349,32 @@ func TestSendRecorder_getMessageHash(t *testing.T) { }, false, }, + { // Different content type - calendar + &pmapi.Message{ + Header: mail.Header{ + "Content-Type": []string{"text/calendar"}, + }, + AddressID: "address123", + Subject: "Subject #1", + Sender: &mail.Address{ + Address: "from@pm.me", + }, + ToList: []*mail.Address{ + {Address: "to@pm.me"}, + }, + CCList: []*mail.Address{}, + BCCList: []*mail.Address{}, + Body: "body", + Attachments: []*pmapi.Attachment{ + { + Name: "att1", + MIMEType: "image/png", + Size: 12345, + }, + }, + }, + false, + }, } for i, tc := range testCases { tc := tc // bind @@ -382,12 +408,13 @@ func TestSendRecorder_isSendingOrSent(t *testing.T) { {"hash", &pmapi.Message{Type: pmapi.MessageTypeDraft, Time: time.Now().Unix()}, nil, true, false}, {"hash", &pmapi.Message{Type: pmapi.MessageTypeSent}, nil, false, true}, {"hash", &pmapi.Message{Type: pmapi.MessageTypeInboxAndSent}, nil, false, true}, + {"", &pmapi.Message{Type: pmapi.MessageTypeInboxAndSent}, nil, false, false}, } for i, tc := range testCases { tc := tc // bind t.Run(fmt.Sprintf("%d / %v / %v / %v", i, tc.hash, tc.message, tc.err), func(t *testing.T) { messageGetter := &testSendRecorderGetMessageMock{message: tc.message, err: tc.err} - isSending, wasSent := q.isSendingOrSent(messageGetter, "hash") + isSending, wasSent := q.isSendingOrSent(messageGetter, tc.hash) assert.Equal(t, tc.wantIsSending, isSending, "isSending does not match") assert.Equal(t, tc.wantWasSent, wasSent, "wasSent does not match") })