Skip to content

Commit 66af508

Browse files
committed
refactor(migration): find and readlegacy config files in the Migration class.
- Make all Migration class members static. - Rename Migration class members. Signed-off-by: Camila Ayres <hello@camilasan.com>
1 parent 489ace4 commit 66af508

10 files changed

Lines changed: 239 additions & 171 deletions

File tree

src/gui/accountmanager.cpp

Lines changed: 52 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ constexpr auto serverDesktopEnterpriseUpdateChannelC = "desktopEnterpriseChannel
8787
constexpr auto generalC = "General";
8888
}
8989

90-
9190
namespace OCC {
9291

9392
Q_LOGGING_CATEGORY(lcAccountManager, "nextcloud.gui.account.manager", QtInfoMsg)
@@ -197,110 +196,64 @@ bool AccountManager::restoreFromLegacySettings()
197196
{
198197
qCInfo(lcAccountManager) << "Migrate: restoreFromLegacySettings, checking settings group"
199198
<< Theme::instance()->appName();
200-
201199
// try to open the correctly themed settings
202200
auto settings = ConfigFile::settingsWithGroup(Theme::instance()->appName());
203-
204201
auto wasLegacyImportDialogDisplayed = false;
205-
const auto displayLegacyImportDialog = Theme::instance()->displayLegacyImportDialog();
206202
QStringList selectedAccountIds;
207-
208-
// if the settings file could not be opened, the childKeys list is empty
209-
// then try to load settings from a very old place
210-
if (settings->childKeys().isEmpty()) {
211-
// Legacy settings used QDesktopServices to get the location for the config folder in 2.4 and before
212-
const auto legacy2_4CfgSettingsLocation = QString(QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/data"));
213-
const auto legacy2_4CfgFileParentFolder = legacy2_4CfgSettingsLocation.left(legacy2_4CfgSettingsLocation.lastIndexOf('/'));
214-
215-
// 2.5+ (rest of 2.x series)
216-
const auto legacy2_5CfgSettingsLocation = QStandardPaths::writableLocation(Utility::isWindows() ? QStandardPaths::AppDataLocation : QStandardPaths::AppConfigLocation);
217-
const auto legacy2_5CfgFileParentFolder = legacy2_5CfgSettingsLocation.left(legacy2_5CfgSettingsLocation.lastIndexOf('/'));
218-
219-
// Now try the locations we use today
220-
const auto fullLegacyCfgFile = QDir::fromNativeSeparators(settings->fileName());
221-
const auto legacyCfgFileParentFolder = fullLegacyCfgFile.left(fullLegacyCfgFile.lastIndexOf('/'));
222-
const auto legacyCfgFileGrandParentFolder = legacyCfgFileParentFolder.left(legacyCfgFileParentFolder.lastIndexOf('/'));
223-
224-
const auto legacyCfgFileNamePath = QString(QStringLiteral("/") + legacyCfgFileNameC);
225-
const auto legacyCfgFileRelativePath = QString(legacyRelativeConfigLocationC);
226-
227-
auto legacyLocations = QVector<QString>{legacy2_4CfgFileParentFolder + legacyCfgFileRelativePath,
228-
legacy2_5CfgFileParentFolder + legacyCfgFileRelativePath,
229-
legacyCfgFileParentFolder + legacyCfgFileNamePath,
230-
legacyCfgFileGrandParentFolder + legacyCfgFileRelativePath};
231-
232-
if (Theme::instance()->isBranded()) {
233-
const auto unbrandedCfgFileNamePath = QString(QStringLiteral("/") + unbrandedCfgFileNameC);
234-
const auto unbrandedCfgFileRelativePath = QString(unbrandedRelativeConfigLocationC);
235-
legacyLocations.append({legacyCfgFileParentFolder + unbrandedCfgFileNamePath, legacyCfgFileGrandParentFolder + unbrandedCfgFileRelativePath});
236-
}
237-
238-
for (const auto &configFile : std::as_const(legacyLocations)) {
239-
auto oCSettings = std::make_unique<QSettings>(configFile, QSettings::IniFormat);
240-
if (oCSettings->status() != QSettings::Status::NoError) {
241-
qCInfo(lcAccountManager) << "Error reading legacy configuration file" << oCSettings->status();
242-
break;
243-
}
244-
245-
oCSettings->beginGroup(QLatin1String(accountsC));
246-
const auto childGroups = oCSettings->childGroups();
247-
const auto accountsListSize = childGroups.size();
248-
oCSettings->endGroup(); //accountsC
249-
if (const QFileInfo configFileInfo(configFile);
250-
configFileInfo.exists() && configFileInfo.isReadable()) {
251-
252-
qCInfo(lcAccountManager) << "Migrate: checking old config " << configFile;
253-
if (!forceLegacyImport() && accountsListSize > 0 && displayLegacyImportDialog) {
254-
wasLegacyImportDialogDisplayed = true;
255-
if (accountsListSize == 1) {
256-
const auto importQuestion =
257-
tr("An account was detected from a legacy desktop client.\n"
258-
"Should the account be imported?");
259-
QMessageBox importMessageBox(QMessageBox::Question, tr("Legacy import"), importQuestion);
260-
importMessageBox.addButton(tr("Import"), QMessageBox::AcceptRole);
261-
const auto skipButton = importMessageBox.addButton(tr("Skip"), QMessageBox::DestructiveRole);
262-
importMessageBox.exec();
263-
if (importMessageBox.clickedButton() == skipButton) {
264-
return false;
265-
}
266-
selectedAccountIds = childGroups;
267-
} else {
268-
QVector<LegacyAccountSelectionDialog::AccountItem> accountsToDisplay;
269-
oCSettings->beginGroup(QLatin1String(accountsC));
270-
for (const auto &accId : childGroups) {
271-
oCSettings->beginGroup(accId);
272-
const auto displayName = oCSettings->value(QLatin1String(displayNameC)).toString();
273-
const auto urlStr = oCSettings->value(QLatin1String(urlC)).toString();
274-
oCSettings->endGroup(); //accId
275-
const auto label = QString("%1 - %2").arg(displayName, urlStr);
276-
accountsToDisplay.push_back({accId, label});
277-
}
278-
oCSettings->endGroup(); //accountsC
279-
280-
LegacyAccountSelectionDialog accountSelectionDialog(accountsToDisplay);
281-
if (accountSelectionDialog.exec() != QDialog::Accepted) {
282-
return false;
283-
}
284-
selectedAccountIds = accountSelectionDialog.selectedAccountIds();
285-
if (selectedAccountIds.isEmpty()) {
286-
return false;
287-
}
288-
}
289-
} else {
290-
selectedAccountIds = childGroups;
203+
Migration migration;
204+
if (const auto legacyData = migration.legacyData(); !legacyData.isNull()) {
205+
206+
const auto displayLegacyImportDialog = Theme::instance()->displayLegacyImportDialog();
207+
208+
auto oCSettings = std::move(legacyData);
209+
210+
oCSettings->beginGroup(QLatin1String(accountsC));
211+
const auto childGroups = oCSettings->childGroups();
212+
const auto accountsListSize = childGroups.size();
213+
oCSettings->endGroup(); // accountsC
214+
215+
qCInfo(lcAccountManager) << "Migrate: checking old config";
216+
if (!forceLegacyImport() && displayLegacyImportDialog && accountsListSize > 0) {
217+
wasLegacyImportDialogDisplayed = true;
218+
if (childGroups.size() == 1) {
219+
const auto importQuestion =
220+
tr("An account was detected from a legacy desktop client.\n"
221+
"Should the account be imported?");
222+
QMessageBox importMessageBox(QMessageBox::Question, tr("Legacy import"), importQuestion);
223+
importMessageBox.addButton(tr("Import"), QMessageBox::AcceptRole);
224+
const auto skipButton = importMessageBox.addButton(tr("Skip"), QMessageBox::DestructiveRole);
225+
importMessageBox.exec();
226+
if (importMessageBox.clickedButton() == skipButton) {
227+
return false;
291228
}
292-
293-
const auto legacyVersion = oCSettings->value(ConfigFile::clientVersionC, {}).toString();
294-
ConfigFile().setClientPreviousVersionString(legacyVersion);
295-
qCInfo(lcAccountManager) << "Migrating from" << legacyVersion;
296-
qCInfo(lcAccountManager) << "Copy settings" << oCSettings->allKeys().join(", ");
297-
settings = std::move(oCSettings);
298-
ConfigFile::setDiscoveredLegacyConfigPath(configFileInfo.canonicalPath());
299-
break;
229+
selectedAccountIds = childGroups;
300230
} else {
301-
qCInfo(lcAccountManager) << "Migrate: could not read old config " << configFile;
231+
QVector<LegacyAccountSelectionDialog::AccountItem> accountsToDisplay;
232+
oCSettings->beginGroup(QLatin1String(accountsC));
233+
for (const auto &accId : childGroups) {
234+
oCSettings->beginGroup(accId);
235+
const auto displayName = oCSettings->value(QLatin1String(displayNameC)).toString();
236+
const auto urlStr = oCSettings->value(QLatin1String(urlC)).toString();
237+
oCSettings->endGroup(); // accId
238+
const auto label = QString("%1 - %2").arg(displayName, urlStr);
239+
accountsToDisplay.push_back({accId, label});
240+
}
241+
oCSettings->endGroup(); // accountsC
242+
243+
LegacyAccountSelectionDialog accountSelectionDialog(accountsToDisplay);
244+
if (accountSelectionDialog.exec() != QDialog::Accepted) {
245+
return false;
246+
}
247+
selectedAccountIds = accountSelectionDialog.selectedAccountIds();
248+
if (selectedAccountIds.isEmpty()) {
249+
return false;
250+
}
302251
}
252+
} else {
253+
selectedAccountIds = childGroups;
303254
}
255+
256+
settings.reset(oCSettings.get());
304257
}
305258

306259
ConfigFile configFile;
@@ -346,8 +299,7 @@ bool AccountManager::restoreFromLegacySettings()
346299
configFile.setDownloadLimit(settings->value(ConfigFile::downloadLimitC, configFile.downloadLimit()).toInt());
347300

348301
// Try to load the single account.
349-
auto migration = configFile.migration();
350-
migration.setMigrationPhase(Migration::MigrationPhase::SetupUsers);
302+
migration.setPhase(Migration::Phase::SetupUsers);
351303
if (!settings->childKeys().isEmpty()) {
352304
settings->beginGroup(accountsC);
353305
const auto childGroups = selectedAccountIds.isEmpty() ? settings->childGroups() : selectedAccountIds;
@@ -696,7 +648,7 @@ AccountPtr AccountManager::loadAccountHelper(QSettings &settings)
696648
acc->setDownloadLimit(settings.value(networkDownloadLimitC).toInt());
697649

698650
ConfigFile configFile;
699-
auto migration = configFile.migration();
651+
Migration migration;
700652
const auto proxyPasswordKey = QString(acc->userIdAtHostWithPort() + networkProxyPasswordKeychainKeySuffixC);
701653
const auto appName = migration.isUnbrandedToBrandedMigration() ? ConfigFile::unbrandedAppName
702654
: Theme::instance()->appName();

src/gui/accountstate.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -298,10 +298,10 @@ void AccountState::checkConnectivity()
298298
if (!account()->credentials()->wasFetched()) {
299299
_waitingForNewCredentials = true;
300300
ConfigFile configFile;
301-
auto migration = configFile.migration();
301+
Migration migration;
302302
const auto shouldTryUnbrandedToBrandedMigration = migration.shouldTryUnbrandedToBrandedMigration();
303303
qCDebug(lcAccountState) << "shouldTryUnbrandedToBrandedMigration?" << shouldTryUnbrandedToBrandedMigration;
304-
qCDebug(lcAccountState) << "migrationPhase?" << migration.migrationPhase();
304+
qCDebug(lcAccountState) << "migration Phase?" << migration.phase();
305305
const auto appName = shouldTryUnbrandedToBrandedMigration ? configFile.unbrandedAppName : "";
306306
account()->credentials()->fetchFromKeychain(appName);
307307
return;
@@ -500,9 +500,9 @@ void AccountState::slotCredentialsFetched(AbstractCredentials *)
500500
<< "attempting to connect";
501501
_waitingForNewCredentials = false;
502502
ConfigFile configFile;
503-
auto migration = configFile.migration();
503+
Migration migration;
504504
if (migration.isInProgress()) {
505-
migration.setMigrationPhase(Migration::MigrationPhase::Done);
505+
migration.setPhase(Migration::Phase::Done);
506506
}
507507
checkConnectivity();
508508
}

src/gui/application.cpp

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -126,11 +126,11 @@ bool Application::configVersionMigration()
126126
const auto shouldTryToMigrate = migration.shouldTryToMigrate();
127127
if (!shouldTryToMigrate) {
128128
qCInfo(lcApplication) << "This is not an upgrade/downgrade/migration. Proceed to read current application config file.";
129-
migration.setMigrationPhase(Migration::MigrationPhase::Done);
129+
migration.setPhase(Migration::Phase::Done);
130130
return false;
131131
}
132132

133-
migration.setMigrationPhase(Migration::MigrationPhase::SetupConfigFile);
133+
migration.setPhase(Migration::Phase::SetupConfigFile);
134134
QStringList deleteKeys, ignoreKeys;
135135
AccountManager::backwardMigrationSettingsKeys(&deleteKeys, &ignoreKeys);
136136
FolderMan::backwardMigrationSettingsKeys(&deleteKeys, &ignoreKeys);
@@ -153,9 +153,25 @@ bool Application::configVersionMigration()
153153
// default is now off to displaying dialog warning user of too many files deletion
154154
configFile.setPromptDeleteFiles(false);
155155

156-
// back up all old config files and message the user either for destructive changes,
156+
// back up all old config files
157+
QStringList backupFilesList;
158+
QDir configDir(configFile.configPath());
159+
const auto anyConfigFileNameList = configDir.entryInfoList({"*.cfg"}, QDir::Files);
160+
for (const auto &oldConfig : anyConfigFileNameList) {
161+
const auto oldConfigFileName = oldConfig.fileName();
162+
const auto oldConfigFilePath = oldConfig.filePath();
163+
const auto newConfigFileName = configFile.configFile();
164+
backupFilesList.append(configFile.backup(oldConfigFileName));
165+
if (oldConfigFilePath != newConfigFileName) {
166+
if (!QFile::rename(oldConfigFilePath, newConfigFileName)) {
167+
qCWarning(lcApplication) << "Failed to rename configuration file from" << oldConfigFilePath << "to" << newConfigFileName;
168+
}
169+
}
170+
}
171+
172+
// We want to message the user either for destructive changes,
157173
// or if we're ignoring something and the client version changed.
158-
if (const auto backupFilesList = configFile.backupConfigFiles(); configFile.showConfigBackupWarning() && backupFilesList.count() > 0) {
174+
if (configFile.showConfigBackupWarning() && backupFilesList.count() > 0) {
159175
QMessageBox box(
160176
QMessageBox::Warning,
161177
APPLICATION_SHORTNAME,
@@ -165,7 +181,7 @@ bool Application::configVersionMigration()
165181
"Continuing will mean <b>%2 these settings</b>.<br>"
166182
"<br>"
167183
"The current configuration file was already backed up to <i>%3</i>.")
168-
.arg((configFile.migration().isDowngrade() ? tr("newer", "newer software version") : tr("older", "older software version")),
184+
.arg((Migration().isDowngrade() ? tr("newer", "newer software version") : tr("older", "older software version")),
169185
deleteKeys.isEmpty()? tr("ignoring") : tr("deleting"),
170186
backupFilesList.join("<br>")));
171187
box.addButton(tr("Quit"), QMessageBox::AcceptRole);
@@ -477,18 +493,18 @@ void Application::setupAccountsAndFolders()
477493
{
478494
_folderManager.reset(new FolderMan);
479495
ConfigFile configFile;
480-
auto migration = configFile.migration();
481-
migration.setMigrationPhase(Migration::MigrationPhase::SetupUsers);
496+
Migration migration;
497+
migration.setPhase(Migration::Phase::SetupUsers);
482498
const auto accountsRestoreResult = restoreLegacyAccount();
483499
if (accountsRestoreResult == AccountManager::AccountsNotFound || accountsRestoreResult == AccountManager::AccountsRestoreFailure) {
484500
qCWarning(lcApplication) << "Migration result: " << accountsRestoreResult;
485501
qCDebug(lcApplication) << "is migration disabled?" << DISABLE_ACCOUNT_MIGRATION;
486502
qCWarning(lcApplication) << "No accounts were migrated, prompting user to set up accounts and folders from scratch.";
487-
migration.setMigrationPhase(Migration::MigrationPhase::Done);
503+
migration.setPhase(Migration::Phase::Done);
488504
return;
489505
}
490506

491-
migration.setMigrationPhase(Migration::MigrationPhase::SetupFolders);
507+
migration.setPhase(Migration::Phase::SetupFolders);
492508
const auto foldersListSize = FolderMan::instance()->setupFolders();
493509
FolderMan::instance()->setSyncEnabled(true);
494510

src/gui/folderman.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <pushnotifications.h>
2121
#include <syncengine.h>
2222
#include "updatee2eefolderusersmetadatajob.h"
23+
#include "settings/migration.h"
2324

2425
#ifdef Q_OS_MACOS
2526
#include <CoreServices/CoreServices.h>
@@ -403,7 +404,8 @@ int FolderMan::setupFoldersMigration()
403404
auto configPath = _folderConfigPath;
404405

405406
#if !DISABLE_ACCOUNT_MIGRATION
406-
if (const auto legacyConfigPath = ConfigFile::discoveredLegacyConfigPath();!legacyConfigPath.isEmpty()) {
407+
Migration migration;
408+
if (const auto legacyConfigPath = migration.discoveredLegacyConfigPath(); !legacyConfigPath.isEmpty()) {
407409
configPath = legacyConfigPath;
408410
qCInfo(lcFolderMan) << "Starting folder migration from legacy path:" << legacyConfigPath;
409411
}

src/gui/folderman.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class SyncResult;
3838
class SocketApi;
3939
class LockWatcher;
4040
class UpdateE2eeFolderUsersMetadataJob;
41+
class Migration;
4142

4243
/**
4344
* @brief The FolderMan class

src/libsync/configfile.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ namespace chrono = std::chrono;
9292
Q_LOGGING_CATEGORY(lcConfigFile, "nextcloud.sync.configfile", QtInfoMsg)
9393

9494
QString ConfigFile::_confDir = {};
95-
Migration ConfigFile::_migration = Migration{};
9695

9796
static chrono::milliseconds millisecondsValue(const QSettings &setting, const char *key,
9897
chrono::milliseconds defaultValue)
@@ -327,7 +326,8 @@ void ConfigFile::restoreGeometryHeader(QHeaderView *header)
327326
QVariant ConfigFile::getPolicySetting(const QString &setting, const QVariant &defaultValue) const
328327
{
329328
if (Utility::isWindows()) {
330-
const auto appName = migration().isUnbrandedToBrandedMigration() ? unbrandedAppName : Theme::instance()->appNameGUI();
329+
Migration migration;
330+
const auto appName = migration.isUnbrandedToBrandedMigration() ? unbrandedAppName : Theme::instance()->appNameGUI();
331331
// check for policies first and return immediately if a value is found.
332332
QSettings userPolicy(QString::fromLatin1(R"(HKEY_CURRENT_USER\Software\Policies\%1\%2)").arg(APPLICATION_VENDOR, appName),
333333
QSettings::NativeFormat);
@@ -381,7 +381,10 @@ QString ConfigFile::excludeFile(Scope scope) const
381381
return ConfigFile::excludeFileFromSystem();
382382
}
383383

384-
const auto excludeFilePath = scope == LegacyScope ? _migration.discoveredLegacyConfigPath() : configPath();
384+
Migration migration;
385+
const auto excludeFilePath = scope == LegacyScope
386+
? migration.discoveredLegacyConfigPath()
387+
: configPath();
385388

386389
// prefer sync-exclude.lst, but if it does not exist, check for exclude.lst
387390
QFileInfo exclFileInfo(excludeFilePath, syncExclFile);
@@ -822,7 +825,8 @@ QVariant ConfigFile::getValue(const QString &param, const QString &group,
822825
const QVariant &defaultValue) const
823826
{
824827
QVariant systemSetting;
825-
const auto appName = migration().isUnbrandedToBrandedMigration() ? unbrandedAppName : Theme::instance()->appNameGUI();
828+
Migration migration;
829+
const auto appName = migration.isUnbrandedToBrandedMigration() ? unbrandedAppName : Theme::instance()->appNameGUI();
826830
if (Utility::isMac()) {
827831
QSettings systemSettings(QLatin1String("/Library/Preferences/" APPLICATION_REV_DOMAIN ".plist"), QSettings::NativeFormat);
828832
if (!group.isEmpty()) {
@@ -1350,8 +1354,4 @@ QStringList ConfigFile::backupConfigFiles() const
13501354
return backupFilesList;
13511355
}
13521356

1353-
Migration &ConfigFile::migration() {
1354-
return _migration;
1355-
}
1356-
13571357
}

0 commit comments

Comments
 (0)