Skip to content

Commit

Permalink
fix(apps-store): Remove apps from force-enabled state when uninstalled
Browse files Browse the repository at this point in the history
If an app is force-enabled and then uninstalled the force-enabled state was kept.
This is now removed, so when the app should be re-installed the compatibility should be reevaluated.

Signed-off-by: Ferdinand Thiessen <[email protected]>
  • Loading branch information
susnux committed Nov 11, 2024
1 parent 8fdae44 commit f185c67
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 35 deletions.
16 changes: 11 additions & 5 deletions apps/settings/lib/Controller/AppSettingsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*/
namespace OCA\Settings\Controller;

use OC\App\AppManager;
use OC\App\AppStore\Bundles\BundleFetcher;
use OC\App\AppStore\Fetcher\AppDiscoverFetcher;
use OC\App\AppStore\Fetcher\AppFetcher;
Expand All @@ -15,7 +16,6 @@
use OC\App\Platform;
use OC\Installer;
use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
Expand Down Expand Up @@ -62,7 +62,7 @@ public function __construct(
private IL10N $l10n,
private IConfig $config,
private INavigationManager $navigationManager,
private IAppManager $appManager,
private AppManager $appManager,
private CategoryFetcher $categoryFetcher,
private AppFetcher $appFetcher,
private IFactory $l10nFactory,
Expand Down Expand Up @@ -592,7 +592,10 @@ public function uninstallApp(string $appId): JSONResponse {
$appId = $this->appManager->cleanAppId($appId);
$result = $this->installer->removeApp($appId);
if ($result !== false) {
$this->appManager->clearAppsCache();
$appManager = $this->appManager;
// If this app was force enabled, remove the force-enabled-state
$appManager->removeOverwriteNextcloudRequirement($appId);
$appManager->clearAppsCache();
return new JSONResponse(['data' => ['appid' => $appId]]);
}
return new JSONResponse(['data' => ['message' => $this->l10n->t('Could not remove app.')]], Http::STATUS_INTERNAL_SERVER_ERROR);
Expand Down Expand Up @@ -630,8 +633,11 @@ private function sortApps($a, $b) {
}

public function force(string $appId): JSONResponse {
$appId = $this->appManager->cleanAppId($appId);
$this->appManager->ignoreNextcloudRequirementForApp($appId);
/** @var \OC\App\AppManager $appManager */
$appManager = $this->appManager;

$appId = $appManager->cleanAppId($appId);
$appManager->overwriteNextcloudRequirement($appId);
return new JSONResponse();
}
}
11 changes: 0 additions & 11 deletions build/psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1026,11 +1026,6 @@
<code><![CDATA[getSettingsManager]]></code>
</UndefinedInterfaceMethod>
</file>
<file src="apps/settings/lib/Controller/AppSettingsController.php">
<UndefinedInterfaceMethod>
<code><![CDATA[ignoreNextcloudRequirementForApp]]></code>
</UndefinedInterfaceMethod>
</file>
<file src="apps/settings/lib/Hooks.php">
<InvalidArrayOffset>
<code><![CDATA[[$user->getEMailAddress() => $user->getDisplayName()]]]></code>
Expand Down Expand Up @@ -1338,12 +1333,6 @@
<code><![CDATA[!is_array($userIds)]]></code>
</TypeDoesNotContainType>
</file>
<file src="lib/private/App/AppManager.php">
<LessSpecificImplementedReturnType>
<code><![CDATA[array]]></code>
<code><![CDATA[array]]></code>
</LessSpecificImplementedReturnType>
</file>
<file src="lib/private/App/AppStore/Fetcher/Fetcher.php">
<TooManyArguments>
<code><![CDATA[fetch]]></code>
Expand Down
34 changes: 19 additions & 15 deletions lib/private/App/AppManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -200,10 +200,6 @@ public function getEnabledAppsForUser(IUser $user) {
return array_keys($appsForUser);
}

/**
* @param IGroup $group
* @return array
*/
public function getEnabledAppsForGroup(IGroup $group): array {
$apps = $this->getInstalledAppsValues();
$appsForGroups = array_filter($apps, function ($enabled) use ($group) {
Expand Down Expand Up @@ -304,10 +300,6 @@ public function getAutoDisabledApps(): array {
return $this->autoDisabledApps;
}

/**
* @param string $appId
* @return array
*/
public function getAppRestriction(string $appId): array {
$values = $this->getInstalledAppsValues();

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


/**
* Check if an app is enabled for user
*
Expand Down Expand Up @@ -410,12 +401,25 @@ public function isInstalled($appId) {
return isset($installedApps[$appId]);
}

public function ignoreNextcloudRequirementForApp(string $appId): void {
/**
* Overwrite the `max-version` requirement for this app.
*/
public function overwriteNextcloudRequirement(string $appId): void {
$ignoreMaxApps = $this->config->getSystemValue('app_install_overwrite', []);
if (!in_array($appId, $ignoreMaxApps, true)) {
$ignoreMaxApps[] = $appId;
$this->config->setSystemValue('app_install_overwrite', $ignoreMaxApps);
}
$this->config->setSystemValue('app_install_overwrite', $ignoreMaxApps);
}

/**
* Remove the `max-version` overwrite for this app.
* This means this app now again can not be enabled if the `max-version` is smaller than the current Nextcloud version.
*/
public function removeOverwriteNextcloudRequirement(string $appId): void {
$ignoreMaxApps = $this->config->getSystemValue('app_install_overwrite', []);
$ignoreMaxApps = array_filter($ignoreMaxApps, fn (string $id) => $id !== $appId);
$this->config->setSystemValue('app_install_overwrite', $ignoreMaxApps);
}

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

if ($forceEnable) {
$this->ignoreNextcloudRequirementForApp($appId);
$this->overwriteNextcloudRequirement($appId);
}

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

if ($forceEnable) {
$this->ignoreNextcloudRequirementForApp($appId);
$this->overwriteNextcloudRequirement($appId);
}

/** @var string[] $groupIds */
Expand All @@ -646,7 +650,7 @@ public function enableAppForGroups(string $appId, array $groups, bool $forceEnab
* @param bool $automaticDisabled
* @throws \Exception if app can't be disabled
*/
public function disableApp($appId, $automaticDisabled = false) {
public function disableApp($appId, $automaticDisabled = false): void {
if ($this->isAlwaysEnabled($appId)) {
throw new \Exception("$appId can't be disabled.");
}
Expand Down Expand Up @@ -706,7 +710,7 @@ public function getAppWebPath(string $appId): string {
/**
* Clear the cached list of apps when enabling/disabling an app
*/
public function clearAppsCache() {
public function clearAppsCache(): void {
$this->appInfos = [];
}

Expand Down
8 changes: 4 additions & 4 deletions lib/public/App/IAppManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public function enableAppForGroups(string $appId, array $groups, bool $forceEnab
* @param bool $automaticDisabled
* @since 8.0.0
*/
public function disableApp($appId, $automaticDisabled = false);
public function disableApp($appId, $automaticDisabled = false): void;

/**
* Get the directory for the given app.
Expand Down Expand Up @@ -185,7 +185,7 @@ public function getInstalledApps();
* Clear the cached list of apps when enabling/disabling an app
* @since 8.1.0
*/
public function clearAppsCache();
public function clearAppsCache(): void;

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

0 comments on commit f185c67

Please sign in to comment.