summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjoern Schiessle <bjoern@schiessle.org>2017-02-24 12:50:43 +0100
committerRoeland Jago Douma <roeland@famdouma.nl>2017-04-11 15:03:59 +0200
commit45aee2e4795ac12d8f46c7659b2604b8cc891750 (patch)
treee1589362806eab43ef5cd7e7131bb8adf83aa8c5
parentafb5d45705f7d7743b9dfd2d79b618938cb05b77 (diff)
downloadnextcloud-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.php9
-rw-r--r--lib/private/OCS/DiscoveryService.php125
-rw-r--r--lib/private/Server.php13
-rw-r--r--lib/public/OCS/IDiscoveryService.php48
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);
+
+}