From 39c28bd05ba7ec106c7e86592e00192a550e50f7 Mon Sep 17 00:00:00 2001
From: Morris Jobke <hey@morrisjobke.de>
Date: Mon, 13 May 2019 14:11:07 +0200
Subject: [PATCH] Enterprise update channel

Allows to select the enterprise update channel for instances that have a valid subscription.

Signed-off-by: Morris Jobke <hey@morrisjobke.de>
---
 .../js/updatenotification.js                  | Bin 565026 -> 565248 bytes
 .../js/updatenotification.js.map              | Bin 1489952 -> 1490308 bytes
 .../updatenotification/lib/Settings/Admin.php |  16 ++++-
 .../src/components/root.vue                   |  41 ++++++------
 .../tests/Settings/AdminTest.php              |  12 +++-
 config/config.sample.php                      |   1 -
 lib/composer/composer/autoload_classmap.php   |   1 +
 lib/composer/composer/autoload_static.php     |   1 +
 lib/private/Repair.php                        |   2 +
 .../Repair/NC17/SwitchUpdateChannel.php       |  60 ++++++++++++++++++
 10 files changed, 111 insertions(+), 23 deletions(-)
 create mode 100644 lib/private/Repair/NC17/SwitchUpdateChannel.php

diff --git a/apps/updatenotification/js/updatenotification.js b/apps/updatenotification/js/updatenotification.js
index def967f63e0b952f493ae062dc3af3621a5292ae..a52628078759ffe2b6dc2954e3152f4c1d1a3311 100644
GIT binary patch
delta 4061
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
Sn_q(;D;@|m`<-3*4*K8nDo}g?

delta 3853
zcmcf^ZFCgX^}N~HofilpYm&_uf!zg`88TV<l8=o;pn@1+W}*|tnry<dJ0Xjk*|0ks
zl9LUH1ySM$IKV?JUur2<1?-ArQ331G<57>6wtB2RLTFFbiXwra_K2swvygzN{^_6o
z*ts9?-uv#m@80|F-gDgh#8K~|>RconH|EwO#n_xX8HvX0xf20Dn_G^g%&-v}4WP^E
zasb#=ym2@s>qg%PrQ}eZoi=8T{Rk^MtMe+?ZS+4-km1J_ATTj!{8%Izk@3IGk#si7
z$GL!P<oGrN?{S}-l5`T<O&4VT;A4?fVdJ13i1&!PKN8YI0y$lQiVZhAAMCWS?tD>i
z&?~)3Z%~-0_i(&uY-1k)|J+>L7*J_X#M_esAZ@DN8jobrsJ224>w;)J%ZWvneVyY~
zpYQTce7uJjGkFuwBBW$~sJsQ-&D>noXB}_Cv|gu8VU^6``P(e^;ss6{?9{Zd8Og@c
zg}1}EaMA6QqLR8gW{k0MQ7t8^L|BZ*<g1l>K<{ZuX<<DY*W8jpFV;$BmDl~v%Z2$_
z7!i~#Y!}2#@8Xp<*zgB=X$63$Ho?J2d{Wf|Qs#-|X9##3Q#VsKiI*~eTIB`W_@;AG
zfy8%cevlHf-*j5yc;or|iZgXxV<|X{-koo`yMFbZ;ONQKoq#V{v$90gSdCBc)-Ck(
zTy;^*^sNyXkQ}|i1<E&U_^0hUnbo*}R^1X$upOa<J1WSTNxhF*p1%F?A<K*IP4&5w
z#;cv-SSq3hB;&7}*1<I`-P}Mc8mp5NpP)i8`RC15Lv#V<k&UuPw>V`DZX(KY>2$*9
zi~4-BaqQ8PpuEd?20UH3W#R}~hj>NQn5wISVyxY=5BTg>g5=Ect&Jt%WW|9?4lrMK
z*aIs!9)1j1A0E!PuIjTFr&^%=B`+$MqC$5#p@wudphWppJ7krG_3*V(W6z8tqwRM`
zL7hKRZF#<{IJ4%+7Z5&U#jE$hxBpd$hJlYx2irAAZ?U-)R^@MvvbtXjwW;Z}x5LYE
zypq}ZT78aR7UuhW?KSOz7_V4pYfWn)!iyH#QqvMh@sfphrPFPEtuUXQc!DW1ro9vM
ziX0!0!>uS_>NbBkq=nU3OpVmAD}27}f^7W$o#Qu4KA!|P!ULC$TJkc-XQ9IJTAUrs
zHkRwYtn?#e>GWkCG4s~DZ<o??6mn_Xr{Cp3{2n=X(-=9<-l4LpKinFPMG~sUao6TA
z#Npg}2+yki<&+dBdmp2VjEntGK?dwNe;-)zT;O3<x?lxz#6Ssfd;?zsUU0Du_-ijd
z1<~_;V~2Fi@c;V4QK7ImY5sV-RU1ivB$|NojCQC={_Z%$a_dwy14&!&M#qq3RwDFD
zCBV;lG-Vo6i1QTVMIxCULKSwI)wyo6HiU}Fnl~8+R@a2kcvuB6+M#L@FE5c}r<f_Q
zaw&wi!%A--^DL6cxz(tMObQ_f35HP-FkrdNd?<`K3d!WTzcZysHczOiW(JVXov6_Q
zJCK)b+KJ`@{_`DZJo$DfngsZ<9cUE!_in_HMY~V|Fq(Iv>ChEP-J@tMIkF4YIu%`z
z_3FX<af>?HyBnOY+>Oe?Coo(|61zcHv<y!qhjybWfDan3032+NC3E&57X`{-coMmP
z59)S6uZ?m&<h@;}oQ&IxuEP?vIi0VC4cype*6&4UERW_KM!TR*8J>wQo2;_gj!N=h
zMDK%Tj}I4FE$r!;_+GQiL_E~Bx$h-31InD7d>L&(qS^8as)tJ@4=!O$h~>OHnV=P)
z5765-u+Y}X=twc0AER#&;SW+d<a84wgTUlwX25RN{|!yZ1+Bh&m?BfunKL#seI6Cj
zS6BpC737{Yv)-)z78T~fu1$8T40i3ZQ@kC>eZwf35?ONnEaWmr45#v*1l3UosJQ@|
z4p80T*vAJbA5iEZRS6DN9i-NQ-fs_5DKNtxqUxOhdtRf;seB14SC6N{t!fgAN07|@
zuTx*ck;(Qqs4$%T(i_yvc2?E}Z(B%<wx?ntD@naPT%lKsYpRzQ0c#IwRh^Js=Ban6
z)szg02m&0JQ1w(ob1Qna)h<=R;*0RuXjx3sx#}wts?Vp@D0%=Ih*qQ4h|uWufF&*K
zT#ZbgeUI8dO@@aOjQV_@TD?KhgM0$4K-CViBw&TIEZE|*lxW`nK2@FrA$aN|>Tx*p
zoWD>uyAxD+-M7%^Q~m9!WGgG0^(Uz<lnsoM^eJkzl~@jQ<Z0?H+mCq!c$_)mA5?)2
z$!7KE)VmmL<9-OQLLTa;+5mjtPmM$32KRZ&bf35Nepe+!coOljnoN2HA;s21MGJ$e
z53LDaTOlqi^S3}V^ms_kUZ}*czM$vkE71OWt^|mc(`loBeF3@k3_S*NYvma_ZB^#k
zujrjt9-gHi1cyq$rr)%(weK7~61qJ(*H6P!M{3X0r-8DX6q$2@hVDUP7ibZ{kqfld
z9{MiOvw$iapk)9n2I#SHj)w>6Dp-4Efc_Q&_rgUw?F3ts8GAV_ij2J?M}fB61t(I>
zBx9!$k~ef>JNz7GCuVxNGFi~rSu?HU0-VKNQ}1TQ6y`&yCv)Hi=3xwG>t-{Bgv@5j
zaus;sT0*IqHOi2^%kWszH=BX1H$R=t{LDJk<VnayYUVJ*fVXfCGq)Jj|Mxm{6u~L1
z3j8&c8@_^POV5PT`{dfH>t%kT>NYbr3AFyd-M2K??E9J-=c|Bn4C@Wv=H_rbp;oO(
zHYZy{2{qE(><#h?@wjkdo~*+Jq5JPvyOMyAliSb)vciRjK?M7Eqe7?0qkx2>yQ7+0
z?|~{ZRt_&DZh|m*(S@xXd2&0NX_ggZ7_UTAD8XAs5I6KjB4wcOV;?RdC&mMLd<(LZ
zuYQF}D@0ZBHpG`%v!#1(VtJ}f)%0Z0o2`8*+gC>_Dm+o};=@SH34%zr`0zs5>XZ+A
zDM=-JpNH{CAte*=8Ax)P#S35vH5YR@4_->MfyW&%kePp+ikH}6ToUHN;NsWftFk*N
z<krc!kVrG|Xvm1R8Cau4&Fb)FFnM*t@Wrcq7Yqw9D|?}?tcE0!5i{`)h{*n#_!p2)
z{4BiA!%VqhYB<y~otSswrXgZf10FX-ENH;ZL&S3pcs9PGqmul4>Cq(Eh+SktBhI_Z
zA34%iLGl`L>Bt6ah_C9X8r<gIMjXB>=PtIvE$nj?5myjTAL4Jj4a|-RVuo}D@%-U~
z+XZ<yaW=xKYl7HLo(bY%<jWw=8S?E?5YPRwjpa*mIa%F=T|;cLasypJ4mRQGLuy|(
z;l?3CZpL>F5r>-bqW{($PF|QtmyznFI5s4C;99~H!UwLZWzXn;(7}-NAzVMC0Yb&3
z?hOYvW6SU;hq<Q}f1X1{b+R#mdjXntDLer=qq_C{c<U1JNGkhhf;6P?xPm3oSj-)Y
ztqOG|-Oz43q7jv}C2<9LB#CFQNhMRESggz48ftG>wWNDhRBv_bt*SezhT~eq-4@m2
z33mcU>rhg4vz`7){wbV01S@e3)S@j};i#6>ty$C^O~O_%K}Wh^J-Y<YqMFpN*y&Ic
zNq8jvUU*T#e85Zg>$qSTxHaf<)hZkqcFhs0QrKf1v8w}jqTH*3UJto`6%^TZop|lF
z>;MV1;gX+-#ao@2wPJR@6Hm4bj_<-H6shaL4zj%)FR*9#BnQ_~F7k9Yc3taJUK*E}
YpLFBzX)|Xn-cdGqG3IX`$9K^G0jga4{{R30

diff --git a/apps/updatenotification/js/updatenotification.js.map b/apps/updatenotification/js/updatenotification.js.map
index ed234f4ec8a1c342ef586bb4a7ea0ee10fc1b255..a6171f24d16d5bf574e342ab6a2fcfbafe0bf181 100644
GIT binary patch
delta 5617
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

delta 5351
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
b>BnECubK;9*q5%*qh=L1U;Y|>?dX32+ZF&}

diff --git a/apps/updatenotification/lib/Settings/Admin.php b/apps/updatenotification/lib/Settings/Admin.php
index 571a8e9f906..e7a8f07a183 100644
--- a/apps/updatenotification/lib/Settings/Admin.php
+++ b/apps/updatenotification/lib/Settings/Admin.php
@@ -34,6 +34,7 @@ use OCP\IGroupManager;
 use OCP\IUserSession;
 use OCP\L10N\IFactory;
 use OCP\Settings\ISettings;
+use OCP\Support\Subscription\IRegistry;
 use OCP\Util;
 
 class Admin implements ISettings {
@@ -47,19 +48,23 @@ class Admin implements ISettings {
 	private $dateTimeFormatter;
 	/** @var IFactory */
 	private $l10nFactory;
+	/** @var IRegistry */
+	private $subscriptionRegistry;
 
 	public function __construct(
 		IConfig $config,
 		UpdateChecker $updateChecker,
 		IGroupManager $groupManager,
 		IDateTimeFormatter $dateTimeFormatter,
-		IFactory $l10nFactory
+		IFactory $l10nFactory,
+		IRegistry $subscriptionRegistry
 	) {
 		$this->config = $config;
 		$this->updateChecker = $updateChecker;
 		$this->groupManager = $groupManager;
 		$this->dateTimeFormatter = $dateTimeFormatter;
 		$this->l10nFactory = $l10nFactory;
+		$this->subscriptionRegistry = $subscriptionRegistry;
 	}
 
 	/**
@@ -86,6 +91,12 @@ class Admin implements ISettings {
 
 		$defaultUpdateServerURL = 'https://updates.nextcloud.com/updater_server/';
 		$updateServerURL = $this->config->getSystemValue('updater.server.url', $defaultUpdateServerURL);
+		$defaultCustomerUpdateServerURLPrefix = 'https://updates.nextcloud.com/customers/';
+
+		$isDefaultUpdateServerURL = $updateServerURL === $defaultUpdateServerURL
+			|| $updateServerURL === substr($updateServerURL, 0, strlen($defaultCustomerUpdateServerURLPrefix));
+
+		$hasValidSubscription = $this->subscriptionRegistry->delegateHasValidSubscription();
 
 		$params = [
 			'isNewVersionAvailable' => !empty($updateState['updateAvailable']),
@@ -99,9 +110,10 @@ class Admin implements ISettings {
 			'changes' => $this->filterChanges($updateState['changes'] ?? []),
 			'updaterEnabled' => empty($updateState['updaterEnabled']) ? false : $updateState['updaterEnabled'],
 			'versionIsEol' => empty($updateState['versionIsEol']) ? false : $updateState['versionIsEol'],
-			'isDefaultUpdateServerURL' => $updateServerURL === $defaultUpdateServerURL,
+			'isDefaultUpdateServerURL' => $isDefaultUpdateServerURL,
 			'updateServerURL' => $updateServerURL,
 			'notifyGroups' => $this->getSelectedGroups($notifyGroups),
+			'hasValidSubscription' => $hasValidSubscription,
 		];
 
 		$params = [
diff --git a/apps/updatenotification/src/components/root.vue b/apps/updatenotification/src/components/root.vue
index 60b631922eb..54fc54cd2c1 100644
--- a/apps/updatenotification/src/components/root.vue
+++ b/apps/updatenotification/src/components/root.vue
@@ -115,6 +115,7 @@
 				versionIsEol: false,
 				downloadLink: '',
 				isNewVersionAvailable: false,
+				hasValidSubscription: false,
 				updateServerURL: '',
 				changelogURL: '',
 				whatsNewData: [],
@@ -224,7 +225,7 @@
 				if(this.changelogURL) {
 					whatsNew.push({
 						href: this.changelogURL,
-						text: t('updatenotificaiton', 'View changelog'),
+						text: t('updatenotification', 'View changelog'),
 						icon: 'icon-link',
 						target: '_blank',
 						action: ''
@@ -237,7 +238,16 @@
 				let channelList = [];
 
 				channelList.push({
-					text: t('updatenotificaiton', 'Stable'),
+					text: t('updatenotification', 'Enterprise'),
+					longtext: t('updatenotification', 'For enterprise use. Provides always the latest patch level, but will not update to the next major release immediately. That update happens once Nextcloud GmbH has done additional hardening and testing for large-scale and mission-critical deployments. This channel is only available to customers and provides the Nextcloud Enterprise package.'),
+					icon: 'icon-star',
+					active: this.currentChannel === 'enterprise',
+					disabled: !this.hasValidSubscription,
+					action: this.changeReleaseChannelToEnterprise
+				});
+
+				channelList.push({
+					text: t('updatenotification', 'Stable'),
 					longtext: t('updatenotification', 'The most recent stable version. It is suited for regular use and will always update to the latest major version.'),
 					icon: 'icon-checkmark',
 					active: this.currentChannel === 'stable',
@@ -245,15 +255,7 @@
 				});
 
 				channelList.push({
-					text: t('updatenotificaiton', 'Production'),
-					longtext: t('updatenotification', 'Will always provide the latest patch level, but not update to the next major release immediately. That update usually happens with the second minor release (x.0.2) and only if the instance is already on the latest minor version.'),
-					icon: 'icon-star',
-					active: this.currentChannel === 'production',
-					action: this.changeReleaseChannelToProduction
-				});
-
-				channelList.push({
-					text: t('updatenotificaiton', 'Beta'),
+					text: t('updatenotification', 'Beta'),
 					longtext: t('updatenotification', 'A pre-release version only for testing new features, not for production environments.'),
 					icon: 'icon-category-customization',
 					active: this.currentChannel === 'beta',
@@ -272,19 +274,19 @@
 			},
 
 			isNonDefaultChannel: function() {
-				return this.currentChannel !== 'production' && this.currentChannel !== 'stable' && this.currentChannel !== 'beta';
+				return this.currentChannel !== 'enterprise' && this.currentChannel !== 'stable' && this.currentChannel !== 'beta';
 			},
 
 			localizedChannelName: function() {
 				switch (this.currentChannel) {
-					case 'production':
-						return t('updatenotificaiton', 'Production');
+					case 'enterprise':
+						return t('updatenotification', 'Enterprise');
 						break;
 					case 'stable':
-						return t('updatenotificaiton', 'Stable');
+						return t('updatenotification', 'Stable');
 						break;
 					case 'beta':
-						return t('updatenotificaiton', 'Beta');
+						return t('updatenotification', 'Beta');
 						break;
 					default:
 						return this.currentChannel;
@@ -317,12 +319,12 @@
 					form.submit();
 				}.bind(this));
 			},
+			changeReleaseChannelToEnterprise: function() {
+				this.changeReleaseChannel('enterprise')
+			},
 			changeReleaseChannelToStable: function() {
 				this.changeReleaseChannel('stable')
 			},
-			changeReleaseChannelToProduction: function() {
-				this.changeReleaseChannel('production')
-			},
 			changeReleaseChannelToBeta: function() {
 				this.changeReleaseChannel('beta')
 			},
@@ -375,6 +377,7 @@
 			this.notifyGroups = data.notifyGroups;
 			this.isDefaultUpdateServerURL = data.isDefaultUpdateServerURL;
 			this.versionIsEol = data.versionIsEol;
+			this.hasValidSubscription = data.hasValidSubscription;
 			if(data.changes && data.changes.changelogURL) {
 				this.changelogURL = data.changes.changelogURL;
 			}
diff --git a/apps/updatenotification/tests/Settings/AdminTest.php b/apps/updatenotification/tests/Settings/AdminTest.php
index 9d40cb4d292..d2d4b503bad 100644
--- a/apps/updatenotification/tests/Settings/AdminTest.php
+++ b/apps/updatenotification/tests/Settings/AdminTest.php
@@ -35,6 +35,7 @@ use OCP\IGroupManager;
 use OCP\IUserSession;
 use OCP\L10N\IFactory;
 use OCP\L10N\ILanguageIterator;
+use OCP\Support\Subscription\IRegistry;
 use OCP\Util;
 use Test\TestCase;
 
@@ -51,6 +52,8 @@ class AdminTest extends TestCase {
 	private $groupManager;
 	/** @var IDateTimeFormatter|\PHPUnit_Framework_MockObject_MockObject */
 	private $dateTimeFormatter;
+	/** @var IRegistry|\PHPUnit_Framework_MockObject_MockObject */
+	private $subscriptionRegistry;
 
 	public function setUp() {
 		parent::setUp();
@@ -60,9 +63,10 @@ class AdminTest extends TestCase {
 		$this->groupManager = $this->createMock(IGroupManager::class);
 		$this->dateTimeFormatter = $this->createMock(IDateTimeFormatter::class);
 		$this->l10nFactory = $this->createMock(IFactory::class);
+		$this->subscriptionRegistry = $this->createMock(IRegistry::class);
 
 		$this->admin = new Admin(
-			$this->config, $this->updateChecker, $this->groupManager, $this->dateTimeFormatter, $this->l10nFactory
+			$this->config, $this->updateChecker, $this->groupManager, $this->dateTimeFormatter, $this->l10nFactory, $this->subscriptionRegistry
 		);
 	}
 
@@ -120,6 +124,11 @@ class AdminTest extends TestCase {
 			->with('admin')
 			->willReturn($group);
 
+		$this->subscriptionRegistry
+			->expects($this->once())
+			->method('delegateHasValidSubscription')
+			->willReturn(true);
+
 		$params = [
 			'json' => json_encode([
 				'isNewVersionAvailable' => true,
@@ -138,6 +147,7 @@ class AdminTest extends TestCase {
 				'notifyGroups' => [
 					['value' => 'admin', 'label' => 'Administrators'],
 				],
+				'hasValidSubscription' => true,
 			]),
 		];
 
diff --git a/config/config.sample.php b/config/config.sample.php
index 36429492bf6..f939fc371b7 100644
--- a/config/config.sample.php
+++ b/config/config.sample.php
@@ -653,7 +653,6 @@ $CONFIG = array(
  *   - ``daily``
  *   - ``beta``
  *   - ``stable``
- *   - ``production``
  */
 'updater.release.channel' => 'stable',
 
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 300e3df9129..c8ee14ada70 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -1063,6 +1063,7 @@ return array(
     'OC\\Repair\\NC16\\AddClenupLoginFlowV2BackgroundJob' => $baseDir . '/lib/private/Repair/NC16/AddClenupLoginFlowV2BackgroundJob.php',
     'OC\\Repair\\NC16\\CleanupCardDAVPhotoCache' => $baseDir . '/lib/private/Repair/NC16/CleanupCardDAVPhotoCache.php',
     'OC\\Repair\\NC16\\RemoveCypressFiles' => $baseDir . '/lib/private/Repair/NC16/RemoveCypressFiles.php',
+    'OC\\Repair\\NC17\\SwitchUpdateChannel' => $baseDir . '/lib/private/Repair/NC17/SwitchUpdateChannel.php',
     'OC\\Repair\\OldGroupMembershipShares' => $baseDir . '/lib/private/Repair/OldGroupMembershipShares.php',
     'OC\\Repair\\Owncloud\\DropAccountTermsTable' => $baseDir . '/lib/private/Repair/Owncloud/DropAccountTermsTable.php',
     'OC\\Repair\\Owncloud\\SaveAccountsTableData' => $baseDir . '/lib/private/Repair/Owncloud/SaveAccountsTableData.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index 9df8b8769dc..dba20667a31 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -1097,6 +1097,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
         'OC\\Repair\\NC16\\AddClenupLoginFlowV2BackgroundJob' => __DIR__ . '/../../..' . '/lib/private/Repair/NC16/AddClenupLoginFlowV2BackgroundJob.php',
         'OC\\Repair\\NC16\\CleanupCardDAVPhotoCache' => __DIR__ . '/../../..' . '/lib/private/Repair/NC16/CleanupCardDAVPhotoCache.php',
         'OC\\Repair\\NC16\\RemoveCypressFiles' => __DIR__ . '/../../..' . '/lib/private/Repair/NC16/RemoveCypressFiles.php',
+        'OC\\Repair\\NC17\\SwitchUpdateChannel' => __DIR__ . '/../../..' . '/lib/private/Repair/NC17/SwitchUpdateChannel.php',
         'OC\\Repair\\OldGroupMembershipShares' => __DIR__ . '/../../..' . '/lib/private/Repair/OldGroupMembershipShares.php',
         'OC\\Repair\\Owncloud\\DropAccountTermsTable' => __DIR__ . '/../../..' . '/lib/private/Repair/Owncloud/DropAccountTermsTable.php',
         'OC\\Repair\\Owncloud\\SaveAccountsTableData' => __DIR__ . '/../../..' . '/lib/private/Repair/Owncloud/SaveAccountsTableData.php',
diff --git a/lib/private/Repair.php b/lib/private/Repair.php
index 4fbc89835cc..bd2fc081131 100644
--- a/lib/private/Repair.php
+++ b/lib/private/Repair.php
@@ -43,6 +43,7 @@ use OC\Repair\NC14\AddPreviewBackgroundCleanupJob;
 use OC\Repair\NC16\AddClenupLoginFlowV2BackgroundJob;
 use OC\Repair\NC16\CleanupCardDAVPhotoCache;
 use OC\Repair\NC16\RemoveCypressFiles;
+use OC\Repair\NC17\SwitchUpdateChannel;
 use OC\Repair\OldGroupMembershipShares;
 use OC\Repair\Owncloud\DropAccountTermsTable;
 use OC\Repair\Owncloud\SaveAccountsTableData;
@@ -149,6 +150,7 @@ class Repair implements IOutput {
 			new AddClenupLoginFlowV2BackgroundJob(\OC::$server->getJobList()),
 			new RemoveLinkShares(\OC::$server->getDatabaseConnection(), \OC::$server->getConfig(), \OC::$server->getGroupManager(), \OC::$server->getNotificationManager(), \OC::$server->query(ITimeFactory::class)),
 			\OC::$server->query(RemoveCypressFiles::class),
+			\OC::$server->query(SwitchUpdateChannel::class),
 		];
 	}
 
diff --git a/lib/private/Repair/NC17/SwitchUpdateChannel.php b/lib/private/Repair/NC17/SwitchUpdateChannel.php
new file mode 100644
index 00000000000..cfa72d86b1e
--- /dev/null
+++ b/lib/private/Repair/NC17/SwitchUpdateChannel.php
@@ -0,0 +1,60 @@
+<?php
+declare(strict_types=1);
+/**
+ * @copyright Copyright (c) 2019, Morris Jobke <hey@morrisjobke.de>
+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OC\Repair\NC17;
+
+use OCP\IConfig;
+use OCP\Migration\IOutput;
+use OCP\Migration\IRepairStep;
+use OCP\Support\Subscription\IRegistry;
+/**
+ * @deprecated - can be removed in 18
+ */
+class SwitchUpdateChannel implements IRepairStep {
+
+	/** @var IConfig */
+	private $config;
+
+	/** @var IRegistry */
+	private $subscriptionRegistry;
+
+	public function __construct(IConfig $config, IRegistry $subscriptionRegistry) {
+		$this->config = $config;
+		$this->subscriptionRegistry = $subscriptionRegistry;
+	}
+
+	public function getName(): string {
+		return 'Switches from deprecated "production" to "stable" update channel';
+	}
+
+	public function run(IOutput $output): void {
+		$currentChannel = $this->config->getSystemValue('updater.release.channel', 'stable');
+
+		if ($currentChannel === 'production') {
+			if ($this->subscriptionRegistry->delegateHasValidSubscription()) {
+				$this->config->setSystemValue('updater.release.channel', 'enterprise');
+			} else {
+				$this->config->setSystemValue('updater.release.channel', 'stable');
+			}
+		}
+	}
+}
-- 
GitLab