Skip to content

Commit

Permalink
fix migration from old settings configuration files
Browse files Browse the repository at this point in the history
Signed-off-by: Matthieu Gallien <matthieu.gallien@nextcloud.com>
  • Loading branch information
mgallien authored and claucambra committed Nov 30, 2022
1 parent 4b5186d commit 04ec5ac
Show file tree
Hide file tree
Showing 2 changed files with 131 additions and 81 deletions.
90 changes: 54 additions & 36 deletions src/gui/accountmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ constexpr auto httpAuthPrefix = "http_";
constexpr auto webflowAuthPrefix = "webflow_";

constexpr auto legacyRelativeConfigLocationC = "/ownCloud/owncloud.cfg";
constexpr auto legacyOcSettingsC = "ownCloud";
constexpr auto legacyCfgFileNameC = "owncloud.cfg";

// The maximum versions that this client can read
constexpr auto maxAccountsVersion = 2;
Expand Down Expand Up @@ -142,53 +142,71 @@ bool AccountManager::restoreFromLegacySettings()
qCInfo(lcAccountManager) << "Migrate: restoreFromLegacySettings, checking settings group"
<< Theme::instance()->appName();

// try to open the correctly themed settings
// try to open the correctly themed settings
auto settings = ConfigFile::settingsWithGroup(Theme::instance()->appName());

