mirror of
https://github.com/nextcloud/server.git
synced 2026-06-10 01:00:50 -04:00
Merge pull request #53352 from nextcloud/fix/install-app-before-enable
fix: Do not enable applications which are not installed yet
This commit is contained in:
commit
5488f7e8b1
8 changed files with 55 additions and 4 deletions
|
|
@ -8,6 +8,8 @@ declare(strict_types=1);
|
|||
*/
|
||||
namespace OCA\Provisioning_API\Controller;
|
||||
|
||||
use OC\App\AppStore\AppNotFoundException;
|
||||
use OC\Installer;
|
||||
use OC_App;
|
||||
use OCP\App\AppPathNotFoundException;
|
||||
use OCP\App\IAppManager;
|
||||
|
|
@ -16,6 +18,7 @@ use OCP\AppFramework\Http\Attribute\PasswordConfirmationRequired;
|
|||
use OCP\AppFramework\Http\DataResponse;
|
||||
use OCP\AppFramework\OCS\OCSException;
|
||||
use OCP\AppFramework\OCSController;
|
||||
use OCP\IAppConfig;
|
||||
use OCP\IRequest;
|
||||
|
||||
class AppsController extends OCSController {
|
||||
|
|
@ -23,6 +26,8 @@ class AppsController extends OCSController {
|
|||
string $appName,
|
||||
IRequest $request,
|
||||
private IAppManager $appManager,
|
||||
private Installer $installer,
|
||||
private IAppConfig $appConfig,
|
||||
) {
|
||||
parent::__construct($appName, $request);
|
||||
}
|
||||
|
|
@ -108,10 +113,19 @@ class AppsController extends OCSController {
|
|||
public function enable(string $app): DataResponse {
|
||||
try {
|
||||
$app = $this->verifyAppId($app);
|
||||
|
||||
if (!$this->installer->isDownloaded($app)) {
|
||||
$this->installer->downloadApp($app);
|
||||
}
|
||||
|
||||
if ($this->appConfig->getValueString($app, 'installed_version', '') === '') {
|
||||
$this->installer->installApp($app);
|
||||
}
|
||||
|
||||
$this->appManager->enableApp($app);
|
||||
} catch (\InvalidArgumentException $e) {
|
||||
throw new OCSException($e->getMessage(), OCSController::RESPOND_UNAUTHORISED);
|
||||
} catch (AppPathNotFoundException $e) {
|
||||
} catch (AppPathNotFoundException|AppNotFoundException $e) {
|
||||
throw new OCSException('The request app was not found', OCSController::RESPOND_NOT_FOUND);
|
||||
}
|
||||
return new DataResponse();
|
||||
|
|
|
|||
|
|
@ -7,14 +7,17 @@
|
|||
*/
|
||||
namespace OCA\Provisioning_API\Tests\Controller;
|
||||
|
||||
use OC\Installer;
|
||||
use OCA\Provisioning_API\Controller\AppsController;
|
||||
use OCA\Provisioning_API\Tests\TestCase;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\AppFramework\OCS\OCSException;
|
||||
use OCP\IAppConfig;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\IRequest;
|
||||
use OCP\IUserSession;
|
||||
use OCP\Server;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
|
||||
/**
|
||||
* Class AppsTest
|
||||
|
|
@ -25,6 +28,8 @@ use OCP\Server;
|
|||
*/
|
||||
class AppsControllerTest extends TestCase {
|
||||
private IAppManager $appManager;
|
||||
private IAppConfig&MockObject $appConfig;
|
||||
private Installer&MockObject $installer;
|
||||
private AppsController $api;
|
||||
private IUserSession $userSession;
|
||||
|
||||
|
|
@ -34,13 +39,17 @@ class AppsControllerTest extends TestCase {
|
|||
$this->appManager = Server::get(IAppManager::class);
|
||||
$this->groupManager = Server::get(IGroupManager::class);
|
||||
$this->userSession = Server::get(IUserSession::class);
|
||||
$this->appConfig = $this->createMock(IAppConfig::class);
|
||||
$this->installer = $this->createMock(Installer::class);
|
||||
|
||||
$request = $this->createMock(IRequest::class);
|
||||
|
||||
$this->api = new AppsController(
|
||||
'provisioning_api',
|
||||
$request,
|
||||
$this->appManager
|
||||
$this->appManager,
|
||||
$this->installer,
|
||||
$this->appConfig,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ HIDE_OC_LOGS=$2
|
|||
INSTALLED=$($OCC status | grep installed: | cut -d " " -f 5)
|
||||
|
||||
if [ "$INSTALLED" == "true" ]; then
|
||||
# Disable appstore to avoid spamming from CI
|
||||
$OCC config:system:set appstoreenabled --value=false --type=boolean
|
||||
# Disable bruteforce protection because the integration tests do trigger them
|
||||
$OCC config:system:set auth.bruteforce.protection.enabled --value false --type bool
|
||||
# Disable rate limit protection because the integration tests do trigger them
|
||||
|
|
|
|||
|
|
@ -1049,6 +1049,7 @@ return array(
|
|||
'OC\\AppScriptDependency' => $baseDir . '/lib/private/AppScriptDependency.php',
|
||||
'OC\\AppScriptSort' => $baseDir . '/lib/private/AppScriptSort.php',
|
||||
'OC\\App\\AppManager' => $baseDir . '/lib/private/App/AppManager.php',
|
||||
'OC\\App\\AppStore\\AppNotFoundException' => $baseDir . '/lib/private/App/AppStore/AppNotFoundException.php',
|
||||
'OC\\App\\AppStore\\Bundles\\Bundle' => $baseDir . '/lib/private/App/AppStore/Bundles/Bundle.php',
|
||||
'OC\\App\\AppStore\\Bundles\\BundleFetcher' => $baseDir . '/lib/private/App/AppStore/Bundles/BundleFetcher.php',
|
||||
'OC\\App\\AppStore\\Bundles\\EducationBundle' => $baseDir . '/lib/private/App/AppStore/Bundles/EducationBundle.php',
|
||||
|
|
|
|||
|
|
@ -1090,6 +1090,7 @@ class ComposerStaticInit749170dad3f5e7f9ca158f5a9f04f6a2
|
|||
'OC\\AppScriptDependency' => __DIR__ . '/../../..' . '/lib/private/AppScriptDependency.php',
|
||||
'OC\\AppScriptSort' => __DIR__ . '/../../..' . '/lib/private/AppScriptSort.php',
|
||||
'OC\\App\\AppManager' => __DIR__ . '/../../..' . '/lib/private/App/AppManager.php',
|
||||
'OC\\App\\AppStore\\AppNotFoundException' => __DIR__ . '/../../..' . '/lib/private/App/AppStore/AppNotFoundException.php',
|
||||
'OC\\App\\AppStore\\Bundles\\Bundle' => __DIR__ . '/../../..' . '/lib/private/App/AppStore/Bundles/Bundle.php',
|
||||
'OC\\App\\AppStore\\Bundles\\BundleFetcher' => __DIR__ . '/../../..' . '/lib/private/App/AppStore/Bundles/BundleFetcher.php',
|
||||
'OC\\App\\AppStore\\Bundles\\EducationBundle' => __DIR__ . '/../../..' . '/lib/private/App/AppStore/Bundles/EducationBundle.php',
|
||||
|
|
|
|||
|
|
@ -545,11 +545,16 @@ class AppManager implements IAppManager {
|
|||
* @param string $appId
|
||||
* @param bool $forceEnable
|
||||
* @throws AppPathNotFoundException
|
||||
* @throws \InvalidArgumentException if the application is not installed yet
|
||||
*/
|
||||
public function enableApp(string $appId, bool $forceEnable = false): void {
|
||||
// Check if app exists
|
||||
$this->getAppPath($appId);
|
||||
|
||||
if ($this->config->getAppValue($appId, 'installed_version', '') === '') {
|
||||
throw new \InvalidArgumentException("$appId is not installed, cannot be enabled.");
|
||||
}
|
||||
|
||||
if ($forceEnable) {
|
||||
$this->overwriteNextcloudRequirement($appId);
|
||||
}
|
||||
|
|
@ -596,6 +601,10 @@ class AppManager implements IAppManager {
|
|||
throw new \InvalidArgumentException("$appId can't be enabled for groups.");
|
||||
}
|
||||
|
||||
if ($this->config->getAppValue($appId, 'installed_version', '') === '') {
|
||||
throw new \InvalidArgumentException("$appId is not installed, cannot be enabled.");
|
||||
}
|
||||
|
||||
if ($forceEnable) {
|
||||
$this->overwriteNextcloudRequirement($appId);
|
||||
}
|
||||
|
|
|
|||
13
lib/private/App/AppStore/AppNotFoundException.php
Normal file
13
lib/private/App/AppStore/AppNotFoundException.php
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
|
||||
* SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
*/
|
||||
|
||||
namespace OC\App\AppStore;
|
||||
|
||||
class AppNotFoundException extends \Exception {
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@ declare(strict_types=1);
|
|||
namespace OC;
|
||||
|
||||
use Doctrine\DBAL\Exception\TableExistsException;
|
||||
use OC\App\AppStore\AppNotFoundException;
|
||||
use OC\App\AppStore\Bundles\Bundle;
|
||||
use OC\App\AppStore\Fetcher\AppFetcher;
|
||||
use OC\AppFramework\Bootstrap\Coordinator;
|
||||
|
|
@ -174,6 +175,7 @@ class Installer {
|
|||
* @param string $appId
|
||||
* @param bool [$allowUnstable]
|
||||
*
|
||||
* @throws AppNotFoundException If the app is not found on the appstore
|
||||
* @throws \Exception If the installation was not successful
|
||||
*/
|
||||
public function downloadApp(string $appId, bool $allowUnstable = false): void {
|
||||
|
|
@ -356,9 +358,9 @@ class Installer {
|
|||
}
|
||||
}
|
||||
|
||||
throw new \Exception(
|
||||
throw new AppNotFoundException(
|
||||
sprintf(
|
||||
'Could not download app %s',
|
||||
'Could not download app %s, it was not found on the appstore',
|
||||
$appId
|
||||
)
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in a new issue