Merge pull request #5654 from nextcloud/bugfix/ask-before-importing-legacy

Ask before importing accounts from legacy clients
This commit is contained in:
Claudio Cambra 2023-05-16 22:01:00 +08:00 committed by GitHub
commit 6ff45bf342
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 91 additions and 53 deletions

View file

@ -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();
@ -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;
}
@ -545,4 +560,19 @@ void AccountManager::addAccountState(AccountState *accountState)
ptr->trySignIn();
emit accountAdded(accountState);
}
bool AccountManager::forceLegacyImport() const
{
return _forceLegacyImport;
}
void AccountManager::setForceLegacyImport(const bool forceLegacyImport)
{
if (_forceLegacyImport == forceLegacyImport) {
return;
}
_forceLegacyImport = forceLegacyImport;
Q_EMIT forceLegacyImportChanged();
}
}

View file

@ -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,
@ -38,11 +41,6 @@ public:
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.
*
@ -57,11 +55,6 @@ public:
*/
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)
@ -80,9 +73,10 @@ public:
[[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.
@ -96,6 +90,31 @@ public:
*/
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);
@ -113,19 +132,6 @@ private:
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;
};
}

View file

@ -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()
{
@ -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()) {