Skip to content

Commit 848f6a1

Browse files
authored
Merge pull request #9139 from nextcloud/bugfix/enforceEnterpriseUpdateChannel
Bugfix/enforce enterprise update channel
2 parents cbd529f + 8463862 commit 848f6a1

File tree

11 files changed

+345
-47
lines changed

11 files changed

+345
-47
lines changed

src/gui/accountmanager.cpp

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ constexpr auto maxAccountsVersion = 13;
7878
constexpr auto maxAccountVersion = 13;
7979

8080
constexpr auto serverHasValidSubscriptionC = "serverHasValidSubscription";
81+
constexpr auto serverDesktopEnterpriseUpdateChannelC = "desktopEnterpriseChannel";
8182

8283
constexpr auto generalC = "General";
8384
}
@@ -424,6 +425,7 @@ void AccountManager::saveAccountHelper(const AccountPtr &account, QSettings &set
424425
settings.setValue(QLatin1String(serverColorC), account->_serverColor);
425426
settings.setValue(QLatin1String(serverTextColorC), account->_serverTextColor);
426427
settings.setValue(QLatin1String(serverHasValidSubscriptionC), account->serverHasValidSubscription());
428+
settings.setValue(QLatin1String(serverDesktopEnterpriseUpdateChannelC), account->enterpriseUpdateChannel().toString());
427429
settings.setValue(QLatin1String(encryptionCertificateSha256FingerprintC), account->encryptionCertificateFingerprint());
428430
if (!account->_skipE2eeMetadataChecksumValidation) {
429431
settings.remove(QLatin1String(skipE2eeMetadataChecksumValidationC));
@@ -757,10 +759,9 @@ void AccountManager::deleteAccount(OCC::AccountState *account)
757759

758760
account->account()->deleteAppToken();
759761

760-
// clean up config from subscriptions if the account removed was the only with valid subscription
761-
if (account->account()->serverHasValidSubscription()) {
762-
updateServerHasValidSubscriptionConfig();
763-
}
762+
// clean up config from subscriptions and enterprise channel
763+
updateServerHasValidSubscriptionConfig();
764+
updateServerDesktopEnterpriseUpdateChannel();
764765

765766
emit accountSyncConnectionRemoved(account);
766767
emit accountRemoved(account);
@@ -770,15 +771,28 @@ void AccountManager::updateServerHasValidSubscriptionConfig()
770771
{
771772
auto serverHasValidSubscription = false;
772773
for (const auto &account : std::as_const(_accounts)) {
773-
if (!account->account()->serverHasValidSubscription()) {
774-
continue;
774+
if (account->account()->serverHasValidSubscription()) {
775+
serverHasValidSubscription = true;
776+
break;
775777
}
778+
}
779+
780+
if (ConfigFile().serverHasValidSubscription() != serverHasValidSubscription) {
781+
ConfigFile().setServerHasValidSubscription(serverHasValidSubscription);
782+
}
783+
}
776784

777-
serverHasValidSubscription = true;
778-
break;
785+
void AccountManager::updateServerDesktopEnterpriseUpdateChannel()
786+
{
787+
UpdateChannel most_stable_channel = UpdateChannel::Invalid;
788+
for (const auto &account : std::as_const(_accounts)) {
789+
if (const auto accounts_channel = account->account()->enterpriseUpdateChannel();
790+
account->account()->serverHasValidSubscription() && accounts_channel > most_stable_channel) {
791+
most_stable_channel = accounts_channel;
792+
}
779793
}
780794

781-
ConfigFile().setServerHasValidSubscription(serverHasValidSubscription);
795+
ConfigFile().setDesktopEnterpriseChannel(most_stable_channel.toString());
782796
}
783797

784798
AccountPtr AccountManager::createAccount()
@@ -842,10 +856,8 @@ void AccountManager::addAccountState(AccountState *const accountState)
842856
_accounts << ptr;
843857
ptr->trySignIn();
844858

845-
// update config subscriptions if the account added is the only with valid subscription
846-
if (accountState->account()->serverHasValidSubscription() && !ConfigFile().serverHasValidSubscription()) {
847-
updateServerHasValidSubscriptionConfig();
848-
}
859+
updateServerHasValidSubscriptionConfig();
860+
updateServerDesktopEnterpriseUpdateChannel();
849861

850862
emit accountAdded(accountState);
851863
}

src/gui/accountmanager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ public slots:
126126

127127
// update config serverHasValidSubscription when accounts list changes
128128
void updateServerHasValidSubscriptionConfig();
129+
void updateServerDesktopEnterpriseUpdateChannel();
129130

130131
AccountManager() = default;
131132
QList<AccountStatePtr> _accounts;

src/gui/application.cpp

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,25 @@
99
#include <iostream>
1010
#include <random>
1111

12-
#include "config.h"
1312
#include "account.h"
13+
#include "accountmanager.h"
1414
#include "accountsetupcommandlinemanager.h"
1515
#include "accountstate.h"
16-
#include "editlocallymanager.h"
16+
#include "clientproxy.h"
17+
#include "config.h"
18+
#include "configfile.h"
1719
#include "connectionvalidator.h"
20+
#include "creds/abstractcredentials.h"
21+
#include "editlocallymanager.h"
1822
#include "folder.h"
1923
#include "folderman.h"
2024
#include "logger.h"
21-
#include "configfile.h"
25+
#include "pushnotifications.h"
26+
#include "shellextensionsserver.h"
2227
#include "socketapi/socketapi.h"
2328
#include "sslerrordialog.h"
2429
#include "theme.h"
25-
#include "clientproxy.h"
26-
#include "accountmanager.h"
27-
#include "creds/abstractcredentials.h"
28-
#include "pushnotifications.h"
29-
#include "shellextensionsserver.h"
30+
#include "updatechannel.h"
3031

3132
#if defined(BUILD_UPDATER)
3233
#include "updater/ocupdater.h"
@@ -294,6 +295,10 @@ Application::Application(int &argc, char **argv)
294295
setupConfigFile();
295296
}
296297

298+
// In the config, set the enterprise update channel to invalid, so it can be bumped up
299+
// when recieving server capabilities.
300+
ConfigFile().setDesktopEnterpriseChannel(UpdateChannel::Invalid.toString());
301+
297302
if (_theme->doNotUseProxy()) {
298303
ConfigFile().setProxyType(QNetworkProxy::NoProxy);
299304
const auto &allAccounts = AccountManager::instance()->accounts();

src/libsync/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ set(libsync_SRCS
5858
helpers.cpp
5959
httplogger.h
6060
httplogger.cpp
61+
updatechannel.h
62+
updatechannel.cpp
6163
logger.h
6264
logger.cpp
6365
accessmanager.h

src/libsync/account.cpp

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "networkjobs.h"
1717
#include "pushnotifications.h"
1818
#include "theme.h"
19+
#include "updatechannel.h"
1920
#include "version.h"
2021

2122
#include "deletejob.h"
@@ -1272,6 +1273,16 @@ void Account::setServerHasValidSubscription(bool valid)
12721273
_serverHasValidSubscription = valid;
12731274
}
12741275

1276+
UpdateChannel Account::enterpriseUpdateChannel() const
1277+
{
1278+
return _enterpriseUpdateChannel;
1279+
}
1280+
1281+
void Account::setEnterpriseUpdateChannel(const UpdateChannel &channel)
1282+
{
1283+
_enterpriseUpdateChannel = channel;
1284+
}
1285+
12751286
void Account::updateServerSubcription()
12761287
{
12771288
ConfigFile currentConfig;
@@ -1286,10 +1297,13 @@ void Account::updateServerSubcription()
12861297

12871298
void Account::updateDesktopEnterpriseChannel()
12881299
{
1300+
const auto capabilityEnterpriseChannel = UpdateChannel::fromString(_capabilities.desktopEnterpriseChannel());
1301+
_enterpriseUpdateChannel = capabilityEnterpriseChannel;
1302+
12891303
ConfigFile currentConfig;
1290-
if (const auto desktopEnterpriseChannel = _capabilities.desktopEnterpriseChannel();
1291-
desktopEnterpriseChannel != currentConfig.desktopEnterpriseChannel()) {
1292-
currentConfig.setDesktopEnterpriseChannel(desktopEnterpriseChannel);
1304+
const auto configEnterpriseChannel = UpdateChannel::fromString(currentConfig.desktopEnterpriseChannel());
1305+
if (capabilityEnterpriseChannel > configEnterpriseChannel) {
1306+
currentConfig.setDesktopEnterpriseChannel(capabilityEnterpriseChannel.toString());
12931307
}
12941308
}
12951309

src/libsync/account.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@
1212
#include "clientsideencryption.h"
1313
#include "clientstatusreporting.h"
1414
#include "common/utility.h"
15-
#include "syncfileitem.h"
1615
#include "common/vfs.h"
16+
#include "syncfileitem.h"
17+
#include "updatechannel.h"
1718

1819
#include <QByteArray>
1920
#include <QUrl>
@@ -411,6 +412,9 @@ class OWNCLOUDSYNC_EXPORT Account : public QObject
411412
[[nodiscard]] bool serverHasValidSubscription() const;
412413
void setServerHasValidSubscription(bool valid);
413414

415+
[[nodiscard]] UpdateChannel enterpriseUpdateChannel() const;
416+
void setEnterpriseUpdateChannel(const UpdateChannel &channel);
417+
414418
[[nodiscard]] bool enforceUseHardwareTokenEncryption() const;
415419

416420
[[nodiscard]] QString encryptionHardwareTokenDriverPath() const;
@@ -577,6 +581,7 @@ private slots:
577581
unsigned int _uploadLimit = 0;
578582
unsigned int _downloadLimit = 0;
579583
bool _serverHasValidSubscription = false;
584+
UpdateChannel _enterpriseUpdateChannel = UpdateChannel::Invalid;
580585
QByteArray _encryptionCertificateFingerprint;
581586

582587
/* IMPORTANT - remove later - FIXME MS@2019-12-07 -->

src/libsync/configfile.cpp

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,16 @@
44
* SPDX-License-Identifier: GPL-2.0-or-later
55
*/
66

7-
#include "config.h"
8-
97
#include "configfile.h"
10-
#include "theme.h"
11-
#include "version.h"
12-
#include "common/utility.h"
13-
#include "common/asserts.h"
14-
#include "version.h"
158

16-
#include "creds/abstractcredentials.h"
9+
#include "common/asserts.h"
10+
#include "common/utility.h"
11+
#include "config.h"
1712
#include "creds/keychainchunk.h"
18-
1913
#include "csync_exclude.h"
14+
#include "theme.h"
15+
#include "updatechannel.h"
16+
#include "version.h"
2017

2118
#ifndef TOKEN_AUTH_ONLY
2219
#include <QWidget>
@@ -77,11 +74,6 @@ static constexpr char certPasswd[] = "http_certificatePasswd";
7774
static constexpr char serverHasValidSubscriptionC[] = "serverHasValidSubscription";
7875
static constexpr char desktopEnterpriseChannelName[] = "desktopEnterpriseChannel";
7976

80-
static const QStringList defaultUpdateChannelsList { QStringLiteral("stable"), QStringLiteral("beta"), QStringLiteral("daily") };
81-
static const QString defaultUpdateChannelName = "stable";
82-
static const QStringList enterpriseUpdateChannelsList { QStringLiteral("stable"), QStringLiteral("enterprise") };
83-
static const QString defaultEnterpriseChannel = "enterprise";
84-
8577
static constexpr char languageC[] = "language";
8678

8779
static constexpr char lastSelectedAccountC[] = "lastSelectedAccount";
@@ -686,14 +678,20 @@ QStringList ConfigFile::validUpdateChannels() const
686678
const auto isBranded = Theme::instance()->isBranded();
687679

688680
if (isBranded) {
689-
return { defaultUpdateChannelName };
681+
return {UpdateChannel::defaultUpdateChannel().toString()};
690682
}
691683

684+
const QList<UpdateChannel> *channel_list = &UpdateChannel::defaultUpdateChannelList();
692685
if (serverHasValidSubscription()) {
693-
return enterpriseUpdateChannelsList;
686+
channel_list = &UpdateChannel::enterpriseUpdateChannelsList();
687+
}
688+
689+
QStringList list;
690+
for (const auto &channel : *channel_list) {
691+
list.append(channel.toString());
694692
}
695693

696-
return defaultUpdateChannelsList;
694+
return list;
697695
}
698696

699697
QString ConfigFile::defaultUpdateChannel() const
@@ -713,14 +711,24 @@ QString ConfigFile::defaultUpdateChannel() const
713711
return currentVersionSuffix;
714712
}
715713

716-
qCWarning(lcConfigFile()) << "Default update channel is" << defaultUpdateChannelName;
717-
return defaultUpdateChannelName;
714+
qCWarning(lcConfigFile()) << "Default update channel is" << UpdateChannel::defaultUpdateChannel().toString();
715+
return UpdateChannel::defaultUpdateChannel().toString();
718716
}
719717

720718
QString ConfigFile::currentUpdateChannel() const
721719
{
720+
if (const auto isBranded = Theme::instance()->isBranded(); isBranded) {
721+
return UpdateChannel::defaultUpdateChannel().toString();
722+
}
723+
722724
QSettings settings(configFile(), QSettings::IniFormat);
723-
return settings.value(QLatin1String(updateChannelC), defaultUpdateChannel()).toString();
725+
const auto currentChannel = UpdateChannel::fromString(settings.value(QLatin1String(updateChannelC), defaultUpdateChannel()).toString());
726+
if (serverHasValidSubscription()) {
727+
const auto enterpriseChannel = UpdateChannel::fromString(desktopEnterpriseChannel());
728+
return UpdateChannel::mostStable(currentChannel, enterpriseChannel).toString();
729+
}
730+
731+
return currentChannel.toString();
724732
}
725733

726734
void ConfigFile::setUpdateChannel(const QString &channel)
@@ -1209,13 +1217,13 @@ void ConfigFile::setServerHasValidSubscription(const bool valid)
12091217
QString ConfigFile::desktopEnterpriseChannel() const
12101218
{
12111219
QSettings settings(configFile(), QSettings::IniFormat);
1212-
return settings.value(QLatin1String(desktopEnterpriseChannelName), defaultUpdateChannelName).toString();
1220+
return settings.value(QLatin1String(desktopEnterpriseChannelName), UpdateChannel::defaultUpdateChannel().toString()).toString();
12131221
}
12141222

12151223
void ConfigFile::setDesktopEnterpriseChannel(const QString &channel)
12161224
{
12171225
QSettings settings(configFile(), QSettings::IniFormat);
1218-
settings.setValue(QLatin1String(desktopEnterpriseChannelName), channel);
1226+
settings.setValue(QLatin1String(desktopEnterpriseChannelName), UpdateChannel::fromString(channel).toString());
12191227
}
12201228

12211229
QString ConfigFile::language() const

src/libsync/updatechannel.cpp

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
3+
* SPDX-License-Identifier: GPL-2.0-or-later
4+
*/
5+
6+
#include "updatechannel.h"
7+
8+
#include <QMap>
9+
10+
UpdateChannel::ChannelName UpdateChannel::channelName() const
11+
{
12+
return _channelName;
13+
}
14+
15+
bool UpdateChannel::isValid() const
16+
{
17+
return _channelName != ChannelName::invalid;
18+
}
19+
20+
QString UpdateChannel::toString() const
21+
{
22+
using enum ChannelName;
23+
static const QMap<ChannelName, QString> enumToNameLut = {{invalid, "invalid"},
24+
{daily, "daily"},
25+
{beta, "beta"},
26+
{stable, "stable"},
27+
{enterprise, "enterprise"}};
28+
return enumToNameLut.value(_channelName);
29+
}
30+
31+
std::strong_ordering UpdateChannel::operator<=>(const UpdateChannel &rhs) const = default;
32+
33+
UpdateChannel UpdateChannel::mostStable(const UpdateChannel &channelA, const UpdateChannel &channelB)
34+
{
35+
return std::max(channelA, channelB);
36+
}
37+
38+
const QList<UpdateChannel> &UpdateChannel::defaultUpdateChannelList()
39+
{
40+
static const QList<UpdateChannel> list{UpdateChannel::Stable, UpdateChannel::Beta, UpdateChannel::Daily};
41+
return list;
42+
}
43+
44+
const UpdateChannel &UpdateChannel::defaultUpdateChannel()
45+
{
46+
static const auto channel = UpdateChannel::Stable;
47+
return channel;
48+
}
49+
50+
const QList<UpdateChannel> &UpdateChannel::enterpriseUpdateChannelsList()
51+
{
52+
static const QList<UpdateChannel> list{UpdateChannel::Stable, UpdateChannel::Enterprise};
53+
return list;
54+
}
55+
56+
const UpdateChannel &UpdateChannel::defaultEnterpriseChannel()
57+
{
58+
static const auto channel = UpdateChannel::Enterprise;
59+
return channel;
60+
}
61+
62+
const UpdateChannel UpdateChannel::Invalid = UpdateChannel::fromString("invalid");
63+
const UpdateChannel UpdateChannel::Daily = UpdateChannel::fromString("daily");
64+
const UpdateChannel UpdateChannel::Beta = UpdateChannel::fromString("beta");
65+
const UpdateChannel UpdateChannel::Stable = UpdateChannel::fromString("stable");
66+
const UpdateChannel UpdateChannel::Enterprise = UpdateChannel::fromString("enterprise");
67+
68+
UpdateChannel UpdateChannel::fromString(const QString &channelName) // static
69+
{
70+
using enum ChannelName;
71+
static const QMap<QString, ChannelName> nameToEnumLut = {{"invalid", invalid},
72+
{"daily", daily},
73+
{"beta", beta},
74+
{"stable", stable},
75+
{"enterprise", enterprise}};
76+
auto channelEnum = nameToEnumLut.contains(channelName) ? nameToEnumLut.value(channelName) : invalid;
77+
return UpdateChannel(channelEnum);
78+
}
79+
80+
UpdateChannel::UpdateChannel(const ChannelName &channelName)
81+
: _channelName(channelName)
82+
{
83+
}

0 commit comments

Comments
 (0)