aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/base.php25
-rw-r--r--lib/private/App/AppManager.php75
-rw-r--r--lib/private/Server.php3
-rw-r--r--lib/public/App/IAppManager.php15
-rw-r--r--tests/lib/App/AppManagerTest.php53
-rw-r--r--tests/lib/AppTest.php3
6 files changed, 163 insertions, 11 deletions
diff --git a/lib/base.php b/lib/base.php
index 30d57153de9..7812922c168 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -717,6 +717,7 @@ class OC {
self::registerEncryptionHooks();
self::registerAccountHooks();
self::registerResourceCollectionHooks();
+ self::registerAppRestrictionsHooks();
// Make sure that the application class is not loaded before the database is setup
if ($systemConfig->getValue("installed", false)) {
@@ -848,6 +849,30 @@ class OC {
\OCP\Util::connectHook('OC_User', 'changeUser', $hookHandler, 'changeUserHook');
}
+ private static function registerAppRestrictionsHooks() {
+ $groupManager = self::$server->query(\OCP\IGroupManager::class);
+ $groupManager->listen ('\OC\Group', 'postDelete', function (\OCP\IGroup $group) {
+ $appManager = self::$server->getAppManager();
+ $apps = $appManager->getEnabledAppsForGroup($group);
+ foreach ($apps as $appId) {
+ $restrictions = $appManager->getAppRestriction($appId);
+ if (empty($restrictions)) {
+ continue;
+ }
+ $key = array_search($group->getGID(), $restrictions);
+ unset($restrictions[$key]);
+ $restrictions = array_values($restrictions);
+ if (empty($restrictions)) {
+ $appManager->disableApp($appId);
+ }
+ else{
+ $appManager->enableAppForGroups($appId, $restrictions);
+ }
+
+ }
+ });
+ }
+
private static function registerResourceCollectionHooks() {
\OC\Collaboration\Resources\Listener::register(\OC::$server->getEventDispatcher());
}
diff --git a/lib/private/App/AppManager.php b/lib/private/App/AppManager.php
index 7d4dbbbd34e..17addc86c9d 100644
--- a/lib/private/App/AppManager.php
+++ b/lib/private/App/AppManager.php
@@ -37,7 +37,9 @@ use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
use OCP\App\ManagerEvent;
use OCP\ICacheFactory;
+use OCP\IGroup;
use OCP\IGroupManager;
+use OCP\ILogger;
use OCP\IUser;
use OCP\IUserSession;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
@@ -71,6 +73,9 @@ class AppManager implements IAppManager {
/** @var EventDispatcherInterface */
private $dispatcher;
+ /** @var ILogger */
+ private $logger;
+
/** @var string[] $appId => $enabled */
private $installedAppsCache;
@@ -97,12 +102,14 @@ class AppManager implements IAppManager {
AppConfig $appConfig,
IGroupManager $groupManager,
ICacheFactory $memCacheFactory,
- EventDispatcherInterface $dispatcher) {
+ EventDispatcherInterface $dispatcher,
+ ILogger $logger) {
$this->userSession = $userSession;
$this->appConfig = $appConfig;
$this->groupManager = $groupManager;
$this->memCacheFactory = $memCacheFactory;
$this->dispatcher = $dispatcher;
+ $this->logger = $logger;
}
/**
@@ -149,6 +156,36 @@ class AppManager implements IAppManager {
}
/**
+ * @param \OCP\IGroup $group
+ * @return array
+ */
+ public function getEnabledAppsForGroup(IGroup $group): array {
+ $apps = $this->getInstalledAppsValues();
+ $appsForGroups = array_filter($apps, function ($enabled) use ($group) {
+ return $this->checkAppForGroups($enabled, $group);
+ });
+ return array_keys($appsForGroups);
+ }
+
+ /**
+ * @param string $appId
+ * @return array
+ */
+ public function getAppRestriction(string $appId): array {
+ $values = $this->getInstalledAppsValues();
+
+ if (!isset($values[$appId])) {
+ return [];
+ }
+
+ if ($values[$appId] === 'yes' || $values[$appId] === 'no') {
+ return [];
+ }
+ return json_decode($values[$appId]);
+ }
+
+
+ /**
* Check if an app is enabled for user
*
* @param string $appId
@@ -189,7 +226,7 @@ class AppManager implements IAppManager {
if (!is_array($groupIds)) {
$jsonError = json_last_error();
- \OC::$server->getLogger()->warning('AppManger::checkAppForUser - can\'t decode group IDs: ' . print_r($enabled, true) . ' - json error code: ' . $jsonError, ['app' => 'lib']);
+ $this->logger->warning('AppManger::checkAppForUser - can\'t decode group IDs: ' . print_r($enabled, true) . ' - json error code: ' . $jsonError, ['app' => 'lib']);
return false;
}
@@ -204,11 +241,39 @@ class AppManager implements IAppManager {
}
/**
+ * @param string $enabled
+ * @param IGroup $group
+ * @return bool
+ */
+ private function checkAppForGroups(string $enabled, IGroup $group): bool {
+ if ($enabled === 'yes') {
+ return true;
+ } elseif ($group === null) {
+ return false;
+ } else {
+ if (empty($enabled)) {
+ return false;
+ }
+
+ $groupIds = json_decode($enabled);
+
+ if (!is_array($groupIds)) {
+ $jsonError = json_last_error();
+ $this->logger->warning('AppManger::checkAppForUser - can\'t decode group IDs: ' . print_r($enabled, true) . ' - json error code: ' . $jsonError, ['app' => 'lib']);
+ return false;
+ }
+
+ return in_array($group->getGID(), $groupIds);
+ }
+ }
+
+ /**
* Check if an app is enabled in the instance
*
* Notice: This actually checks if the app is enabled and not only if it is installed.
*
* @param string $appId
+ * @param \OCP\IGroup[]|String[] $groups
* @return bool
*/
public function isInstalled($appId) {
@@ -268,14 +333,18 @@ class AppManager implements IAppManager {
$groupIds = array_map(function ($group) {
/** @var \OCP\IGroup $group */
- return $group->getGID();
+ return ($group instanceof IGroup)
+ ? $group->getGID()
+ : $group;
}, $groups);
+
$this->installedAppsCache[$appId] = json_encode($groupIds);
$this->appConfig->setValue($appId, 'enabled', json_encode($groupIds));
$this->dispatcher->dispatch(ManagerEvent::EVENT_APP_ENABLE_FOR_GROUPS, new ManagerEvent(
ManagerEvent::EVENT_APP_ENABLE_FOR_GROUPS, $appId, $groups
));
$this->clearAppsCache();
+
}
/**
diff --git a/lib/private/Server.php b/lib/private/Server.php
index c716b996a37..ccdb31c3e82 100644
--- a/lib/private/Server.php
+++ b/lib/private/Server.php
@@ -694,7 +694,8 @@ class Server extends ServerContainer implements IServerContainer {
$c->query(\OC\AppConfig::class),
$c->getGroupManager(),
$c->getMemCacheFactory(),
- $c->getEventDispatcher()
+ $c->getEventDispatcher(),
+ $c->getLogger()
);
});
$this->registerAlias('AppManager', AppManager::class);
diff --git a/lib/public/App/IAppManager.php b/lib/public/App/IAppManager.php
index b0d04500f35..6213227bfd1 100644
--- a/lib/public/App/IAppManager.php
+++ b/lib/public/App/IAppManager.php
@@ -28,6 +28,7 @@
namespace OCP\App;
use OCP\IUser;
+use OCP\IGroup;
/**
* Interface IAppManager
@@ -158,4 +159,18 @@ interface IAppManager {
* @since 9.0.0
*/
public function getAlwaysEnabledApps();
+
+ /**
+ * @param \OCP\IGroup $group
+ * @return String[]
+ * @since 17.0.0
+ */
+ public function getEnabledAppsForGroup(IGroup $group): array;
+
+ /**
+ * @param String $appId
+ * @return string[]
+ * @since 17.0.0
+ */
+ public function getAppRestriction(string $appId): array;
}
diff --git a/tests/lib/App/AppManagerTest.php b/tests/lib/App/AppManagerTest.php
index cb94ccf44d0..371c2373f81 100644
--- a/tests/lib/App/AppManagerTest.php
+++ b/tests/lib/App/AppManagerTest.php
@@ -19,6 +19,7 @@ use OCP\ICache;
use OCP\ICacheFactory;
use OCP\IGroup;
use OCP\IGroupManager;
+use OCP\ILogger;
use OCP\IUser;
use OCP\IUserSession;
use OCP\IAppConfig;
@@ -90,6 +91,9 @@ class AppManagerTest extends TestCase {
/** @var EventDispatcherInterface|\PHPUnit_Framework_MockObject_MockObject */
protected $eventDispatcher;
+ /** @var ILogger|\PHPUnit_Framework_MockObject_MockObject */
+ protected $logger;
+
/** @var IAppManager */
protected $manager;
@@ -102,11 +106,12 @@ class AppManagerTest extends TestCase {
$this->cacheFactory = $this->createMock(ICacheFactory::class);
$this->cache = $this->createMock(ICache::class);
$this->eventDispatcher = $this->createMock(EventDispatcherInterface::class);
+ $this->logger = $this->createMock(ILogger::class);
$this->cacheFactory->expects($this->any())
->method('createDistributed')
->with('settings')
->willReturn($this->cache);
- $this->manager = new AppManager($this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher);
+ $this->manager = new AppManager($this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger);
}
protected function expectClearCache() {
@@ -159,7 +164,7 @@ class AppManagerTest extends TestCase {
/** @var AppManager|\PHPUnit_Framework_MockObject_MockObject $manager */
$manager = $this->getMockBuilder(AppManager::class)
->setConstructorArgs([
- $this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher
+ $this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger
])
->setMethods([
'getAppPath',
@@ -206,7 +211,7 @@ class AppManagerTest extends TestCase {
/** @var AppManager|\PHPUnit_Framework_MockObject_MockObject $manager */
$manager = $this->getMockBuilder(AppManager::class)
->setConstructorArgs([
- $this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher
+ $this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger
])
->setMethods([
'getAppPath',
@@ -259,7 +264,7 @@ class AppManagerTest extends TestCase {
/** @var AppManager|\PHPUnit_Framework_MockObject_MockObject $manager */
$manager = $this->getMockBuilder(AppManager::class)
->setConstructorArgs([
- $this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher
+ $this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger
])
->setMethods([
'getAppPath',
@@ -418,7 +423,7 @@ class AppManagerTest extends TestCase {
public function testGetAppsNeedingUpgrade() {
/** @var AppManager|\PHPUnit_Framework_MockObject_MockObject $manager */
$manager = $this->getMockBuilder(AppManager::class)
- ->setConstructorArgs([$this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher])
+ ->setConstructorArgs([$this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger])
->setMethods(['getAppInfo'])
->getMock();
@@ -466,7 +471,7 @@ class AppManagerTest extends TestCase {
public function testGetIncompatibleApps() {
/** @var AppManager|\PHPUnit_Framework_MockObject_MockObject $manager */
$manager = $this->getMockBuilder(AppManager::class)
- ->setConstructorArgs([$this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher])
+ ->setConstructorArgs([$this->userSession, $this->appConfig, $this->groupManager, $this->cacheFactory, $this->eventDispatcher, $this->logger])
->setMethods(['getAppInfo'])
->getMock();
@@ -504,4 +509,40 @@ class AppManagerTest extends TestCase {
$this->assertEquals('test1', $apps[0]['id']);
$this->assertEquals('test3', $apps[1]['id']);
}
+
+ public function testGetEnabledAppsForGroup() {
+ $group = $this->createMock(IGroup::class);
+ $group->expects($this->any())
+ ->method('getGID')
+ ->will($this->returnValue('foo'));
+
+ $this->appConfig->setValue('test1', 'enabled', 'yes');
+ $this->appConfig->setValue('test2', 'enabled', 'no');
+ $this->appConfig->setValue('test3', 'enabled', '["foo"]');
+ $this->appConfig->setValue('test4', 'enabled', '["asd"]');
+ $enabled = [
+ 'cloud_federation_api',
+ 'dav',
+ 'federatedfilesharing',
+ 'files',
+ 'lookup_server_connector',
+ 'oauth2',
+ 'provisioning_api',
+ 'test1',
+ 'test3',
+ 'twofactor_backupcodes',
+ 'workflowengine',
+ ];
+ $this->assertEquals($enabled, $this->manager->getEnabledAppsForGroup($group));
+ }
+
+ public function testGetAppRestriction() {
+ $this->appConfig->setValue('test1', 'enabled', 'yes');
+ $this->appConfig->setValue('test2', 'enabled', 'no');
+ $this->appConfig->setValue('test3', 'enabled', '["foo"]');
+
+ $this->assertEquals([], $this->manager->getAppRestriction('test1'));
+ $this->assertEquals([], $this->manager->getAppRestriction('test2'));
+ $this->assertEquals(['foo'], $this->manager->getAppRestriction('test3'));
+ }
}
diff --git a/tests/lib/AppTest.php b/tests/lib/AppTest.php
index 5d98dc7df57..954ffcfae7f 100644
--- a/tests/lib/AppTest.php
+++ b/tests/lib/AppTest.php
@@ -542,7 +542,8 @@ class AppTest extends \Test\TestCase {
$appConfig,
\OC::$server->getGroupManager(),
\OC::$server->getMemCacheFactory(),
- \OC::$server->getEventDispatcher()
+ \OC::$server->getEventDispatcher(),
+ \OC::$server->getLogger()
));
}