GODT-1051: Add factory reset to bridge object

- remove deleted test no_internet.feature
- clean up old remnants of import export
- FactoryReset docstring
This commit is contained in:
James Houlahan 2021-06-21 10:48:09 +02:00 committed by Jakub
parent 2b1daa60bb
commit f5624c9932
9 changed files with 73 additions and 57 deletions

View File

@ -156,7 +156,7 @@ func (b *Bridge) SetUpdateChannel(channel updater.UpdateChannel) (needRestart bo
// We have to deal right away only with downgrade - that action needs to
// clear data and updates, and install bridge right away. But regular
// upgrade can be leaved out for periodic check.
// upgrade can be left out for periodic check.
if !b.updater.IsDowngrade(version) {
return false, nil
}
@ -164,6 +164,7 @@ func (b *Bridge) SetUpdateChannel(channel updater.UpdateChannel) (needRestart bo
if err := b.Users.ClearData(); err != nil {
log.WithError(err).Error("Failed to clear data while downgrading channel")
}
if err := b.locations.ClearUpdates(); err != nil {
log.WithError(err).Error("Failed to clear updates while downgrading channel")
}
@ -175,6 +176,23 @@ func (b *Bridge) SetUpdateChannel(channel updater.UpdateChannel) (needRestart bo
return true, b.versioner.RemoveOtherVersions(version.Version)
}
// FactoryReset will remove all local cache and settings.
// We want to downgrade to latest stable version if user is early higher than stable.
// Setting the channel back to stable will do this for us.
func (b *Bridge) FactoryReset() {
if _, err := b.SetUpdateChannel(updater.StableChannel); err != nil {
log.WithError(err).Error("Failed to revert to stable update channel")
}
if err := b.Users.ClearUsers(); err != nil {
log.WithError(err).Error("Failed to remove bridge users")
}
if err := b.Users.ClearData(); err != nil {
log.WithError(err).Error("Failed to remove bridge data")
}
}
// GetKeychainApp returns current keychain helper.
func (b *Bridge) GetKeychainApp() string {
return b.settings.Get(settings.PreferredKeychainKey)

View File

@ -192,14 +192,34 @@ func (f *frontendCLI) deleteAccounts(c *ishell.Context) {
if !f.yesNoQuestion("Do you really want remove all accounts") {
return
}
for _, user := range f.bridge.GetUsers() {
if err := f.bridge.DeleteUser(user.ID(), false); err != nil {
f.printAndLogError("Cannot delete account ", user.Username(), ": ", err)
}
}
c.Println("Keychain cleared")
}
func (f *frontendCLI) deleteEverything(c *ishell.Context) {
f.ShowPrompt(false)
defer f.ShowPrompt(true)
if !f.yesNoQuestion("Do you really want remove everything") {
return
}
f.bridge.FactoryReset()
c.Println("Everything cleared")
// Clearing data removes everything (db, preferences, ...) so everything has to be stopped and started again.
f.restarter.SetToRestart()
f.Stop()
}
func (f *frontendCLI) changeMode(c *ishell.Context) {
user := f.askUserByIndexOrName(c)
if user == nil {

View File

@ -84,6 +84,11 @@ func New( //nolint[funlen]
Aliases: []string{"a", "k", "keychain"},
Func: fe.deleteAccounts,
})
clearCmd.AddCmd(&ishell.Cmd{Name: "everything",
Help: "remove everything",
Aliases: []string{"a", "k", "keychain"},
Func: fe.deleteEverything,
})
fe.AddCmd(clearCmd)
// Change commands.

View File

@ -58,14 +58,17 @@ func (f *frontendCLI) deleteCache(c *ishell.Context) {
if !f.yesNoQuestion("Do you really want to remove all stored preferences") {
return
}
if err := f.bridge.ClearData(); err != nil {
f.printAndLogError("Cache clear failed: ", err.Error())
return
}
f.Println("Cached cleared, restarting bridge")
// Clearing data removes everything (db, preferences, ...)
// so everything has to be stopped and started again.
// Clearing data removes everything (db, preferences, ...) so everything has to be stopped and started again.
f.restarter.SetToRestart()
f.Stop()
}

View File

@ -53,6 +53,8 @@ type UserManager interface {
GetUser(query string) (User, error)
DeleteUser(userID string, clearCache bool) error
ClearData() error
ClearUsers() error
FactoryReset()
}
// User is an interface of user needed by frontend.

View File

@ -73,28 +73,20 @@ func (l *Locations) getLicenseFilePath() string {
switch runtime.GOOS {
case "linux":
appName := l.configName
if l.configName == "importExport" {
appName = "import-export"
}
// Most Linux distributions.
path := "/usr/share/doc/protonmail/" + appName + "/LICENSE"
path := "/usr/share/doc/protonmail/" + l.configName + "/LICENSE"
if _, err := os.Stat(path); err == nil {
return path
}
// Arch distributions.
return "/usr/share/licenses/protonmail-" + appName + "/LICENSE"
return "/usr/share/licenses/protonmail-" + l.configName + "/LICENSE"
case "darwin": //nolint[goconst]
path := filepath.Join(filepath.Dir(os.Args[0]), "..", "Resources", "LICENSE")
if _, err := os.Stat(path); err == nil {
return path
}
appName := "ProtonMail Bridge.app"
if l.configName == "importExport" {
appName = "ProtonMail Import-Export.app"
}
return "/Applications/" + appName + "/Contents/Resources/LICENSE"
return "/Applications/ProtonMail Bridge.app/Contents/Resources/LICENSE"
case "windows":
path := filepath.Join(filepath.Dir(os.Args[0]), "LICENSE.txt")
if _, err := os.Stat(path); err == nil {
@ -205,10 +197,10 @@ func (l *Locations) getUpdatesPath() string {
// Clear removes everything except the lock and update files.
func (l *Locations) Clear() error {
return files.Remove(
l.getSettingsPath(),
l.getLogsPath(),
l.getCachePath(),
l.userConfig,
l.userCache,
).Except(
l.GetLockFile(),
l.getUpdatesPath(),
).Do()
}

View File

@ -331,6 +331,7 @@ func (u *Users) ClearData() error {
if err := user.Logout(); err != nil {
result = multierror.Append(result, err)
}
if err := user.closeStore(); err != nil {
result = multierror.Append(result, err)
}
@ -340,8 +341,7 @@ func (u *Users) ClearData() error {
result = multierror.Append(result, err)
}
// Need to clear imap cache otherwise fetch response will be remembered
// from previous test
// Need to clear imap cache otherwise fetch response will be remembered from previous test.
imapcache.Clear()
return result
@ -385,6 +385,19 @@ func (u *Users) DeleteUser(userID string, clearStore bool) error {
return errors.New("user " + userID + " not found")
}
// ClearUsers deletes all users.
func (u *Users) ClearUsers() error {
var result error
for _, user := range u.GetUsers() {
if err := u.DeleteUser(user.ID(), false); err != nil {
result = multierror.Append(result, err)
}
}
return result
}
// SendMetric sends a metric. We don't want to return any errors, only log them.
func (u *Users) SendMetric(m metrics.Metric) error {
cat, act, lab := m.Get()

View File

@ -1,30 +0,0 @@
Feature: Servers are closed when no internet
Scenario: All connection are closed and then restored multiple times
Given there is connected user "user"
And there is IMAP client "i1" logged in as "user"
And there is SMTP client "s1" logged in as "user"
When there is no internet connection
And 1 second pass
Then IMAP client "i1" is logged out
And SMTP client "s1" is logged out
Given the internet connection is restored
And 1 second pass
And there is IMAP client "i2" logged in as "user"
And there is SMTP client "s2" logged in as "user"
When IMAP client "i2" gets info of "INBOX"
When SMTP client "s2" sends "HELO example.com"
Then IMAP response to "i2" is "OK"
Then SMTP response to "s2" is "OK"
When there is no internet connection
And 1 second pass
Then IMAP client "i2" is logged out
And SMTP client "s2" is logged out
Given the internet connection is restored
And 1 second pass
And there is IMAP client "i3" logged in as "user"
And there is SMTP client "s3" logged in as "user"
When IMAP client "i3" gets info of "INBOX"
When SMTP client "s3" sends "HELO example.com"
Then IMAP response to "i3" is "OK"
Then SMTP response to "s3" is "OK"

View File

@ -86,20 +86,13 @@ func (pc *persistentClient) GetEvent(ctx context.Context, eventID string) (*pmap
func SetupPersistentClients() {
app := os.Getenv("TEST_APP")
persistentClients.manager = pmapi.New(pmapi.NewConfig(getAppVersionName(app), constants.Version))
persistentClients.manager = pmapi.New(pmapi.NewConfig(app, constants.Version))
persistentClients.manager.SetLogging(logrus.WithField("pkg", "liveapi"), logrus.GetLevel() == logrus.TraceLevel)
persistentClients.byName = map[string]clientAuthGetter{}
persistentClients.saltByName = map[string]string{}
}
func getAppVersionName(app string) string {
if app == "ie" {
return "importExport"
}
return app
}
func CleanupPersistentClients() {
for username, client := range persistentClients.byName {
if err := client.AuthDelete(context.Background()); err != nil {