Skip to content

Commit e5932c0

Browse files
authored
Merge pull request #48855 from nextcloud/fix/app-store-remove-force-enable
fix(apps-store): Remove apps from force-enabled state when uninstalled
2 parents 6ff7db6 + 9e327a5 commit e5932c0

File tree

5 files changed

+31
-37
lines changed

5 files changed

+31
-37
lines changed

apps/settings/lib/Controller/AppSettingsController.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
*/
77
namespace OCA\Settings\Controller;
88

9+
use OC\App\AppManager;
910
use OC\App\AppStore\Bundles\BundleFetcher;
1011
use OC\App\AppStore\Fetcher\AppDiscoverFetcher;
1112
use OC\App\AppStore\Fetcher\AppFetcher;
@@ -15,7 +16,6 @@
1516
use OC\App\Platform;
1617
use OC\Installer;
1718
use OCP\App\AppPathNotFoundException;
18-
use OCP\App\IAppManager;
1919
use OCP\AppFramework\Controller;
2020
use OCP\AppFramework\Http;
2121
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
@@ -62,7 +62,7 @@ public function __construct(
6262
private IL10N $l10n,
6363
private IConfig $config,
6464
private INavigationManager $navigationManager,
65-
private IAppManager $appManager,
65+
private AppManager $appManager,
6666
private CategoryFetcher $categoryFetcher,
6767
private AppFetcher $appFetcher,
6868
private IFactory $l10nFactory,
@@ -592,6 +592,8 @@ public function uninstallApp(string $appId): JSONResponse {
592592
$appId = $this->appManager->cleanAppId($appId);
593593
$result = $this->installer->removeApp($appId);
594594
if ($result !== false) {
595+
// If this app was force enabled, remove the force-enabled-state
596+
$this->appManager->removeOverwriteNextcloudRequirement($appId);
595597
$this->appManager->clearAppsCache();
596598
return new JSONResponse(['data' => ['appid' => $appId]]);
597599
}
@@ -631,7 +633,7 @@ private function sortApps($a, $b) {
631633

632634
public function force(string $appId): JSONResponse {
633635
$appId = $this->appManager->cleanAppId($appId);
634-
$this->appManager->ignoreNextcloudRequirementForApp($appId);
636+
$this->appManager->overwriteNextcloudRequirement($appId);
635637
return new JSONResponse();
636638
}
637639
}

apps/settings/tests/Controller/AppSettingsControllerTest.php

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,13 @@
66
*/
77
namespace OCA\Settings\Tests\Controller;
88

9+
use OC\App\AppManager;
910
use OC\App\AppStore\Bundles\BundleFetcher;
1011
use OC\App\AppStore\Fetcher\AppDiscoverFetcher;
1112
use OC\App\AppStore\Fetcher\AppFetcher;
1213
use OC\App\AppStore\Fetcher\CategoryFetcher;
1314
use OC\Installer;
1415
use OCA\Settings\Controller\AppSettingsController;
15-
use OCP\App\IAppManager;
1616
use OCP\AppFramework\Http\ContentSecurityPolicy;
1717
use OCP\AppFramework\Http\JSONResponse;
1818
use OCP\AppFramework\Http\TemplateResponse;
@@ -47,8 +47,7 @@ class AppSettingsControllerTest extends TestCase {
4747
private $config;
4848
/** @var INavigationManager|MockObject */
4949
private $navigationManager;
50-
/** @var IAppManager|MockObject */
51-
private $appManager;
50+
private AppManager&MockObject $appManager;
5251
/** @var CategoryFetcher|MockObject */
5352
private $categoryFetcher;
5453
/** @var AppFetcher|MockObject */
@@ -83,7 +82,7 @@ protected function setUp(): void {
8382
->willReturnArgument(0);
8483
$this->config = $this->createMock(IConfig::class);
8584
$this->navigationManager = $this->createMock(INavigationManager::class);
86-
$this->appManager = $this->createMock(IAppManager::class);
85+
$this->appManager = $this->createMock(AppManager::class);
8786
$this->categoryFetcher = $this->createMock(CategoryFetcher::class);
8887
$this->appFetcher = $this->createMock(AppFetcher::class);
8988
$this->l10nFactory = $this->createMock(IFactory::class);

build/psalm-baseline.xml

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,11 +1025,6 @@
10251025
<code><![CDATA[getSettingsManager]]></code>
10261026
</UndefinedInterfaceMethod>
10271027
</file>
1028-
<file src="apps/settings/lib/Controller/AppSettingsController.php">
1029-
<UndefinedInterfaceMethod>
1030-
<code><![CDATA[ignoreNextcloudRequirementForApp]]></code>
1031-
</UndefinedInterfaceMethod>
1032-
</file>
10331028
<file src="apps/settings/lib/Hooks.php">
10341029
<InvalidArrayOffset>
10351030
<code><![CDATA[[$user->getEMailAddress() => $user->getDisplayName()]]]></code>
@@ -1337,12 +1332,6 @@
13371332
<code><![CDATA[!is_array($userIds)]]></code>
13381333
</TypeDoesNotContainType>
13391334
</file>
1340-
<file src="lib/private/App/AppManager.php">
1341-
<LessSpecificImplementedReturnType>
1342-
<code><![CDATA[array]]></code>
1343-
<code><![CDATA[array]]></code>
1344-
</LessSpecificImplementedReturnType>
1345-
</file>
13461335
<file src="lib/private/App/AppStore/Fetcher/Fetcher.php">
13471336
<TooManyArguments>
13481337
<code><![CDATA[fetch]]></code>

lib/private/App/AppManager.php

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -200,10 +200,6 @@ public function getEnabledAppsForUser(IUser $user) {
200200
return array_keys($appsForUser);
201201
}
202202

203-
/**
204-
* @param IGroup $group
205-
* @return array
206-
*/
207203
public function getEnabledAppsForGroup(IGroup $group): array {
208204
$apps = $this->getInstalledAppsValues();
209205
$appsForGroups = array_filter($apps, function ($enabled) use ($group) {
@@ -304,10 +300,6 @@ public function getAutoDisabledApps(): array {
304300
return $this->autoDisabledApps;
305301
}
306302

307-
/**
308-
* @param string $appId
309-
* @return array
310-
*/
311303
public function getAppRestriction(string $appId): array {
312304
$values = $this->getInstalledAppsValues();
313305

@@ -321,7 +313,6 @@ public function getAppRestriction(string $appId): array {
321313
return json_decode($values[$appId], true);
322314
}
323315

324-
325316
/**
326317
* Check if an app is enabled for user
327318
*
@@ -410,12 +401,25 @@ public function isInstalled($appId) {
410401
return isset($installedApps[$appId]);
411402
}
412403

413-
public function ignoreNextcloudRequirementForApp(string $appId): void {
404+
/**
405+
* Overwrite the `max-version` requirement for this app.
406+
*/
407+
public function overwriteNextcloudRequirement(string $appId): void {
414408
$ignoreMaxApps = $this->config->getSystemValue('app_install_overwrite', []);
415409
if (!in_array($appId, $ignoreMaxApps, true)) {
416410
$ignoreMaxApps[] = $appId;
417-
$this->config->setSystemValue('app_install_overwrite', $ignoreMaxApps);
418411
}
412+
$this->config->setSystemValue('app_install_overwrite', $ignoreMaxApps);
413+
}
414+
415+
/**
416+
* Remove the `max-version` overwrite for this app.
417+
* This means this app now again can not be enabled if the `max-version` is smaller than the current Nextcloud version.
418+
*/
419+
public function removeOverwriteNextcloudRequirement(string $appId): void {
420+
$ignoreMaxApps = $this->config->getSystemValue('app_install_overwrite', []);
421+
$ignoreMaxApps = array_filter($ignoreMaxApps, fn (string $id) => $id !== $appId);
422+
$this->config->setSystemValue('app_install_overwrite', $ignoreMaxApps);
419423
}
420424

421425
public function loadApp(string $app): void {
@@ -573,7 +577,7 @@ public function enableApp(string $appId, bool $forceEnable = false): void {
573577
$this->getAppPath($appId);
574578

575579
if ($forceEnable) {
576-
$this->ignoreNextcloudRequirementForApp($appId);
580+
$this->overwriteNextcloudRequirement($appId);
577581
}
578582

579583
$this->installedAppsCache[$appId] = 'yes';
@@ -619,7 +623,7 @@ public function enableAppForGroups(string $appId, array $groups, bool $forceEnab
619623
}
620624

621625
if ($forceEnable) {
622-
$this->ignoreNextcloudRequirementForApp($appId);
626+
$this->overwriteNextcloudRequirement($appId);
623627
}
624628

625629
/** @var string[] $groupIds */
@@ -646,7 +650,7 @@ public function enableAppForGroups(string $appId, array $groups, bool $forceEnab
646650
* @param bool $automaticDisabled
647651
* @throws \Exception if app can't be disabled
648652
*/
649-
public function disableApp($appId, $automaticDisabled = false) {
653+
public function disableApp($appId, $automaticDisabled = false): void {
650654
if ($this->isAlwaysEnabled($appId)) {
651655
throw new \Exception("$appId can't be disabled.");
652656
}
@@ -706,7 +710,7 @@ public function getAppWebPath(string $appId): string {
706710
/**
707711
* Clear the cached list of apps when enabling/disabling an app
708712
*/
709-
public function clearAppsCache() {
713+
public function clearAppsCache(): void {
710714
$this->appInfos = [];
711715
}
712716

lib/public/App/IAppManager.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ public function enableAppForGroups(string $appId, array $groups, bool $forceEnab
144144
* @param bool $automaticDisabled
145145
* @since 8.0.0
146146
*/
147-
public function disableApp($appId, $automaticDisabled = false);
147+
public function disableApp($appId, $automaticDisabled = false): void;
148148

149149
/**
150150
* Get the directory for the given app.
@@ -185,7 +185,7 @@ public function getInstalledApps();
185185
* Clear the cached list of apps when enabling/disabling an app
186186
* @since 8.1.0
187187
*/
188-
public function clearAppsCache();
188+
public function clearAppsCache(): void;
189189

190190
/**
191191
* @param string $appId
@@ -201,7 +201,7 @@ public function isShipped($appId);
201201
* @return bool
202202
*
203203
* This function walks through the Nextcloud directory and loads all apps
204-
* it can find. A directory contains an app if the file /appinfo/info.xml
204+
* it can find. A directory contains an app if the file `/appinfo/info.xml`
205205
* exists.
206206
*
207207
* if $types is set to non-empty array, only apps of those types will be loaded
@@ -271,7 +271,7 @@ public function getDefaultApps(): array;
271271
/**
272272
* Set the global default apps with fallbacks
273273
*
274-
* @param string[] $appId
274+
* @param string[] $defaultApps
275275
* @throws \InvalidArgumentException If any of the apps is not installed
276276
* @since 28.0.0
277277
* @deprecated 31.0.0

0 commit comments

Comments
 (0)