Allow to force enable apps via CLI
Co-authored-by: Christoph Wurst <christoph@winzerhof-wurst.at> Signed-off-by: Joas Schilling <coding@schilljs.com> Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
This commit is contained in:
parent
642606754b
commit
3eee359d7f
8 changed files with 83 additions and 42 deletions
|
@ -549,13 +549,7 @@ class AppSettingsController extends Controller {
|
|||
|
||||
public function force(string $appId): JSONResponse {
|
||||
$appId = OC_App::cleanAppId($appId);
|
||||
|
||||
$ignoreMaxApps = $this->config->getSystemValue('app_install_overwrite', []);
|
||||
if (!in_array($appId, $ignoreMaxApps, true)) {
|
||||
$ignoreMaxApps[] = $appId;
|
||||
$this->config->setSystemValue('app_install_overwrite', $ignoreMaxApps);
|
||||
}
|
||||
|
||||
$this->appManager->ignoreNextcloudRequirementForApp($appId);
|
||||
return new JSONResponse();
|
||||
}
|
||||
|
||||
|
|
|
@ -73,15 +73,22 @@ class Enable extends Command implements CompletionAwareInterface {
|
|||
'g',
|
||||
InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY,
|
||||
'enable the app only for a list of groups'
|
||||
)
|
||||
->addOption(
|
||||
'force',
|
||||
'f',
|
||||
InputOption::VALUE_NONE,
|
||||
'enable the app regardless of the Nextcloud version requirement'
|
||||
);
|
||||
}
|
||||
|
||||
protected function execute(InputInterface $input, OutputInterface $output) {
|
||||
$appIds = $input->getArgument('app-id');
|
||||
$groups = $this->resolveGroupIds($input->getOption('groups'));
|
||||
$forceEnable = (bool) $input->getOption('force');
|
||||
|
||||
foreach ($appIds as $appId) {
|
||||
$this->enableApp($appId, $groups, $output);
|
||||
$this->enableApp($appId, $groups, $forceEnable, $output);
|
||||
}
|
||||
|
||||
return $this->exitCode;
|
||||
|
@ -90,9 +97,10 @@ class Enable extends Command implements CompletionAwareInterface {
|
|||
/**
|
||||
* @param string $appId
|
||||
* @param array $groupIds
|
||||
* @param bool $forceEnable
|
||||
* @param OutputInterface $output
|
||||
*/
|
||||
private function enableApp(string $appId, array $groupIds, OutputInterface $output): void {
|
||||
private function enableApp(string $appId, array $groupIds, bool $forceEnable, OutputInterface $output): void {
|
||||
$groupNames = array_map(function (IGroup $group) {
|
||||
return $group->getDisplayName();
|
||||
}, $groupIds);
|
||||
|
@ -106,13 +114,13 @@ class Enable extends Command implements CompletionAwareInterface {
|
|||
$installer->downloadApp($appId);
|
||||
}
|
||||
|
||||
$installer->installApp($appId);
|
||||
$installer->installApp($appId, $forceEnable);
|
||||
|
||||
if ($groupIds === []) {
|
||||
$this->appManager->enableApp($appId);
|
||||
$this->appManager->enableApp($appId, $forceEnable);
|
||||
$output->writeln($appId . ' enabled');
|
||||
} else {
|
||||
$this->appManager->enableAppForGroups($appId, $groupIds);
|
||||
$this->appManager->enableAppForGroups($appId, $groupIds, $forceEnable);
|
||||
$output->writeln($appId . ' enabled for groups: ' . implode(', ', $groupNames));
|
||||
}
|
||||
} catch (AppPathNotFoundException $e) {
|
||||
|
|
|
@ -42,6 +42,7 @@ use OCP\App\AppPathNotFoundException;
|
|||
use OCP\App\IAppManager;
|
||||
use OCP\App\ManagerEvent;
|
||||
use OCP\ICacheFactory;
|
||||
use OCP\IConfig;
|
||||
use OCP\IGroup;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\ILogger;
|
||||
|
@ -66,6 +67,9 @@ class AppManager implements IAppManager {
|
|||
/** @var IUserSession */
|
||||
private $userSession;
|
||||
|
||||
/** @var IConfig */
|
||||
private $config;
|
||||
|
||||
/** @var AppConfig */
|
||||
private $appConfig;
|
||||
|
||||
|
@ -101,18 +105,21 @@ class AppManager implements IAppManager {
|
|||
|
||||
/**
|
||||
* @param IUserSession $userSession
|
||||
* @param IConfig $config
|
||||
* @param AppConfig $appConfig
|
||||
* @param IGroupManager $groupManager
|
||||
* @param ICacheFactory $memCacheFactory
|
||||
* @param EventDispatcherInterface $dispatcher
|
||||
*/
|
||||
public function __construct(IUserSession $userSession,
|
||||
IConfig $config,
|
||||
AppConfig $appConfig,
|
||||
IGroupManager $groupManager,
|
||||
ICacheFactory $memCacheFactory,
|
||||
EventDispatcherInterface $dispatcher,
|
||||
ILogger $logger) {
|
||||
$this->userSession = $userSession;
|
||||
$this->config = $config;
|
||||
$this->appConfig = $appConfig;
|
||||
$this->groupManager = $groupManager;
|
||||
$this->memCacheFactory = $memCacheFactory;
|
||||
|
@ -296,16 +303,29 @@ class AppManager implements IAppManager {
|
|||
return isset($installedApps[$appId]);
|
||||
}
|
||||
|
||||
public function ignoreNextcloudRequirementForApp(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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable an app for every user
|
||||
*
|
||||
* @param string $appId
|
||||
* @param bool $forceEnable
|
||||
* @throws AppPathNotFoundException
|
||||
*/
|
||||
public function enableApp($appId) {
|
||||
public function enableApp(string $appId, bool $forceEnable = false): void {
|
||||
// Check if app exists
|
||||
$this->getAppPath($appId);
|
||||
|
||||
if ($forceEnable) {
|
||||
$this->ignoreNextcloudRequirementForApp($appId);
|
||||
}
|
||||
|
||||
$this->installedAppsCache[$appId] = 'yes';
|
||||
$this->appConfig->setValue($appId, 'enabled', 'yes');
|
||||
$this->dispatcher->dispatch(ManagerEvent::EVENT_APP_ENABLE, new ManagerEvent(
|
||||
|
@ -334,10 +354,11 @@ class AppManager implements IAppManager {
|
|||
*
|
||||
* @param string $appId
|
||||
* @param \OCP\IGroup[] $groups
|
||||
* @param bool $forceEnable
|
||||
* @throws \InvalidArgumentException if app can't be enabled for groups
|
||||
* @throws AppPathNotFoundException
|
||||
*/
|
||||
public function enableAppForGroups($appId, $groups) {
|
||||
public function enableAppForGroups(string $appId, array $groups, bool $forceEnable = false): void {
|
||||
// Check if app exists
|
||||
$this->getAppPath($appId);
|
||||
|
||||
|
@ -346,6 +367,10 @@ class AppManager implements IAppManager {
|
|||
throw new \InvalidArgumentException("$appId can't be enabled for groups.");
|
||||
}
|
||||
|
||||
if ($forceEnable) {
|
||||
$this->ignoreNextcloudRequirementForApp($appId);
|
||||
}
|
||||
|
||||
$groupIds = array_map(function ($group) {
|
||||
/** @var \OCP\IGroup $group */
|
||||
return ($group instanceof IGroup)
|
||||
|
|
|
@ -94,10 +94,11 @@ class Installer {
|
|||
* Installs an app that is located in one of the app folders already
|
||||
*
|
||||
* @param string $appId App to install
|
||||
* @param bool $forceEnable
|
||||
* @throws \Exception
|
||||
* @return string app ID
|
||||
*/
|
||||
public function installApp($appId) {
|
||||
public function installApp(string $appId, bool $forceEnable = false): string {
|
||||
$app = \OC_App::findAppInDirectories($appId);
|
||||
if($app === false) {
|
||||
throw new \Exception('App not found in any app directory');
|
||||
|
@ -117,7 +118,7 @@ class Installer {
|
|||
}
|
||||
|
||||
$ignoreMaxApps = $this->config->getSystemValue('app_install_overwrite', []);
|
||||
$ignoreMax = in_array($appId, $ignoreMaxApps);
|
||||
$ignoreMax = $forceEnable || in_array($appId, $ignoreMaxApps, true);
|
||||
|
||||
$version = implode('.', \OCP\Util::getVersion());
|
||||
if (!\OC_App::isAppCompatible($version, $info, $ignoreMax)) {
|
||||
|
|
|
@ -798,6 +798,7 @@ class Server extends ServerContainer implements IServerContainer {
|
|||
$this->registerService(AppManager::class, function (Server $c) {
|
||||
return new \OC\App\AppManager(
|
||||
$c->getUserSession(),
|
||||
$c->getConfig(),
|
||||
$c->query(\OC\AppConfig::class),
|
||||
$c->getGroupManager(),
|
||||
$c->getMemCacheFactory(),
|
||||
|
|
|
@ -86,10 +86,11 @@ interface IAppManager {
|
|||
* Enable an app for every user
|
||||
*
|
||||
* @param string $appId
|
||||
* @param bool $forceEnable
|
||||
* @throws AppPathNotFoundException
|
||||
* @since 8.0.0
|
||||
*/
|
||||
public function enableApp($appId);
|
||||
public function enableApp(string $appId, bool $forceEnable = false): void;
|
||||
|
||||
/**
|
||||
* Whether a list of types contains a protected app type
|
||||
|
@ -105,10 +106,11 @@ interface IAppManager {
|
|||
*
|
||||
* @param string $appId
|
||||
* @param \OCP\IGroup[] $groups
|
||||
* @param bool $forceEnable
|
||||
* @throws \Exception
|
||||
* @since 8.0.0
|
||||
*/
|
||||
public function enableAppForGroups($appId, $groups);
|
||||
public function enableAppForGroups(string $appId, array $groups, bool $forceEnable = false): void;
|
||||
|
||||
/**
|
||||
* Disable an app for every user
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?php
|
||||
<?php declare(strict_types=1);
|
||||
|
||||
/**
|
||||
* Copyright (c) 2014 Robin Appelman <icewind@owncloud.com>
|
||||
|
@ -11,20 +11,17 @@ namespace Test\App;
|
|||
|
||||
use OC\App\AppManager;
|
||||
use OC\AppConfig;
|
||||
use OC\Group\Group;
|
||||
use OC\User\User;
|
||||
use OCP\App\AppPathNotFoundException;
|
||||
use OCP\App\IAppManager;
|
||||
use OCP\IAppConfig;
|
||||
use OCP\ICache;
|
||||
use OCP\ICacheFactory;
|
||||
use OCP\IConfig;
|
||||
use OCP\IGroup;
|
||||
use OCP\IGroupManager;
|
||||
use OCP\ILogger;
|
||||
use OCP\IURLGenerator;
|
||||
use OCP\IUser;
|
||||
use OCP\IUserSession;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
|
||||
use Test\TestCase;
|
||||
|
||||
|
@ -35,7 +32,7 @@ use Test\TestCase;
|
|||
*/
|
||||
class AppManagerTest extends TestCase {
|
||||
/**
|
||||
* @return AppConfig|\PHPUnit_Framework_MockObject_MockObject
|
||||
* @return AppConfig|MockObject
|
||||
*/
|
||||
protected function getAppConfig() {
|
||||
$appConfig = array();
|
||||
|
@ -73,25 +70,28 @@ class AppManagerTest extends TestCase {
|
|||
return $config;
|
||||
}
|
||||
|
||||
/** @var IUserSession|\PHPUnit_Framework_MockObject_MockObject */
|
||||
/** @var IUserSession|MockObject */
|
||||
protected $userSession;
|
||||
|
||||
/** @var IGroupManager|\PHPUnit_Framework_MockObject_MockObject */
|
||||
/** @var IConfig|MockObject */
|
||||
private $config;
|
||||
|
||||
/** @var IGroupManager|MockObject */
|
||||
protected $groupManager;
|
||||
|
||||
/** @var AppConfig|\PHPUnit_Framework_MockObject_MockObject */
|
||||
/** @var AppConfig|MockObject */
|
||||
protected $appConfig;
|
||||
|
||||
/** @var ICache|\PHPUnit_Framework_MockObject_MockObject */
|
||||
/** @var ICache|MockObject */
|
||||
protected $cache;
|
||||
|
||||
/** @var ICacheFactory|\PHPUnit_Framework_MockObject_MockObject */
|
||||
/** @var ICacheFactory|MockObject */
|
||||
protected $cacheFactory;
|
||||
|
||||
/** @var EventDispatcherInterface|\PHPUnit_Framework_MockObject_MockObject */
|
||||
/** @var EventDispatcherInterface|MockObject */
|
||||
protected $eventDispatcher;
|
||||
|
||||
/** @var ILogger|\PHPUnit_Framework_MockObject_MockObject */
|
||||
/** @var ILogger|MockObject */
|
||||
protected $logger;
|
||||
|
||||
/** @var IAppManager */
|
||||
|
@ -102,6 +102,7 @@ class AppManagerTest extends TestCase {
|
|||
|
||||
$this->userSession = $this->createMock(IUserSession::class);
|
||||
$this->groupManager = $this->createMock(IGroupManager::class);
|
||||
$this->config = $this->createMock(IConfig::class);
|
||||
$this->appConfig = $this->getAppConfig();
|
||||
$this->cacheFactory = $this->createMock(ICacheFactory::class);
|
||||
$this->cache = $this->createMock(ICache::class);
|
||||
|
@ -111,7 +112,15 @@ class AppManagerTest extends TestCase {
|
|||
->method('createDistributed')
|
||||
->with('settings')
|
||||
->willReturn($this->cache);
|
||||
$this->manager = new AppManager($this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger);
|
||||
$this->manager = new AppManager(
|
||||
$this->userSession,
|
||||
$this->config,
|
||||
$this->appConfig,
|
||||
$this->groupManager,
|
||||
$this->cacheFactory,
|
||||
$this->eventDispatcher,
|
||||
$this->logger
|
||||
);
|
||||
}
|
||||
|
||||
protected function expectClearCache() {
|
||||
|
@ -161,10 +170,10 @@ class AppManagerTest extends TestCase {
|
|||
$groups = [$group1, $group2];
|
||||
$this->expectClearCache();
|
||||
|
||||
/** @var AppManager|\PHPUnit_Framework_MockObject_MockObject $manager */
|
||||
/** @var AppManager|MockObject $manager */
|
||||
$manager = $this->getMockBuilder(AppManager::class)
|
||||
->setConstructorArgs([
|
||||
$this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger
|
||||
$this->userSession, $this->config, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger
|
||||
])
|
||||
->setMethods([
|
||||
'getAppPath',
|
||||
|
@ -208,10 +217,10 @@ class AppManagerTest extends TestCase {
|
|||
$groups = [$group1, $group2];
|
||||
$this->expectClearCache();
|
||||
|
||||
/** @var AppManager|\PHPUnit_Framework_MockObject_MockObject $manager */
|
||||
/** @var AppManager|MockObject $manager */
|
||||
$manager = $this->getMockBuilder(AppManager::class)
|
||||
->setConstructorArgs([
|
||||
$this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger
|
||||
$this->userSession, $this->config, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger
|
||||
])
|
||||
->setMethods([
|
||||
'getAppPath',
|
||||
|
@ -262,10 +271,10 @@ class AppManagerTest extends TestCase {
|
|||
|
||||
$groups = [$group1, $group2];
|
||||
|
||||
/** @var AppManager|\PHPUnit_Framework_MockObject_MockObject $manager */
|
||||
/** @var AppManager|MockObject $manager */
|
||||
$manager = $this->getMockBuilder(AppManager::class)
|
||||
->setConstructorArgs([
|
||||
$this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger
|
||||
$this->userSession, $this->config, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger
|
||||
])
|
||||
->setMethods([
|
||||
'getAppPath',
|
||||
|
@ -426,9 +435,9 @@ class AppManagerTest extends TestCase {
|
|||
}
|
||||
|
||||
public function testGetAppsNeedingUpgrade() {
|
||||
/** @var AppManager|\PHPUnit_Framework_MockObject_MockObject $manager */
|
||||
/** @var AppManager|MockObject $manager */
|
||||
$manager = $this->getMockBuilder(AppManager::class)
|
||||
->setConstructorArgs([$this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger])
|
||||
->setConstructorArgs([$this->userSession, $this->config, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger])
|
||||
->setMethods(['getAppInfo'])
|
||||
->getMock();
|
||||
|
||||
|
@ -476,9 +485,9 @@ class AppManagerTest extends TestCase {
|
|||
}
|
||||
|
||||
public function testGetIncompatibleApps() {
|
||||
/** @var AppManager|\PHPUnit_Framework_MockObject_MockObject $manager */
|
||||
/** @var AppManager|MockObject $manager */
|
||||
$manager = $this->getMockBuilder(AppManager::class)
|
||||
->setConstructorArgs([$this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger])
|
||||
->setConstructorArgs([$this->userSession, $this->config, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger])
|
||||
->setMethods(['getAppInfo'])
|
||||
->getMock();
|
||||
|
||||
|
|
|
@ -549,6 +549,7 @@ class AppTest extends \Test\TestCase {
|
|||
$this->overwriteService('AppConfig', $appConfig);
|
||||
$this->overwriteService('AppManager', new \OC\App\AppManager(
|
||||
\OC::$server->getUserSession(),
|
||||
\OC::$server->getConfig(),
|
||||
$appConfig,
|
||||
\OC::$server->getGroupManager(),
|
||||
\OC::$server->getMemCacheFactory(),
|
||||
|
|
Loading…
Reference in a new issue