aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Petry <pvince81@owncloud.com>2016-12-07 00:19:14 +0100
committerJulius Härtl <jus@bitgrid.net>2017-10-14 20:50:53 +0200
commita829ac787aa2dc56b780b7719f0b023daaaf48b6 (patch)
tree38165028462941f649fdc0ed5e11fed8aabddb9d
parent7a05cf300c6b3d4bdfff1bb61aa39822ff88fb8b (diff)
downloadnextcloud-server-a829ac787aa2dc56b780b7719f0b023daaaf48b6.tar.gz
nextcloud-server-a829ac787aa2dc56b780b7719f0b023daaaf48b6.zip
Let apps register Sabre plugins or collections
upstream #26761 Signed-off-by: Julius Härtl <jus@bitgrid.net>
-rw-r--r--apps/dav/appinfo/v2/remote.php1
-rw-r--r--apps/dav/lib/AppInfo/PluginManager.php170
-rw-r--r--apps/dav/lib/Server.php16
-rw-r--r--apps/dav/tests/unit/AppInfo/PluginManagerTest.php104
-rw-r--r--apps/dav/tests/unit/ServerTest.php4
5 files changed, 291 insertions, 4 deletions
diff --git a/apps/dav/appinfo/v2/remote.php b/apps/dav/appinfo/v2/remote.php
index 3a00c8006ec..c1b29a4a177 100644
--- a/apps/dav/appinfo/v2/remote.php
+++ b/apps/dav/appinfo/v2/remote.php
@@ -3,6 +3,7 @@
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
* @author Thomas Müller <thomas.mueller@tmit.eu>
+ * @author Vincent Petry <pvince81@owncloud.com>
*
* @license AGPL-3.0
*
diff --git a/apps/dav/lib/AppInfo/PluginManager.php b/apps/dav/lib/AppInfo/PluginManager.php
new file mode 100644
index 00000000000..411cf73e815
--- /dev/null
+++ b/apps/dav/lib/AppInfo/PluginManager.php
@@ -0,0 +1,170 @@
+<?php
+/**
+ * @author Vincent Petry <pvince81@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud GmbH.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+namespace OCA\DAV\AppInfo;
+
+use OCP\App\IAppManager;
+use OC\ServerContainer;
+use OCP\AppFramework\QueryException;
+
+/**
+ * Manager for DAV plugins from apps, used to register them
+ * to the Sabre server.
+ */
+class PluginManager {
+
+ /**
+ * @var ServerContainer
+ */
+ private $container;
+
+ /**
+ * @var IAppManager
+ */
+ private $appManager;
+
+ /**
+ * App plugins
+ *
+ * @var array
+ */
+ private $plugins = null;
+
+ /**
+ * App collections
+ *
+ * @var array
+ */
+ private $collections = null;
+
+ /**
+ * Contstruct a PluginManager
+ *
+ * @param ServerContainer $container server container for resolving plugin classes
+ * @param IAppManager $appManager app manager to loading apps and their info
+ */
+ public function __construct(ServerContainer $container, IAppManager $appManager) {
+ $this->container = $container;
+ $this->appManager = $appManager;
+ }
+
+ /**
+ * Returns an array of app-registered plugins
+ *
+ * @return array
+ */
+ public function getAppPlugins() {
+ if (is_null($this->plugins)) {
+ $this->populate();
+ }
+ return $this->plugins;
+ }
+
+ /**
+ * Returns an array of app-registered collections
+ *
+ * @return array
+ */
+ public function getAppCollections() {
+ if (is_null($this->collections)) {
+ $this->populate();
+ }
+ return $this->collections;
+ }
+
+ /**
+ * Retrieve plugin and collection list and populate attributes
+ */
+ private function populate() {
+ $this->plugins = [];
+ $this->collections = [];
+ foreach ($this->appManager->getInstalledApps() as $app) {
+ // load plugins and collections from info.xml
+ $info = $this->appManager->getAppInfo($app);
+ if (!isset($info['types']) || !in_array('dav', $info['types'])) {
+ continue;
+ }
+ // FIXME: switch to public API once available
+ // load app to make sure its classes are available
+ \OC_App::loadApp($app);
+ $this->loadSabrePluginsFromInfoXml($this->extractPluginList($info));
+ $this->loadSabreCollectionsFromInfoXml($this->extractCollectionList($info));
+ }
+ }
+
+ private function extractPluginList($array) {
+ if (isset($array['sabre']) && is_array($array['sabre'])) {
+ if (isset($array['sabre']['plugins']) && is_array($array['sabre']['plugins'])) {
+ if (isset($array['sabre']['plugins']['plugin'])) {
+ $items = $array['sabre']['plugins']['plugin'];
+ if (!is_array($items)) {
+ $items = [$items];
+ }
+ return $items;
+ }
+ }
+ }
+ return [];
+ }
+
+ private function extractCollectionList($array) {
+ if (isset($array['sabre']) && is_array($array['sabre'])) {
+ if (isset($array['sabre']['collections']) && is_array($array['sabre']['collections'])) {
+ if (isset($array['sabre']['collections']['collection'])) {
+ $items = $array['sabre']['collections']['collection'];
+ if (!is_array($items)) {
+ $items = [$items];
+ }
+ return $items;
+ }
+ }
+ }
+ return [];
+ }
+
+ private function loadSabrePluginsFromInfoXml($plugins) {
+ foreach ($plugins as $plugin) {
+ try {
+ $this->plugins[] = $this->container->query($plugin);
+ } catch (QueryException $e) {
+ if (class_exists($plugin)) {
+ $this->plugins[] = new $plugin();
+ } else {
+ throw new \Exception("Sabre plugin class '$plugin' is unknown and could not be loaded");
+ }
+ }
+ }
+ }
+
+ private function loadSabreCollectionsFromInfoXml($collections) {
+ foreach ($collections as $collection) {
+ try {
+ $this->collections[] = $this->container->query($collection);
+ } catch (QueryException $e) {
+ if (class_exists($collection)) {
+ $this->collections[] = new $collection();
+ } else {
+ throw new \Exception("Sabre collection class '$collection' is unknown and could not be loaded");
+ }
+ }
+ };
+ }
+
+}
diff --git a/apps/dav/lib/Server.php b/apps/dav/lib/Server.php
index 6f3ab3971ef..162833951a3 100644
--- a/apps/dav/lib/Server.php
+++ b/apps/dav/lib/Server.php
@@ -55,8 +55,8 @@ use OCP\SabrePluginEvent;
use Sabre\CardDAV\VCFExportPlugin;
use Sabre\DAV\Auth\Plugin;
use OCA\DAV\Connector\Sabre\TagsPlugin;
-use Sabre\HTTP\Auth\Bearer;
use SearchDAV\DAV\SearchPlugin;
+use OCA\DAV\AppInfo\PluginManager;
class Server {
@@ -184,7 +184,7 @@ class Server {
}
// wait with registering these until auth is handled and the filesystem is setup
- $this->server->on('beforeMethod', function () {
+ $this->server->on('beforeMethod', function () use ($root) {
// custom properties plugin must be the last one
$userSession = \OC::$server->getUserSession();
$user = $userSession->getUser();
@@ -252,6 +252,18 @@ class Server {
)));
}
}
+
+ // register plugins from apps
+ $pluginManager = new PluginManager(
+ \OC::$server,
+ \OC::$server->getAppManager()
+ );
+ foreach ($pluginManager->getAppPlugins() as $appPlugin) {
+ $this->server->addPlugin($appPlugin);
+ }
+ foreach ($pluginManager->getAppCollections() as $appCollection) {
+ $root->addChild($appCollection);
+ }
});
}
diff --git a/apps/dav/tests/unit/AppInfo/PluginManagerTest.php b/apps/dav/tests/unit/AppInfo/PluginManagerTest.php
new file mode 100644
index 00000000000..5776b939123
--- /dev/null
+++ b/apps/dav/tests/unit/AppInfo/PluginManagerTest.php
@@ -0,0 +1,104 @@
+<?php
+/**
+ * @author Vincent Petry <pvince81@owncloud.com>
+ *
+ * @copyright Copyright (c) 2016, ownCloud GmbH.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program. If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\DAV\Tests\unit\AppInfo;
+
+use Test\TestCase;
+use OCP\App\IAppManager;
+use OC\ServerContainer;
+use OCA\DAV\AppInfo\PluginManager;
+
+/**
+ * Class PluginManagerTest
+ *
+ * @package OCA\DAV\Tests\Unit\AppInfo
+ */
+class PluginManagerTest extends TestCase {
+ public function test() {
+ $server = $this->createMock(ServerContainer::class);
+
+
+ $appManager = $this->createMock(IAppManager::class);
+ $appManager->method('getInstalledApps')
+ ->willReturn(['adavapp', 'adavapp2']);
+
+ $appInfo1 = [
+ 'types' => ['dav'],
+ 'sabre' => [
+ 'plugins' => [
+ 'plugin' => [
+ '\OCA\DAV\ADavApp\PluginOne',
+ '\OCA\DAV\ADavApp\PluginTwo',
+ ],
+ ],
+ 'collections' => [
+ 'collection' => [
+ '\OCA\DAV\ADavApp\CollectionOne',
+ '\OCA\DAV\ADavApp\CollectionTwo',
+ ]
+ ],
+ ],
+ ];
+ $appInfo2 = [
+ 'types' => ['logging', 'dav'],
+ 'sabre' => [
+ 'plugins' => [
+ 'plugin' => '\OCA\DAV\ADavApp2\PluginOne',
+ ],
+ 'collections' => [
+ 'collection' => '\OCA\DAV\ADavApp2\CollectionOne',
+ ],
+ ],
+ ];
+
+ $appManager->method('getAppInfo')
+ ->will($this->returnValueMap([
+ ['adavapp', $appInfo1],
+ ['adavapp2', $appInfo2],
+ ]));
+
+ $pluginManager = new PluginManager($server, $appManager);
+
+ $server->method('query')
+ ->will($this->returnValueMap([
+ ['\OCA\DAV\ADavApp\PluginOne', 'dummyplugin1'],
+ ['\OCA\DAV\ADavApp\PluginTwo', 'dummyplugin2'],
+ ['\OCA\DAV\ADavApp\CollectionOne', 'dummycollection1'],
+ ['\OCA\DAV\ADavApp\CollectionTwo', 'dummycollection2'],
+ ['\OCA\DAV\ADavApp2\PluginOne', 'dummy2plugin1'],
+ ['\OCA\DAV\ADavApp2\CollectionOne', 'dummy2collection1'],
+ ]));
+
+ $expectedPlugins = [
+ 'dummyplugin1',
+ 'dummyplugin2',
+ 'dummy2plugin1',
+ ];
+ $expectedCollections = [
+ 'dummycollection1',
+ 'dummycollection2',
+ 'dummy2collection1',
+ ];
+
+ $this->assertEquals($expectedPlugins, $pluginManager->getAppPlugins());
+ $this->assertEquals($expectedCollections, $pluginManager->getAppCollections());
+ }
+}
diff --git a/apps/dav/tests/unit/ServerTest.php b/apps/dav/tests/unit/ServerTest.php
index 19e75c7b24e..1b430b0f198 100644
--- a/apps/dav/tests/unit/ServerTest.php
+++ b/apps/dav/tests/unit/ServerTest.php
@@ -26,6 +26,7 @@ namespace OCA\DAV\Tests\unit;
use OCA\DAV\Server;
use OCP\IRequest;
+use OCA\DAV\AppInfo\PluginManager;
/**
* Class ServerTest
@@ -38,8 +39,7 @@ class ServerTest extends \Test\TestCase {
public function test() {
/** @var IRequest $r */
- $r = $this->getMockBuilder('\OCP\IRequest')
- ->disableOriginalConstructor()->getMock();
+ $r = $this->createMock(IRequest::class);
$s = new Server($r, '/');
$this->assertInstanceOf('OCA\DAV\Server', $s);
}