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
								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
- 
					7apps/federatedfilesharing/lib/BackgroundJob/RetryJob.php
- 
					6apps/federatedfilesharing/lib/Controller/MountPublicLinkController.php
- 
					6apps/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
- 
					33apps/files_sharing/lib/External/Manager.php
- 
					14apps/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