// if the settings file could not be opened, the childKeys list is empty
// then try to load settings from a very old place
// if the settings file could not be opened, the childKeys list is empty
// then try to load settings from a very old place
if (settings->childKeys().isEmpty()) {
// Now try to open the original ownCloud settings to see if they exist.
auto oCCfgFile = QDir::fromNativeSeparators(settings->fileName());
const auto fullLegacyCfgFile = QDir::fromNativeSeparators(settings->fileName());
// replace the last two segments with ownCloud/owncloud.cfg
oCCfgFile = oCCfgFile.left(oCCfgFile.lastIndexOf('/'));
oCCfgFile = oCCfgFile.left(oCCfgFile.lastIndexOf('/'));
oCCfgFile += QLatin1String(legacyRelativeConfigLocationC);

qCInfo(lcAccountManager) << "Migrate: checking old config " << oCCfgFile;

QFileInfo fi(oCCfgFile);
if (fi.isReadable()) {
std::unique_ptr<QSettings> oCSettings(new QSettings(oCCfgFile, QSettings::IniFormat));
oCSettings->beginGroup(QLatin1String(legacyOcSettingsC));

// Check the theme url to see if it is the same url that the oC config was for
auto overrideUrl = Theme::instance()->overrideServerUrl();
if (!overrideUrl.isEmpty()) {
if (overrideUrl.endsWith('/')) {
overrideUrl.chop(1);
}
auto oCUrl = oCSettings->value(QLatin1String(urlC)).toString();
if (oCUrl.endsWith('/')) {
oCUrl.chop(1);
}

// in case the urls are equal reset the settings object to read from
// the ownCloud settings object
qCInfo(lcAccountManager) << "Migrate oC config if " << oCUrl << " == " << overrideUrl << ":"
<< (oCUrl == overrideUrl ? "Yes" : "No");
if (oCUrl == overrideUrl) {
settings = std::move(oCSettings);
const auto legacyCfgFileParentFolder = fullLegacyCfgFile.left(fullLegacyCfgFile.lastIndexOf('/'));
const auto legacyCfgFileGrandParentFolder = legacyCfgFileParentFolder.left(legacyCfgFileParentFolder.lastIndexOf('/'));

for (const auto &configFile : {QString{legacyCfgFileParentFolder + "/" + legacyCfgFileNameC}, QString{legacyCfgFileGrandParentFolder + QLatin1String(legacyRelativeConfigLocationC)}}) {
if (QFileInfo::exists(configFile)) {
qCInfo(lcAccountManager) << "Migrate: checking old config " << configFile;

QFileInfo fi(configFile);
if (fi.isReadable()) {
std::unique_ptr<QSettings> oCSettings(new QSettings(configFile, QSettings::IniFormat));
if (oCSettings->status() != QSettings::Status::NoError) {
qCInfo(lcAccountManager) << "Error reading legacy configuration file" << oCSettings->status();
}

// Check the theme url to see if it is the same url that the oC config was for
auto overrideUrl = Theme::instance()->overrideServerUrl();
qCInfo(lcAccountManager) << "Migrate: overrideUrl" << overrideUrl;
if (!overrideUrl.isEmpty()) {
if (overrideUrl.endsWith('/')) {
overrideUrl.chop(1);
}
auto oCUrl = oCSettings->value(QLatin1String(urlC)).toString();
if (oCUrl.endsWith('/')) {
oCUrl.chop(1);
}

// in case the urls are equal reset the settings object to read from
// the ownCloud settings object
qCInfo(lcAccountManager) << "Migrate oC config if " << oCUrl << " == " << overrideUrl << ":"
<< (oCUrl == overrideUrl ? "Yes" : "No");
if (oCUrl == overrideUrl) {
qCInfo(lcAccountManager) << "Copy settings" << oCSettings->allKeys().join(", ");
settings = std::move(oCSettings);
}
} else {
qCInfo(lcAccountManager) << "Copy settings" << oCSettings->allKeys().join(", ");
settings = std::move(oCSettings);
}

break;
}
}
}
}

// Try to load the single account.
if (!settings->childKeys().isEmpty()) {
if (const auto acc = loadAccountHelper(*settings)) {
addAccount(acc);
return true;
settings->beginGroup(accountsC);
const auto childGroups = settings->childGroups();
for (const auto &accountId : childGroups) {
settings->beginGroup(accountId);
if (const auto acc = loadAccountHelper(*settings)) {
addAccount(acc);

return true;
}
}
}
return false;
Expand Down
122 changes: 77 additions & 45 deletions src/gui/folderman.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,11 @@
#include <QNetworkProxy>

namespace {
#ifndef VERSION_C
#define VERSION_C
constexpr auto versionC= "version";
#endif
constexpr auto accountsC = "Accounts";
constexpr auto foldersC = "Folders";
constexpr auto versionC = "version";
constexpr auto maxFoldersVersion = 1;
}
static const int maxFoldersVersion = 1;

namespace OCC {

Expand Down Expand Up @@ -347,7 +346,7 @@ int FolderMan::setupFoldersMigration()
{
ConfigFile cfg;
QDir storageDir(cfg.configPath());
_folderConfigPath = cfg.configPath() + QLatin1String("folders");
_folderConfigPath = cfg.configPath();

qCInfo(lcFolderMan) << "Setup folders from " << _folderConfigPath << "(migration)";

Expand Down Expand Up @@ -509,57 +508,90 @@ Folder *FolderMan::setupFolderFromOldConfigFile(const QString &file, AccountStat
// Check if the filename is equal to the group setting. If not, use the group
// name as an alias.
QStringList groups = settings.childGroups();
if (groups.isEmpty()) {
qCWarning(lcFolderMan) << "empty file:" << cfgFile.filePath();
return folder;
}

if (!groups.contains(escapedAlias) && groups.count() > 0) {
escapedAlias = groups.first();
if (!accountState) {
qCCritical(lcFolderMan) << "can't create folder without an account";
return nullptr;
}

settings.beginGroup(escapedAlias); // read the group with the same name as the file which is the folder alias
settings.beginGroup(accountsC);
const auto rootChildGroups = settings.childGroups();
for (const auto &accountId : rootChildGroups) {
qCDebug(lcFolderMan) << "try to migrate accountId:" << accountId;
settings.beginGroup(accountId);
settings.beginGroup(foldersC);

QString path = settings.value(QLatin1String("localPath")).toString();
QString backend = settings.value(QLatin1String("backend")).toString();
QString targetPath = settings.value(QLatin1String("targetPath")).toString();
bool paused = settings.value(QLatin1String("paused"), false).toBool();
// QString connection = settings.value( QLatin1String("connection") ).toString();
QString alias = unescapeAlias(escapedAlias);
if (settings.childGroups().isEmpty()) {
continue;
}

if (backend.isEmpty() || backend != QLatin1String("owncloud")) {
qCWarning(lcFolderMan) << "obsolete configuration of type" << backend;
return nullptr;
}
const auto childGroups = settings.childGroups();
for (const auto &alias : childGroups) {
settings.beginGroup(alias);
qCDebug(lcFolderMan) << "try to migrate folder alias:" << alias;

// cut off the leading slash, oCUrl always has a trailing.
if (targetPath.startsWith(QLatin1Char('/'))) {
targetPath.remove(0, 1);
}
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 (!accountState) {
qCCritical(lcFolderMan) << "can't create folder without an account";
return nullptr;
}
if (path.isEmpty()) {
qCDebug(lcFolderMan) << "localPath is empty";
settings.endGroup();
continue;
}

FolderDefinition folderDefinition;
folderDefinition.alias = alias;
folderDefinition.localPath = path;
folderDefinition.targetPath = targetPath;
folderDefinition.paused = paused;
folderDefinition.ignoreHiddenFiles = ignoreHiddenFiles();
if (targetPath.isEmpty()) {
qCDebug(lcFolderMan) << "targetPath is empty";
settings.endGroup();
continue;
}

folder = addFolderInternal(folderDefinition, accountState, std::make_unique<VfsOff>());
if (folder) {
QStringList blackList = settings.value(QLatin1String("blackList")).toStringList();
if (!blackList.empty()) {
//migrate settings
folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, blackList);
settings.remove(QLatin1String("blackList"));
// FIXME: If you remove this codepath, you need to provide another way to do
// this via theme.h or the normal FolderMan::setupFolders
if (journalPath.isEmpty()) {
qCDebug(lcFolderMan) << "journalPath 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;

folder = addFolderInternal(folderDefinition, accountState, std::make_unique<VfsOff>());
if (folder) {
const auto blackList = settings.value(QLatin1String("blackList")).toStringList();
if (!blackList.empty()) {
//migrate settings
folder->journalDb()->setSelectiveSyncList(SyncJournalDb::SelectiveSyncBlackList, blackList);
settings.remove(QLatin1String("blackList"));
// FIXME: If you remove this codepath, you need to provide another way to do
// this via theme.h or the normal FolderMan::setupFolders
}

folder->saveToSettings();
}
qCInfo(lcFolderMan) << "Migrated!" << folder;
settings.sync();

if (folder) {
return folder;
}

settings.endGroup();
}

folder->saveToSettings();
settings.endGroup();
settings.endGroup();
}
qCInfo(lcFolderMan) << "Migrated!" << folder;
settings.sync();
return folder;
}

Expand Down

0 comments on commit 04ec5ac

Please sign in to comment.