Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 88 additions & 13 deletions src/gui/accountmanager.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/*
* SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2015 ownCloud GmbH
Expand Down Expand Up @@ -72,10 +72,6 @@
constexpr auto unbrandedRelativeConfigLocationC = "/Nextcloud/nextcloud.cfg";
constexpr auto unbrandedCfgFileNameC = "nextcloud.cfg";

// The maximum versions that this client can read
constexpr auto maxAccountsVersion = 13;
constexpr auto maxAccountVersion = 13;

constexpr auto serverHasValidSubscriptionC = "serverHasValidSubscription";

constexpr auto generalC = "General";
Expand All @@ -84,7 +80,18 @@

namespace OCC {

namespace {
template<typename VersionType>
inline VersionType VersionFromSetting(QSettings *settings) {

Check warning on line 85 in src/gui/accountmanager.cpp

View workflow job for this annotation

GitHub Actions / build

src/gui/accountmanager.cpp:85:24 [modernize-use-trailing-return-type]

use a trailing return type for this function
return settings->value(QLatin1String(versionC), int(VersionType::Min)).value<VersionType>();
}
template<typename VersionType>
inline void VersionToSetting(QSettings *settings, VersionType version) {
settings->setValue(QLatin1String(versionC), int(version));
}
}

Q_LOGGING_CATEGORY(lcAccountManager, "nextcloud.gui.account.manager", QtInfoMsg)

Check warning on line 94 in src/gui/accountmanager.cpp

View workflow job for this annotation

GitHub Actions / build

src/gui/accountmanager.cpp:94:1 [cppcoreguidelines-avoid-non-const-global-variables]

variable 'Q_LOGGING_CATEGORY' is non-const and globally accessible, consider making it const

AccountManager *AccountManager::instance()
{
Expand Down Expand Up @@ -149,35 +156,50 @@
}

ConfigFile().cleanupGlobalNetworkConfiguration();
ClientProxy().cleanupGlobalNetworkConfiguration();
ClientProxy().cleanupGlobalNetworkConfiguration();

return result;
}

void AccountManager::backwardMigrationSettingsKeys(QStringList *deleteKeys, QStringList *ignoreKeys)
{
const auto settings = ConfigFile::settingsWithGroup(QLatin1String(accountsC));
const auto accountsVersion = settings->value(QLatin1String(versionC)).toInt();
const auto accountsVersion = VersionFromSetting<AccountsVersion>(settings.get());

qCInfo(lcAccountManager) << "Checking for accounts versions.";
qCInfo(lcAccountManager) << "Config accounts version:" << accountsVersion;
qCInfo(lcAccountManager) << "Max accounts Version is set to:" << maxAccountsVersion;
if (accountsVersion <= maxAccountsVersion) {
qCInfo(lcAccountManager) << "Max accounts Version is set to:" << AccountsVersion::Max;
if (accountsVersion <= AccountsVersion::Max) {
const auto settingsChildGroups = settings->childGroups();
for (const auto &accountId : settingsChildGroups) {
settings->beginGroup(accountId);
const auto accountVersion = settings->value(QLatin1String(versionC), 1).toInt();
const auto accountVersion = VersionFromSetting<AccountVersion>(settings.get());

if (accountVersion > maxAccountVersion) {
if (accountVersion > AccountVersion::Max) {
ignoreKeys->append(settings->group());
qCInfo(lcAccountManager) << "Ignoring account" << accountId << "because of version" << accountVersion;
}

settings->endGroup();
}
} else {
deleteKeys->append(settings->group());
}
}

void AccountManager::migrateToActualVersion()
{
const auto settings = ConfigFile::settingsWithGroup(QLatin1String(accountsC));

migrateAccountsSettings(settings);

for (const auto &accountId : settings->childGroups()) {
settings->beginGroup(accountId);
migrateAccountSettings(settings);
settings->endGroup();
}
}

#if !DISABLE_ACCOUNT_MIGRATION
bool AccountManager::restoreFromLegacySettings()
{
Expand Down Expand Up @@ -317,7 +339,7 @@
moveNetworkSettingsFromGlobalToAccount(acc);
}
configFile.cleanupGlobalNetworkConfiguration();
ClientProxy().cleanupGlobalNetworkConfiguration();
ClientProxy().cleanupGlobalNetworkConfiguration();
return true;
}

Expand All @@ -339,7 +361,9 @@
void AccountManager::save(bool saveCredentials)
{
const auto settings = ConfigFile::settingsWithGroup(QLatin1String(accountsC));
settings->setValue(QLatin1String(versionC), maxAccountsVersion);

VersionToSetting(settings.get(), AccountsVersion::Max);

for (const auto &acc : std::as_const(_accounts)) {
settings->beginGroup(acc->account()->id());
saveAccountHelper(acc->account(), *settings, saveCredentials);
Expand Down Expand Up @@ -376,7 +400,7 @@
void AccountManager::saveAccountHelper(const AccountPtr &account, QSettings &settings, bool saveCredentials)
{
qCDebug(lcAccountManager) << "Saving settings to" << settings.fileName();
settings.setValue(QLatin1String(versionC), maxAccountVersion);
VersionToSetting(&settings, AccountVersion::Max);
if (account->isPublicShareLink()) {
settings.setValue(QLatin1String(urlC), account->publicShareLinkUrl().toString());
} else {
Expand Down Expand Up @@ -798,4 +822,55 @@
_forceLegacyImport = forceLegacyImport;
Q_EMIT forceLegacyImportChanged();
}

void AccountManager::migrateAccountsSettings(const std::unique_ptr<QSettings> &settings)
{
const auto accountsVersion = VersionFromSetting<AccountsVersion>(settings.get());

switch (accountsVersion) {
// Nothing here for now
default:
VersionToSetting(settings.get(), AccountsVersion::Max);
break;
}
}

void AccountManager::migrateAccountSettings(const std::unique_ptr<QSettings> &settings)
{
const auto accountVersion = VersionFromSetting<AccountVersion>(settings.get());

switch (accountVersion)
{
// No previous statements
case AccountVersion::V13: {
// Related to issue #9037
const auto networkLimitSettingFix = [&settings](const QString &key) {
using NetworkLimitSetting = Account::AccountNetworkTransferLimitSetting;

const auto limitSetting = settings->value(key).value<NetworkLimitSetting>();

switch (limitSetting) {
case NetworkLimitSetting::LegacyGlobalLimit:
[[fallthrough]];
case NetworkLimitSetting::AutoLimit:
settings->setValue(key, int(NetworkLimitSetting::NoLimit));
break;
default:
break;
}
};

qCInfo(lcAccountManager) << "Migrating account" << settings->group()
<< "settings from version" << accountVersion
<< "to" << AccountVersion::V14;

networkLimitSettingFix(networkDownloadLimitSettingC);
networkLimitSettingFix(networkUploadLimitSettingC);
} [[fallthrough]];
// Tip: add new migration rules here
default:
VersionToSetting(settings.get(), AccountVersion::Max);
break;
}
}
}
24 changes: 24 additions & 0 deletions src/gui/accountmanager.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
/*
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
* SPDX-FileCopyrightText: 2015 ownCloud GmbH
Expand All @@ -6,7 +6,7 @@

#pragma once

#include "account.h"

Check failure on line 9 in src/gui/accountmanager.h

View workflow job for this annotation

GitHub Actions / build

src/gui/accountmanager.h:9:10 [clang-diagnostic-error]

'account.h' file not found
#include "accountstate.h"

namespace OCC {
Expand All @@ -31,6 +31,21 @@
};
Q_ENUM (AccountsRestoreResult);

enum class AccountsVersion {
V13 = 13,
Min = V13,
Max = V13
};
Q_ENUM (AccountsVersion);

enum class AccountVersion {
V13 = 13,
V14,
Min = V13,
Max = V14
};
Q_ENUM (AccountVersion);

static AccountManager *instance();
~AccountManager() override = default;

Expand Down Expand Up @@ -83,6 +98,12 @@
*/
static void backwardMigrationSettingsKeys(QStringList *deleteKeys, QStringList *ignoreKeys);

