Skip to content

Commit

Permalink
Revert "GODT-2229: Allow changing cache folder to a non-empty folder."
Browse files Browse the repository at this point in the history
This reverts commit b19e16e.
  • Loading branch information
cuthix committed Jan 11, 2023
1 parent 606a8f1 commit 715efaa
Show file tree
Hide file tree
Showing 15 changed files with 61 additions and 185 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -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=
Expand Down
6 changes: 0 additions & 6 deletions internal/bridge/bridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
21 changes: 17 additions & 4 deletions internal/bridge/bridge_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import (
"fmt"
"net/http"
"os"
"path/filepath"
"runtime"
"sync"
"testing"
"time"
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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)
Expand All @@ -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())
})
})
}
Expand Down
74 changes: 0 additions & 74 deletions internal/bridge/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@
package bridge

import (
"fmt"
"io"
"os"
"path/filepath"
)
Expand Down Expand Up @@ -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
}
9 changes: 4 additions & 5 deletions internal/bridge/imap.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}
Expand All @@ -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,
Expand Down Expand Up @@ -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),
Expand Down
98 changes: 27 additions & 71 deletions internal/bridge/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"context"
"fmt"
"net"
"os"
"path/filepath"

"github.com/Masterminds/semver/v3"
Expand Down Expand Up @@ -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,
Expand All @@ -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 {
Expand Down
1 change: 0 additions & 1 deletion internal/bridge/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion internal/frontend/cli/system.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

Expand Down
6 changes: 3 additions & 3 deletions internal/frontend/grpc/service_methods.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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()))
}
}()

Expand Down

0 comments on commit 715efaa

Please sign in to comment.