diff options
author | Thomas Müller <thomas.mueller@tmit.eu> | 2016-01-07 14:57:05 +0100 |
---|---|---|
committer | Thomas Müller <thomas.mueller@tmit.eu> | 2016-01-07 14:57:05 +0100 |
commit | 601457d2217ec1ed18b49061e38d4cda3703c9f6 (patch) | |
tree | 5e27256a3442453f3544ad4f107aa60114275a99 /apps | |
parent | 9d3c14c7dd102784a4e1b57ed063cddf59f63f8c (diff) | |
parent | 1358e5dcd9af0ecace07115a790544a22d5eb3bd (diff) | |
download | nextcloud-server-601457d2217ec1ed18b49061e38d4cda3703c9f6.tar.gz nextcloud-server-601457d2217ec1ed18b49061e38d4cda3703c9f6.zip |
Merge pull request #20773 from owncloud/share2.0_create
[Sharing 2.0] create share
Diffstat (limited to 'apps')
-rw-r--r-- | apps/files_sharing/api/ocssharewrapper.php | 13 | ||||
-rw-r--r-- | apps/files_sharing/api/share20ocs.php | 153 | ||||
-rw-r--r-- | apps/files_sharing/tests/api/share20ocstest.php | 295 |
3 files changed, 451 insertions, 10 deletions
diff --git a/apps/files_sharing/api/ocssharewrapper.php b/apps/files_sharing/api/ocssharewrapper.php index ca04c656c28..4640f4ea185 100644 --- a/apps/files_sharing/api/ocssharewrapper.php +++ b/apps/files_sharing/api/ocssharewrapper.php @@ -29,13 +29,18 @@ class OCSShareWrapper { return new Share20OCS( new \OC\Share20\Manager( \OC::$server->getLogger(), - \OC::$server->getAppConfig(), + \OC::$server->getConfig(), new \OC\Share20\DefaultShareProvider( \OC::$server->getDatabaseConnection(), \OC::$server->getUserManager(), \OC::$server->getGroupManager(), \OC::$server->getRootFolder() - ) + ), + \OC::$server->getSecureRandom(), + \OC::$server->getHasher(), + \OC::$server->getMountManager(), + \OC::$server->getGroupManager(), + \OC::$server->getL10N('core') ), \OC::$server->getGroupManager(), \OC::$server->getUserManager(), @@ -49,8 +54,8 @@ class OCSShareWrapper { return \OCA\Files_Sharing\API\Local::getAllShares($params); } - public function createShare($params) { - return \OCA\Files_Sharing\API\Local::createShare($params); + public function createShare() { + return $this->getShare20OCS()->createShare(); } public function getShare($params) { diff --git a/apps/files_sharing/api/share20ocs.php b/apps/files_sharing/api/share20ocs.php index 6c25b4a4426..003c028bf97 100644 --- a/apps/files_sharing/api/share20ocs.php +++ b/apps/files_sharing/api/share20ocs.php @@ -25,7 +25,6 @@ use OC\Share20\IShare; use OCP\IGroupManager; use OCP\IUserManager; use OCP\IRequest; -use OCP\Files\Folder; use OCP\IURLGenerator; use OCP\IUser; use OCP\Files\IRootFolder; @@ -98,7 +97,7 @@ class Share20OCS { $result['item_type'] = 'file'; } $result['storage_id'] = $path->getStorage()->getId(); - $result['storage'] = \OC\Files\Cache\Storage::getNumericStorageId($path->getStorage()->getId()); + $result['storage'] = $path->getStorage()->getCache()->getNumericStorageId(); $result['item_source'] = $path->getId(); $result['file_source'] = $path->getId(); $result['file_parent'] = $path->getParent()->getId(); @@ -192,6 +191,130 @@ class Share20OCS { } /** + * @return \OC_OCS_Result + */ + public function createShare() { + $share = $this->shareManager->newShare(); + + // Verify path + $path = $this->request->getParam('path', null); + if ($path === null) { + return new \OC_OCS_Result(null, 404, 'please specify a file or folder path'); + } + + $userFolder = $this->rootFolder->getUserFolder($this->currentUser->getUID()); + try { + $path = $userFolder->get($path); + } catch (\OCP\Files\NotFoundException $e) { + return new \OC_OCS_Result(null, 404, 'wrong path, file/folder doesn\'t exist'); + } + + $share->setPath($path); + + // Parse permissions (if available) + $permissions = $this->request->getParam('permissions', null); + if ($permissions === null) { + $permissions = \OCP\Constants::PERMISSION_ALL; + } else { + $permissions = (int)$permissions; + } + + if ($permissions < 0 || $permissions > \OCP\Constants::PERMISSION_ALL) { + return new \OC_OCS_Result(null, 404, 'invalid permissions'); + } + + // Shares always require read permissions + $permissions |= \OCP\Constants::PERMISSION_READ; + + if ($path instanceof \OCP\Files\File) { + // Single file shares should never have delete or create permissions + $permissions &= ~\OCP\Constants::PERMISSION_DELETE; + $permissions &= ~\OCP\Constants::PERMISSION_CREATE; + } + + $shareWith = $this->request->getParam('shareWith', null); + $shareType = (int)$this->request->getParam('shareType', '-1'); + + if ($shareType === \OCP\Share::SHARE_TYPE_USER) { + // Valid user is required to share + if ($shareWith === null || !$this->userManager->userExists($shareWith)) { + return new \OC_OCS_Result(null, 404, 'please specify a valid user'); + } + $share->setSharedWith($this->userManager->get($shareWith)); + $share->setPermissions($permissions); + } else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) { + // Valid group is required to share + if ($shareWith === null || !$this->groupManager->groupExists($shareWith)) { + return new \OC_OCS_Result(null, 404, 'please specify a valid group'); + } + $share->setSharedWith($this->groupManager->get($shareWith)); + $share->setPermissions($permissions); + } else if ($shareType === \OCP\Share::SHARE_TYPE_LINK) { + //Can we even share links? + if (!$this->shareManager->shareApiAllowLinks()) { + return new \OC_OCS_Result(null, 404, 'public link sharing is disabled by the administrator'); + } + + $publicUpload = $this->request->getParam('publicUpload', null); + if ($publicUpload === 'true') { + // Check if public upload is allowed + if (!$this->shareManager->shareApiLinkAllowPublicUpload()) { + return new \OC_OCS_Result(null, 403, '"public upload disabled by the administrator'); + } + + // Public upload can only be set for folders + if ($path instanceof \OCP\Files\File) { + return new \OC_OCS_Result(null, 404, '"public upload is only possible for public shared folders'); + } + + $share->setPermissions( + \OCP\Constants::PERMISSION_READ | + \OCP\Constants::PERMISSION_CREATE | + \OCP\Constants::PERMISSION_UPDATE + ); + } else { + $share->setPermissions(\OCP\Constants::PERMISSION_READ); + } + + // Set password + $share->setPassword($this->request->getParam('password', null)); + + //Expire date + $expireDate = $this->request->getParam('expireDate', null); + + if ($expireDate !== null) { + try { + $expireDate = $this->parseDate($expireDate); + $share->setExpirationDate($expireDate); + } catch (\Exception $e) { + return new \OC_OCS_Result(null, 404, 'Invalid Date. Format must be YYYY-MM-DD.'); + } + } + + } else if ($shareType === \OCP\Share::SHARE_TYPE_REMOTE) { + //fixme Remote shares are handled by old code path for now + return \OCA\Files_Sharing\API\Local::createShare([]); + } else { + return new \OC_OCS_Result(null, 400, "unknown share type"); + } + + $share->setShareType($shareType); + $share->setSharedBy($this->currentUser); + + try { + $share = $this->shareManager->createShare($share); + } catch (\OC\HintException $e) { + $code = $e->getCode() === 0 ? 403 : $e->getCode(); + return new \OC_OCS_Result(null, $code, $e->getHint()); + }catch (\Exception $e) { + return new \OC_OCS_Result(null, 403, $e->getMessage()); + } + + $share = $this->formatShare($share); + return new \OC_OCS_Result($share); + } + + /** * @param IShare $share * @return bool */ @@ -216,4 +339,30 @@ class Share20OCS { return false; } + + /** + * Make sure that the passed date is valid ISO 8601 + * So YYYY-MM-DD + * If not throw an exception + * + * @param string $expireDate + * + * @throws \Exception + * @return \DateTime + */ + private function parseDate($expireDate) { + try { + $date = new \DateTime($expireDate); + } catch (\Exception $e) { + throw new \Exception('Invalid date. Format must be YYYY-MM-DD'); + } + + if ($date === false) { + throw new \Exception('Invalid date. Format must be YYYY-MM-DD'); + } + + $date->setTime(0,0,0); + + return $date; + } } diff --git a/apps/files_sharing/tests/api/share20ocstest.php b/apps/files_sharing/tests/api/share20ocstest.php index b7c56fe17f6..74a5d0752a4 100644 --- a/apps/files_sharing/tests/api/share20ocstest.php +++ b/apps/files_sharing/tests/api/share20ocstest.php @@ -65,6 +65,7 @@ class Share20OCSTest extends \Test\TestCase { $this->rootFolder = $this->getMock('OCP\Files\IRootFolder'); $this->urlGenerator = $this->getMock('OCP\IURLGenerator'); $this->currentUser = $this->getMock('OCP\IUser'); + $this->currentUser->method('getUID')->willReturn('currentUser'); $this->ocs = new Share20OCS( $this->shareManager, @@ -171,8 +172,18 @@ class Share20OCSTest extends \Test\TestCase { $group = $this->getMock('OCP\IGroup'); $group->method('getGID')->willReturn('groupId'); - $storage = $this->getMock('OCP\Files\Storage'); + $cache = $this->getMockBuilder('OC\Files\Cache\Cache') + ->disableOriginalConstructor() + ->getMock(); + $cache->method('getNumericStorageId')->willReturn(101); + + $storage = $this->getMockBuilder('OC\Files\Storage\Storage') + ->disableOriginalConstructor() + ->getMock(); $storage->method('getId')->willReturn('STORAGE'); + $storage->method('getCache')->willReturn($cache); + + $parentFolder = $this->getMock('OCP\Files\Folder'); $parentFolder->method('getId')->willReturn(3); @@ -223,7 +234,7 @@ class Share20OCSTest extends \Test\TestCase { 'parent' => 6, 'storage_id' => 'STORAGE', 'path' => 'file', - 'storage' => null, // HACK around static function + 'storage' => 101, 'mail_send' => 0, ]; $data[] = [$share, $expected]; @@ -262,7 +273,7 @@ class Share20OCSTest extends \Test\TestCase { 'parent' => 6, 'storage_id' => 'STORAGE', 'path' => 'folder', - 'storage' => null, // HACK around static function + 'storage' => 101, 'mail_send' => 0, ]; $data[] = [$share, $expected]; @@ -304,7 +315,7 @@ class Share20OCSTest extends \Test\TestCase { 'parent' => 6, 'storage_id' => 'STORAGE', 'path' => 'folder', - 'storage' => null, // HACK around static function + 'storage' => 101, 'mail_send' => 0, 'url' => 'url', ]; @@ -391,4 +402,280 @@ class Share20OCSTest extends \Test\TestCase { $share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_LINK); $this->assertFalse($this->invokePrivate($this->ocs, 'canAccessShare', [$share])); } + + public function testCreateShareNoPath() { + $expected = new \OC_OCS_Result(null, 404, 'please specify a file or folder path'); + + $result = $this->ocs->createShare(); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testCreateShareInvalidPath() { + $this->request + ->method('getParam') + ->will($this->returnValueMap([ + ['path', null, 'invalid-path'], + ])); + + $userFolder = $this->getMock('\OCP\Files\Folder'); + $this->rootFolder->expects($this->once()) + ->method('getUserFolder') + ->with('currentUser') + ->willReturn($userFolder); + + $userFolder->expects($this->once()) + ->method('get') + ->with('invalid-path') + ->will($this->throwException(new \OCP\Files\NotFoundException())); + + $expected = new \OC_OCS_Result(null, 404, 'wrong path, file/folder doesn\'t exist'); + + $result = $this->ocs->createShare(); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testCreateShareInvalidPermissions() { + $share = $this->getMock('\OC\Share20\IShare'); + $this->shareManager->method('newShare')->willReturn($share); + + $this->request + ->method('getParam') + ->will($this->returnValueMap([ + ['path', null, 'valid-path'], + ['permissions', null, 32], + ])); + + $userFolder = $this->getMock('\OCP\Files\Folder'); + $this->rootFolder->expects($this->once()) + ->method('getUserFolder') + ->with('currentUser') + ->willReturn($userFolder); + + $path = $this->getMock('\OCP\Files\File'); + $userFolder->expects($this->once()) + ->method('get') + ->with('valid-path') + ->willReturn($path); + + $expected = new \OC_OCS_Result(null, 404, 'invalid permissions'); + + $result = $this->ocs->createShare(); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testCreateShareUserNoShareWith() { + $share = $this->getMock('\OC\Share20\IShare'); + $this->shareManager->method('newShare')->willReturn($share); + + $this->request + ->method('getParam') + ->will($this->returnValueMap([ + ['path', null, 'valid-path'], + ['permissions', null, \OCP\Constants::PERMISSION_ALL], + ['shareType', $this->any(), \OCP\Share::SHARE_TYPE_USER], + ])); + + $userFolder = $this->getMock('\OCP\Files\Folder'); + $this->rootFolder->expects($this->once()) + ->method('getUserFolder') + ->with('currentUser') + ->willReturn($userFolder); + + $path = $this->getMock('\OCP\Files\File'); + $userFolder->expects($this->once()) + ->method('get') + ->with('valid-path') + ->willReturn($path); + + $expected = new \OC_OCS_Result(null, 404, 'please specify a valid user'); + + $result = $this->ocs->createShare(); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testCreateShareUserNoValidShareWith() { + $share = $this->getMock('\OC\Share20\IShare'); + $this->shareManager->method('newShare')->willReturn($share); + + $this->request + ->method('getParam') + ->will($this->returnValueMap([ + ['path', null, 'valid-path'], + ['permissions', null, \OCP\Constants::PERMISSION_ALL], + ['shareType', $this->any(), \OCP\Share::SHARE_TYPE_USER], + ['shareWith', $this->any(), 'invalidUser'], + ])); + + $userFolder = $this->getMock('\OCP\Files\Folder'); + $this->rootFolder->expects($this->once()) + ->method('getUserFolder') + ->with('currentUser') + ->willReturn($userFolder); + + $path = $this->getMock('\OCP\Files\File'); + $userFolder->expects($this->once()) + ->method('get') + ->with('valid-path') + ->willReturn($path); + + $expected = new \OC_OCS_Result(null, 404, 'please specify a valid user'); + + $result = $this->ocs->createShare(); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testCreateShareUser() { + $share = $this->getMock('\OC\Share20\IShare'); + $this->shareManager->method('newShare')->willReturn($share); + + $ocs = $this->getMockBuilder('OCA\Files_Sharing\API\Share20OCS') + ->setConstructorArgs([ + $this->shareManager, + $this->groupManager, + $this->userManager, + $this->request, + $this->rootFolder, + $this->urlGenerator, + $this->currentUser + ])->setMethods(['formatShare']) + ->getMock(); + + $this->request + ->method('getParam') + ->will($this->returnValueMap([ + ['path', null, 'valid-path'], + ['permissions', null, \OCP\Constants::PERMISSION_ALL], + ['shareType', $this->any(), \OCP\Share::SHARE_TYPE_USER], + ['shareWith', null, 'validUser'], + ])); + + $userFolder = $this->getMock('\OCP\Files\Folder'); + $this->rootFolder->expects($this->once()) + ->method('getUserFolder') + ->with('currentUser') + ->willReturn($userFolder); + + $path = $this->getMock('\OCP\Files\File'); + $userFolder->expects($this->once()) + ->method('get') + ->with('valid-path') + ->willReturn($path); + + $user = $this->getMock('\OCP\IUser'); + $this->userManager->method('userExists')->with('validUser')->willReturn(true); + $this->userManager->method('get')->with('validUser')->willReturn($user); + + $share->method('setPath')->with($path); + $share->method('setPermissions') + ->with( + \OCP\Constants::PERMISSION_ALL & + ~\OCP\Constants::PERMISSION_DELETE & + ~\OCP\Constants::PERMISSION_CREATE); + $share->method('setShareType')->with(\OCP\Share::SHARE_TYPE_USER); + $share->method('setSharedWith')->with($user); + $share->method('setSharedBy')->with($this->currentUser); + + $expected = new \OC_OCS_Result(); + $result = $ocs->createShare(); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testCreateShareGroupNoValidShareWith() { + $share = $this->getMock('\OC\Share20\IShare'); + $this->shareManager->method('newShare')->willReturn($share); + + $this->request + ->method('getParam') + ->will($this->returnValueMap([ + ['path', null, 'valid-path'], + ['permissions', null, \OCP\Constants::PERMISSION_ALL], + ['shareType', $this->any(), \OCP\Share::SHARE_TYPE_GROUP], + ['shareWith', $this->any(), 'invalidGroup'], + ])); + + $userFolder = $this->getMock('\OCP\Files\Folder'); + $this->rootFolder->expects($this->once()) + ->method('getUserFolder') + ->with('currentUser') + ->willReturn($userFolder); + + $path = $this->getMock('\OCP\Files\File'); + $userFolder->expects($this->once()) + ->method('get') + ->with('valid-path') + ->willReturn($path); + + $expected = new \OC_OCS_Result(null, 404, 'please specify a valid user'); + + $result = $this->ocs->createShare(); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } + + public function testCreateShareGroup() { + $share = $this->getMock('\OC\Share20\IShare'); + $this->shareManager->method('newShare')->willReturn($share); + + $ocs = $this->getMockBuilder('OCA\Files_Sharing\API\Share20OCS') + ->setConstructorArgs([ + $this->shareManager, + $this->groupManager, + $this->userManager, + $this->request, + $this->rootFolder, + $this->urlGenerator, + $this->currentUser + ])->setMethods(['formatShare']) + ->getMock(); + + $this->request + ->method('getParam') + ->will($this->returnValueMap([ + ['path', null, 'valid-path'], + ['permissions', null, \OCP\Constants::PERMISSION_ALL], + ['shareType', '-1', \OCP\Share::SHARE_TYPE_GROUP], + ['shareWith', null, 'validGroup'], + ])); + + $userFolder = $this->getMock('\OCP\Files\Folder'); + $this->rootFolder->expects($this->once()) + ->method('getUserFolder') + ->with('currentUser') + ->willReturn($userFolder); + + $path = $this->getMock('\OCP\Files\Folder'); + $userFolder->expects($this->once()) + ->method('get') + ->with('valid-path') + ->willReturn($path); + + $group = $this->getMock('\OCP\IGroup'); + $this->groupManager->method('groupExists')->with('validGroup')->willReturn(true); + $this->groupManager->method('get')->with('validGroup')->willReturn($group); + + $share->method('setPath')->with($path); + $share->method('setPermissions')->with(\OCP\Constants::PERMISSION_ALL); + $share->method('setShareType')->with(\OCP\Share::SHARE_TYPE_GROUP); + $share->method('setSharedWith')->with($group); + $share->method('setSharedBy')->with($this->currentUser); + + $expected = new \OC_OCS_Result(); + $result = $ocs->createShare(); + + $this->assertEquals($expected->getMeta(), $result->getMeta()); + $this->assertEquals($expected->getData(), $result->getData()); + } } |