Merge pull request #6835 from nextcloud/dav-plugins-from-apps-only
Let apps register Sabre plugins or collections (v2)
This commit is contained in:
commit
3a3e6c34d0
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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 (null === $this->plugins) {
|
||||
$this->populate();
|
||||
}
|
||||
return $this->plugins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of app-registered collections
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getAppCollections() {
|
||||
if (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'], true)) {
|
||||
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 $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 $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(array $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(array $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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue