Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ask before importing accounts from legacy clients #5654

Merged
merged 8 commits into from
May 16, 2023
38 changes: 34 additions & 4 deletions src/gui/accountmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -175,11 +175,20 @@ bool AccountManager::restoreFromLegacySettings()
legacyCfgFileGrandParentFolder + legacyCfgFileRelativePath};

for (const auto &configFile : legacyLocations) {
if (const QFileInfo configFileInfo(configFile);
configFileInfo.exists() && configFileInfo.isReadable()) {

if (const QFileInfo configFileInfo(configFile); configFileInfo.exists() && configFileInfo.isReadable()) {
qCInfo(lcAccountManager) << "Migrate: checking old config " << configFile;

if (!forceLegacyImport()) {
const auto importQuestion = tr("An existing configuration from a legacy desktop client was detected.\n"
"Should an account import be attempted?");
const auto messageBoxSelection = QMessageBox::question(nullptr, tr("Legacy import"), importQuestion);

if (messageBoxSelection == QMessageBox::No) {
// User said don't import, return immediately
return false;
}
}

auto oCSettings = std::make_unique<QSettings>(configFile, QSettings::IniFormat);
if (oCSettings->status() != QSettings::Status::NoError) {
qCInfo(lcAccountManager) << "Error reading legacy configuration file" << oCSettings->status();
Expand Down Expand Up @@ -239,11 +248,17 @@ bool AccountManager::restoreFromLegacySettings()
settings->beginGroup(accountId);
if (const auto acc = loadAccountHelper(*settings)) {
addAccount(acc);

QMessageBox::information(nullptr,
tr("Legacy import"),
tr("Successfully imported account from legacy client: %1").arg(acc->prettyName()));
return true;
}
}
}

QMessageBox::information(nullptr,
tr("Legacy import"),
tr("Could not import accounts from legacy client configuration."));
return false;
}

Expand Down Expand Up @@ -545,4 +560,19 @@ void AccountManager::addAccountState(AccountState *accountState)
ptr->trySignIn();
emit accountAdded(accountState);
}

bool AccountManager::forceLegacyImport() const
claucambra marked this conversation as resolved.
Show resolved Hide resolved
{
return _forceLegacyImport;
}

