From e3826871682a15b5c543c0063ef1a06e09871920 Mon Sep 17 00:00:00 2001 From: James Houlahan Date: Tue, 31 Jan 2023 11:04:19 +0100 Subject: [PATCH] fix(GODT-2318): Remove gluon DB if label sync was incomplete --- internal/bridge/imap.go | 24 +++++++++++++++++++++++- internal/user/user.go | 5 +++++ internal/vault/user.go | 5 +++++ 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/internal/bridge/imap.go b/internal/bridge/imap.go index b9fd540f..e8deded8 100644 --- a/internal/bridge/imap.go +++ b/internal/bridge/imap.go @@ -100,6 +100,8 @@ func (bridge *Bridge) closeIMAP(ctx context.Context) error { } // addIMAPUser connects the given user to gluon. +// +//nolint:funlen func (bridge *Bridge) addIMAPUser(ctx context.Context, user *user.User) error { if bridge.imapServer == nil { return fmt.Errorf("no imap server instance running") @@ -125,13 +127,33 @@ func (bridge *Bridge) addIMAPUser(ctx context.Context, user *user.User) error { return fmt.Errorf("failed to load IMAP user: %w", err) } - // If the DB was newly created, clear the sync status; gluon's DB was not found. if isNew { + // If the DB was newly created, clear the sync status; gluon's DB was not found. logrus.Warn("IMAP user DB was newly created, clearing sync status") if err := user.ClearSyncStatus(); err != nil { return fmt.Errorf("failed to clear sync status: %w", err) } + } else if status := user.GetSyncStatus(); !status.HasLabels { + // Otherwise, the DB already exists -- if the labels are not yet synced, we need to re-create the DB. + if err := bridge.imapServer.RemoveUser(ctx, gluonID, true); err != nil { + return fmt.Errorf("failed to remove old IMAP user: %w", err) + } + + if err := user.RemoveGluonID(addrID, gluonID); err != nil { + return fmt.Errorf("failed to remove old IMAP user ID: %w", err) + } + + gluonID, err := bridge.imapServer.AddUser(ctx, imapConn, user.GluonKey()) + if err != nil { + return fmt.Errorf("failed to add IMAP user: %w", err) + } + + if err := user.SetGluonID(addrID, gluonID); err != nil { + return fmt.Errorf("failed to set IMAP user ID: %w", err) + } + + log.WithField("gluonID", gluonID).Info("Re-created IMAP user") } } else { log.Info("Creating new IMAP user") diff --git a/internal/user/user.go b/internal/user/user.go index f1c4b9fd..abdbadb3 100644 --- a/internal/user/user.go +++ b/internal/user/user.go @@ -477,6 +477,11 @@ func (user *User) OnStatusDown(context.Context) { user.abortable.Abort() } +// GetSyncStatus returns the sync status of the user. +func (user *User) GetSyncStatus() vault.SyncStatus { + return user.vault.GetSyncStatus() +} + // ClearSyncStatus clears the sync status of the user. This triggers a resync. func (user *User) ClearSyncStatus() error { user.abortable.Abort() diff --git a/internal/vault/user.go b/internal/vault/user.go index f80011bb..1f3bf8b6 100644 --- a/internal/vault/user.go +++ b/internal/vault/user.go @@ -197,6 +197,11 @@ func (user *User) RemFailedMessageID(messageID string) error { }) } +// GetSyncStatus returns the user's sync status. +func (user *User) GetSyncStatus() SyncStatus { + return user.vault.getUser(user.userID).SyncStatus +} + // ClearSyncStatus clears the user's sync status. func (user *User) ClearSyncStatus() error { return user.vault.modUser(user.userID, func(data *UserData) {