Other: Wipe vault properly on factory reset

Deleting the file isn't enough because it's still held in memory
and is written back to disk on the next write (SetLastVersion during
bridge teardown).
This commit is contained in:
James Houlahan
2022-11-29 09:59:30 +01:00
parent f176174fca
commit 9f64e8a6fa
5 changed files with 53 additions and 7 deletions

View File

@ -423,15 +423,27 @@ func TestBridge_AddressWithoutKeys(t *testing.T) {
func TestBridge_FactoryReset(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) {
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, _ *bridge.Mocks) {
// The settings should be their default values.
require.True(t, bridge.GetAutoUpdate())
require.Equal(t, updater.StableChannel, bridge.GetUpdateChannel())
// Login the user.
userID, err := bridge.LoginFull(ctx, username, password, nil, nil)
require.NoError(t, err)
// Change some settings.
require.NoError(t, bridge.SetAutoUpdate(false))
require.NoError(t, bridge.SetUpdateChannel(updater.EarlyChannel))
// The user is now connected.
require.Equal(t, []string{userID}, bridge.GetUserIDs())
require.Equal(t, []string{userID}, getConnectedUserIDs(t, bridge))
// The settings should be changed.
require.False(t, bridge.GetAutoUpdate())
require.Equal(t, updater.EarlyChannel, bridge.GetUpdateChannel())
// Perform a factory reset.
bridge.FactoryReset(ctx)
@ -439,6 +451,12 @@ func TestBridge_FactoryReset(t *testing.T) {
require.Equal(t, []string{}, bridge.GetUserIDs())
require.Equal(t, []string{}, getConnectedUserIDs(t, bridge))
})
withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, _ *bridge.Mocks) {
// The settings should be reset.
require.True(t, bridge.GetAutoUpdate())
require.Equal(t, updater.StableChannel, bridge.GetUpdateChannel())
})
})
}

View File

@ -287,14 +287,16 @@ func (bridge *Bridge) FactoryReset(ctx context.Context) {
for _, user := range bridge.users {
bridge.logoutUser(ctx, user, true, true)
}
for _, user := range bridge.vault.GetUserIDs() {
if err := bridge.vault.DeleteUser(user); err != nil {
logrus.WithError(err).Error("failed to delete vault user")
}
}
}, bridge.usersLock)
// Wipe the vault.
gluonDir, err := bridge.locator.ProvideGluonPath()
if err != nil {
logrus.WithError(err).Error("Failed to provide gluon dir")
} else if err := bridge.vault.Reset(gluonDir); err != nil {
logrus.WithError(err).Error("Failed to reset vault")
}
// Then delete all files.
if err := bridge.locator.Clear(); err != nil {
logrus.WithError(err).Error("Failed to clear data paths")

View File

@ -26,6 +26,7 @@ import (
type Locator interface {
ProvideSettingsPath() (string, error)
ProvideLogsPath() (string, error)
ProvideGluonPath() (string, error)
GetLicenseFilePath() string
GetDependencyLicensesLink() string
Clear() error

View File

@ -185,6 +185,12 @@ func (vault *Vault) SetMigrated() error {
})
}
func (vault *Vault) Reset(gluonDir string) error {
return vault.mod(func(data *Data) {
*data = newDefaultData(gluonDir)
})
}
func (vault *Vault) Close() error {
vault.refLock.Lock()
defer vault.refLock.Unlock()

View File

@ -77,6 +77,25 @@ func TestVault_Corrupt_JunkData(t *testing.T) {
}
}
func TestVault_Reset(t *testing.T) {
s := newVault(t)
// Write some data.
require.NoError(t, s.SetIMAPPort(1234))
require.NoError(t, s.SetSMTPPort(5678))
// The data was written.
require.Equal(t, 1234, s.GetIMAPPort())
require.Equal(t, 5678, s.GetSMTPPort())
// Reset.
require.NoError(t, s.Reset(s.GetGluonDir()))
// The data is gone.
require.Equal(t, 1143, s.GetIMAPPort())
require.Equal(t, 1025, s.GetSMTPPort())
}
func newVault(t *testing.T) *vault.Vault {
t.Helper()