forked from ProtonMail/proton-bridge
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
GODT-1508: Splash screen for rebranding.
* Use old keychain until manual update. * Improve desktop files migration for windows and linux. * Revert, need admin rights to change desktop and start menu files.
- Loading branch information
Showing
15 changed files
with
3,238 additions
and
250 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,197 @@ | ||
// Copyright (c) 2022 Proton AG | ||
// | ||
// This file is part of Proton Mail Bridge. | ||
// | ||
// Proton Mail Bridge is free software: you can redistribute it and/or modify | ||
// it under the terms of the GNU General Public License as published by | ||
// the Free Software Foundation, either version 3 of the License, or | ||
// (at your option) any later version. | ||
// | ||
// Proton Mail Bridge is distributed in the hope that it will be useful, | ||
// but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
// GNU General Public License for more details. | ||
// | ||
// You should have received a copy of the GNU General Public License | ||
// along with Proton Mail Bridge. If not, see <https://www.gnu.org/licenses/>. | ||
|
||
package base | ||
|
||
import ( | ||
"errors" | ||
"os" | ||
"path/filepath" | ||
"runtime" | ||
"strings" | ||
|
||
"github.com/ProtonMail/proton-bridge/internal/config/settings" | ||
"github.com/ProtonMail/proton-bridge/pkg/keychain" | ||
"github.com/hashicorp/go-multierror" | ||
"github.com/sirupsen/logrus" | ||
) | ||
|
||
const darwin = "darwin" | ||
|
||
func migrateRebranding(settingsObj *settings.Settings, keychainName string) (result error) { | ||
if err := migrateStartupBeforeRebranding(); err != nil { | ||
result = multierror.Append(result, err) | ||
} | ||
|
||
lastUsedVersion := settingsObj.Get(settings.LastVersionKey) | ||
|
||
// Skipping migration: it is first bridge start or cache was cleared. | ||
if lastUsedVersion == "" { | ||
settingsObj.SetBool(settings.RebrandingMigrationKey, true) | ||
return | ||
} | ||
|
||
// Skipping rest of migration: already done | ||
if settingsObj.GetBool(settings.RebrandingMigrationKey) { | ||
return | ||
} | ||
|
||
switch runtime.GOOS { | ||
case "windows", "linux": | ||
// GODT-1260 we would need admin rights to changes desktop files | ||
// and start menu items. | ||
settingsObj.SetBool(settings.RebrandingMigrationKey, true) | ||
case darwin: | ||
if shouldContinue, err := isMacBeforeRebranding(); !shouldContinue || err != nil { | ||
if err != nil { | ||
result = multierror.Append(result, err) | ||
} | ||
break | ||
} | ||
|
||
if err := migrateMacKeychainBeforeRebranding(settingsObj, keychainName); err != nil { | ||
result = multierror.Append(result, err) | ||
} | ||
|
||
settingsObj.SetBool(settings.RebrandingMigrationKey, true) | ||
} | ||
|
||
return result | ||
} | ||
|
||
// migrateMacKeychainBeforeRebranding deals with write access restriction to | ||
// mac keychain passwords which are caused by application renaming. The old | ||
// passwords are copied under new name in order to have write access afer | ||
// renaming. | ||
func migrateMacKeychainBeforeRebranding(settingsObj *settings.Settings, keychainName string) error { | ||
l := logrus.WithField("pkg", "app/base/migration") | ||
l.Warn("Migrating mac keychain") | ||
|
||
helperConstructor, ok := keychain.Helpers["macos-keychain"] | ||
if !ok { | ||
return errors.New("cannot find macos-keychain helper") | ||
} | ||
|
||
oldKC, err := helperConstructor("ProtonMailBridgeService") | ||
if err != nil { | ||
l.WithError(err).Error("Keychain constructor failed") | ||
return err | ||
} | ||
|
||
idByURL, err := oldKC.List() | ||
if err != nil { | ||
l.WithError(err).Error("List old keychain failed") | ||
return err | ||
} | ||
|
||
newKC, err := keychain.NewKeychain(settingsObj, keychainName) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
for url, id := range idByURL { | ||
li := l.WithField("id", id).WithField("url", url) | ||
userID, secret, err := oldKC.Get(url) | ||
if err != nil { | ||
li.WithField("userID", userID). | ||
WithField("err", err). | ||
Error("Faild to get old item") | ||
continue | ||
} | ||
|
||
if _, _, err := newKC.Get(userID); err == nil { | ||
li.Warn("Skipping migration, item already exists.") | ||
continue | ||
} | ||
|
||
if err := newKC.Put(userID, secret); err != nil { | ||
li.WithError(err).Error("Failed to migrate user") | ||
} | ||
|
||
li.Info("Item migrated") | ||
} | ||
|
||
return nil | ||
} | ||
|
||
// migrateStartupBeforeRebranding removes old startup links. The creation of new links is | ||
// handled by bridge initialisation. | ||
func migrateStartupBeforeRebranding() error { | ||
path, err := os.UserHomeDir() | ||
if err != nil { | ||
return err | ||
} | ||
|
||
switch runtime.GOOS { | ||
case "windows": | ||
path = filepath.Join(path, `AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup\ProtonMail Bridge.lnk`) | ||
case "linux": | ||
path = filepath.Join(path, `.config/autostart/ProtonMail Bridge.desktop`) | ||
case darwin: | ||
path = filepath.Join(path, `Library/LaunchAgents/ProtonMail Bridge.plist`) | ||
default: | ||
return errors.New("unknown GOOS") | ||
} | ||
|
||
if _, err := os.Stat(path); os.IsNotExist(err) { | ||
return nil | ||
} | ||
|
||
logrus.WithField("pkg", "app/base/migration").Warn("Migrating autostartup links") | ||
return os.Remove(path) | ||
} | ||
|
||
// startupNameForRebranding returns the name for autostart launcher based on | ||
// type of rebranded instance i.e. update or manual. | ||
// | ||
// This only affects darwin when udpate re-writes the old startup and then | ||
// manual installed it would not run proper exe. Therefore we return "old" name | ||
// for updates and "new" name for manual which would be properly migrated. | ||
// | ||
// For orther (linux and windows) the link is always pointing to launcher which | ||
// path didn't changed. | ||
func startupNameForRebranding(origin string) string { | ||
if runtime.GOOS == darwin { | ||
if path, err := os.Executable(); err == nil && strings.Contains(path, "ProtonMail Bridge") { | ||
return "ProtonMail Bridge" | ||
} | ||
} | ||
|
||
// No need to solve for other OS. See comment above. | ||
return origin | ||
} | ||
|
||
// isBeforeRebranding decide if last used version was older than 2.2.0. If | ||
// cannot decide it returns false with error. | ||
func isMacBeforeRebranding() (bool, error) { | ||
// previous version | update | do mac migration | | ||
// | first | false | | ||
// cleared-cache | manual | false | | ||
// cleared-cache | in-app | false | | ||
// old | in-app | false | | ||
// old in-app | in-app | false | | ||
// old | manual | true | | ||
// old in-app | manual | true | | ||
// manual | in-app | false | | ||
|
||
// Skip if it was in-app update and not manual | ||
if path, err := os.Executable(); err != nil || strings.Contains(path, "ProtonMail Bridge") { | ||
return false, err | ||
} | ||
|
||
return true, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.