From 0e9428aaaef7f2d4895f27fe9cf67c440f59c201 Mon Sep 17 00:00:00 2001 From: Leander Beernaert Date: Tue, 17 Jan 2023 13:38:06 +0100 Subject: [PATCH] GODT-2252: Recover from deleted cached messages Update to latest Gluon version and implement the new `Connector.GetMessageLiteral` function. --- go.mod | 2 +- go.sum | 4 ++-- internal/user/imap.go | 23 +++++++++++++++++++++++ tests/bdd_test.go | 1 + tests/bridge_test.go | 10 ++++++++++ tests/features/imap/message/fetch.feature | 9 ++++++++- 6 files changed, 45 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 5166e91d..ed409fed 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.18 require ( github.com/0xAX/notificator v0.0.0-20220220101646-ee9b8921e557 github.com/Masterminds/semver/v3 v3.1.1 - github.com/ProtonMail/gluon v0.14.2-0.20230113145313-7dc070e73340 + github.com/ProtonMail/gluon v0.14.2-0.20230117124414-549c1f016d6e github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a github.com/ProtonMail/go-proton-api v0.2.4-0.20230112102613-6ad201cdb337 github.com/ProtonMail/go-rfc5322 v0.11.0 diff --git a/go.sum b/go.sum index 82a0fd20..38f8846c 100644 --- a/go.sum +++ b/go.sum @@ -28,8 +28,8 @@ github.com/ProtonMail/bcrypt v0.0.0-20211005172633-e235017c1baf h1:yc9daCCYUefEs github.com/ProtonMail/bcrypt v0.0.0-20211005172633-e235017c1baf/go.mod h1:o0ESU9p83twszAU8LBeJKFAAMX14tISa0yk4Oo5TOqo= github.com/ProtonMail/docker-credential-helpers v1.1.0 h1:+kvUIpwWcbtP3WFv5sSvkFn/XLzSqPOB5AAthuk9xPk= github.com/ProtonMail/docker-credential-helpers v1.1.0/go.mod h1:mK0aBveCxhnQ756AmaTfXMZDeULvheYVhF/MWMErN5g= -github.com/ProtonMail/gluon v0.14.2-0.20230113145313-7dc070e73340 h1:NrE0XbpppwSPRDbhK0LMoyIkE/+89Nj83MF9jg/f0X8= -github.com/ProtonMail/gluon v0.14.2-0.20230113145313-7dc070e73340/go.mod h1:z2AxLIiBCT1K+0OBHyaDI7AEaO5qI6/BEC2TE42vs4Q= +github.com/ProtonMail/gluon v0.14.2-0.20230117124414-549c1f016d6e h1:OAbPvjrynaGbxQdRPSprV2tK73AlNOM9vzFSnyG4iBk= +github.com/ProtonMail/gluon v0.14.2-0.20230117124414-549c1f016d6e/go.mod h1:z2AxLIiBCT1K+0OBHyaDI7AEaO5qI6/BEC2TE42vs4Q= github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a h1:D+aZah+k14Gn6kmL7eKxoo/4Dr/lK3ChBcwce2+SQP4= github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a/go.mod h1:oTGdE7/DlWIr23G0IKW3OXK9wZ5Hw1GGiaJFccTvZi4= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= diff --git a/internal/user/imap.go b/internal/user/imap.go index 29261d94..cd0b3ff7 100644 --- a/internal/user/imap.go +++ b/internal/user/imap.go @@ -321,6 +321,29 @@ func (conn *imapConnector) CreateMessage( return conn.importMessage(ctx, literal, wantLabelIDs, wantFlags, unread) } +func (conn *imapConnector) GetMessageLiteral(ctx context.Context, id imap.MessageID) ([]byte, error) { + msg, err := conn.client.GetFullMessage(ctx, string(id)) + if err != nil { + return nil, err + } + + return safe.RLockRetErr(func() ([]byte, error) { + var literal []byte + err := withAddrKR(conn.apiUser, conn.apiAddrs[msg.AddressID], conn.vault.KeyPass(), func(_, addrKR *crypto.KeyRing) error { + l, buildErr := message.BuildRFC822(addrKR, msg.Message, msg.AttData, defaultJobOpts()) + if buildErr != nil { + return buildErr + } + + literal = l + + return nil + }) + + return literal, err + }, conn.apiUserLock, conn.apiAddrsLock) +} + // AddMessagesToMailbox labels the given messages with the given label ID. func (conn *imapConnector) AddMessagesToMailbox(ctx context.Context, messageIDs []imap.MessageID, mailboxID imap.MailboxID) error { defer conn.goPollAPIEvents(false) diff --git a/tests/bdd_test.go b/tests/bdd_test.go index 302d9f44..2fcb1e5d 100644 --- a/tests/bdd_test.go +++ b/tests/bdd_test.go @@ -137,6 +137,7 @@ func TestFeatures(testingT *testing.T) { ctx.Step(`^the user sets the address mode of user "([^"]*)" to "([^"]*)"$`, s.theUserSetsTheAddressModeOfUserTo) ctx.Step(`^the user changes the gluon path$`, s.theUserChangesTheGluonPath) ctx.Step(`^the user deletes the gluon files$`, s.theUserDeletesTheGluonFiles) + ctx.Step(`^the user deletes the gluon cache$`, s.theUserDeletesTheGluonCache) ctx.Step(`^the user reports a bug$`, s.theUserReportsABug) ctx.Step(`^the user hides All Mail$`, s.theUserHidesAllMail) ctx.Step(`^the user shows All Mail$`, s.theUserShowsAllMail) diff --git a/tests/bridge_test.go b/tests/bridge_test.go index da3df3c8..dda24012 100644 --- a/tests/bridge_test.go +++ b/tests/bridge_test.go @@ -103,6 +103,16 @@ func (s *scenario) theUserDeletesTheGluonFiles() error { return nil } +func (s *scenario) theUserDeletesTheGluonCache() error { + if path, err := s.t.locator.ProvideGluonCachePath(); err != nil { + return fmt.Errorf("failed to get gluon cache path: %w", err) + } else if err := os.RemoveAll(path); err != nil { + return fmt.Errorf("failed to remove gluon cache path: %w", err) + } + + return nil +} + func (s *scenario) theUserHasDisabledAutomaticUpdates() error { var started bool diff --git a/tests/features/imap/message/fetch.feature b/tests/features/imap/message/fetch.feature index ffe19813..7c4d6fcc 100644 --- a/tests/features/imap/message/fetch.feature +++ b/tests/features/imap/message/fetch.feature @@ -16,4 +16,11 @@ Feature: IMAP Fetch Given IMAP client "1" sees the following messages in "INBOX": | from | to | subject | date | | john.doe@mail.com | [user:user]@[domain] | foo | 13 Aug 82 00:00 +0000 | - Then IMAP client "1" sees header "X-Original-Date: Sun, 13 Jul 1969 00:00:00 +0000" in message with subject "foo" in "INBOX" \ No newline at end of file + Then IMAP client "1" sees header "X-Original-Date: Sun, 13 Jul 1969 00:00:00 +0000" in message with subject "foo" in "INBOX" + + + Scenario: Fetch from deleted cache + When the user deletes the gluon cache + Then IMAP client "1" sees the following messages in "INBOX": + | from | to | subject | date | + | john.doe@mail.com | [user:user]@[domain] | foo | 13 Aug 82 00:00 +0000 |