/**
* Checks the versions of account groups and each account individually
* then attempts a soft migration.
*/
static void migrateToActualVersion();

public slots:
/// Saves account data when adding user, when updating e.g. dav user, not including the credentials
void saveAccount(const OCC::AccountPtr &newAccountData);
Expand Down Expand Up @@ -110,6 +131,9 @@
void capabilitiesChanged();

private:
static void migrateAccountsSettings(const std::unique_ptr<QSettings> &settings);
static void migrateAccountSettings(const std::unique_ptr<QSettings> &settings);

// saving and loading Account to settings
void saveAccountHelper(const AccountPtr &account, QSettings &settings, bool saveCredentials = true);
AccountPtr loadAccountHelper(QSettings &settings);
Expand Down
36 changes: 21 additions & 15 deletions src/gui/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,14 +141,6 @@ bool Application::configVersionMigration()
return true;
}

// 'Launch on system startup' defaults to true > 3.11.x
const auto theme = Theme::instance();
configFile.setLaunchOnSystemStartup(configFile.launchOnSystemStartup());
Utility::setLaunchOnStartup(theme->appName(), theme->appNameGUI(), configFile.launchOnSystemStartup());

// default is now off to displaying dialog warning user of too many files deletion
configFile.setPromptDeleteFiles(false);

// back up all old config files
QStringList backupFilesList;
QDir configDir(configFile.configPath());
Expand Down Expand Up @@ -190,15 +182,27 @@ bool Application::configVersionMigration()
}
}

if (!deleteKeys.isEmpty()) {
auto settings = ConfigFile::settingsWithGroup("foo");
settings->endGroup();
if (downgrading) {
// 'Launch on system startup' defaults to true > 3.11.x
const auto theme = Theme::instance();
configFile.setLaunchOnSystemStartup(configFile.launchOnSystemStartup());
Utility::setLaunchOnStartup(theme->appName(), theme->appNameGUI(), configFile.launchOnSystemStartup());

// default is now off to displaying dialog warning user of too many files deletion
configFile.setPromptDeleteFiles(false);

// 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.";
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.";
}
}
} else { // upgrading
AccountManager::migrateToActualVersion();
}

configFile.setClientVersionString(MIRALL_VERSION_STRING);
Expand Down Expand Up @@ -323,6 +327,8 @@ Application::Application(int &argc, char **argv)
// only copy the settings and check what should be skipped
if (!configVersionMigration()) {
qCWarning(lcApplication) << "Config version migration was not possible.";
} else {
AccountManager::instance()->save();
}

ConfigFile cfg;
Expand Down
28 changes: 16 additions & 12 deletions src/gui/networksettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,36 +198,40 @@

void NetworkSettings::saveBWLimitSettings()
{
using NetworkTransferLimitSetting = Account::AccountNetworkTransferLimitSetting;

const auto downloadLimit = _ui->downloadSpinBox->value();
const auto uploadLimit = _ui->uploadSpinBox->value();

auto useDownloadLimit = 0;
auto useUploadLimit = 0;
auto useDownloadLimit = NetworkTransferLimitSetting::NoLimit;
auto useUploadLimit = NetworkTransferLimitSetting::NoLimit;

if (_ui->downloadLimitRadioButton->isChecked()) {

Check warning on line 209 in src/gui/networksettings.cpp

View workflow job for this annotation

GitHub Actions / build

src/gui/networksettings.cpp:209:53 [bugprone-branch-clone]

repeated branch in conditional chain
useDownloadLimit = 1;
useDownloadLimit = NetworkTransferLimitSetting::ManualLimit;
} else if (_ui->noDownloadLimitRadioButton->isChecked()) {
useDownloadLimit = 0;
useDownloadLimit = NetworkTransferLimitSetting::NoLimit;
} else if (_ui->autoDownloadLimitRadioButton->isChecked()) {
useDownloadLimit = -1;
useDownloadLimit = NetworkTransferLimitSetting::AutoLimit;
} else if (_account) {
useDownloadLimit = -2;
// Legacy global. See Account::AccountNetworkTransferLimitSetting::LegacyGlobalLimit
useDownloadLimit = NetworkTransferLimitSetting::NoLimit;
}

if (_ui->uploadLimitRadioButton->isChecked()) {

Check warning on line 220 in src/gui/networksettings.cpp

View workflow job for this annotation

GitHub Actions / build

src/gui/networksettings.cpp:220:51 [bugprone-branch-clone]

repeated branch in conditional chain
useUploadLimit = 1;
useUploadLimit = NetworkTransferLimitSetting::ManualLimit;
} else if (_ui->noUploadLimitRadioButton->isChecked()) {
useUploadLimit = 0;
useUploadLimit = NetworkTransferLimitSetting::NoLimit;
} else if (_ui->autoUploadLimitRadioButton->isChecked()) {
useUploadLimit = -1;
useUploadLimit = NetworkTransferLimitSetting::AutoLimit;
} else if (_account) {
useUploadLimit = -2;
// Legacy global. See Account::AccountNetworkTransferLimitSetting::LegacyGlobalLimit
useUploadLimit = NetworkTransferLimitSetting::NoLimit;
}

if (_account) {
_account->setDownloadLimitSetting(static_cast<Account::AccountNetworkTransferLimitSetting>(useDownloadLimit));
_account->setDownloadLimitSetting(useDownloadLimit);
_account->setDownloadLimit(downloadLimit);
_account->setUploadLimitSetting(static_cast<Account::AccountNetworkTransferLimitSetting>(useUploadLimit));
_account->setUploadLimitSetting(useUploadLimit);
_account->setUploadLimit(uploadLimit);
AccountManager::instance()->saveAccount(_account);
}
Expand Down
Loading