Skip to content

Commit

Permalink
Merge pull request #6790 from nextcloud/feature/update-channel-2
Browse files Browse the repository at this point in the history
 Add new update channels part 2.
  • Loading branch information
camilasan authored Jul 4, 2024
2 parents 14a5f4c + 9bd4ef1 commit cb47b1b
Show file tree
Hide file tree
Showing 10 changed files with 149 additions and 10 deletions.
4 changes: 4 additions & 0 deletions src/gui/accountmanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ constexpr auto legacyCfgFileNameC = "owncloud.cfg";
// The maximum versions that this client can read
constexpr auto maxAccountsVersion = 2;
constexpr auto maxAccountVersion = 1;

constexpr auto serverHasValidSubscriptionC = "serverHasValidSubscription";
}


Expand Down Expand Up @@ -321,6 +323,8 @@ void AccountManager::saveAccountHelper(Account *acc, QSettings &settings, bool s
settings.setValue(QLatin1String(serverVersionC), acc->_serverVersion);
settings.setValue(QLatin1String(serverColorC), acc->_serverColor);
settings.setValue(QLatin1String(serverTextColorC), acc->_serverTextColor);
settings.setValue(QLatin1String(serverHasValidSubscriptionC), acc->capabilities().serverHasValidSubscription());

if (!acc->_skipE2eeMetadataChecksumValidation) {
settings.remove(QLatin1String(skipE2eeMetadataChecksumValidationC));
} else {
Expand Down
20 changes: 16 additions & 4 deletions src/gui/generalsettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ void GeneralSettings::loadMiscSettings()
_ui->monoIconsCheckBox->setChecked(cfgFile.monoIcons());

#if defined(BUILD_UPDATER)
auto validUpdateChannels = cfgFile.validUpdateChannels();
const auto validUpdateChannels = cfgFile.validUpdateChannels();
_ui->updateChannel->addItems(validUpdateChannels);
const auto currentUpdateChannelIndex = validUpdateChannels.indexOf(cfgFile.currentUpdateChannel());
_ui->updateChannel->setCurrentIndex(currentUpdateChannelIndex != -1? currentUpdateChannelIndex : 0);
Expand Down Expand Up @@ -359,6 +359,10 @@ void GeneralSettings::slotUpdateChannelChanged()
return tr("daily");
}

if (channel == QStringLiteral("enterprise")) {
return tr("enterprise");
}

return QString{};
};

Expand All @@ -370,24 +374,32 @@ void GeneralSettings::slotUpdateChannelChanged()
case 2:
return QStringLiteral("daily");
break;
case 3:
return QStringLiteral("enterprise");
break;
default:
return QStringLiteral("stable");
}
};

ConfigFile configFile;
const auto channel = updateChannelFromLocalized(_ui->updateChannel->currentIndex());
if (channel == ConfigFile().currentUpdateChannel()) {
if (channel == configFile.currentUpdateChannel()) {
return;
}

const auto enterprise = configFile.validUpdateChannels().contains("enterprise") ? tr("- enterprise: contains stable versions for customers.\n",
"description of enterprise update channel for enterprise customers")
: "";
auto msgBox = new QMessageBox(
QMessageBox::Warning,
tr("Changing update channel?"),
tr("The channel determines which upgrades will be offered to install:\n"
"- stable: contains tested versions considered reliable\n"
"- beta: contains versions with new features that may not be tested thoroughly\n"
"- daily: contains versions created daily only for testing and development\n\n"
"Downgrading versions is not possible immediately: changing from beta to stable means waiting for the new stable version."),
"- daily: contains versions created daily only for testing and development\n"
"%1\n"
"Downgrading versions is not possible immediately: changing from beta to stable means waiting for the new stable version.").arg(enterprise),
QMessageBox::NoButton,
this);
const auto acceptButton = msgBox->addButton(tr("Change update channel"), QMessageBox::AcceptRole);
Expand Down
21 changes: 21 additions & 0 deletions src/libsync/account.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -689,6 +689,8 @@ void Account::setCapabilities(const QVariantMap &caps)
_capabilities = Capabilities(caps);

updateServerColors();
updateServerSubcription();
updateDesktopEnterpriseChannel();

emit capabilitiesChanged();

Expand Down Expand Up @@ -1068,4 +1070,23 @@ void Account::setAskUserForMnemonic(const bool ask)
emit askUserForMnemonicChanged();
}

