From 715efaa087c9b71fe6624acdfe962a04b405ea36 Mon Sep 17 00:00:00 2001 From: Jakub Date: Wed, 11 Jan 2023 10:19:38 +0100 Subject: [PATCH] Revert "GODT-2229: Allow changing cache folder to a non-empty folder." This reverts commit b19e16e4b869830aed34529ceb57347890ac80ea. --- go.mod | 2 +- go.sum | 4 +- internal/bridge/bridge.go | 6 -- internal/bridge/bridge_test.go | 21 ++++- internal/bridge/files.go | 74 ----------------- internal/bridge/imap.go | 9 +-- internal/bridge/settings.go | 98 +++++++---------------- internal/bridge/types.go | 1 - internal/frontend/cli/system.go | 2 +- internal/frontend/grpc/service_methods.go | 6 +- internal/locations/locations.go | 11 --- internal/vault/migrate_test.go | 2 +- internal/vault/settings.go | 4 +- internal/vault/settings_test.go | 4 +- internal/vault/vault_test.go | 2 +- 15 files changed, 61 insertions(+), 185 deletions(-) diff --git a/go.mod b/go.mod index 5c963d07e..58f60fcdc 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.20230109095028-c7d839d4f215 + github.com/ProtonMail/gluon v0.14.2-0.20230106095250-7e99ea4da61e github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a github.com/ProtonMail/go-proton-api v0.2.4-0.20230109143101-f8fd857ee5b4 github.com/ProtonMail/go-rfc5322 v0.11.0 diff --git a/go.sum b/go.sum index bb31abc6f..33e9fce72 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.20230109095028-c7d839d4f215 h1:bU2iPSNTobEokyNw95u5KG8v8nfz18Iab2cTm9k4pss= -github.com/ProtonMail/gluon v0.14.2-0.20230109095028-c7d839d4f215/go.mod h1:z2AxLIiBCT1K+0OBHyaDI7AEaO5qI6/BEC2TE42vs4Q= +github.com/ProtonMail/gluon v0.14.2-0.20230106095250-7e99ea4da61e h1://xRNjGTAMXw2U91MtqPc4krUtxQmt2+4z1oYrBaOWU= +github.com/ProtonMail/gluon v0.14.2-0.20230106095250-7e99ea4da61e/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/bridge/bridge.go b/internal/bridge/bridge.go index dd17febe9..6772d7277 100644 --- a/internal/bridge/bridge.go +++ b/internal/bridge/bridge.go @@ -221,14 +221,8 @@ func newBridge( return nil, fmt.Errorf("failed to get Gluon directory: %w", err) } - gluonDBDir, err := locator.ProvideGluonDatabasePath() - if err != nil { - return nil, fmt.Errorf("failed to get Gluon Database directory: %w", err) - } - imapServer, err := newIMAPServer( gluonDir, - gluonDBDir, curVersion, tlsConfig, reporter, diff --git a/internal/bridge/bridge_test.go b/internal/bridge/bridge_test.go index 6928d5a28..9aaa6f2d9 100644 --- a/internal/bridge/bridge_test.go +++ b/internal/bridge/bridge_test.go @@ -23,7 +23,7 @@ import ( "fmt" "net/http" "os" - "path/filepath" + "runtime" "sync" "testing" "time" @@ -361,7 +361,7 @@ func TestBridge_MissingGluonDir(t *testing.T) { require.NoError(t, bridge.SetGluonDir(ctx, t.TempDir())) // Get the gluon dir. - gluonDir = bridge.GetGluonCacheDir() + gluonDir = bridge.GetGluonDir() }) // The user removes the gluon dir while bridge is not running. @@ -456,11 +456,24 @@ func TestBridge_FactoryReset(t *testing.T) { }) } +func TestBridge_ChangeCacheDirectoryFailsBetweenDifferentVolumes(t *testing.T) { + if runtime.GOOS != "windows" { + t.Skip("Test only necessary on windows") + } + withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, vaultKey []byte) { + withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { + // Change directory + err := bridge.SetGluonDir(ctx, "XX:\\") + require.Error(t, err) + }) + }) +} + func TestBridge_ChangeCacheDirectory(t *testing.T) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, vaultKey []byte) { withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { newCacheDir := t.TempDir() - currentCacheDir := bridge.GetGluonCacheDir() + currentCacheDir := bridge.GetGluonDir() // Login the user. userID, err := bridge.LoginFull(ctx, username, password, nil, nil) @@ -477,7 +490,7 @@ func TestBridge_ChangeCacheDirectory(t *testing.T) { _, err = os.ReadDir(currentCacheDir) require.True(t, os.IsNotExist(err)) - require.Equal(t, filepath.Join(newCacheDir, "gluon"), bridge.GetGluonCacheDir()) + require.Equal(t, newCacheDir, bridge.GetGluonDir()) }) }) } diff --git a/internal/bridge/files.go b/internal/bridge/files.go index 475b19256..7301872c0 100644 --- a/internal/bridge/files.go +++ b/internal/bridge/files.go @@ -18,8 +18,6 @@ package bridge import ( - "fmt" - "io" "os" "path/filepath" ) @@ -64,75 +62,3 @@ func moveFile(from, to string) error { return nil } - -func copyDir(from, to string) error { - entries, err := os.ReadDir(from) - if err != nil { - return err - } - if err := createIfNotExists(to, 0o700); err != nil { - return err - } - for _, entry := range entries { - sourcePath := filepath.Join(from, entry.Name()) - destPath := filepath.Join(to, entry.Name()) - - if entry.IsDir() { - if err := copyDir(sourcePath, destPath); err != nil { - return err - } - } else { - if err := copyFile(sourcePath, destPath); err != nil { - return err - } - } - } - return nil -} - -func copyFile(srcFile, dstFile string) error { - out, err := os.Create(filepath.Clean(dstFile)) - defer func(out *os.File) { - _ = out.Close() - }(out) - - if err != nil { - return err - } - - in, err := os.Open(filepath.Clean(srcFile)) - defer func(in *os.File) { - _ = in.Close() - }(in) - - if err != nil { - return err - } - - _, err = io.Copy(out, in) - if err != nil { - return err - } - - return nil -} - -func exists(filePath string) bool { - if _, err := os.Stat(filePath); os.IsNotExist(err) { - return false - } - - return true -} - -func createIfNotExists(dir string, perm os.FileMode) error { - if exists(dir) { - return nil - } - - if err := os.MkdirAll(dir, perm); err != nil { - return fmt.Errorf("failed to create directory: '%s', error: '%s'", dir, err.Error()) - } - - return nil -} diff --git a/internal/bridge/imap.go b/internal/bridge/imap.go index 3848d6bc0..67a98b415 100644 --- a/internal/bridge/imap.go +++ b/internal/bridge/imap.go @@ -199,13 +199,13 @@ func (bridge *Bridge) handleIMAPEvent(event imapEvents.Event) { } func getGluonDir(encVault *vault.Vault) (string, error) { - empty, exists, err := isEmpty(encVault.GetGluonCacheDir()) + empty, exists, err := isEmpty(encVault.GetGluonDir()) if err != nil { return "", fmt.Errorf("failed to check if gluon dir is empty: %w", err) } if !exists { - if err := os.MkdirAll(encVault.GetGluonCacheDir(), 0o700); err != nil { + if err := os.MkdirAll(encVault.GetGluonDir(), 0o700); err != nil { return "", fmt.Errorf("failed to create gluon dir: %w", err) } } @@ -218,12 +218,12 @@ func getGluonDir(encVault *vault.Vault) (string, error) { } } - return encVault.GetGluonCacheDir(), nil + return encVault.GetGluonDir(), nil } // nolint:funlen func newIMAPServer( - gluonDir, gluonDBDir string, + gluonDir string, version *semver.Version, tlsConfig *tls.Config, reporter reporter.Reporter, @@ -264,7 +264,6 @@ func newIMAPServer( imapServer, err := gluon.New( gluon.WithTLS(tlsConfig), gluon.WithDataDir(gluonDir), - gluon.WithDatabaseDir(gluonDBDir), gluon.WithStoreBuilder(new(storeBuilder)), gluon.WithLogger(imapClientLog, imapServerLog), getGluonVersionInfo(version), diff --git a/internal/bridge/settings.go b/internal/bridge/settings.go index 7ebf93864..64efe88b7 100644 --- a/internal/bridge/settings.go +++ b/internal/bridge/settings.go @@ -21,7 +21,6 @@ import ( "context" "fmt" "net" - "os" "path/filepath" "github.com/Masterminds/semver/v3" @@ -115,48 +114,38 @@ func (bridge *Bridge) SetSMTPSSL(newSSL bool) error { return bridge.restartSMTP() } -func (bridge *Bridge) GetGluonCacheDir() string { - return bridge.vault.GetGluonCacheDir() -} - -func (bridge *Bridge) GetGluonConfigDir() (string, error) { - return bridge.locator.ProvideGluonDatabasePath() +func (bridge *Bridge) GetGluonDir() string { + return bridge.vault.GetGluonDir() } func (bridge *Bridge) SetGluonDir(ctx context.Context, newGluonDir string) error { return safe.RLockRet(func() error { - currentGluonDir := bridge.GetGluonCacheDir() - newGluonDir = filepath.Join(newGluonDir, "gluon") + currentGluonDir := bridge.GetGluonDir() if newGluonDir == currentGluonDir { return fmt.Errorf("new gluon dir is the same as the old one") } - if err := bridge.stopEventLoops(); err != nil { - return err + currentVolumeName := filepath.VolumeName(currentGluonDir) + newVolumeName := filepath.VolumeName(newGluonDir) + + if currentVolumeName != newVolumeName { + return fmt.Errorf("it's currently not possible to move the cache between different volumes") } - defer func() { - err := bridge.startEventLoops(ctx) - if err != nil { - panic(err) - } - }() - oldGluonDir := bridge.GetGluonCacheDir() - if err := bridge.moveGluonCacheDir(oldGluonDir, newGluonDir); err != nil { - logrus.WithError(err).Error("failed to move GluonCacheDir") - if err := bridge.vault.SetGluonDir(oldGluonDir); err != nil { - panic(err) - } + if err := bridge.closeIMAP(context.Background()); err != nil { + return fmt.Errorf("failed to close IMAP: %w", err) } - gluonDBDir, err := bridge.GetGluonConfigDir() - if err != nil { - panic(fmt.Errorf("failed to get Gluon Database directory: %w", err)) + if err := moveDir(bridge.GetGluonDir(), newGluonDir); err != nil { + return fmt.Errorf("failed to move gluon dir: %w", err) + } + + if err := bridge.vault.SetGluonDir(newGluonDir); err != nil { + return fmt.Errorf("failed to set new gluon dir: %w", err) } imapServer, err := newIMAPServer( - bridge.vault.GetGluonCacheDir(), - gluonDBDir, + bridge.vault.GetGluonDir(), bridge.curVersion, bridge.tlsConfig, bridge.reporter, @@ -166,56 +155,23 @@ func (bridge *Bridge) SetGluonDir(ctx context.Context, newGluonDir string) error bridge.tasks, ) if err != nil { - panic(fmt.Errorf("failed to create new IMAP server: %w", err)) + return fmt.Errorf("failed to create new IMAP server: %w", err) } bridge.imapServer = imapServer - return nil - }, bridge.usersLock) -} - -func (bridge *Bridge) moveGluonCacheDir(oldGluonDir, newGluonDir string) error { - if err := copyDir(oldGluonDir, newGluonDir); err != nil { - return fmt.Errorf("failed to copy gluon dir: %w", err) - } - - if err := bridge.vault.SetGluonDir(newGluonDir); err != nil { - return fmt.Errorf("failed to set new gluon dir: %w", err) - } - - if err := os.RemoveAll(oldGluonDir); err != nil { - logrus.WithError(err).Error("failed to remove old gluon dir") - } - return nil -} - -func (bridge *Bridge) stopEventLoops() error { - if err := bridge.closeIMAP(context.Background()); err != nil { - return fmt.Errorf("failed to close IMAP: %w", err) - } - - if err := bridge.closeSMTP(); err != nil { - return fmt.Errorf("failed to close SMTP: %w", err) - } - return nil -} - -func (bridge *Bridge) startEventLoops(ctx context.Context) error { - for _, user := range bridge.users { - if err := bridge.addIMAPUser(ctx, user); err != nil { - return fmt.Errorf("failed to add users to new IMAP server: %w", err) + for _, user := range bridge.users { + if err := bridge.addIMAPUser(ctx, user); err != nil { + return fmt.Errorf("failed to add users to new IMAP server: %w", err) + } } - } - if err := bridge.serveIMAP(); err != nil { - panic(fmt.Errorf("failed to serve IMAP: %w", err)) - } + if err := bridge.serveIMAP(); err != nil { + return fmt.Errorf("failed to serve IMAP: %w", err) + } - if err := bridge.serveSMTP(); err != nil { - panic(fmt.Errorf("failed to serve SMTP: %w", err)) - } - return nil + return nil + }, bridge.usersLock) } func (bridge *Bridge) GetProxyAllowed() bool { diff --git a/internal/bridge/types.go b/internal/bridge/types.go index 0e07be619..c42bae812 100644 --- a/internal/bridge/types.go +++ b/internal/bridge/types.go @@ -27,7 +27,6 @@ type Locator interface { ProvideSettingsPath() (string, error) ProvideLogsPath() (string, error) ProvideGluonPath() (string, error) - ProvideGluonDatabasePath() (string, error) GetLicenseFilePath() string GetDependencyLicensesLink() string Clear() error diff --git a/internal/frontend/cli/system.go b/internal/frontend/cli/system.go index c92df83f1..262be1200 100644 --- a/internal/frontend/cli/system.go +++ b/internal/frontend/cli/system.go @@ -196,7 +196,7 @@ func (f *frontendCLI) showAllMail(c *ishell.Context) { } func (f *frontendCLI) setGluonLocation(c *ishell.Context) { - if gluonDir := f.bridge.GetGluonCacheDir(); gluonDir != "" { + if gluonDir := f.bridge.GetGluonDir(); gluonDir != "" { f.Println("The current message cache location is:", gluonDir) } diff --git a/internal/frontend/grpc/service_methods.go b/internal/frontend/grpc/service_methods.go index 9e8556a12..0eabbe450 100644 --- a/internal/frontend/grpc/service_methods.go +++ b/internal/frontend/grpc/service_methods.go @@ -591,7 +591,7 @@ func (s *Service) IsAutomaticUpdateOn(ctx context.Context, _ *emptypb.Empty) (*w func (s *Service) DiskCachePath(ctx context.Context, _ *emptypb.Empty) (*wrapperspb.StringValue, error) { s.log.Debug("DiskCachePath") - return wrapperspb.String(s.bridge.GetGluonCacheDir()), nil + return wrapperspb.String(s.bridge.GetGluonDir()), nil } func (s *Service) SetDiskCachePath(ctx context.Context, newPath *wrapperspb.StringValue) (*emptypb.Empty, error) { @@ -609,14 +609,14 @@ func (s *Service) SetDiskCachePath(ctx context.Context, newPath *wrapperspb.Stri path = path[1:] } - if path != s.bridge.GetGluonCacheDir() { + if path != s.bridge.GetGluonDir() { if err := s.bridge.SetGluonDir(context.Background(), path); err != nil { s.log.WithError(err).Error("The local cache location could not be changed.") _ = s.SendEvent(NewDiskCacheErrorEvent(DiskCacheErrorType_CANT_MOVE_DISK_CACHE_ERROR)) return } - _ = s.SendEvent(NewDiskCachePathChangedEvent(s.bridge.GetGluonCacheDir())) + _ = s.SendEvent(NewDiskCachePathChangedEvent(s.bridge.GetGluonDir())) } }() diff --git a/internal/locations/locations.go b/internal/locations/locations.go index cb87d4564..44c096278 100644 --- a/internal/locations/locations.go +++ b/internal/locations/locations.go @@ -148,17 +148,6 @@ func (l *Locations) ProvideGluonPath() (string, error) { return l.getGluonPath(), nil } -// ProvideGluonDatabasePath returns a location for gluon database. -// It creates it if it doesn't already exist. -func (l *Locations) ProvideGluonDatabasePath() (string, error) { - dbPath := filepath.Join(l.userData, "gluonDB") - if err := os.MkdirAll(dbPath, 0o700); err != nil { - return "", err - } - - return dbPath, nil -} - // ProvideLogsPath returns a location for user logs (e.g. ~/.local/share///logs). // It creates it if it doesn't already exist. func (l *Locations) ProvideLogsPath() (string, error) { diff --git a/internal/vault/migrate_test.go b/internal/vault/migrate_test.go index 32af3a194..a92bb57e3 100644 --- a/internal/vault/migrate_test.go +++ b/internal/vault/migrate_test.go @@ -57,7 +57,7 @@ func TestMigrate(t *testing.T) { require.False(t, corrupt) // Check the migrated vault. - require.Equal(t, "v2.3.x-gluon-dir", s.GetGluonCacheDir()) + require.Equal(t, "v2.3.x-gluon-dir", s.GetGluonDir()) require.Equal(t, 1234, s.GetIMAPPort()) require.Equal(t, 5678, s.GetSMTPPort()) diff --git a/internal/vault/settings.go b/internal/vault/settings.go index 434cabb58..1b2752b9e 100644 --- a/internal/vault/settings.go +++ b/internal/vault/settings.go @@ -70,8 +70,8 @@ func (vault *Vault) SetSMTPSSL(ssl bool) error { }) } -// GetGluonCacheDir sets the directory where the gluon should store its data. -func (vault *Vault) GetGluonCacheDir() string { +// GetGluonDir sets the directory where the gluon should store its data. +func (vault *Vault) GetGluonDir() string { return vault.get().Settings.GluonDir } diff --git a/internal/vault/settings_test.go b/internal/vault/settings_test.go index 8e5cec9bf..f75b64d8b 100644 --- a/internal/vault/settings_test.go +++ b/internal/vault/settings_test.go @@ -67,13 +67,13 @@ func TestVault_Settings_GluonDir(t *testing.T) { require.False(t, corrupt) // Check the default gluon dir. - require.Equal(t, "/path/to/gluon", s.GetGluonCacheDir()) + require.Equal(t, "/path/to/gluon", s.GetGluonDir()) // Modify the gluon dir. require.NoError(t, s.SetGluonDir("/tmp/gluon")) // Check the new gluon dir. - require.Equal(t, "/tmp/gluon", s.GetGluonCacheDir()) + require.Equal(t, "/tmp/gluon", s.GetGluonDir()) } func TestVault_Settings_UpdateChannel(t *testing.T) { diff --git a/internal/vault/vault_test.go b/internal/vault/vault_test.go index 07b2b3294..bf478f696 100644 --- a/internal/vault/vault_test.go +++ b/internal/vault/vault_test.go @@ -89,7 +89,7 @@ func TestVault_Reset(t *testing.T) { require.Equal(t, 5678, s.GetSMTPPort()) // Reset. - require.NoError(t, s.Reset(s.GetGluonCacheDir())) + require.NoError(t, s.Reset(s.GetGluonDir())) // The data is gone. require.Equal(t, 1143, s.GetIMAPPort())