From a08c497808e6dde60508c1eaaaaad819e9210814 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Tue, 15 Dec 2015 09:53:16 +0100 Subject: [PATCH] [Share 2.0] Make share provider ready for create shares --- lib/private/share20/defaultshareprovider.php | 124 +++++++++++- lib/private/share20/ishareprovider.php | 3 +- .../lib/share20/defaultshareprovidertest.php | 188 ++++++++++++++++++ 3 files changed, 302 insertions(+), 13 deletions(-) diff --git a/lib/private/share20/defaultshareprovider.php b/lib/private/share20/defaultshareprovider.php index bc3bc0ce9e..a715564492 100644 --- a/lib/private/share20/defaultshareprovider.php +++ b/lib/private/share20/defaultshareprovider.php @@ -64,11 +64,90 @@ class DefaultShareProvider implements IShareProvider { /** * Share a path - * + * * @param IShare $share * @return IShare The share object + * @throws ShareNotFound + * @throws \Exception */ public function create(IShare $share) { + $qb = $this->dbConn->getQueryBuilder(); + + $qb->insert('share'); + $qb->setValue('share_type', $qb->createNamedParameter($share->getShareType())); + + if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) { + //Set the UID of the user we share with + $qb->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()->getUID())); + } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) { + //Set the GID of the group we share with + $qb->setValue('share_with', $qb->createNamedParameter($share->getSharedWith()->getGID())); + } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) { + //Set the token of the share + $qb->setValue('token', $qb->createNamedParameter($share->getToken())); + + //If a password is set store it + if ($share->getPassword() !== null) { + $qb->setValue('share_with', $qb->createNamedParameter($share->getPassword())); + } + + //If an expiration date is set store it + if ($share->getExpirationDate() !== null) { + $qb->setValue('expiration', $qb->createNamedParameter($share->getExpirationDate(), 'datetime')); + } + } else { + throw new \Exception('invalid share type!'); + } + + // Set what is shares + $qb->setValue('item_type', $qb->createParameter('itemType')); + if ($share->getPath() instanceof \OCP\Files\File) { + $qb->setParameter('itemType', 'file'); + } else { + $qb->setParameter('itemType', 'folder'); + } + + // Set the file id + $qb->setValue('item_source', $qb->createNamedParameter($share->getPath()->getId())); + $qb->setValue('file_source', $qb->createNamedParameter($share->getPath()->getId())); + + // set the permissions + $qb->setValue('permissions', $qb->createNamedParameter($share->getPermissions())); + + // Set who created this share + $qb->setValue('uid_initiator', $qb->createNamedParameter($share->getSharedBy()->getUID())); + + // Set who is the owner of this file/folder (and this the owner of the share) + $qb->setValue('uid_owner', $qb->createNamedParameter($share->getShareOwner()->getUID())); + + // Set the file target + $qb->setValue('file_target', $qb->createNamedParameter($share->getTarget())); + + // Set the time this share was created + $qb->setValue('stime', $qb->createNamedParameter(time())); + + // insert the data and fetch the id of the share + $this->dbConn->beginTransaction(); + $qb->execute(); + $id = $this->dbConn->lastInsertId('*PREFIX*share'); + $this->dbConn->commit(); + + // Now fetch the inserted share and create a complete share object + $qb = $this->dbConn->getQueryBuilder(); + $qb->select('*') + ->from('*PREFIX*share') + ->where($qb->expr()->eq('id', $qb->createNamedParameter($id))); + + $cursor = $qb->execute(); + $data = $cursor->fetch(); + $cursor->closeCursor(); + + if ($data === false) { + throw new ShareNotFound(); + } + + $share = $this->createShare($data); + return $share; } /** @@ -170,11 +249,29 @@ class DefaultShareProvider implements IShareProvider { /** * Get shares for a given path * - * @param \OCP\IUser $user * @param \OCP\Files\Node $path * @return IShare[] */ - public function getSharesByPath(IUser $user, Node $path) { + public function getSharesByPath(Node $path) { + $qb = $this->dbConn->getQueryBuilder(); + + $cursor = $qb->select('*') + ->from('share') + ->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId()))) + ->andWhere( + $qb->expr()->orX( + $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_USER)), + $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_GROUP)) + ) + )->execute(); + + $shares = []; + while($data = $cursor->fetch()) { + $shares[] = $this->createShare($data); + } + $cursor->closeCursor(); + + return $shares; } /** @@ -223,16 +320,21 @@ class DefaultShareProvider implements IShareProvider { $share->setSharedWith($data['share_with']); } - $share->setSharedBy($this->userManager->get($data['uid_owner'])); + if ($data['uid_initiator'] === null) { + //OLD SHARE + $share->setSharedBy($this->userManager->get($data['uid_owner'])); + $folder = $this->rootFolder->getUserFolder($share->getSharedBy()->getUID()); + $path = $folder->getById((int)$data['file_source'])[0]; - // TODO: getById can return an array. How to handle this properly?? - $folder = $this->rootFolder->getUserFolder($share->getSharedBy()->getUID()); - $path = $folder->getById((int)$data['file_source'])[0]; + $owner = $path->getOwner(); + $share->setShareOwner($owner); + } else { + //New share! + $share->setSharedBy($this->userManager->get($data['uid_initiator'])); + $share->setShareOwner($this->userManager->get($data['uid_owner'])); + } - $owner = $path->getOwner(); - $share->setShareOwner($owner); - - $path = $this->rootFolder->getUserFolder($owner->getUID())->getById((int)$data['file_source'])[0]; + $path = $this->rootFolder->getUserFolder($share->getShareOwner()->getUID())->getById((int)$data['file_source'])[0]; $share->setPath($path); if ($data['expiration'] !== null) { diff --git a/lib/private/share20/ishareprovider.php b/lib/private/share20/ishareprovider.php index 56a550acf7..97a2b728d5 100644 --- a/lib/private/share20/ishareprovider.php +++ b/lib/private/share20/ishareprovider.php @@ -81,11 +81,10 @@ interface IShareProvider { /** * Get shares for a given path * - * @param \OCP\IUser $user * @param \OCP\Files\Node $path * @return IShare[] */ - public function getSharesByPath(\OCP\IUser $user, \OCP\Files\Node $path); + public function getSharesByPath(\OCP\Files\Node $path); /** * Get shared with the given user diff --git a/tests/lib/share20/defaultshareprovidertest.php b/tests/lib/share20/defaultshareprovidertest.php index dc45bc7c08..beef4c9ef5 100644 --- a/tests/lib/share20/defaultshareprovidertest.php +++ b/tests/lib/share20/defaultshareprovidertest.php @@ -26,6 +26,12 @@ use OCP\IGroupManager; use OCP\Files\IRootFolder; use OC\Share20\DefaultShareProvider; +/** + * Class DefaultShareProviderTest + * + * @package Test\Share20 + * @group DB + */ class DefaultShareProviderTest extends \Test\TestCase { /** @var IDBConnection */ @@ -533,4 +539,186 @@ class DefaultShareProviderTest extends \Test\TestCase { $this->assertEquals(null, $children[1]->getExpirationDate()); $this->assertEquals('myTarget2', $children[1]->getTarget()); } + + public function testCreateUserShare() { + $share = new \OC\Share20\Share(); + + $sharedWith = $this->getMock('OCP\IUser'); + $sharedWith->method('getUID')->willReturn('sharedWith'); + $sharedBy = $this->getMock('OCP\IUser'); + $sharedBy->method('getUID')->willReturn('sharedBy'); + $shareOwner = $this->getMock('OCP\IUser'); + $shareOwner->method('getUID')->WillReturn('shareOwner'); + + $this->userManager + ->method('get') + ->will($this->returnValueMap([ + ['sharedWith', $sharedWith], + ['sharedBy', $sharedBy], + ['shareOwner', $shareOwner], + ])); + + $path = $this->getMock('\OCP\Files\File'); + $path->method('getId')->willReturn(100); + $path->method('getOwner')->willReturn($shareOwner); + + $ownerFolder = $this->getMock('OCP\Files\Folder'); + $userFolder = $this->getMock('OCP\Files\Folder'); + $this->rootFolder + ->method('getUserFolder') + ->will($this->returnValueMap([ + ['sharedBy', $userFolder], + ['shareOwner', $ownerFolder], + ])); + + $userFolder->method('getById') + ->with(100) + ->willReturn([$path]); + $ownerFolder->method('getById') + ->with(100) + ->willReturn([$path]); + + $share->setShareType(\OCP\Share::SHARE_TYPE_USER); + $share->setSharedWith($sharedWith); + $share->setSharedBy($sharedBy); + $share->setShareOwner($shareOwner); + $share->setPath($path); + $share->setPermissions(1); + $share->setTarget('/target'); + + $share2 = $this->provider->create($share); + + $this->assertNotNull($share2->getId()); + $this->assertSame(\OCP\Share::SHARE_TYPE_USER, $share2->getShareType()); + $this->assertSame($sharedWith, $share2->getSharedWith()); + $this->assertSame($sharedBy, $share2->getSharedBy()); + $this->assertSame($shareOwner, $share2->getShareOwner()); + $this->assertSame(1, $share2->getPermissions()); + $this->assertSame('/target', $share2->getTarget()); + $this->assertLessThanOrEqual(time(), $share2->getSharetime()); + $this->assertSame($path, $share2->getPath()); + } + + public function testCreateGroupShare() { + $share = new \OC\Share20\Share(); + + $sharedWith = $this->getMock('OCP\IGroup'); + $sharedWith->method('getGID')->willReturn('sharedWith'); + $sharedBy = $this->getMock('OCP\IUser'); + $sharedBy->method('getUID')->willReturn('sharedBy'); + $shareOwner = $this->getMock('OCP\IUser'); + $shareOwner->method('getUID')->WillReturn('shareOwner'); + + $this->userManager + ->method('get') + ->will($this->returnValueMap([ + ['sharedBy', $sharedBy], + ['shareOwner', $shareOwner], + ])); + $this->groupManager + ->method('get') + ->with('sharedWith') + ->willReturn($sharedWith); + + $path = $this->getMock('\OCP\Files\Folder'); + $path->method('getId')->willReturn(100); + $path->method('getOwner')->willReturn($shareOwner); + + $ownerFolder = $this->getMock('OCP\Files\Folder'); + $userFolder = $this->getMock('OCP\Files\Folder'); + $this->rootFolder + ->method('getUserFolder') + ->will($this->returnValueMap([ + ['sharedBy', $userFolder], + ['shareOwner', $ownerFolder], + ])); + + $userFolder->method('getById') + ->with(100) + ->willReturn([$path]); + $ownerFolder->method('getById') + ->with(100) + ->willReturn([$path]); + + $share->setShareType(\OCP\Share::SHARE_TYPE_GROUP); + $share->setSharedWith($sharedWith); + $share->setSharedBy($sharedBy); + $share->setShareOwner($shareOwner); + $share->setPath($path); + $share->setPermissions(1); + $share->setTarget('/target'); + + $share2 = $this->provider->create($share); + + $this->assertNotNull($share2->getId()); + $this->assertSame(\OCP\Share::SHARE_TYPE_GROUP, $share2->getShareType()); + $this->assertSame($sharedWith, $share2->getSharedWith()); + $this->assertSame($sharedBy, $share2->getSharedBy()); + $this->assertSame($shareOwner, $share2->getShareOwner()); + $this->assertSame(1, $share2->getPermissions()); + $this->assertSame('/target', $share2->getTarget()); + $this->assertLessThanOrEqual(time(), $share2->getSharetime()); + $this->assertSame($path, $share2->getPath()); + } + + public function testCreateLinkShare() { + $share = new \OC\Share20\Share(); + + $sharedBy = $this->getMock('OCP\IUser'); + $sharedBy->method('getUID')->willReturn('sharedBy'); + $shareOwner = $this->getMock('OCP\IUser'); + $shareOwner->method('getUID')->WillReturn('shareOwner'); + + $this->userManager + ->method('get') + ->will($this->returnValueMap([ + ['sharedBy', $sharedBy], + ['shareOwner', $shareOwner], + ])); + + $path = $this->getMock('\OCP\Files\Folder'); + $path->method('getId')->willReturn(100); + $path->method('getOwner')->willReturn($shareOwner); + + $ownerFolder = $this->getMock('OCP\Files\Folder'); + $userFolder = $this->getMock('OCP\Files\Folder'); + $this->rootFolder + ->method('getUserFolder') + ->will($this->returnValueMap([ + ['sharedBy', $userFolder], + ['shareOwner', $ownerFolder], + ])); + + $userFolder->method('getById') + ->with(100) + ->willReturn([$path]); + $ownerFolder->method('getById') + ->with(100) + ->willReturn([$path]); + + $share->setShareType(\OCP\Share::SHARE_TYPE_LINK); + $share->setSharedBy($sharedBy); + $share->setShareOwner($shareOwner); + $share->setPath($path); + $share->setPermissions(1); + $share->setPassword('password'); + $share->setToken('token'); + $expireDate = new \DateTime(); + $share->setExpirationDate($expireDate); + $share->setTarget('/target'); + + $share2 = $this->provider->create($share); + + $this->assertNotNull($share2->getId()); + $this->assertSame(\OCP\Share::SHARE_TYPE_LINK, $share2->getShareType()); + $this->assertSame($sharedBy, $share2->getSharedBy()); + $this->assertSame($shareOwner, $share2->getShareOwner()); + $this->assertSame(1, $share2->getPermissions()); + $this->assertSame('/target', $share2->getTarget()); + $this->assertLessThanOrEqual(time(), $share2->getSharetime()); + $this->assertSame($path, $share2->getPath()); + $this->assertSame('password', $share2->getPassword()); + $this->assertSame('token', $share2->getToken()); + $this->assertEquals($expireDate, $share2->getExpirationDate()); + } }