Browse Source
remove discovery manager in favour of the OCSDiscoveryService
remove discovery manager in favour of the OCSDiscoveryService
Signed-off-by: Bjoern Schiessle <bjoern@schiessle.org>pull/3614/head
committed by
Roeland Jago Douma
No known key found for this signature in database
GPG Key ID: F941078878347C0C
18 changed files with 81 additions and 468 deletions
-
11apps/federatedfilesharing/lib/AppInfo/Application.php
-
9apps/federatedfilesharing/lib/BackgroundJob/RetryJob.php
-
6apps/federatedfilesharing/lib/Controller/MountPublicLinkController.php
-
20apps/federatedfilesharing/lib/Controller/RequestHandlerController.php
-
143apps/federatedfilesharing/lib/DiscoveryManager.php
-
14apps/federatedfilesharing/lib/Notifications.php
-
6apps/federatedfilesharing/tests/Controller/RequestHandlerControllerTest.php
-
217apps/federatedfilesharing/tests/DiscoveryManagerTest.php
-
13apps/federatedfilesharing/tests/NotificationsTest.php
-
6apps/files_sharing/lib/AppInfo/Application.php
-
35apps/files_sharing/lib/External/Manager.php
-
16apps/files_sharing/lib/External/Storage.php
-
6apps/files_sharing/lib/Hooks.php
-
15apps/files_sharing/tests/External/ManagerTest.php
-
8lib/private/Share/Share.php
-
6lib/private/Share20/ProviderFactory.php
-
6lib/public/IServerContainer.php
-
12tests/lib/Share/ShareTest.php
@ -1,143 +0,0 @@ |
|||
<?php |
|||
/** |
|||
* @copyright Copyright (c) 2016, ownCloud, Inc. |
|||
* |
|||
* @author Bjoern Schiessle <bjoern@schiessle.org> |
|||
* @author Joas Schilling <coding@schilljs.com> |
|||
* @author Lukas Reschke <lukas@statuscode.ch> |
|||
* @author Vincent Petry <pvince81@owncloud.com> |
|||
* |
|||
* @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\FederatedFileSharing; |
|||
|
|||
use GuzzleHttp\Exception\ClientException; |
|||
use GuzzleHttp\Exception\ConnectException; |
|||
use OCP\Http\Client\IClient; |
|||
use OCP\Http\Client\IClientService; |
|||
use OCP\ICache; |
|||
use OCP\ICacheFactory; |
|||
|
|||
/** |
|||
* Class DiscoveryManager handles the discovery of endpoints used by Federated |
|||
* Cloud Sharing. |
|||
* |
|||
* @package OCA\FederatedFileSharing |
|||
*/ |
|||
class DiscoveryManager { |
|||
/** @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(); |
|||
} |
|||
|
|||
/** |
|||
* 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); |
|||
} |
|||
|
|||
/** |
|||
* Discover the actual data and do some naive caching to ensure that the data |
|||
* is not requested multiple times. |
|||
* |
|||
* If no valid discovery data is found the Nextcloud defaults are returned. |
|||
* |
|||
* @param string $remote |
|||
* @return array |
|||
*/ |
|||
private function discover($remote) { |
|||
// Check if something is in the cache
|
|||
if($cacheData = $this->cache->get($remote)) { |
|||
return json_decode($cacheData, true); |
|||
} |
|||
|
|||
// Default response body
|
|||
$discoveredServices = [ |
|||
'webdav' => '/public.php/webdav', |
|||
'share' => '/ocs/v1.php/cloud/shares', |
|||
]; |
|||
|
|||
// Read the data from the response body
|
|||
try { |
|||
$response = $this->client->get($remote . '/ocs-provider/', [ |
|||
'timeout' => 10, |
|||
'connect_timeout' => 10, |
|||
]); |
|||
if($response->getStatusCode() === 200) { |
|||
$decodedService = json_decode($response->getBody(), true); |
|||
if(is_array($decodedService)) { |
|||
$endpoints = [ |
|||
'webdav', |
|||
'share', |
|||
]; |
|||
|
|||
foreach($endpoints as $endpoint) { |
|||
if(isset($decodedService['services']['FEDERATED_SHARING']['endpoints'][$endpoint])) { |
|||
$endpointUrl = (string)$decodedService['services']['FEDERATED_SHARING']['endpoints'][$endpoint]; |
|||
if($this->isSafeUrl($endpointUrl)) { |
|||
$discoveredServices[$endpoint] = $endpointUrl; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} catch (ClientException $e) { |
|||
// Don't throw any exception since exceptions are handled before
|
|||
} catch (ConnectException $e) { |
|||
// Don't throw any exception since exceptions are handled before
|
|||
} |
|||
|
|||
// Write into cache
|
|||
$this->cache->set($remote, json_encode($discoveredServices)); |
|||
return $discoveredServices; |
|||
} |
|||
|
|||
/** |
|||
* Return the public WebDAV endpoint used by the specified remote |
|||
* |
|||
* @param string $host |
|||
* @return string |
|||
*/ |
|||
public function getWebDavEndpoint($host) { |
|||
return $this->discover($host)['webdav']; |
|||
} |
|||
|
|||
/** |
|||
* Return the sharing endpoint used by the specified remote |
|||
* |
|||
* @param string $host |
|||
* @return string |
|||
*/ |
|||
public function getShareEndpoint($host) { |
|||
return $this->discover($host)['share']; |
|||
} |
|||
} |
@ -1,217 +0,0 @@ |
|||
<?php |
|||
/** |
|||
* @copyright Copyright (c) 2016, ownCloud, Inc. |
|||
* |
|||
* @author Björn Schießle <bjoern@schiessle.org> |
|||
* @author Lukas Reschke <lukas@statuscode.ch> |
|||
* @author Vincent Petry <pvince81@owncloud.com> |
|||
* |
|||
* @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\FederatedFileSharing\Tests; |
|||
|
|||
use OCA\FederatedFileSharing\DiscoveryManager; |
|||
use OCP\Http\Client\IClient; |
|||
use OCP\Http\Client\IClientService; |
|||
use OCP\ICache; |
|||
use OCP\ICacheFactory; |
|||
|
|||
class DiscoveryManagerTest extends \Test\TestCase { |
|||
/** @var ICache */ |
|||
private $cache; |
|||
/** @var IClient */ |
|||
private $client; |
|||
/** @var DiscoveryManager */ |
|||
private $discoveryManager; |
|||
|
|||
public function setUp() { |
|||
parent::setUp(); |
|||
$this->cache = $this->getMockBuilder('\OCP\ICache') |
|||
->getMock(); |
|||
/** @var ICacheFactory $cacheFactory */ |
|||
$cacheFactory = $this->getMockBuilder('\OCP\ICacheFactory') |
|||
->disableOriginalConstructor()->getMock(); |
|||
$cacheFactory |
|||
->expects($this->once()) |
|||
->method('create') |
|||
->with('ocs-discovery') |
|||
->willReturn($this->cache); |
|||
|
|||
$this->client = $this->getMockBuilder('\OCP\Http\Client\IClient') |
|||
->disableOriginalConstructor()->getMock(); |
|||
/** @var IClientService $clientService */ |
|||
$clientService = $this->getMockBuilder('\OCP\Http\Client\IClientService') |
|||
->disableOriginalConstructor()->getMock(); |
|||
$clientService |
|||
->expects($this->once()) |
|||
->method('newClient') |
|||
->willReturn($this->client); |
|||
|
|||
$this->discoveryManager = new DiscoveryManager( |
|||
$cacheFactory, |
|||
$clientService |
|||
); |
|||
} |
|||
|
|||
public function testWithMalformedFormattedEndpointCached() { |
|||
$response = $this->getMockBuilder('\OCP\Http\Client\IResponse') |
|||
->getMock(); |
|||
$response |
|||
->expects($this->once()) |
|||
->method('getStatusCode') |
|||
->willReturn(200); |
|||
$response |
|||
->expects($this->once()) |
|||
->method('getBody') |
|||
->willReturn('CertainlyNotJson'); |
|||
$this->client |
|||
->expects($this->once()) |
|||
->method('get') |
|||
->with('https://myhost.com/ocs-provider/', [ |
|||
'timeout' => 10, |
|||
'connect_timeout' => 10, |
|||
]) |
|||
->willReturn($response); |
|||
$this->cache |
|||
->expects($this->at(0)) |
|||
->method('get') |
|||
->with('https://myhost.com') |
|||
->willReturn(null); |
|||
$this->cache |
|||
->expects($this->at(1)) |
|||
->method('set') |
|||
->with('https://myhost.com', '{"webdav":"\/public.php\/webdav","share":"\/ocs\/v1.php\/cloud\/shares"}'); |
|||
$this->cache |
|||
->expects($this->at(2)) |
|||
->method('get') |
|||
->with('https://myhost.com') |
|||
->willReturn('{"webdav":"\/public.php\/webdav","share":"\/ocs\/v1.php\/cloud\/shares"}'); |
|||
|
|||
$this->assertSame('/public.php/webdav', $this->discoveryManager->getWebDavEndpoint('https://myhost.com')); |
|||
$this->assertSame('/ocs/v1.php/cloud/shares', $this->discoveryManager->getShareEndpoint('https://myhost.com')); |
|||
} |
|||
|
|||
public function testGetWebDavEndpointWithValidFormattedEndpointAndNotCached() { |
|||
$response = $this->getMockBuilder('\OCP\Http\Client\IResponse') |
|||
->getMock(); |
|||
$response |
|||
->expects($this->once()) |
|||
->method('getStatusCode') |
|||
->willReturn(200); |
|||
$response |
|||
->expects($this->once()) |
|||
->method('getBody') |
|||
->willReturn('{"version":2,"services":{"PRIVATE_DATA":{"version":1,"endpoints":{"store":"\/ocs\/v2.php\/privatedata\/setattribute","read":"\/ocs\/v2.php\/privatedata\/getattribute","delete":"\/ocs\/v2.php\/privatedata\/deleteattribute"}},"SHARING":{"version":1,"endpoints":{"share":"\/ocs\/v2.php\/apps\/files_sharing\/api\/v1\/shares"}},"FEDERATED_SHARING":{"version":1,"endpoints":{"share":"\/ocs\/v2.php\/cloud\/shares","webdav":"\/public.php\/MyCustomEndpoint\/"}},"ACTIVITY":{"version":1,"endpoints":{"list":"\/ocs\/v2.php\/cloud\/activity"}},"PROVISIONING":{"version":1,"endpoints":{"user":"\/ocs\/v2.php\/cloud\/users","groups":"\/ocs\/v2.php\/cloud\/groups","apps":"\/ocs\/v2.php\/cloud\/apps"}}}}'); |
|||
$this->client |
|||
->expects($this->once()) |
|||
->method('get') |
|||
->with('https://myhost.com/ocs-provider/', [ |
|||
'timeout' => 10, |
|||
'connect_timeout' => 10, |
|||
]) |
|||
->willReturn($response); |
|||
|
|||
$expectedResult = '/public.php/MyCustomEndpoint/'; |
|||
$this->assertSame($expectedResult, $this->discoveryManager->getWebDavEndpoint('https://myhost.com')); |
|||
} |
|||
|
|||
public function testGetWebDavEndpointWithValidFormattedEndpointWithoutDataAndNotCached() { |
|||
$response = $this->getMockBuilder('\OCP\Http\Client\IResponse') |
|||
->getMock(); |
|||
$response |
|||
->expects($this->once()) |
|||
->method('getStatusCode') |
|||
->willReturn(200); |
|||
$response |
|||
->expects($this->once()) |
|||
->method('getBody') |
|||
->willReturn('{"version":2,"PRIVATE_DATA":{"version":1,"endpoints":{"store":"\/ocs\/v2.php\/privatedata\/setattribute","read":"\/ocs\/v2.php\/privatedata\/getattribute","delete":"\/ocs\/v2.php\/privatedata\/deleteattribute"}},"SHARING":{"version":1,"endpoints":{"share":"\/ocs\/v2.php\/apps\/files_sharing\/api\/v1\/shares"}},"FEDERATED_SHARING":{"version":1,"endpoints":{"share":"\/ocs\/v2.php\/cloud\/shares","webdav":"\/public.php\/MyCustomEndpoint\/"}},"ACTIVITY":{"version":1,"endpoints":{"list":"\/ocs\/v2.php\/cloud\/activity"}},"PROVISIONING":{"version":1,"endpoints":{"user":"\/ocs\/v2.php\/cloud\/users","groups":"\/ocs\/v2.php\/cloud\/groups","apps":"\/ocs\/v2.php\/cloud\/apps"}}}'); |
|||
$this->client |
|||
->expects($this->once()) |
|||
->method('get') |
|||
->with('https://myhost.com/ocs-provider/', [ |
|||
'timeout' => 10, |
|||
'connect_timeout' => 10, |
|||
]) |
|||
->willReturn($response); |
|||
|
|||
$expectedResult = '/public.php/webdav'; |
|||
$this->assertSame($expectedResult, $this->discoveryManager->getWebDavEndpoint('https://myhost.com')); |
|||
} |
|||
|
|||
public function testGetShareEndpointWithValidFormattedEndpointAndNotCached() { |
|||
$response = $this->getMockBuilder('\OCP\Http\Client\IResponse') |
|||
->getMock(); |
|||
$response |
|||
->expects($this->once()) |
|||
->method('getStatusCode') |
|||
->willReturn(200); |
|||
$response |
|||
->expects($this->once()) |
|||
->method('getBody') |
|||
->willReturn('{"version":2,"services":{"PRIVATE_DATA":{"version":1,"endpoints":{"store":"\/ocs\/v2.php\/privatedata\/setattribute","read":"\/ocs\/v2.php\/privatedata\/getattribute","delete":"\/ocs\/v2.php\/privatedata\/deleteattribute"}},"SHARING":{"version":1,"endpoints":{"share":"\/ocs\/v2.php\/apps\/files_sharing\/api\/v1\/shares"}},"FEDERATED_SHARING":{"version":1,"endpoints":{"share":"\/ocs\/v2.php\/cloud\/MyCustomShareEndpoint","webdav":"\/public.php\/MyCustomEndpoint\/"}},"ACTIVITY":{"version":1,"endpoints":{"list":"\/ocs\/v2.php\/cloud\/activity"}},"PROVISIONING":{"version":1,"endpoints":{"user":"\/ocs\/v2.php\/cloud\/users","groups":"\/ocs\/v2.php\/cloud\/groups","apps":"\/ocs\/v2.php\/cloud\/apps"}}}}'); |
|||
$this->client |
|||
->expects($this->once()) |
|||
->method('get') |
|||
->with('https://myhost.com/ocs-provider/', [ |
|||
'timeout' => 10, |
|||
'connect_timeout' => 10, |
|||
]) |
|||
->willReturn($response); |
|||
|
|||
$expectedResult = '/ocs/v2.php/cloud/MyCustomShareEndpoint'; |
|||
$this->assertSame($expectedResult, $this->discoveryManager->getShareEndpoint('https://myhost.com')); |
|||
} |
|||
|
|||
public function testWithMaliciousEndpointCached() { |
|||
$response = $this->getMockBuilder('\OCP\Http\Client\IResponse') |
|||
->getMock(); |
|||
$response |
|||
->expects($this->once()) |
|||
->method('getStatusCode') |
|||
->willReturn(200); |
|||
$response |
|||
->expects($this->once()) |
|||
->method('getBody') |
|||
->willReturn('{"version":2,"services":{"PRIVATE_DATA":{"version":1,"endpoints":{"store":"\/ocs\/v2.php\/privatedata\/setattribute","read":"\/ocs\/v2.php\/privatedata\/getattribute","delete":"\/ocs\/v2.php\/privatedata\/deleteattribute"}},"SHARING":{"version":1,"endpoints":{"share":"\/ocs\/v2.php\/apps\/files_sharing\/api\/v1\/shares"}},"FEDERATED_SHARING":{"version":1,"endpoints":{"share":"\/ocs\/v2.php\/cl@oud\/MyCustomShareEndpoint","webdav":"\/public.php\/MyC:ustomEndpoint\/"}},"ACTIVITY":{"version":1,"endpoints":{"list":"\/ocs\/v2.php\/cloud\/activity"}},"PROVISIONING":{"version":1,"endpoints":{"user":"\/ocs\/v2.php\/cloud\/users","groups":"\/ocs\/v2.php\/cloud\/groups","apps":"\/ocs\/v2.php\/cloud\/apps"}}}}'); |
|||
$this->client |
|||
->expects($this->once()) |
|||
->method('get') |
|||
->with('https://myhost.com/ocs-provider/', [ |
|||
'timeout' => 10, |
|||
'connect_timeout' => 10, |
|||
]) |
|||
->willReturn($response); |
|||
$this->cache |
|||
->expects($this->at(0)) |
|||
->method('get') |
|||
->with('https://myhost.com') |
|||
->willReturn(null); |
|||
$this->cache |
|||
->expects($this->at(1)) |
|||
->method('set') |
|||
->with('https://myhost.com', '{"webdav":"\/public.php\/webdav","share":"\/ocs\/v1.php\/cloud\/shares"}'); |
|||
$this->cache |
|||
->expects($this->at(2)) |
|||
->method('get') |
|||
->with('https://myhost.com') |
|||
->willReturn('{"webdav":"\/public.php\/webdav","share":"\/ocs\/v1.php\/cloud\/shares"}'); |
|||
|
|||
$this->assertSame('/public.php/webdav', $this->discoveryManager->getWebDavEndpoint('https://myhost.com')); |
|||
$this->assertSame('/ocs/v1.php/cloud/shares', $this->discoveryManager->getShareEndpoint('https://myhost.com')); |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue