From 43eb375ace5c62201e2323b39a5f400b2bdc97b7 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Fri, 7 Nov 2014 14:26:12 +0100 Subject: [PATCH] Add \OC\App\Manager to handle enabling/disabling apps --- lib/private/app/appmanager.php | 138 ++++++++++++++++++++++ lib/private/server.php | 15 +++ lib/public/app/iappmanager.php | 51 +++++++++ lib/public/iservercontainer.php | 7 ++ tests/lib/app/manager.php | 195 ++++++++++++++++++++++++++++++++ 5 files changed, 406 insertions(+) create mode 100644 lib/private/app/appmanager.php create mode 100644 lib/public/app/iappmanager.php create mode 100644 tests/lib/app/manager.php diff --git a/lib/private/app/appmanager.php b/lib/private/app/appmanager.php new file mode 100644 index 00000000000..6d9aa0bfe37 --- /dev/null +++ b/lib/private/app/appmanager.php @@ -0,0 +1,138 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OC\App; + +use OCP\App\IAppManager; +use OCP\IAppConfig; +use OCP\IGroupManager; +use OCP\IUserSession; + +class AppManager implements IAppManager { + /** + * @var \OCP\IUserSession + */ + private $userSession; + + /** + * @var \OCP\IAppConfig + */ + private $appConfig; + + /** + * @var \OCP\IGroupManager + */ + private $groupManager; + + /** + * @var string[] $appId => $enabled + */ + private $installedAppsCache; + + /** + * @param \OCP\IUserSession $userSession + * @param \OCP\IAppConfig $appConfig + * @param \OCP\IGroupManager $groupManager + */ + public function __construct(IUserSession $userSession, IAppConfig $appConfig, IGroupManager $groupManager) { + $this->userSession = $userSession; + $this->appConfig = $appConfig; + $this->groupManager = $groupManager; + } + + /** + * @return string[] $appId => $enabled + */ + private function getInstalledApps() { + if (!$this->installedAppsCache) { + $values = $this->appConfig->getValues(false, 'enabled'); + $this->installedAppsCache = array_filter($values, function ($value) { + return $value !== 'no'; + }); + ksort($this->installedAppsCache); + } + return $this->installedAppsCache; + } + + /** + * Check if an app is enabled for user + * + * @param string $appId + * @param \OCP\IUser $user (optional) if not defined, the currently logged in user will be used + * @return bool + */ + public function isEnabledForUser($appId, $user = null) { + if (is_null($user)) { + $user = $this->userSession->getUser(); + } + $installedApps = $this->getInstalledApps(); + if (isset($installedApps[$appId])) { + $enabled = $installedApps[$appId]; + if ($enabled === 'yes') { + return true; + } elseif (is_null($user)) { + return false; + } else { + $groupIds = json_decode($enabled); + $userGroups = $this->groupManager->getUserGroupIds($user); + foreach ($userGroups as $groupId) { + if (array_search($groupId, $groupIds) !== false) { + return true; + } + } + return false; + } + } else { + return false; + } + } + + /** + * Check if an app is installed in the instance + * + * @param string $appId + * @return bool + */ + public function isInstalled($appId) { + $installedApps = $this->getInstalledApps(); + return isset($installedApps[$appId]); + } + + /** + * Enable an app for every user + * + * @param string $appId + */ + public function enableApp($appId) { + $this->appConfig->setValue($appId, 'enabled', 'yes'); + } + + /** + * Enable an app only for specific groups + * + * @param string $appId + * @param \OCP\IGroup[] $groups + */ + public function enableAppForGroups($appId, $groups) { + $groupIds = array_map(function ($group) { + /** @var \OCP\IGroup $group */ + return $group->getGID(); + }, $groups); + $this->appConfig->setValue($appId, 'enabled', json_encode($groupIds)); + } + + /** + * Disable an app for every user + * + * @param string $appId + */ + public function disableApp($appId) { + $this->appConfig->setValue($appId, 'enabled', 'no'); + } +} diff --git a/lib/private/server.php b/lib/private/server.php index f43613e8188..c413ee8bf6d 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -237,6 +237,12 @@ class Server extends SimpleContainer implements IServerContainer { /** @var Server $c */ return new TempManager(get_temp_dir(), $c->getLogger()); }); + $this->registerService('AppManager', function(Server $c) { + $userSession = $c->getUserSession(); + $appConfig = $c->getAppConfig(); + $groupManager = $c->getGroupManager(); + return new \OC\App\AppManager($userSession, $appConfig, $groupManager); + }); } /** @@ -616,4 +622,13 @@ class Server extends SimpleContainer implements IServerContainer { function getTempManager() { return $this->query('TempManager'); } + + /** + * Get the app manager + * + * @return \OCP\App\IAppManager + */ + function getAppManager() { + return $this->query('AppManager'); + } } diff --git a/lib/public/app/iappmanager.php b/lib/public/app/iappmanager.php new file mode 100644 index 00000000000..ebd84a1ce9d --- /dev/null +++ b/lib/public/app/iappmanager.php @@ -0,0 +1,51 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace OCP\App; + +interface IAppManager { + /** + * Check if an app is enabled for user + * + * @param string $appId + * @param \OCP\IUser $user (optional) if not defined, the currently loggedin user will be used + * @return bool + */ + public function isEnabledForUser($appId, $user = null); + + /** + * Check if an app is installed in the instance + * + * @param string $appId + * @return bool + */ + public function isInstalled($appId); + + /** + * Enable an app for every user + * + * @param string $appId + */ + public function enableApp($appId); + + /** + * Enable an app only for specific groups + * + * @param string $appId + * @param \OCP\IGroup[] $groups + */ + public function enableAppForGroups($appId, $groups); + + /** + * Disable an app for every user + * + * @param string $appId + */ + public function disableApp($appId); +} diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php index 794bba6bfb6..b734d1b4161 100644 --- a/lib/public/iservercontainer.php +++ b/lib/public/iservercontainer.php @@ -291,4 +291,11 @@ interface IServerContainer { * @return \OCP\ITempManager */ function getTempManager(); + + /** + * Get the app manager + * + * @return \OCP\App\IAppManager + */ + function getAppManager(); } diff --git a/tests/lib/app/manager.php b/tests/lib/app/manager.php new file mode 100644 index 00000000000..4c0555b501f --- /dev/null +++ b/tests/lib/app/manager.php @@ -0,0 +1,195 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +namespace Test\App; + +use OC\Group\Group; +use OC\User\User; + +class Manager extends \PHPUnit_Framework_TestCase { + /** + * @return \OCP\IAppConfig | \PHPUnit_Framework_MockObject_MockObject + */ + protected function getAppConfig() { + $appConfig = array(); + $config = $this->getMockBuilder('\OCP\IAppConfig') + ->disableOriginalConstructor() + ->getMock(); + + $config->expects($this->any()) + ->method('getValue') + ->will($this->returnCallback(function ($app, $key, $default) use (&$appConfig) { + return (isset($appConfig[$app]) and isset($appConfig[$app][$key])) ? $appConfig[$app][$key] : $default; + })); + $config->expects($this->any()) + ->method('setValue') + ->will($this->returnCallback(function ($app, $key, $value) use (&$appConfig) { + if (!isset($appConfig[$app])) { + $appConfig[$app] = array(); + } + $appConfig[$app][$key] = $value; + })); + $config->expects($this->any()) + ->method('getValues') + ->will($this->returnCallback(function ($app, $key) use (&$appConfig) { + if ($app) { + return $appConfig[$app]; + } else { + $values = array(); + foreach ($appConfig as $app => $appData) { + if (isset($appData[$key])) { + $values[$app] = $appData[$key]; + } + } + return $values; + } + })); + + return $config; + } + + public function testEnableApp() { + $userSession = $this->getMock('\OCP\IUserSession'); + $groupManager = $this->getMock('\OCP\IGroupManager'); + $appConfig = $this->getAppConfig(); + $manager = new \OC\App\AppManager($userSession, $appConfig, $groupManager); + $manager->enableApp('test'); + $this->assertEquals('yes', $appConfig->getValue('test', 'enabled', 'no')); + } + + public function testDisableApp() { + $userSession = $this->getMock('\OCP\IUserSession'); + $groupManager = $this->getMock('\OCP\IGroupManager'); + $appConfig = $this->getAppConfig(); + $manager = new \OC\App\AppManager($userSession, $appConfig, $groupManager); + $manager->disableApp('test'); + $this->assertEquals('no', $appConfig->getValue('test', 'enabled', 'no')); + } + + public function testEnableAppForGroups() { + $groups = array( + new Group('group1', array(), null), + new Group('group2', array(), null) + ); + $groupManager = $this->getMock('\OCP\IGroupManager'); + $userSession = $this->getMock('\OCP\IUserSession'); + $appConfig = $this->getAppConfig(); + $manager = new \OC\App\AppManager($userSession, $appConfig, $groupManager); + $manager->enableAppForGroups('test', $groups); + $this->assertEquals('["group1","group2"]', $appConfig->getValue('test', 'enabled', 'no')); + } + + public function testIsInstalledEnabled() { + $userSession = $this->getMock('\OCP\IUserSession'); + $groupManager = $this->getMock('\OCP\IGroupManager'); + $appConfig = $this->getAppConfig(); + $manager = new \OC\App\AppManager($userSession, $appConfig, $groupManager); + $appConfig->setValue('test', 'enabled', 'yes'); + $this->assertTrue($manager->isInstalled('test')); + } + + public function testIsInstalledDisabled() { + $userSession = $this->getMock('\OCP\IUserSession'); + $groupManager = $this->getMock('\OCP\IGroupManager'); + $appConfig = $this->getAppConfig(); + $manager = new \OC\App\AppManager($userSession, $appConfig, $groupManager); + $appConfig->setValue('test', 'enabled', 'no'); + $this->assertFalse($manager->isInstalled('test')); + } + + public function testIsInstalledEnabledForGroups() { + $userSession = $this->getMock('\OCP\IUserSession'); + $groupManager = $this->getMock('\OCP\IGroupManager'); + $appConfig = $this->getAppConfig(); + $manager = new \OC\App\AppManager($userSession, $appConfig, $groupManager); + $appConfig->setValue('test', 'enabled', '["foo"]'); + $this->assertTrue($manager->isInstalled('test')); + } + + public function testIsEnabledForUserEnabled() { + $userSession = $this->getMock('\OCP\IUserSession'); + $groupManager = $this->getMock('\OCP\IGroupManager'); + $appConfig = $this->getAppConfig(); + $manager = new \OC\App\AppManager($userSession, $appConfig, $groupManager); + $appConfig->setValue('test', 'enabled', 'yes'); + $user = new User('user1', null); + $this->assertTrue($manager->isEnabledForUser('test', $user)); + } + + public function testIsEnabledForUserDisabled() { + $userSession = $this->getMock('\OCP\IUserSession'); + $groupManager = $this->getMock('\OCP\IGroupManager'); + $appConfig = $this->getAppConfig(); + $manager = new \OC\App\AppManager($userSession, $appConfig, $groupManager); + $appConfig->setValue('test', 'enabled', 'no'); + $user = new User('user1', null); + $this->assertFalse($manager->isEnabledForUser('test', $user)); + } + + public function testIsEnabledForUserEnabledForGroup() { + $userSession = $this->getMock('\OCP\IUserSession'); + $groupManager = $this->getMock('\OCP\IGroupManager'); + $user = new User('user1', null); + + $groupManager->expects($this->once()) + ->method('getUserGroupIds') + ->with($user) + ->will($this->returnValue(array('foo', 'bar'))); + + $appConfig = $this->getAppConfig(); + $manager = new \OC\App\AppManager($userSession, $appConfig, $groupManager); + $appConfig->setValue('test', 'enabled', '["foo"]'); + $this->assertTrue($manager->isEnabledForUser('test', $user)); + } + + public function testIsEnabledForUserDisabledForGroup() { + $userSession = $this->getMock('\OCP\IUserSession'); + $groupManager = $this->getMock('\OCP\IGroupManager'); + $user = new User('user1', null); + + $groupManager->expects($this->once()) + ->method('getUserGroupIds') + ->with($user) + ->will($this->returnValue(array('bar'))); + + $appConfig = $this->getAppConfig(); + $manager = new \OC\App\AppManager($userSession, $appConfig, $groupManager); + $appConfig->setValue('test', 'enabled', '["foo"]'); + $this->assertFalse($manager->isEnabledForUser('test', $user)); + } + + public function testIsEnabledForUserLoggedOut() { + $userSession = $this->getMock('\OCP\IUserSession'); + $groupManager = $this->getMock('\OCP\IGroupManager'); + + $appConfig = $this->getAppConfig(); + $manager = new \OC\App\AppManager($userSession, $appConfig, $groupManager); + $appConfig->setValue('test', 'enabled', '["foo"]'); + $this->assertFalse($manager->IsEnabledForUser('test')); + } + + public function testIsEnabledForUserLoggedIn() { + $userSession = $this->getMock('\OCP\IUserSession'); + $groupManager = $this->getMock('\OCP\IGroupManager'); + $user = new User('user1', null); + + $userSession->expects($this->once()) + ->method('getUser') + ->will($this->returnValue($user)); + $groupManager->expects($this->once()) + ->method('getUserGroupIds') + ->with($user) + ->will($this->returnValue(array('foo', 'bar'))); + + $appConfig = $this->getAppConfig(); + $manager = new \OC\App\AppManager($userSession, $appConfig, $groupManager); + $appConfig->setValue('test', 'enabled', '["foo"]'); + $this->assertTrue($manager->isEnabledForUser('test')); + } +}