diff options
author | Robin Appelman <robin@icewind.nl> | 2017-02-09 14:54:32 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-09 14:54:32 +0100 |
commit | bf88060a98ce397768d4afa7935b80751e4533f8 (patch) | |
tree | 6baaf10832fa68999eea01ab3df5241fdd3ece0a /apps/files_sharing | |
parent | 4a5a3681d921adad8c4cb5bb29180514446ea2b9 (diff) | |
parent | 0d8d658b7e3885d92103a6e6248b37863f9acf1b (diff) | |
download | nextcloud-server-bf88060a98ce397768d4afa7935b80751e4533f8.tar.gz nextcloud-server-bf88060a98ce397768d4afa7935b80751e4533f8.zip |
Merge pull request #3297 from nextcloud/cloud-id-resolve
Add a single public api for resolving a cloud id to a user and remote and back
Diffstat (limited to 'apps/files_sharing')
10 files changed, 106 insertions, 73 deletions
diff --git a/apps/files_sharing/lib/Activity/Providers/RemoteShares.php b/apps/files_sharing/lib/Activity/Providers/RemoteShares.php index 425defe57e4..4e7d8ef3e27 100644 --- a/apps/files_sharing/lib/Activity/Providers/RemoteShares.php +++ b/apps/files_sharing/lib/Activity/Providers/RemoteShares.php @@ -24,18 +24,39 @@ namespace OCA\Files_Sharing\Activity\Providers; use OCP\Activity\IEvent; use OCP\Activity\IManager; use OCP\Activity\IProvider; +use OCP\Federation\ICloudIdManager; use OCP\IL10N; use OCP\IURLGenerator; +use OCP\IUserManager; use OCP\L10N\IFactory; class RemoteShares extends Base { + protected $cloudIdManager; + const SUBJECT_REMOTE_SHARE_ACCEPTED = 'remote_share_accepted'; const SUBJECT_REMOTE_SHARE_DECLINED = 'remote_share_declined'; const SUBJECT_REMOTE_SHARE_RECEIVED = 'remote_share_received'; const SUBJECT_REMOTE_SHARE_UNSHARED = 'remote_share_unshared'; /** + * @param IFactory $languageFactory + * @param IURLGenerator $url + * @param IManager $activityManager + * @param IUserManager $userManager + * @param ICloudIdManager $cloudIdManager + */ + public function __construct(IFactory $languageFactory, + IURLGenerator $url, + IManager $activityManager, + IUserManager $userManager, + ICloudIdManager $cloudIdManager + ) { + parent::__construct($languageFactory, $url, $activityManager, $userManager); + $this->cloudIdManager = $cloudIdManager; + } + + /** * @param IEvent $event * @return IEvent * @throws \InvalidArgumentException @@ -115,12 +136,12 @@ class RemoteShares extends Base { * @return array */ protected function getFederatedUser($cloudId) { - $remoteUser = explode('@', $cloudId, 2); + $remoteUser = $this->cloudIdManager->resolveCloudId($cloudId); return [ 'type' => 'user', - 'id' => $remoteUser[0], + 'id' => $remoteUser->getUser(), 'name' => $cloudId,// Todo display name from contacts - 'server' => $remoteUser[1], + 'server' => $remoteUser->getRemote(), ]; } } diff --git a/apps/files_sharing/lib/AppInfo/Application.php b/apps/files_sharing/lib/AppInfo/Application.php index 403d30ae2e6..c8cf723630b 100644 --- a/apps/files_sharing/lib/AppInfo/Application.php +++ b/apps/files_sharing/lib/AppInfo/Application.php @@ -35,6 +35,7 @@ use OC\AppFramework\Utility\SimpleContainer; use OCA\Files_Sharing\Controller\ExternalSharesController; use OCA\Files_Sharing\Controller\ShareController; use OCA\Files_Sharing\Middleware\SharingCheckMiddleware; +use OCP\Federation\ICloudIdManager; use \OCP\IContainer; use OCP\IServerContainer; @@ -84,6 +85,9 @@ class Application extends App { $container->registerService('HttpClientService', function (SimpleContainer $c) use ($server) { return $server->getHTTPClientService(); }); + $container->registerService(ICloudIdManager::class, function (SimpleContainer $c) use ($server) { + return $server->getCloudIdManager(); + }); $container->registerService('ExternalManager', function (SimpleContainer $c) use ($server) { $user = $server->getUserSession()->getUser(); $uid = $user ? $user->getUID() : null; @@ -145,7 +149,8 @@ class Application extends App { $server->getDatabaseConnection(), function() use ($c) { return $c->query('ExternalManager'); - } + }, + $server->getCloudIdManager() ); }); diff --git a/apps/files_sharing/lib/Controller/ShareesAPIController.php b/apps/files_sharing/lib/Controller/ShareesAPIController.php index cd5139693cf..40a9b272bc8 100644 --- a/apps/files_sharing/lib/Controller/ShareesAPIController.php +++ b/apps/files_sharing/lib/Controller/ShareesAPIController.php @@ -28,6 +28,7 @@ use OCP\AppFramework\Http; use OCP\AppFramework\OCS\OCSBadRequestException; use OCP\AppFramework\OCSController; use OCP\Contacts\IManager; +use OCP\Federation\ICloudIdManager; use OCP\Http\Client\IClientService; use OCP\IGroup; use OCP\IGroupManager; @@ -69,6 +70,9 @@ class ShareesAPIController extends OCSController { /** @var IClientService */ protected $clientService; + /** @var ICloudIdManager */ + protected $cloudIdManager; + /** @var bool */ protected $shareWithGroupOnly = false; @@ -110,6 +114,7 @@ class ShareesAPIController extends OCSController { * @param ILogger $logger * @param \OCP\Share\IManager $shareManager * @param IClientService $clientService + * @param ICloudIdManager $cloudIdManager */ public function __construct($appName, IRequest $request, @@ -121,7 +126,9 @@ class ShareesAPIController extends OCSController { IURLGenerator $urlGenerator, ILogger $logger, \OCP\Share\IManager $shareManager, - IClientService $clientService) { + IClientService $clientService, + ICloudIdManager $cloudIdManager + ) { parent::__construct($appName, $request); $this->groupManager = $groupManager; @@ -133,6 +140,7 @@ class ShareesAPIController extends OCSController { $this->logger = $logger; $this->shareManager = $shareManager; $this->clientService = $clientService; + $this->cloudIdManager = $cloudIdManager; } /** @@ -339,7 +347,7 @@ class ShareesAPIController extends OCSController { $result['results'] = []; } - if (!$result['exactIdMatch'] && substr_count($search, '@') >= 1 && $this->offset === 0) { + if (!$result['exactIdMatch'] && $this->cloudIdManager->isValidCloudId($search) && $this->offset === 0) { $result['exact'][] = [ 'label' => $search, 'value' => [ @@ -362,42 +370,12 @@ class ShareesAPIController extends OCSController { * @throws \Exception */ public function splitUserRemote($address) { - if (strpos($address, '@') === false) { - throw new \Exception('Invalid Federated Cloud ID'); - } - - // Find the first character that is not allowed in user names - $id = str_replace('\\', '/', $address); - $posSlash = strpos($id, '/'); - $posColon = strpos($id, ':'); - - if ($posSlash === false && $posColon === false) { - $invalidPos = strlen($id); - } else if ($posSlash === false) { - $invalidPos = $posColon; - } else if ($posColon === false) { - $invalidPos = $posSlash; - } else { - $invalidPos = min($posSlash, $posColon); - } - - // Find the last @ before $invalidPos - $pos = $lastAtPos = 0; - while ($lastAtPos !== false && $lastAtPos <= $invalidPos) { - $pos = $lastAtPos; - $lastAtPos = strpos($id, '@', $pos + 1); - } - - if ($pos !== false) { - $user = substr($id, 0, $pos); - $remote = substr($id, $pos + 1); - $remote = $this->fixRemoteURL($remote); - if (!empty($user) && !empty($remote)) { - return array($user, $remote); - } + try { + $cloudId = $this->cloudIdManager->resolveCloudId($address); + return [$cloudId->getUser(), $cloudId->getRemote()]; + } catch (\InvalidArgumentException $e) { + throw new \Exception('Invalid Federated Cloud ID', 0, $e); } - - throw new \Exception('Invalid Federated Cloud ID'); } /** diff --git a/apps/files_sharing/lib/External/Cache.php b/apps/files_sharing/lib/External/Cache.php index eaf8e0c4acf..c7793cf0595 100644 --- a/apps/files_sharing/lib/External/Cache.php +++ b/apps/files_sharing/lib/External/Cache.php @@ -24,21 +24,25 @@ namespace OCA\Files_Sharing\External; +use OCP\Federation\ICloudId; + class Cache extends \OC\Files\Cache\Cache { + /** @var ICloudId */ + private $cloudId; private $remote; private $remoteUser; private $storage; /** * @param \OCA\Files_Sharing\External\Storage $storage - * @param string $remote - * @param string $remoteUser + * @param ICloudId $cloudId */ - public function __construct($storage, $remote, $remoteUser) { + public function __construct($storage, ICloudId $cloudId) { + $this->cloudId = $cloudId; $this->storage = $storage; - list(, $remote) = explode('://', $remote, 2); + list(, $remote) = explode('://', $cloudId->getRemote(), 2); $this->remote = $remote; - $this->remoteUser = $remoteUser; + $this->remoteUser = $cloudId->getUser(); parent::__construct($storage); } @@ -47,7 +51,7 @@ class Cache extends \OC\Files\Cache\Cache { if (!$result) { return false; } - $result['displayname_owner'] = $this->remoteUser . '@' . $this->remote; + $result['displayname_owner'] = $this->cloudId->getDisplayId(); if (!$file || $file === '') { $result['is_share_mount_point'] = true; $mountPoint = rtrim($this->storage->getMountPoint()); @@ -59,7 +63,7 @@ class Cache extends \OC\Files\Cache\Cache { public function getFolderContentsById($id) { $results = parent::getFolderContentsById($id); foreach ($results as &$file) { - $file['displayname_owner'] = $this->remoteUser . '@' . $this->remote; + $file['displayname_owner'] = $this->cloudId->getDisplayId(); } return $results; } diff --git a/apps/files_sharing/lib/External/MountProvider.php b/apps/files_sharing/lib/External/MountProvider.php index 3f2f39a74f7..27ee9fcb46b 100644 --- a/apps/files_sharing/lib/External/MountProvider.php +++ b/apps/files_sharing/lib/External/MountProvider.php @@ -22,6 +22,7 @@ namespace OCA\Files_Sharing\External; +use OCP\Federation\ICloudIdManager; use OCP\Files\Config\IMountProvider; use OCP\Files\Storage\IStorageFactory; use OCP\IDBConnection; @@ -41,12 +42,19 @@ class MountProvider implements IMountProvider { private $managerProvider; /** + * @var ICloudIdManager + */ + private $cloudIdManager; + + /** * @param \OCP\IDBConnection $connection * @param callable $managerProvider due to setup order we need a callable that return the manager instead of the manager itself + * @param ICloudIdManager $cloudIdManager */ - public function __construct(IDBConnection $connection, callable $managerProvider) { + public function __construct(IDBConnection $connection, callable $managerProvider, ICloudIdManager $cloudIdManager) { $this->connection = $connection; $this->managerProvider = $managerProvider; + $this->cloudIdManager = $cloudIdManager; } public function getMount(IUser $user, $data, IStorageFactory $storageFactory) { @@ -55,6 +63,7 @@ class MountProvider implements IMountProvider { $data['manager'] = $manager; $mountPoint = '/' . $user->getUID() . '/files/' . ltrim($data['mountpoint'], '/'); $data['mountpoint'] = $mountPoint; + $data['cloudId'] = $this->cloudIdManager->getCloudId($data['owner'], $data['remote']); $data['certificateManager'] = \OC::$server->getCertificateManager($user->getUID()); $data['HttpClientService'] = \OC::$server->getHTTPClientService(); return new Mount(self::STORAGE, $mountPoint, $data, $manager, $storageFactory); diff --git a/apps/files_sharing/lib/External/Storage.php b/apps/files_sharing/lib/External/Storage.php index 93f3571e803..51d97388db7 100644 --- a/apps/files_sharing/lib/External/Storage.php +++ b/apps/files_sharing/lib/External/Storage.php @@ -35,15 +35,14 @@ use OC\ForbiddenException; use OCA\FederatedFileSharing\DiscoveryManager; use OCA\Files_Sharing\ISharedStorage; use OCP\AppFramework\Http; +use OCP\Federation\ICloudId; use OCP\Files\NotFoundException; use OCP\Files\StorageInvalidException; use OCP\Files\StorageNotAvailableException; class Storage extends DAV implements ISharedStorage { - /** @var string */ - private $remoteUser; - /** @var string */ - private $remote; + /** @var ICloudId */ + private $cloudId; /** @var string */ private $mountPoint; /** @var string */ @@ -72,9 +71,8 @@ class Storage extends DAV implements ISharedStorage { $this->manager = $options['manager']; $this->certificateManager = $options['certificateManager']; - $this->remote = $options['remote']; - $this->remoteUser = $options['owner']; - list($protocol, $remote) = explode('://', $this->remote); + $this->cloudId = $options['cloudId']; + list($protocol, $remote) = explode('://', $this->cloudId->getRemote()); if (strpos($remote, '/')) { list($host, $root) = explode('/', $remote, 2); } else { @@ -82,7 +80,7 @@ class Storage extends DAV implements ISharedStorage { $root = ''; } $secure = $protocol === 'https'; - $root = rtrim($root, '/') . $discoveryManager->getWebDavEndpoint($this->remote); + $root = rtrim($root, '/') . $discoveryManager->getWebDavEndpoint($this->cloudId->getRemote()); $this->mountPoint = $options['mountpoint']; $this->token = $options['token']; parent::__construct(array( @@ -106,11 +104,11 @@ class Storage extends DAV implements ISharedStorage { } public function getRemoteUser() { - return $this->remoteUser; + return $this->cloudId->getUser(); } public function getRemote() { - return $this->remote; + return $this->cloudId->getRemote(); } public function getMountPoint() { @@ -130,12 +128,12 @@ class Storage extends DAV implements ISharedStorage { * @return string */ public function getId() { - return 'shared::' . md5($this->token . '@' . $this->remote); + return 'shared::' . md5($this->token . '@' . $this->getRemote()); } public function getCache($path = '', $storage = null) { if (is_null($this->cache)) { - $this->cache = new Cache($this, $this->remote, $this->remoteUser); + $this->cache = new Cache($this, $this->cloudId); } return $this->cache; } @@ -251,9 +249,9 @@ class Storage extends DAV implements ISharedStorage { */ protected function testRemote() { try { - return $this->testRemoteUrl($this->remote . '/ocs-provider/index.php') - || $this->testRemoteUrl($this->remote . '/ocs-provider/') - || $this->testRemoteUrl($this->remote . '/status.php'); + return $this->testRemoteUrl($this->getRemote() . '/ocs-provider/index.php') + || $this->testRemoteUrl($this->getRemote() . '/ocs-provider/') + || $this->testRemoteUrl($this->getRemote() . '/status.php'); } catch (\Exception $e) { return false; } @@ -343,8 +341,7 @@ class Storage extends DAV implements ISharedStorage { } public function getOwner($path) { - list(, $remote) = explode('://', $this->remote, 2); - return $this->remoteUser . '@' . $remote; + return $this->cloudId->getDisplayId(); } public function isSharable($path) { diff --git a/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php b/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php index c68e2304743..035085d811a 100644 --- a/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php +++ b/apps/files_sharing/tests/Controller/ShareesAPIControllerTest.php @@ -25,10 +25,12 @@ namespace OCA\Files_Sharing\Tests\Controller; +use OC\Federation\CloudIdManager; use OCA\Files_Sharing\Controller\ShareesAPIController; use OCA\Files_Sharing\Tests\TestCase; use OCP\AppFramework\Http; use OCP\AppFramework\OCS\OCSBadRequestException; +use OCP\Federation\ICloudIdManager; use OCP\Http\Client\IClientService; use OCP\Share; @@ -64,6 +66,9 @@ class ShareesAPIControllerTest extends TestCase { /** @var IClientService|\PHPUnit_Framework_MockObject_MockObject */ private $clientService; + /** @var ICloudIdManager */ + private $cloudIdManager; + protected function setUp() { parent::setUp(); @@ -93,6 +98,8 @@ class ShareesAPIControllerTest extends TestCase { $this->clientService = $this->createMock(IClientService::class); + $this->cloudIdManager = new CloudIdManager(); + $this->sharees = new ShareesAPIController( 'files_sharing', $this->request, @@ -104,7 +111,8 @@ class ShareesAPIControllerTest extends TestCase { $this->getMockBuilder('OCP\IURLGenerator')->disableOriginalConstructor()->getMock(), $this->getMockBuilder('OCP\ILogger')->disableOriginalConstructor()->getMock(), $this->shareManager, - $this->clientService + $this->clientService, + $this->cloudIdManager ); } @@ -1434,7 +1442,8 @@ class ShareesAPIControllerTest extends TestCase { $this->getMockBuilder('OCP\IURLGenerator')->disableOriginalConstructor()->getMock(), $this->getMockBuilder('OCP\ILogger')->disableOriginalConstructor()->getMock(), $this->shareManager, - $this->clientService + $this->clientService, + $this->cloudIdManager ]) ->setMethods(array('searchSharees', 'isRemoteSharingAllowed', 'shareProviderExists')) ->getMock(); @@ -1526,7 +1535,8 @@ class ShareesAPIControllerTest extends TestCase { $this->getMockBuilder('OCP\IURLGenerator')->disableOriginalConstructor()->getMock(), $this->getMockBuilder('OCP\ILogger')->disableOriginalConstructor()->getMock(), $this->shareManager, - $this->clientService + $this->clientService, + $this->cloudIdManager ]) ->setMethods(array('searchSharees', 'isRemoteSharingAllowed')) ->getMock(); @@ -1692,7 +1702,8 @@ class ShareesAPIControllerTest extends TestCase { $this->getMockBuilder('OCP\IURLGenerator')->disableOriginalConstructor()->getMock(), $this->getMockBuilder('OCP\ILogger')->disableOriginalConstructor()->getMock(), $this->shareManager, - $this->clientService + $this->clientService, + $this->cloudIdManager ]) ->setMethods(array('getShareesForShareIds', 'getUsers', 'getGroups', 'getRemote')) ->getMock(); diff --git a/apps/files_sharing/tests/External/CacheTest.php b/apps/files_sharing/tests/External/CacheTest.php index a31a748a69b..0129e760648 100644 --- a/apps/files_sharing/tests/External/CacheTest.php +++ b/apps/files_sharing/tests/External/CacheTest.php @@ -24,7 +24,9 @@ */ namespace OCA\Files_Sharing\Tests\External; +use OC\Federation\CloudIdManager; use OCA\Files_Sharing\Tests\TestCase; +use OCP\Federation\ICloudIdManager; /** * Class Cache @@ -50,9 +52,13 @@ class CacheTest extends TestCase { */ private $remoteUser; + /** @var ICloudIdManager */ + private $cloudIdManager; + protected function setUp() { parent::setUp(); + $this->cloudIdManager = new CloudIdManager(); $this->remoteUser = $this->getUniqueID('remoteuser'); $this->storage = $this->getMockBuilder('\OCA\Files_Sharing\External\Storage') @@ -64,8 +70,7 @@ class CacheTest extends TestCase { ->will($this->returnValue('dummystorage::')); $this->cache = new \OCA\Files_Sharing\External\Cache( $this->storage, - 'http://example.com/owncloud', - $this->remoteUser + $this->cloudIdManager->getCloudId($this->remoteUser, 'http://example.com/owncloud') ); $this->cache->put( 'test.txt', diff --git a/apps/files_sharing/tests/External/ManagerTest.php b/apps/files_sharing/tests/External/ManagerTest.php index 48476888bdd..f2a55babcc7 100644 --- a/apps/files_sharing/tests/External/ManagerTest.php +++ b/apps/files_sharing/tests/External/ManagerTest.php @@ -25,6 +25,7 @@ namespace OCA\Files_Sharing\Tests\External; +use OC\Federation\CloudIdManager; use OC\Files\Storage\StorageFactory; use OCA\FederatedFileSharing\DiscoveryManager; use OCA\Files_Sharing\External\Manager; @@ -84,7 +85,7 @@ class ManagerTest extends TestCase { ); $this->testMountProvider = new MountProvider(\OC::$server->getDatabaseConnection(), function() { return $this->manager; - }); + }, new CloudIdManager()); } private function setupMounts() { diff --git a/apps/files_sharing/tests/ExternalStorageTest.php b/apps/files_sharing/tests/ExternalStorageTest.php index 49b72be1391..1246b0edb98 100644 --- a/apps/files_sharing/tests/ExternalStorageTest.php +++ b/apps/files_sharing/tests/ExternalStorageTest.php @@ -25,6 +25,7 @@ */ namespace OCA\Files_Sharing\Tests; +use OC\Federation\CloudId; use OCP\Http\Client\IClient; use OCP\Http\Client\IClientService; use OCP\Http\Client\IResponse; @@ -90,6 +91,7 @@ class ExternalStorageTest extends \Test\TestCase { return new TestSharingExternalStorage( array( + 'cloudId' => new CloudId('testOwner@' . $uri, 'testOwner', $uri), 'remote' => $uri, 'owner' => 'testOwner', 'mountpoint' => 'remoteshare', |