diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/composer/composer/autoload_classmap.php | 2 | ||||
-rw-r--r-- | lib/composer/composer/autoload_static.php | 2 | ||||
-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 | ||||
-rw-r--r-- | lib/private/legacy/response.php | 2 | ||||
-rw-r--r-- | lib/public/OCS/IDiscoveryService.php | 48 |
8 files changed, 187 insertions, 11 deletions
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index c80881262d7..ab6a3781147 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -220,6 +220,7 @@ return array( 'OCP\\Notification\\IManager' => $baseDir . '/lib/public/Notification/IManager.php', 'OCP\\Notification\\INotification' => $baseDir . '/lib/public/Notification/INotification.php', 'OCP\\Notification\\INotifier' => $baseDir . '/lib/public/Notification/INotifier.php', + 'OCP\\OCS\\IDiscoveryService' => $baseDir . '/lib/public/OCS/IDiscoveryService.php', 'OCP\\PreConditionNotMetException' => $baseDir . '/lib/public/PreConditionNotMetException.php', 'OCP\\Preview\\IProvider' => $baseDir . '/lib/public/Preview/IProvider.php', 'OCP\\Response' => $baseDir . '/lib/public/Response.php', @@ -662,6 +663,7 @@ return array( 'OC\\Notification\\Manager' => $baseDir . '/lib/private/Notification/Manager.php', 'OC\\Notification\\Notification' => $baseDir . '/lib/private/Notification/Notification.php', 'OC\\OCS\\CoreCapabilities' => $baseDir . '/lib/private/OCS/CoreCapabilities.php', + 'OC\\OCS\\DiscoveryService' => $baseDir . '/lib/private/OCS/DiscoveryService.php', 'OC\\OCS\\Exception' => $baseDir . '/lib/private/OCS/Exception.php', 'OC\\OCS\\PrivateData' => $baseDir . '/lib/private/OCS/PrivateData.php', 'OC\\OCS\\Provider' => $baseDir . '/lib/private/OCS/Provider.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 8955d2de6ce..1b2c9f84df8 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -250,6 +250,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OCP\\Notification\\IManager' => __DIR__ . '/../../..' . '/lib/public/Notification/IManager.php', 'OCP\\Notification\\INotification' => __DIR__ . '/../../..' . '/lib/public/Notification/INotification.php', 'OCP\\Notification\\INotifier' => __DIR__ . '/../../..' . '/lib/public/Notification/INotifier.php', + 'OCP\\OCS\\IDiscoveryService' => __DIR__ . '/../../..' . '/lib/public/OCS/IDiscoveryService.php', 'OCP\\PreConditionNotMetException' => __DIR__ . '/../../..' . '/lib/public/PreConditionNotMetException.php', 'OCP\\Preview\\IProvider' => __DIR__ . '/../../..' . '/lib/public/Preview/IProvider.php', 'OCP\\Response' => __DIR__ . '/../../..' . '/lib/public/Response.php', @@ -692,6 +693,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Notification\\Manager' => __DIR__ . '/../../..' . '/lib/private/Notification/Manager.php', 'OC\\Notification\\Notification' => __DIR__ . '/../../..' . '/lib/private/Notification/Notification.php', 'OC\\OCS\\CoreCapabilities' => __DIR__ . '/../../..' . '/lib/private/OCS/CoreCapabilities.php', + 'OC\\OCS\\DiscoveryService' => __DIR__ . '/../../..' . '/lib/private/OCS/DiscoveryService.php', 'OC\\OCS\\Exception' => __DIR__ . '/../../..' . '/lib/private/OCS/Exception.php', 'OC\\OCS\\PrivateData' => __DIR__ . '/../../..' . '/lib/private/OCS/PrivateData.php', 'OC\\OCS\\Provider' => __DIR__ . '/../../..' . '/lib/private/OCS/Provider.php', 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( diff --git a/lib/private/legacy/response.php b/lib/private/legacy/response.php index 115eb5baa68..fa73f3d6d0d 100644 --- a/lib/private/legacy/response.php +++ b/lib/private/legacy/response.php @@ -257,7 +257,7 @@ class OC_Response { . 'object-src \'none\'; ' . 'base-uri \'self\'; '; header('Content-Security-Policy:' . $policy); - header('X-Frame-Options: Sameorigin'); // Disallow iFraming from other domains + header('X-Frame-Options: SAMEORIGIN'); // Disallow iFraming from other domains // Send fallback headers for installations that don't have the possibility to send // custom headers on the webserver side 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); + +} |