void AccountManager::setForceLegacyImport(const bool forceLegacyImport)
{
if (_forceLegacyImport == forceLegacyImport) {
return;
}

_forceLegacyImport = forceLegacyImport;
Q_EMIT forceLegacyImportChanged();
}
}
58 changes: 32 additions & 26 deletions src/gui/accountmanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ namespace OCC {
class AccountManager : public QObject
{
Q_OBJECT

Q_PROPERTY(bool forceLegacyImport READ forceLegacyImport WRITE setForceLegacyImport NOTIFY forceLegacyImportChanged)

public:
enum AccountsRestoreResult {
AccountsRestoreFailure = 0,
Expand All @@ -38,11 +41,6 @@ class AccountManager : public QObject
static AccountManager *instance();
~AccountManager() override = default;

/**
* Saves the accounts to a given settings file
*/
void save(bool saveCredentials = true);

/**
* Creates account objects from a given settings file.
*
Expand All @@ -57,11 +55,6 @@ class AccountManager : public QObject
*/
AccountState *addAccount(const AccountPtr &newAccount);

/**
* remove all accounts
*/
void shutdown();

/**
* Return a list of all accounts.
* (this is a list of QSharedPointer for internal reasons, one should normally not keep a copy of them)
Expand All @@ -80,9 +73,10 @@ class AccountManager : public QObject
[[nodiscard]] AccountStatePtr accountFromUserId(const QString &id) const;

/**
* Delete the AccountState
* Returns whether the account setup will force an import of
* legacy clients' accounts (true), or ask first (false)
*/
void deleteAccount(AccountState *account);
[[nodiscard]] bool forceLegacyImport() const;

/**
* Creates an account and sets up some basic handlers.
Expand All @@ -96,6 +90,31 @@ class AccountManager : public QObject
*/
static void backwardMigrationSettingsKeys(QStringList *deleteKeys, QStringList *ignoreKeys);

public slots:
/// Saves account data, not including the credentials
void saveAccount(OCC::Account *a);

/// Saves account state data, not including the account
void saveAccountState(OCC::AccountState *a);

/// Saves the accounts to a given settings file
void save(bool saveCredentials = true);

/// Delete the AccountState
void deleteAccount(AccountState *account);

/// Remove all accounts
void shutdown();

void setForceLegacyImport(const bool forceLegacyImport);

signals:
void accountAdded(OCC::AccountState *account);
void accountRemoved(OCC::AccountState *account);
void accountSyncConnectionRemoved(OCC::AccountState *account);
void removeAccountFolders(OCC::AccountState *account);
void forceLegacyImportChanged();

private:
// saving and loading Account to settings
void saveAccountHelper(Account *account, QSettings &settings, bool saveCredentials = true);
Expand All @@ -113,19 +132,6 @@ class AccountManager : public QObject
QList<AccountStatePtr> _accounts;
/// Account ids from settings that weren't read
QSet<QString> _additionalBlockedAccountIds;

public slots:
/// Saves account data, not including the credentials
void saveAccount(OCC::Account *a);

/// Saves account state data, not including the account
void saveAccountState(OCC::AccountState *a);


Q_SIGNALS:
void accountAdded(OCC::AccountState *account);
void accountRemoved(OCC::AccountState *account);
void accountSyncConnectionRemoved(OCC::AccountState *account);
void removeAccountFolders(OCC::AccountState *account);
bool _forceLegacyImport = false;
};
}
48 changes: 25 additions & 23 deletions src/gui/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,27 +77,28 @@ namespace {

static const char optionsC[] =
"Options:\n"
" --help, -h : show this help screen.\n"
" --version, -v : show version information.\n"
" -q --quit : quit the running instance\n"
" --logwindow, -l : open a window to show log output.\n"
" --logfile <filename> : write log output to file <filename>.\n"
" --logdir <name> : write each sync log output in a new file\n"
" in folder <name>.\n"
" --logexpire <hours> : removes logs older than <hours> hours.\n"
" (to be used with --logdir)\n"
" --logflush : flush the log file after every write.\n"
" --logdebug : also output debug-level messages in the log.\n"
" --confdir <dirname> : Use the given configuration folder.\n"
" --background : launch the application in the background.\n"
" --overrideserverurl : specify a server URL to use for the force override to be used in the account setup wizard.\n"
" --overridelocaldir : specify a local dir to be used in the account setup wizard.\n"
" --userid : userId (username as on the server) to pass when creating an account via command-line.\n"
" --apppassword : appPassword to pass when creating an account via command-line.\n"
" --localdirpath : (optional) path where to create a local sync folder when creating an account via command-line.\n"
" --isvfsenabled : whether to set a VFS or non-VFS folder (1 for 'yes' or 0 for 'no') when creating an account via command-line.\n"
" --remotedirpath : (optional) path to a remote subfolder when creating an account via command-line.\n"
" --serverurl : a server URL to use when creating an account via command-line.\n";
" --help, -h : show this help screen.\n"
" --version, -v : show version information.\n"
" -q --quit : quit the running instance\n"
" --logwindow, -l : open a window to show log output.\n"
" --logfile <filename> : write log output to file <filename>.\n"
" --logdir <name> : write each sync log output in a new file\n"
" in folder <name>.\n"
" --logexpire <hours> : removes logs older than <hours> hours.\n"
" (to be used with --logdir)\n"
" --logflush : flush the log file after every write.\n"
" --logdebug : also output debug-level messages in the log.\n"
" --confdir <dirname> : Use the given configuration folder.\n"
" --background : launch the application in the background.\n"
" --overrideserverurl : specify a server URL to use for the force override to be used in the account setup wizard.\n"
" --overridelocaldir : specify a local dir to be used in the account setup wizard.\n"
" --userid : userId (username as on the server) to pass when creating an account via command-line.\n"
" --apppassword : appPassword to pass when creating an account via command-line.\n"
" --localdirpath : (optional) path where to create a local sync folder when creating an account via command-line.\n"
" --isvfsenabled : whether to set a VFS or non-VFS folder (1 for 'yes' or 0 for 'no') when creating an account via command-line.\n"
" --remotedirpath : (optional) path to a remote subfolder when creating an account via command-line.\n"
" --serverurl : a server URL to use when creating an account via command-line.\n"
" --forcelegacyconfigimport : forcefully import account configurations from legacy clients (if available).\n";

QString applicationTrPath()
{
Expand Down Expand Up @@ -755,8 +756,9 @@ void Application::parseOptions(const QStringList &options)
} else {
showHint("Invalid URL passed to --overridelocaldir");
}
}
else {
} else if (option == QStringLiteral("--forcelegacyconfigimport")) {
AccountManager::instance()->setForceLegacyImport(true);
} else {
QString errorMessage;
if (!AccountSetupCommandLineManager::instance()->parseCommandlineOption(option, it, errorMessage)) {
if (!errorMessage.isEmpty()) {
Expand Down