diff options
author | Bjoern Schiessle <bjoern@schiessle.org> | 2017-02-24 12:50:43 +0100 |
---|---|---|
committer | Roeland Jago Douma <roeland@famdouma.nl> | 2017-04-11 15:03:59 +0200 |
commit | 45aee2e4795ac12d8f46c7659b2604b8cc891750 (patch) | |
tree | e1589362806eab43ef5cd7e7131bb8adf83aa8c5 | |
parent | afb5d45705f7d7743b9dfd2d79b618938cb05b77 (diff) | |
download | nextcloud-server-45aee2e4795ac12d8f46c7659b2604b8cc891750.tar.gz nextcloud-server-45aee2e4795ac12d8f46c7659b2604b8cc891750.zip |
provide public discovery service to discover OCS end-points on another server
Signed-off-by: Bjoern Schiessle <bjoern@schiessle.org>
-rw-r--r-- | lib/private/AppFramework/DependencyInjection/DIContainer.php | 9 | ||||
-rw-r--r-- | lib/private/OCS/DiscoveryService.php | 125 | ||||
-rw-r--r-- | lib/private/Server.php | 13 | ||||
-rw-r--r-- | lib/public/OCS/IDiscoveryService.php | 48 |
4 files changed, 195 insertions, 0 deletions
diff --git a/lib/private/AppFramework/DependencyInjection/DIContainer.php b/lib/private/AppFramework/DependencyInjection/DIContainer.php index 4fb13b09ae0..4b72c2c9e3e 100644 --- a/lib/private/AppFramework/DependencyInjection/DIContainer.php +++ b/lib/private/AppFramework/DependencyInjection/DIContainer.php @@ -56,6 +56,8 @@ use OCP\IL10N; use OCP\IRequest; use OCP\IServerContainer; use OCP\IUserSession; +use OCP\Files\Mount\IMountManager; +use OCP\OCS\IDiscoveryService; use OCP\RichObjectStrings\IValidator; use OCP\Util; @@ -137,6 +139,13 @@ class DIContainer extends SimpleContainer implements IAppContainer { return $c; }); + $this->registerService(IMountManager::class, function () { + return $this->getServer()->getMountManager(); + }); + $this->registerService(IDiscoveryService::class, function($c) { + return $this->getServer()->getOCSDiscoveryService(); + }); + // commonly used attributes $this->registerService('UserId', function ($c) { return $c->query('OCP\\IUserSession')->getSession()->get('user_id'); diff --git a/lib/private/OCS/DiscoveryService.php b/lib/private/OCS/DiscoveryService.php new file mode 100644 index 00000000000..a7945681183 --- /dev/null +++ b/lib/private/OCS/DiscoveryService.php @@ -0,0 +1,125 @@ +<?php +/** + * @copyright Copyright (c) 2017 Bjoern Schiessle <bjoern@schiessle.org> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OC\OCS; + +use OCP\AppFramework\Http; +use OCP\Http\Client\IClient; +use OCP\Http\Client\IClientService; +use OCP\ICache; +use OCP\ICacheFactory; +use OCP\OCS\IDiscoveryService; + +class DiscoveryService implements IDiscoveryService { + + /** @var ICache */ + private $cache; + + /** @var IClient */ + private $client; + + /** + * @param ICacheFactory $cacheFactory + * @param IClientService $clientService + */ + public function __construct(ICacheFactory $cacheFactory, + IClientService $clientService + ) { + $this->cache = $cacheFactory->create('ocs-discovery'); + $this->client = $clientService->newClient(); + } + + + /** + * Discover OCS end-points + * + * If no valid discovery data is found the defaults are returned + * + * @param string $remote + * @param string $service the service you want to discover + * @return array + */ + public function discover($remote, $service) { + // Check the cache first + $cacheData = $this->cache->get($remote . '#' . $service); + if($cacheData) { + return json_decode($cacheData, true); + } + + $discoveredServices = []; + + // query the remote server for available services + try { + $response = $this->client->get($remote . '/ocs-provider/', [ + 'timeout' => 10, + 'connect_timeout' => 10, + ]); + if($response->getStatusCode() === Http::STATUS_OK) { + $decodedServices = json_decode($response->getBody(), true); + $discoveredServices = $this->getEndpoints($decodedServices, $service); + } + } catch (\Exception $e) { + // if we couldn't discover the service or any end-points we return a empty array + return []; + } + + // Write into cache + $this->cache->set($remote . '#' . $service, json_encode($discoveredServices)); + return $discoveredServices; + } + + /** + * get requested end-points from the requested service + * + * @param $decodedServices + * @param $service + * @return array + */ + private function getEndpoints($decodedServices, $service) { + + $discoveredServices = []; + + if(is_array($decodedServices) && + isset($decodedServices['services'][$service]['endpoints']) + ) { + foreach ($decodedServices['services'][$service]['endpoints'] as $endpoint => $url) { + if($this->isSafeUrl($url)) { + $discoveredServices[$endpoint] = $url; + } + } + } + + return $discoveredServices; + } + + /** + * Returns whether the specified URL includes only safe characters, if not + * returns false + * + * @param string $url + * @return bool + */ + private function isSafeUrl($url) { + return (bool)preg_match('/^[\/\.A-Za-z0-9]+$/', $url); + } + +} diff --git a/lib/private/Server.php b/lib/private/Server.php index 9b2380ac7ac..13387ebd3ed 100644 --- a/lib/private/Server.php +++ b/lib/private/Server.php @@ -77,6 +77,7 @@ use OC\Mail\Mailer; use OC\Memcache\ArrayCache; use OC\Memcache\Factory; use OC\Notification\Manager; +use OC\OCS\DiscoveryService; use OC\Repair\NC11\CleanPreviewsBackgroundJob; use OC\RichObjectStrings\Validator; use OC\Security\Bruteforce\Throttler; @@ -936,6 +937,10 @@ class Server extends ServerContainer implements IServerContainer { }); }); + $this->registerService('OCSDiscoveryService', function (Server $c) { + return new DiscoveryService($c->getMemCacheFactory(), $c->getHTTPClientService()); + }); + $this->registerService(ICloudIdManager::class, function (Server $c) { return new CloudIdManager(); }); @@ -997,6 +1002,14 @@ class Server extends ServerContainer implements IServerContainer { } /** + * @return \OC\OCS\DiscoveryService + */ + public function getOCSDiscoveryService() { + return $this->query('OCSDiscoveryService'); + } + + + /** * The current request object holding all information about the request * currently being processed is returned from this method. * In case the current execution was not initiated by a web request null is returned diff --git a/lib/public/OCS/IDiscoveryService.php b/lib/public/OCS/IDiscoveryService.php new file mode 100644 index 00000000000..eee5bf97f93 --- /dev/null +++ b/lib/public/OCS/IDiscoveryService.php @@ -0,0 +1,48 @@ +<?php +/** + * @copyright Copyright (c) 2017 Bjoern Schiessle <bjoern@schiessle.org> + * + * @license GNU AGPL version 3 or any later version + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * 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 + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + */ + + +namespace OCP\OCS; + +/** + * Interface IDiscoveryService + * + * Allows you to discover OCS end-points on a remote server + * + * @package OCP\OCS + * @since 12.0.0 + */ +interface IDiscoveryService { + + /** + * Discover OCS end-points + * + * If no valid discovery data is found the defaults are returned + * + * @since 12.0.0 + * + * @param string $remote + * @param string $service the service you want to discover + * @return array + */ + public function discover($remote, $service); + +} |