void Account::updateServerSubcription()
{
ConfigFile currentConfig;
if (const auto serverHasValidSubscription = _capabilities.serverHasValidSubscription();
serverHasValidSubscription != currentConfig.serverHasValidSubscription()) {
currentConfig.setServerHasValidSubscription(serverHasValidSubscription);
}
}

void Account::updateDesktopEnterpriseChannel()
{
ConfigFile currentConfig;
if (const auto desktopEnterpriseChannel = _capabilities.desktopEnterpriseChannel();
desktopEnterpriseChannel != currentConfig.desktopEnterpriseChannel()) {
currentConfig.setDesktopEnterpriseChannel(desktopEnterpriseChannel);
}
}


} // namespace OCC
3 changes: 3 additions & 0 deletions src/libsync/account.h
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,9 @@ class OWNCLOUDSYNC_EXPORT Account : public QObject

[[nodiscard]] bool askUserForMnemonic() const;

void updateServerSubcription();
void updateDesktopEnterpriseChannel();

public slots:
/// Used when forgetting credentials
void clearQNAMCache();
Expand Down
11 changes: 11 additions & 0 deletions src/libsync/capabilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
*/

#include "capabilities.h"
#include "configfile.h"

#include <QVariantMap>
#include <QLoggingCategory>
Expand Down Expand Up @@ -388,6 +389,16 @@ bool Capabilities::groupFoldersAvailable() const
return _capabilities[QStringLiteral("groupfolders")].toMap().value(QStringLiteral("hasGroupFolders"), false).toBool();
}

bool Capabilities::serverHasValidSubscription() const
{
return _capabilities[QStringLiteral("support")].toMap().value(QStringLiteral("hasValidSubscription"), false).toBool();
}

QString Capabilities::desktopEnterpriseChannel() const
{
return _capabilities[QStringLiteral("support")].toMap().value(QStringLiteral("desktopEnterpriseChannel"), ConfigFile().defaultUpdateChannel()).toString();
}

QStringList Capabilities::blacklistedFiles() const
{
return _capabilities["files"].toMap()["blacklisted_files"].toStringList();
Expand Down
3 changes: 3 additions & 0 deletions src/libsync/capabilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,9 @@ class OWNCLOUDSYNC_EXPORT Capabilities

[[nodiscard]] bool groupFoldersAvailable() const;

[[nodiscard]] bool serverHasValidSubscription() const;
[[nodiscard]] QString desktopEnterpriseChannel() const;

// Direct Editing
void addDirectEditor(DirectEditor* directEditor);
DirectEditor* getDirectEditorForMimetype(const QMimeType &mimeType);
Expand Down
60 changes: 55 additions & 5 deletions src/libsync/configfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,13 @@ static constexpr char forceLoginV2C[] = "forceLoginV2";
static constexpr char certPath[] = "http_certificatePath";
static constexpr char certPasswd[] = "http_certificatePasswd";

static const QStringList validUpdateChannelsList { QStringLiteral("stable"), QStringLiteral("beta"), QStringLiteral("daily") };
static constexpr char defaultUpdateChannelName[] = "stable";
static constexpr char serverHasValidSubscriptionC[] = "serverHasValidSubscription";
static constexpr char desktopEnterpriseChannelName[] = "desktopEnterpriseChannel";

static const QStringList defaultUpdateChannelsList { QStringLiteral("stable"), QStringLiteral("beta"), QStringLiteral("daily") };
static const QString defaultUpdateChannelName = "stable";
static const QStringList enterpriseUpdateChannelsList { QStringLiteral("stable"), QStringLiteral("enterprise") };
static const QString defaultEnterpriseChannel = "enterprise";
}

