diff --git a/src/gui/accountmanager.cpp b/src/gui/accountmanager.cpp index 36f6110821bd5..f89085664ceda 100644 --- a/src/gui/accountmanager.cpp +++ b/src/gui/accountmanager.cpp @@ -78,8 +78,8 @@ constexpr auto unbrandedRelativeConfigLocationC = "/Nextcloud/nextcloud.cfg"; constexpr auto unbrandedCfgFileNameC = "nextcloud.cfg"; // The maximum versions that this client can read -constexpr auto maxAccountsVersion = 2; -constexpr auto maxAccountVersion = 1; +constexpr auto maxAccountsVersion = 13; +constexpr auto maxAccountVersion = 13; constexpr auto serverHasValidSubscriptionC = "serverHasValidSubscription"; } @@ -150,6 +150,9 @@ void AccountManager::backwardMigrationSettingsKeys(QStringList *deleteKeys, QStr const auto settings = ConfigFile::settingsWithGroup(QLatin1String(accountsC)); const auto accountsVersion = settings->value(QLatin1String(versionC)).toInt(); + qCInfo(lcAccountManager) << "Checking for accounts versions."; + qCInfo(lcAccountManager) << "Config accounts version:" << accountsVersion; + qCInfo(lcAccountManager) << "Max accounts Version is set to:" << maxAccountsVersion; if (accountsVersion <= maxAccountsVersion) { const auto settingsChildGroups = settings->childGroups(); for (const auto &accountId : settingsChildGroups) { @@ -158,6 +161,7 @@ void AccountManager::backwardMigrationSettingsKeys(QStringList *deleteKeys, QStr if (accountVersion > maxAccountVersion) { ignoreKeys->append(settings->group()); + qCInfo(lcAccountManager) << "Ignoring account" << accountId << "because of version" << accountVersion; } settings->endGroup(); } @@ -236,41 +240,8 @@ bool AccountManager::restoreFromLegacySettings() } } - // Check the theme url to see if it is the same url that the oC config was for - const auto overrideUrl = Theme::instance()->overrideServerUrl(); - const auto cleanOverrideUrl = overrideUrl.endsWith('/') ? overrideUrl.chopped(1) : overrideUrl; - qCInfo(lcAccountManager) << "Migrate: overrideUrl" << cleanOverrideUrl; - - if (!cleanOverrideUrl.isEmpty()) { - oCSettings->beginGroup(QLatin1String(accountsC)); - const auto accountsChildGroups = oCSettings->childGroups(); - for (const auto &accountId : accountsChildGroups) { - oCSettings->beginGroup(accountId); - const auto oCUrl = oCSettings->value(QLatin1String(urlC)).toString(); - const auto cleanOCUrl = oCUrl.endsWith('/') ? oCUrl.chopped(1) : oCUrl; - - // in case the urls are equal reset the settings object to read from - // the ownCloud settings object - qCInfo(lcAccountManager) << "Migrate oC config if " << cleanOCUrl << " == " << cleanOverrideUrl << ":" - << (cleanOCUrl == cleanOverrideUrl ? "Yes" : "No"); - if (cleanOCUrl == cleanOverrideUrl) { - qCInfo(lcAccountManager) << "Copy settings" << oCSettings->allKeys().join(", "); - oCSettings->endGroup(); // current accountID group - oCSettings->endGroup(); // accounts group - settings = std::move(oCSettings); - break; - } - - oCSettings->endGroup(); - } - - if (oCSettings) { - oCSettings->endGroup(); - } - } else { - qCInfo(lcAccountManager) << "Copy settings" << oCSettings->allKeys().join(", "); - settings = std::move(oCSettings); - } + qCInfo(lcAccountManager) << "Copy settings" << oCSettings->allKeys().join(", "); + settings = std::move(oCSettings); ConfigFile::setDiscoveredLegacyConfigPath(configFileInfo.canonicalPath()); break; diff --git a/src/gui/application.cpp b/src/gui/application.cpp index 4175ae5f0649b..080ad34e63af0 100644 --- a/src/gui/application.cpp +++ b/src/gui/application.cpp @@ -143,6 +143,11 @@ bool Application::configVersionMigration() const auto versionChanged = previousVersion != currentVersion; const auto downgrading = previousVersion > currentVersion; + if (versionChanged) { + qCInfo(lcApplication) << "Version changed. Removing updater settings from config."; + configFile.cleanUpdaterConfiguration(); + } + if (!versionChanged && !(!deleteKeys.isEmpty() || (!ignoreKeys.isEmpty() && versionChanged))) { return true; } @@ -194,13 +199,16 @@ bool Application::configVersionMigration() QTimer::singleShot(0, qApp, &QCoreApplication::quit); return false; } + } + if (!deleteKeys.isEmpty()) { auto settings = ConfigFile::settingsWithGroup("foo"); settings->endGroup(); // Wipe confusing keys from the future, ignore the others for (const auto &badKey : std::as_const(deleteKeys)) { settings->remove(badKey); + qCInfo(lcApplication) << "Migration: removed" << badKey << "key from settings."; } } @@ -236,14 +244,14 @@ Application::Application(int &argc, char **argv) setWindowIcon(_theme->applicationIcon()); if (!ConfigFile().exists()) { - // Migrate from version <= 2.4 setApplicationName(_theme->appNameGUI()); - // We need to use the deprecated QDesktopServices::storageLocation because of its Qt4 - // behavior of adding "data" to the path - QString oldDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + "/data/" + organizationName() + "/" + applicationName(); - if (oldDir.endsWith('/')) oldDir.chop(1); // macOS 10.11.x does not like trailing slash for rename/move. + QString legacyDir = QStandardPaths::writableLocation(QStandardPaths::GenericConfigLocation) + "/" + APPLICATION_CONFIG_NAME; + + if (legacyDir.endsWith('/')) { + legacyDir.chop(1); // macOS 10.11.x does not like trailing slash for rename/move. + } setApplicationName(_theme->appName()); - if (QFileInfo(oldDir).isDir()) { + if (QFileInfo(legacyDir).isDir()) { auto confDir = ConfigFile().configPath(); // macOS 10.11.x does not like trailing slash for rename/move. @@ -251,17 +259,17 @@ Application::Application(int &argc, char **argv) confDir.chop(1); } - qCInfo(lcApplication) << "Migrating old config from" << oldDir << "to" << confDir; + qCInfo(lcApplication) << "Migrating old config from" << legacyDir << "to" << confDir; - if (!QFile::rename(oldDir, confDir)) { - qCWarning(lcApplication) << "Failed to move the old config directory to its new location (" << oldDir << "to" << confDir << ")"; + if (!QFile::rename(legacyDir, confDir)) { + qCWarning(lcApplication) << "Failed to move the old config directory to its new location (" << legacyDir << "to" << confDir << ")"; // Try to move the files one by one if (QFileInfo(confDir).isDir() || QDir().mkdir(confDir)) { - const QStringList filesList = QDir(oldDir).entryList(QDir::Files); + const QStringList filesList = QDir(legacyDir).entryList(QDir::Files); qCInfo(lcApplication) << "Will move the individual files" << filesList; for (const auto &name : filesList) { - if (!QFile::rename(oldDir + "/" + name, confDir + "/" + name)) { + if (!QFile::rename(legacyDir + "/" + name, confDir + "/" + name)) { qCWarning(lcApplication) << "Fallback move of " << name << "also failed"; } } @@ -269,7 +277,7 @@ Application::Application(int &argc, char **argv) } else { #ifndef Q_OS_WIN // Create a symbolic link so a downgrade of the client would still find the config. - QFile::link(confDir, oldDir); + QFile::link(confDir, legacyDir); #endif } } diff --git a/src/gui/folder.h b/src/gui/folder.h index 7b1b53929223e..741ce76b10dfa 100644 --- a/src/gui/folder.h +++ b/src/gui/folder.h @@ -85,8 +85,9 @@ class FolderDefinition * (version remains readable by 2.5.1) * Version 3: introduction of new windows vfs mode in 2.6.0 * Version 5: available in oC client 4.0.0 and 4.2.0 + * Version 13: available in oC client 5.2.0 and 5.3.1 */ - static int maxSettingsVersion() { return 5; } + static int maxSettingsVersion() { return 13; } /// Ensure / as separator and trailing /. static QString prepareLocalPath(const QString &path); diff --git a/src/gui/folderman.cpp b/src/gui/folderman.cpp index 69c7dfeab836e..6f84af9ad4f10 100644 --- a/src/gui/folderman.cpp +++ b/src/gui/folderman.cpp @@ -42,6 +42,7 @@ namespace { constexpr auto settingsAccountsC = "Accounts"; constexpr auto settingsFoldersC = "Folders"; +constexpr auto settingsFoldersWithPlaceholdersC = "FoldersWithPlaceholders"; constexpr auto settingsVersionC = "version"; constexpr auto maxFoldersVersion = 1; @@ -388,16 +389,19 @@ void FolderMan::backwardMigrationSettingsKeys(QStringList *deleteKeys, QStringLi auto processSubgroup = [&](const QString &name) { settings->beginGroup(name); const auto foldersVersion = settings->value(QLatin1String(settingsVersionC), 1).toInt(); + qCInfo(lcFolderMan) << "FolderDefinition::maxSettingsVersion:" << FolderDefinition::maxSettingsVersion(); if (foldersVersion <= maxFoldersVersion) { for (const auto &folderAlias : settings->childGroups()) { settings->beginGroup(folderAlias); const auto folderVersion = settings->value(QLatin1String(settingsVersionC), 1).toInt(); if (folderVersion > FolderDefinition::maxSettingsVersion()) { + qCInfo(lcFolderMan) << "Ignoring folder:" << folderAlias << "version:" << folderVersion; ignoreKeys->append(settings->group()); } settings->endGroup(); } } else { + qCInfo(lcFolderMan) << "Ignoring group:" << name << "version:" << foldersVersion; deleteKeys->append(settings->group()); } settings->endGroup(); @@ -523,89 +527,97 @@ void FolderMan::setupLegacyFolder(const QString &fileNamePath, AccountState *acc return; } - settings.beginGroup(settingsAccountsC); - qCDebug(lcFolderMan) << "try to migrate accountId:" << accountState->account()->id(); - settings.beginGroup(accountState->account()->id()); - settings.beginGroup(settingsFoldersC); - - if (settings.childGroups().isEmpty()) { - qCDebug(lcFolderMan) << "there are no legacy folders for accountId:" << accountState->account()->id(); - return; - } - - const auto childGroups = settings.childGroups(); - for (const auto &alias : childGroups) { - settings.beginGroup(alias); - qCDebug(lcFolderMan) << "try to migrate folder alias:" << alias; - - const auto path = settings.value(QLatin1String("localPath")).toString(); - const auto targetPath = settings.value(QLatin1String("targetPath")).toString(); - const auto journalPath = settings.value(QLatin1String("journalPath")).toString(); - const auto paused = settings.value(QLatin1String("paused"), false).toBool(); - const auto ignoreHiddenFiles = settings.value(QLatin1String("ignoreHiddenFiles"), false).toBool(); - - if (path.isEmpty()) { - qCDebug(lcFolderMan) << "localPath is empty"; - settings.endGroup(); - continue; - } - - if (targetPath.isEmpty()) { - qCDebug(lcFolderMan) << "targetPath is empty"; - settings.endGroup(); - continue; + auto migrateFoldersGroup = [&](const QString &folderGroupName) { + const auto childGroups = settings.childGroups(); + if (childGroups.isEmpty()) { + qCDebug(lcFolderMan) << "There are no" << folderGroupName << "to migrate from account" << accountState->account()->id(); + return; } + for (const auto &alias : childGroups) { + settings.beginGroup(alias); + qCDebug(lcFolderMan) << "try to migrate" << folderGroupName << "alias:" << alias; + + const auto path = settings.value(QLatin1String("localPath")).toString(); + const auto targetPath = settings.value(QLatin1String("targetPath")).toString(); + const auto journalPath = settings.value(QLatin1String("journalPath")).toString(); + const auto paused = settings.value(QLatin1String("paused"), false).toBool(); + const auto ignoreHiddenFiles = settings.value(QLatin1String("ignoreHiddenFiles"), false).toBool(); + + if (path.isEmpty()) { + qCDebug(lcFolderMan) << "localPath is empty"; + settings.endGroup(); + continue; + } - if (journalPath.isEmpty()) { - qCDebug(lcFolderMan) << "journalPath is empty"; - settings.endGroup(); - continue; - } + if (targetPath.isEmpty()) { + qCDebug(lcFolderMan) << "targetPath is empty"; + settings.endGroup(); + continue; + } - FolderDefinition folderDefinition; - folderDefinition.alias = alias; - folderDefinition.localPath = path; - folderDefinition.targetPath = targetPath; - folderDefinition.journalPath = journalPath; - folderDefinition.paused = paused; - folderDefinition.ignoreHiddenFiles = ignoreHiddenFiles; - - if (const auto folder = addFolderInternal(folderDefinition, accountState, std::make_unique())) { - auto ok = true; - auto legacyBlacklist = folder->journalDb()->getSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, - &ok); - if (!ok) { - qCInfo(lcFolderMan) << "There was a problem retrieving the database selective sync for " << folder; + if (journalPath.isEmpty()) { + qCDebug(lcFolderMan) << "journalPath is empty"; + settings.endGroup(); + continue; } - legacyBlacklist << settings.value(QLatin1String("blackList")).toStringList(); - if (!legacyBlacklist.isEmpty()) { - qCInfo(lcFolderMan) << "Legacy selective sync list found:" << legacyBlacklist; - for (const auto &legacyFolder : legacyBlacklist) { - folder->migrateBlackListPath(legacyFolder); + qCDebug(lcFolderMan) << folderGroupName << "located at" << path; + + FolderDefinition folderDefinition; + folderDefinition.alias = alias; + folderDefinition.localPath = path; + folderDefinition.targetPath = targetPath; + folderDefinition.journalPath = journalPath; + folderDefinition.paused = paused; + folderDefinition.ignoreHiddenFiles = ignoreHiddenFiles; + + if (const auto folder = addFolderInternal(folderDefinition, accountState, std::make_unique())) { + auto ok = true; + auto legacyBlacklist = folder->journalDb()->getSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, + &ok); + if (!ok) { + qCInfo(lcFolderMan) << "There was a problem retrieving the database selective sync for " << folder; + } + + legacyBlacklist << settings.value(QLatin1String("blackList")).toStringList(); + if (!legacyBlacklist.isEmpty()) { + qCInfo(lcFolderMan) << "Legacy selective sync list found:" << legacyBlacklist; + for (const auto &legacyFolder : legacyBlacklist) { + folder->migrateBlackListPath(legacyFolder); + } + settings.remove(QLatin1String("blackList")); } - settings.remove(QLatin1String("blackList")); - } - folder->saveToSettings(); + folder->saveToSettings(); - qCInfo(lcFolderMan) << "Migrated!" << folder->path(); - settings.sync(); + qCInfo(lcFolderMan) << "Migrated!" << folder->path(); + settings.sync(); - if (!folder) { - continue; - } + if (!folder) { + continue; + } - scheduleFolder(folder); - emit folderSyncStateChange(folder); + scheduleFolder(folder); + emit folderSyncStateChange(folder); + } + settings.endGroup(); // folder alias } + }; - settings.endGroup(); - } + settings.beginGroup(settingsAccountsC); + qCDebug(lcFolderMan) << "try to migrate accountId:" << accountState->account()->id(); + settings.beginGroup(accountState->account()->id()); + settings.beginGroup(settingsFoldersWithPlaceholdersC); + migrateFoldersGroup(settingsFoldersWithPlaceholdersC); settings.endGroup(); + + settings.beginGroup(settingsFoldersC); + migrateFoldersGroup(settingsFoldersC); settings.endGroup(); + settings.endGroup(); + settings.endGroup(); return; } diff --git a/src/libsync/configfile.cpp b/src/libsync/configfile.cpp index 37ea14d6ff3d3..b1cb4268d1059 100644 --- a/src/libsync/configfile.cpp +++ b/src/libsync/configfile.cpp @@ -453,6 +453,17 @@ QString ConfigFile::excludeFileFromSystem() return fi.absoluteFilePath(); } +void OCC::ConfigFile::cleanUpdaterConfiguration() +{ + QSettings settings(configFile(), QSettings::IniFormat); + settings.beginGroup("Updater"); + settings.remove("autoUpdateAttempted"); + settings.remove("updateTargetVersion"); + settings.remove("updateTargetVersionString"); + settings.remove("updateAvailable"); + settings.sync(); +} + QString ConfigFile::backup(const QString &fileName) const { const QString baseFilePath = configPath() + fileName; @@ -1260,6 +1271,12 @@ void ConfigFile::setupDefaultExcludeFilePaths(ExcludedFiles &excludedFiles) const auto userList = cfg.excludeFile(ConfigFile::UserScope); const auto legacyList = cfg.excludeFile(ConfigFile::LegacyScope); + if (Theme::instance()->isBranded() && QFile::exists(systemList) && QFile::copy(systemList, userList)) { + qCInfo(lcConfigFile) << "Overwriting user list" << userList << "with system list" << systemList; + excludedFiles.addExcludeFilePath(systemList); + return; + } + if (!QFile::exists(userList)) { qCInfo(lcConfigFile) << "User defined ignore list does not exist:" << userList; diff --git a/src/libsync/configfile.h b/src/libsync/configfile.h index 844036336a6f9..f38fba1f11ab0 100644 --- a/src/libsync/configfile.h +++ b/src/libsync/configfile.h @@ -48,6 +48,8 @@ class OWNCLOUDSYNC_EXPORT ConfigFile [[nodiscard]] QString excludeFile(Scope scope) const; static QString excludeFileFromSystem(); // doesn't access config dir + void cleanUpdaterConfiguration(); + /** * Creates a backup of any given fileName in the config folder *