diff options
author | Björn Schießle <bjoern@schiessle.org> | 2017-04-12 16:01:07 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-04-12 16:01:07 +0200 |
commit | b90e91144bc8d378f6f52025f04383ae2e7c647b (patch) | |
tree | 616619d3778182ac53e77dc605fc9bded595fc63 /lib/private | |
parent | 3cf2f6e31bca4b704549e428d7fcbf6c4ecd6c37 (diff) | |
parent | 42f40659f664b4cdcdd5f19cf7300ad740aec6a4 (diff) | |
download | nextcloud-server-b90e91144bc8d378f6f52025f04383ae2e7c647b.tar.gz nextcloud-server-b90e91144bc8d378f6f52025f04383ae2e7c647b.zip |
Merge pull request #3614 from nextcloud/discover-federatedsharing-endpoints
Discover federatedsharing endpoints
Diffstat (limited to 'lib/private')
-rw-r--r-- | lib/private/OCS/DiscoveryService.php | 125 | ||||
-rw-r--r-- | lib/private/Server.php | 5 | ||||
-rw-r--r-- | lib/private/Share/Share.php | 8 | ||||
-rw-r--r-- | lib/private/Share20/ProviderFactory.php | 6 |
4 files changed, 134 insertions, 10 deletions
diff --git a/lib/private/OCS/DiscoveryService.php b/lib/private/OCS/DiscoveryService.php new file mode 100644 index 00000000000..5534fb24ef5 --- /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 + */ + protected 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 + */ + protected 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 011263cd2d8..00698a04f89 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; @@ -938,6 +939,10 @@ class Server extends ServerContainer implements IServerContainer { }); }); + $this->registerService(\OCP\OCS\IDiscoveryService::class, function (Server $c) { + return new DiscoveryService($c->getMemCacheFactory(), $c->getHTTPClientService()); + }); + $this->registerService(ICloudIdManager::class, function (Server $c) { return new CloudIdManager(); }); diff --git a/lib/private/Share/Share.php b/lib/private/Share/Share.php index 924e2f68396..b3e4cb2d4aa 100644 --- a/lib/private/Share/Share.php +++ b/lib/private/Share/Share.php @@ -2742,12 +2742,10 @@ class Share extends Constants { 'result' => '', ]; $try = 0; - $discoveryManager = new DiscoveryManager( - \OC::$server->getMemCacheFactory(), - \OC::$server->getHTTPClientService() - ); + $discoveryService = \OC::$server->query(\OCP\OCS\IDiscoveryService::class); while ($result['success'] === false && $try < 2) { - $endpoint = $discoveryManager->getShareEndpoint($protocol . $remoteDomain); + $federationEndpoints = $discoveryService->discover($protocol . $remoteDomain, 'FEDERATED_SHARING'); + $endpoint = isset($federationEndpoints['share']) ? $federationEndpoints['share'] : '/ocs/v2.php/cloud/shares'; $result = \OC::$server->getHTTPHelper()->post($protocol . $remoteDomain . $endpoint . $urlSuffix . '?format=' . self::RESPONSE_FORMAT, $fields); $try++; $protocol = 'http://'; diff --git a/lib/private/Share20/ProviderFactory.php b/lib/private/Share20/ProviderFactory.php index b411f42b262..ba6699ae7ad 100644 --- a/lib/private/Share20/ProviderFactory.php +++ b/lib/private/Share20/ProviderFactory.php @@ -104,14 +104,10 @@ class ProviderFactory implements IProviderFactory { $l, $this->serverContainer->getCloudIdManager() ); - $discoveryManager = new DiscoveryManager( - $this->serverContainer->getMemCacheFactory(), - $this->serverContainer->getHTTPClientService() - ); $notifications = new Notifications( $addressHandler, $this->serverContainer->getHTTPClientService(), - $discoveryManager, + $this->serverContainer->query(\OCP\OCS\IDiscoveryService::class), $this->serverContainer->getJobList() ); $tokenHandler = new TokenHandler( |