namespace OCC {
Expand Down Expand Up @@ -689,17 +694,37 @@ int ConfigFile::updateSegment() const

QStringList ConfigFile::validUpdateChannels() const
{
return validUpdateChannelsList;
const auto isBranded = Theme::instance()->isBranded();

if (isBranded) {
return { defaultUpdateChannelName };
}

if (serverHasValidSubscription()) {
return enterpriseUpdateChannelsList;
}

return defaultUpdateChannelsList;
}

QString ConfigFile::defaultUpdateChannel() const
{
const auto isBranded = Theme::instance()->isBranded();
if (serverHasValidSubscription() && !isBranded) {
if (const auto serverChannel = desktopEnterpriseChannel();
validUpdateChannels().contains(serverChannel)) {
qCWarning(lcConfigFile()) << "Enforcing update channel" << serverChannel << "because that is the desktop enterprise channel returned by the server.";
return serverChannel;
}
}

if (const auto currentVersionSuffix = Theme::instance()->versionSuffix();
validUpdateChannels().contains(currentVersionSuffix)) {
validUpdateChannels().contains(currentVersionSuffix) && !isBranded) {
qCWarning(lcConfigFile()) << "Enforcing update channel" << currentVersionSuffix << "because of the version suffix of the current client.";
return currentVersionSuffix;
}

qCWarning(lcConfigFile()) << "Enforcing default update channel" << defaultUpdateChannelName;
return defaultUpdateChannelName;
}

Expand All @@ -721,7 +746,7 @@ void ConfigFile::setUpdateChannel(const QString &channel)
if (!validUpdateChannels().contains(channel)) {
qCWarning(lcConfigFile()) << "Received invalid update channel:"
<< channel
<< "can only accept 'stable', 'beta' or 'daily'. Ignoring.";
<< "can only accept" << validUpdateChannels() << ". Ignoring.";
return;
}

Expand Down Expand Up @@ -1176,6 +1201,31 @@ void ConfigFile::setLaunchOnSystemStartup(const bool autostart)
settings.setValue(QLatin1String(launchOnSystemStartupC), autostart);
}

bool ConfigFile::serverHasValidSubscription() const
{
QSettings settings(configFile(), QSettings::IniFormat);
return settings.value(QLatin1String(serverHasValidSubscriptionC), false).toBool();
}

void ConfigFile::setServerHasValidSubscription(const bool valid)
{
QSettings settings(configFile(), QSettings::IniFormat);
settings.setValue(QLatin1String(serverHasValidSubscriptionC), valid);
}

QString ConfigFile::desktopEnterpriseChannel() const
{
QSettings settings(configFile(), QSettings::IniFormat);
return settings.value(QLatin1String(desktopEnterpriseChannelName), defaultUpdateChannel()).toString();
}

void ConfigFile::setDesktopEnterpriseChannel(const QString &channel)
{
QSettings settings(configFile(), QSettings::IniFormat);
settings.setValue(QLatin1String(desktopEnterpriseChannelName), channel);
}


Q_GLOBAL_STATIC(QString, g_configFileName)

std::unique_ptr<QSettings> ConfigFile::settingsWithGroup(const QString &group, QObject *parent)
Expand Down
6 changes: 6 additions & 0 deletions src/libsync/configfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,12 @@ class OWNCLOUDSYNC_EXPORT ConfigFile
[[nodiscard]] bool launchOnSystemStartup() const;
void setLaunchOnSystemStartup(const bool autostart);

[[nodiscard]] bool serverHasValidSubscription() const;
void setServerHasValidSubscription(bool valid);

[[nodiscard]] QString desktopEnterpriseChannel() const;
void setDesktopEnterpriseChannel(const QString &channel);

/** Returns a new settings pre-set in a specific group. The Settings will be created
with the given parent. If no parent is specified, the caller must destroy the settings */
static std::unique_ptr<QSettings> settingsWithGroup(const QString &group, QObject *parent = nullptr);
Expand Down
2 changes: 1 addition & 1 deletion src/libsync/theme.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ QString Theme::statusHeaderText(SyncResult::Status status) const

bool Theme::isBranded() const
{
return appNameGUI() != QStringLiteral("Nextcloud");
return (appNameGUI() != QStringLiteral("Nextcloud") && NEXTCLOUD_DEV == 0);
}

QString Theme::appNameGUI() const
Expand Down
29 changes: 29 additions & 0 deletions test/testcapabilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,35 @@ private slots:

QCOMPARE(filesLockAvailable, true);
}

void testSupport_hasValidSubscription_returnTrue()
{
QVariantMap supportMap;
supportMap["hasValidSubscription"] = "true";

QVariantMap capabilitiesMap;
capabilitiesMap["support"] = supportMap;

const auto &capabilities = OCC::Capabilities(capabilitiesMap);
const auto serverHasValidSubscription = capabilities.serverHasValidSubscription();

QCOMPARE(serverHasValidSubscription, true);
}

void testSupport_desktopEnterpriseChannel_returnString()
{
QVariantMap supportMap;
const auto defaultChannel = "stable";
supportMap["desktopEnterpriseChannel"] = defaultChannel;

QVariantMap capabilitiesMap;
capabilitiesMap["support"] = supportMap;

const auto &capabilities = OCC::Capabilities(capabilitiesMap);
const auto enterpriseChannel = capabilities.desktopEnterpriseChannel();

QCOMPARE(enterpriseChannel, defaultChannel);
}
};

QTEST_GUILESS_MAIN(TestCapabilities)
Expand Down

0 comments on commit cb47b1b

Please sign in to comment.