diff --git a/lib/private/Share/Share.php b/lib/private/Share/Share.php index 44e03e5d2ec3..936f27a5f340 100644 --- a/lib/private/Share/Share.php +++ b/lib/private/Share/Share.php @@ -45,6 +45,7 @@ use OC\Group\Group; use OCA\FederatedFileSharing\DiscoveryManager; use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\Events\EventEmitterTrait; use OCP\IUser; use OCP\IUserSession; use OCP\IDBConnection; @@ -60,6 +61,8 @@ */ class Share extends Constants { + use EventEmitterTrait; + /** CRUDS permissions (Create, Read, Update, Delete, Share) using a bitmask * Construct permissions for share() and setPermissions with Or (|) e.g. * Give user read and update permissions: PERMISSION_READ | PERMISSION_UPDATE @@ -996,12 +999,17 @@ public static function unshareAll($itemType, $itemSource) { 'itemSource' => $itemSource, 'shares' => $shares, ]; - \OC_Hook::emit('OCP\Share', 'pre_unshareAll', $hookParams); - foreach ($shares as $share) { - self::unshareItem($share); - } - \OC_Hook::emit('OCP\Share', 'post_unshareAll', $hookParams); - return true; + return (new self)->emittingCall(function () use (&$hookParams, $shares) { + \OC_Hook::emit('OCP\Share', 'pre_unshareAll', $hookParams); + foreach ($shares as $share) { + self::unshareItem($share); + } + \OC_Hook::emit('OCP\Share', 'post_unshareAll', $hookParams); + return true; + }, [ + 'before' => ['share' => $hookParams], + 'after' => ['share' => $hookParams]], + 'file', 'unshareAll'); } return false; } @@ -1532,11 +1540,17 @@ protected static function unshareItem(array $item, $newParent = null) { $hookParams['fileTarget'] = $item['file_target']; } - \OC_Hook::emit('OCP\Share', 'pre_unshare', $hookParams); - $deletedShares = Helper::delete($item['id'], false, null, $newParent); - $deletedShares[] = $hookParams; - $hookParams['deletedShares'] = $deletedShares; - \OC_Hook::emit('OCP\Share', 'post_unshare', $hookParams); + (new self)->emittingCall(function () use (&$hookParams, &$item, &$newParent) { + \OC_Hook::emit('OCP\Share', 'pre_unshare', $hookParams); + $deletedShares = Helper::delete($item['id'], false, null, $newParent); + $deletedShares[] = $hookParams; + $hookParams['deletedShares'] = $deletedShares; + \OC_Hook::emit('OCP\Share', 'post_unshare', $hookParams); + return true; + }, [ + 'before' => ['share' => $hookParams], + 'after' => ['share' => &$hookParams], + ], 'file', 'unshare'); if ((int)$item['share_type'] === \OCP\Share::SHARE_TYPE_REMOTE && \OC::$server->getUserSession()->getUser()) { list(, $remote) = Helper::splitUserRemote($item['share_with']); self::sendRemoteUnshare($remote, $item['id'], $item['token']); @@ -2223,118 +2237,128 @@ private static function put($itemType, $itemSource, $shareType, $shareWith, $uid throw new \Exception($error); } - foreach ($users as $user) { - $sourceId = ($itemType === 'file' || $itemType === 'folder') ? $fileSource : $itemSource; - $sourceExists = self::getItemSharedWithBySource($itemType, $sourceId, self::FORMAT_NONE, null, true, $user); + $postHookData = []; + return (new self)->emittingCall(function () use (&$preHookData, &$users, &$itemType, + &$isGroupShare, &$groupItemTarget, &$fileSource, &$itemSource, + &$shareType, &$uidOwner, &$suggestedItemTarget, &$parent, + &$parentFolder, &$suggestedItemTarget, &$suggestedFileTarget, + &$filePath, &$groupFileTarget, &$permissions, &$expirationDate, + &$token, &$shareWith, &$queriesToExecute, &$postHookData) { + foreach ($users as $user) { + $sourceId = ($itemType === 'file' || $itemType === 'folder') ? $fileSource : $itemSource; + $sourceExists = self::getItemSharedWithBySource($itemType, $sourceId, self::FORMAT_NONE, null, true, $user); - $userShareType = ($isGroupShare) ? self::$shareTypeGroupUserUnique : $shareType; + $userShareType = ($isGroupShare) ? self::$shareTypeGroupUserUnique : $shareType; - if ($sourceExists && $sourceExists['item_source'] === $itemSource) { - $fileTarget = $sourceExists['file_target']; - $itemTarget = $sourceExists['item_target']; + if ($sourceExists && $sourceExists['item_source'] === $itemSource) { + $fileTarget = $sourceExists['file_target']; + $itemTarget = $sourceExists['item_target']; - // for group shares we don't need a additional entry if the target is the same - if($isGroupShare && $groupItemTarget === $itemTarget) { - continue; - } + // for group shares we don't need a additional entry if the target is the same + if($isGroupShare && $groupItemTarget === $itemTarget) { + continue; + } - } elseif(!$sourceExists && !$isGroupShare) { - - $itemTarget = Helper::generateTarget($itemType, $itemSource, $userShareType, $user, - $uidOwner, $suggestedItemTarget, $parent); - if (isset($fileSource)) { - if ($parentFolder) { - if ($parentFolder === true) { - $fileTarget = Helper::generateTarget('file', $filePath, $userShareType, $user, - $uidOwner, $suggestedFileTarget, $parent); - if ($fileTarget != $groupFileTarget) { - $parentFolders[$user]['folder'] = $fileTarget; + } elseif(!$sourceExists && !$isGroupShare) { + + $itemTarget = Helper::generateTarget($itemType, $itemSource, $userShareType, $user, + $uidOwner, $suggestedItemTarget, $parent); + if (isset($fileSource)) { + if ($parentFolder) { + if ($parentFolder === true) { + $fileTarget = Helper::generateTarget('file', $filePath, $userShareType, $user, + $uidOwner, $suggestedFileTarget, $parent); + if ($fileTarget != $groupFileTarget) { + $parentFolders[$user]['folder'] = $fileTarget; + } + } else if (isset($parentFolder[$user])) { + $fileTarget = $parentFolder[$user]['folder'].$itemSource; + $parent = $parentFolder[$user]['id']; } - } else if (isset($parentFolder[$user])) { - $fileTarget = $parentFolder[$user]['folder'].$itemSource; - $parent = $parentFolder[$user]['id']; + } else { + $fileTarget = Helper::generateTarget('file', $filePath, $userShareType, + $user, $uidOwner, $suggestedFileTarget, $parent); } } else { - $fileTarget = Helper::generateTarget('file', $filePath, $userShareType, - $user, $uidOwner, $suggestedFileTarget, $parent); + $fileTarget = null; } - } else { - $fileTarget = null; - } - } else { + } else { - // group share which doesn't exists until now, check if we need a unique target for this user + // group share which doesn't exists until now, check if we need a unique target for this user - $itemTarget = Helper::generateTarget($itemType, $itemSource, self::SHARE_TYPE_USER, $user, - $uidOwner, $suggestedItemTarget, $parent); + $itemTarget = Helper::generateTarget($itemType, $itemSource, self::SHARE_TYPE_USER, $user, + $uidOwner, $suggestedItemTarget, $parent); - // do we also need a file target - if (isset($fileSource)) { - $fileTarget = Helper::generateTarget('file', $filePath, self::SHARE_TYPE_USER, $user, - $uidOwner, $suggestedFileTarget, $parent); - } else { - $fileTarget = null; - } + // do we also need a file target + if (isset($fileSource)) { + $fileTarget = Helper::generateTarget('file', $filePath, self::SHARE_TYPE_USER, $user, + $uidOwner, $suggestedFileTarget, $parent); + } else { + $fileTarget = null; + } - if (($itemTarget === $groupItemTarget) && - (!isset($fileSource) || $fileTarget === $groupFileTarget)) { - continue; + if (($itemTarget === $groupItemTarget) && + (!isset($fileSource) || $fileTarget === $groupFileTarget)) { + continue; + } } - } - $queriesToExecute[] = [ - 'itemType' => $itemType, - 'itemSource' => $itemSource, - 'itemTarget' => $itemTarget, - 'shareType' => $userShareType, - 'shareWith' => $user, - 'uidOwner' => $uidOwner, - 'permissions' => $permissions, - 'shareTime' => time(), - 'fileSource' => $fileSource, - 'fileTarget' => $fileTarget, - 'token' => $token, - 'parent' => $parent, - 'expiration' => $expirationDate, - ]; - - } + $queriesToExecute[] = [ + 'itemType' => $itemType, + 'itemSource' => $itemSource, + 'itemTarget' => $itemTarget, + 'shareType' => $userShareType, + 'shareWith' => $user, + 'uidOwner' => $uidOwner, + 'permissions' => $permissions, + 'shareTime' => time(), + 'fileSource' => $fileSource, + 'fileTarget' => $fileTarget, + 'token' => $token, + 'parent' => $parent, + 'expiration' => $expirationDate, + ]; - $id = false; - if ($isGroupShare) { - $id = self::insertShare($queriesToExecute['groupShare']); - // Save this id, any extra rows for this group share will need to reference it - $parent = \OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*share'); - unset($queriesToExecute['groupShare']); - } + } - foreach ($queriesToExecute as $shareQuery) { - $shareQuery['parent'] = $parent; - $id = self::insertShare($shareQuery); - } + $id = false; + if ($isGroupShare) { + $id = self::insertShare($queriesToExecute['groupShare']); + // Save this id, any extra rows for this group share will need to reference it + $parent = \OC::$server->getDatabaseConnection()->lastInsertId('*PREFIX*share'); + unset($queriesToExecute['groupShare']); + } - $postHookData = [ - 'itemType' => $itemType, - 'itemSource' => $itemSource, - 'parent' => $parent, - 'shareType' => $shareType, - 'uidOwner' => $uidOwner, - 'permissions' => $permissions, - 'fileSource' => $fileSource, - 'id' => $parent, - 'token' => $token, - 'expirationDate' => $expirationDate, - ]; + foreach ($queriesToExecute as $shareQuery) { + $shareQuery['parent'] = $parent; + $id = self::insertShare($shareQuery); + } - $postHookData['shareWith'] = ($isGroupShare) ? $shareWith['group'] : $shareWith; - $postHookData['itemTarget'] = ($isGroupShare) ? $groupItemTarget : $itemTarget; - $postHookData['fileTarget'] = ($isGroupShare) ? $groupFileTarget : $fileTarget; + $postHookData = [ + 'itemType' => $itemType, + 'itemSource' => $itemSource, + 'parent' => $parent, + 'shareType' => $shareType, + 'uidOwner' => $uidOwner, + 'permissions' => $permissions, + 'fileSource' => $fileSource, + 'id' => $parent, + 'token' => $token, + 'expirationDate' => $expirationDate, + ]; - \OC_Hook::emit('OCP\Share', 'post_shared', $postHookData); + $postHookData['shareWith'] = ($isGroupShare) ? $shareWith['group'] : $shareWith; + $postHookData['itemTarget'] = ($isGroupShare) ? $groupItemTarget : $itemTarget; + $postHookData['fileTarget'] = ($isGroupShare) ? $groupFileTarget : $fileTarget; + \OC_Hook::emit('OCP\Share', 'post_shared', $postHookData); - return $id ? $id : false; + return $id ? $id : false; + }, [ + 'before' => ['sharedata' => $preHookData], + 'after' => ['sharedata' => &$postHookData] + ], 'file', 'share'); } /** diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php index 0aa6a7f148cc..aab6e5fda8c3 100644 --- a/lib/private/Share20/Manager.php +++ b/lib/private/Share20/Manager.php @@ -28,6 +28,7 @@ use OC\Cache\CappedMemoryCache; use OC\Files\Mount\MoveableMount; +use OCP\Events\EventEmitterTrait; use OCP\Files\File; use OCP\Files\Folder; use OCP\Files\IRootFolder; @@ -51,6 +52,7 @@ */ class Manager implements IManager { + use EventEmitterTrait; /** @var IProviderFactory */ private $factory; /** @var ILogger */ @@ -633,35 +635,38 @@ public function createShare(\OCP\Share\IShare $share) { 'run' => &$run, 'error' => &$error, ]; - \OC_Hook::emit('OCP\Share', 'pre_shared', $preHookData); + $postHookData = []; + return $this->emittingCall(function () use (&$preHookData, &$postHookData, &$share, &$run, &$error) { + \OC_Hook::emit('OCP\Share', 'pre_shared', $preHookData); - if ($run === false) { - throw new \Exception($error); - } + if ($run === false) { + throw new \Exception($error); + } - $provider = $this->factory->getProviderForType($share->getShareType()); - $share = $provider->create($share); + $provider = $this->factory->getProviderForType($share->getShareType()); + $share = $provider->create($share); - // Post share hook - $postHookData = [ - 'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder', - 'itemSource' => $share->getNode()->getId(), - 'shareType' => $share->getShareType(), - 'uidOwner' => $share->getSharedBy(), - 'permissions' => $share->getPermissions(), - 'fileSource' => $share->getNode()->getId(), - 'expiration' => $share->getExpirationDate(), - 'token' => $share->getToken(), - 'id' => $share->getId(), - 'shareWith' => $share->getSharedWith(), - 'itemTarget' => $share->getTarget(), - 'fileTarget' => $share->getTarget(), - 'passwordEnabled' => (!is_null($share->getPassword()) and ($share->getPassword() !== '')), - ]; + // Post share hook + $postHookData = [ + 'itemType' => $share->getNode() instanceof \OCP\Files\File ? 'file' : 'folder', + 'itemSource' => $share->getNode()->getId(), + 'shareType' => $share->getShareType(), + 'uidOwner' => $share->getSharedBy(), + 'permissions' => $share->getPermissions(), + 'fileSource' => $share->getNode()->getId(), + 'expiration' => $share->getExpirationDate(), + 'token' => $share->getToken(), + 'id' => $share->getId(), + 'shareWith' => $share->getSharedWith(), + 'itemTarget' => $share->getTarget(), + 'fileTarget' => $share->getTarget(), + 'passwordEnabled' => (!is_null($share->getPassword()) and ($share->getPassword() !== '')), + ]; - \OC_Hook::emit('OCP\Share', 'post_shared', $postHookData); + \OC_Hook::emit('OCP\Share', 'post_shared', $postHookData); - return $share; + return $share; + }, ['before' => ['sharedata' => $preHookData], 'after' => ['sharedata' => $postHookData]], 'file', 'share'); } /** @@ -843,26 +848,32 @@ public function deleteShare(\OCP\Share\IShare $share) { $hookParams = self::formatUnshareHookParams($share); - // Emit pre-hook - \OC_Hook::emit('OCP\Share', 'pre_unshare', $hookParams); + return $this->emittingCall(function () use (&$share, &$hookParams) { - // Get all children and delete them as well - $deletedShares = $this->deleteChildren($share); + // Emit pre-hook + \OC_Hook::emit('OCP\Share', 'pre_unshare', $hookParams); - // Do the actual delete - $provider = $this->factory->getProviderForType($share->getShareType()); - $provider->delete($share); + // Get all children and delete them as well + $deletedShares = $this->deleteChildren($share); - // All the deleted shares caused by this delete - $deletedShares[] = $share; + // Do the actual delete + $provider = $this->factory->getProviderForType($share->getShareType()); + $provider->delete($share); - //Format hook info - $formattedDeletedShares = array_map('self::formatUnshareHookParams', $deletedShares); + // All the deleted shares caused by this delete + $deletedShares[] = $share; - $hookParams['deletedShares'] = $formattedDeletedShares; + //Format hook info + $formattedDeletedShares = array_map('self::formatUnshareHookParams', $deletedShares); - // Emit post hook - \OC_Hook::emit('OCP\Share', 'post_unshare', $hookParams); + $hookParams['deletedShares'] = $formattedDeletedShares; + + // Emit post hook + \OC_Hook::emit('OCP\Share', 'post_unshare', $hookParams); + + //This return is to trigger after dispatch event + return true; + }, ['before' => ['share' => $share], 'after' => ['share' => $hookParams]], 'file', 'unshare'); } diff --git a/tests/lib/Share/ShareTest.php b/tests/lib/Share/ShareTest.php index 238dfce2f0fd..1cfb4da2ce0e 100644 --- a/tests/lib/Share/ShareTest.php +++ b/tests/lib/Share/ShareTest.php @@ -21,6 +21,7 @@ namespace Test\Share; +use Symfony\Component\EventDispatcher\GenericEvent; use Test\Traits\UserTrait; /** @@ -282,12 +283,51 @@ public function testShareWithUser() { $this->assertEquals($message, $exception->getMessage()); } + $calledBeforeUnshareEvent = []; + $calledAfterUnshareEvent = []; + \OC::$server->getEventDispatcher()->addListener('file.beforeunshare', + function (GenericEvent $event) use (&$calledBeforeUnshareEvent) { + $calledBeforeUnshareEvent[] = 'file.beforeunshare'; + $calledBeforeUnshareEvent[] = $event; + }); + \OC::$server->getEventDispatcher()->addListener('file.afterunshare', + function (GenericEvent $event) use (&$calledAfterUnshareEvent) { + $calledAfterUnshareEvent[] = 'file.afterunshare'; + $calledAfterUnshareEvent[] = $event; + }); + // Unshare \OC_User::setUserId($this->user1); $this->assertTrue(\OCP\Share::unshare('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user2)); + $this->assertInstanceOf(GenericEvent::class, $calledBeforeUnshareEvent[1]); + $this->assertInstanceOf(GenericEvent::class, $calledAfterUnshareEvent[1]); + $this->assertArrayHasKey('share', $calledBeforeUnshareEvent[1]); + $this->assertArrayHasKey('share', $calledAfterUnshareEvent[1]); + $this->assertEquals('file.beforeunshare', $calledBeforeUnshareEvent[0]); + $this->assertEquals('file.afterunshare', $calledAfterUnshareEvent[0]); + $this->assertArrayHasKey('deletedShares', $calledAfterUnshareEvent[1]->getArgument('share')); + + $calledBeforeSharedEvent = []; + $calledAfterSharedEvent = []; + \OC::$server->getEventDispatcher()->addListener('file.beforeshare', + function (GenericEvent $event) use (&$calledBeforeSharedEvent) { + $calledBeforeSharedEvent[] = 'file.beforeshare'; + $calledBeforeSharedEvent[] = $event; + }); + \OC::$server->getEventDispatcher()->addListener('file.aftershare', + function (GenericEvent $event) use (&$calledAfterSharedEvent) { + $calledAfterSharedEvent[] = 'file.aftershare'; + $calledAfterSharedEvent[] = $event; + }); // Attempt reshare without share permission $this->assertTrue(\OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_READ)); + $this->assertInstanceOf(GenericEvent::class, $calledBeforeSharedEvent[1]); + $this->assertInstanceOf(GenericEvent::class, $calledAfterSharedEvent[1]); + $this->assertEquals('file.beforeshare', $calledBeforeSharedEvent[0]); + $this->assertEquals('file.aftershare', $calledAfterSharedEvent[0]); + $this->assertArrayHasKey('sharedata', $calledBeforeSharedEvent[1]); + $this->assertArrayHasKey('sharedata', $calledAfterSharedEvent[1]); \OC_User::setUserId($this->user2); $message = 'Sharing test.txt failed, because resharing is not allowed'; try { @@ -568,9 +608,29 @@ public function testShareWithGroupAndUserBothHaveTheSameId() { $this->assertEquals([], \OCP\Share::getItemSharedWith('test', 'test.txt', Backend::FORMAT_SOURCE), 'User2 sees test.txt but it was only shared with the user "groupAndUser" and not with group'); + $calledBeforeUnshareAllEvent = []; + $calledAfterUnshareAllEvent = []; + \OC::$server->getEventDispatcher()->addListener('file.beforeunshareAll', + function (GenericEvent $event) use (&$calledBeforeUnshareAllEvent) { + $calledBeforeUnshareAllEvent[] = 'file.beforeunshareAll'; + $calledBeforeUnshareAllEvent[] = $event; + }); + \OC::$server->getEventDispatcher()->addListener('file.afterunshareAll', + function (GenericEvent $event) use (&$calledAfterUnshareAllEvent) { + $calledAfterUnshareAllEvent[] = 'file.afterunshareAll'; + $calledAfterUnshareAllEvent[] = $event; + }); + \OC_User::setUserId($this->user1); $this->assertTrue(\OCP\Share::unshareAll('test', 'test.txt')); + $this->assertInstanceOf(GenericEvent::class, $calledBeforeUnshareAllEvent[1]); + $this->assertInstanceOf(GenericEvent::class, $calledAfterUnshareAllEvent[1]); + $this->assertArrayHasKey('share', $calledBeforeUnshareAllEvent[1]); + $this->assertArrayHasKey('share', $calledAfterUnshareAllEvent[1]); + $this->assertEquals('file.beforeunshareAll', $calledBeforeUnshareAllEvent[0]); + $this->assertEquals('file.afterunshareAll', $calledAfterUnshareAllEvent[0]); + $this->assertTrue( \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_GROUP, $this->groupAndUser, \OCP\Constants::PERMISSION_READ), 'Failed asserting that user 1 successfully shared text.txt with group 1.' @@ -1431,8 +1491,28 @@ public function testReshareWithLinkDefaultExpirationDate() { $expireDate = new \DateTime($result['expiration']); $this->assertEquals($date, $expireDate); + $calledBeforeUnshareEvent = []; + $calledAfterUnshareEvent = []; + \OC::$server->getEventDispatcher()->addListener('file.beforeunshare', + function (GenericEvent $event) use (&$calledBeforeUnshareEvent) { + $calledBeforeUnshareEvent[] = 'file.beforeunshare'; + $calledBeforeUnshareEvent[] = $event; + }); + \OC::$server->getEventDispatcher()->addListener('file.afterunshare', + function (GenericEvent $event) use (&$calledAfterUnshareEvent) { + $calledAfterUnshareEvent[] = 'file.afterunshare'; + $calledAfterUnshareEvent[] = $event; + }); + //Unshare $this->assertTrue(\OCP\Share::unshareAll('test', 'test.txt')); + $this->assertInstanceOf(GenericEvent::class, $calledBeforeUnshareEvent[1]); + $this->assertInstanceOf(GenericEvent::class, $calledAfterUnshareEvent[1]); + $this->assertArrayHasKey('share', $calledBeforeUnshareEvent[1]); + $this->assertArrayHasKey('share', $calledAfterUnshareEvent[1]); + $this->assertEquals('file.beforeunshare', $calledBeforeUnshareEvent[0]); + $this->assertEquals('file.afterunshare', $calledAfterUnshareEvent[0]); + $this->assertArrayHasKey('deletedShares', $calledAfterUnshareEvent[1]->getArgument('share')); //Reset config $config->deleteAppValue('core', 'shareapi_default_expire_date'); @@ -1454,10 +1534,31 @@ public function testShareWithSelfError() { public function testShareWithOwnerError() { \OC_User::setUserId($this->user1); + $calledBeforeSharedEvent = []; + $calledAfterSharedEvent = []; + \OC::$server->getEventDispatcher()->addListener('file.beforeshare', + function (GenericEvent $event) use (&$calledBeforeSharedEvent) { + $calledBeforeSharedEvent[] = 'file.beforeshare'; + $calledBeforeSharedEvent[] = $event; + }); + \OC::$server->getEventDispatcher()->addListener('file.aftershare', + function (GenericEvent $event) use (&$calledAfterSharedEvent) { + $calledAfterSharedEvent[] = 'file.aftershare'; + $calledAfterSharedEvent[] = $event; + }); + $this->assertTrue( \OCP\Share::shareItem('test', 'test.txt', \OCP\Share::SHARE_TYPE_USER, $this->user2, \OCP\Constants::PERMISSION_ALL), 'Failed asserting that user 1 successfully shared "test" with user 2.' ); + $this->assertInstanceOf(GenericEvent::class, $calledBeforeSharedEvent[1]); + $this->assertInstanceOf(GenericEvent::class, $calledAfterSharedEvent[1]); + $this->assertEquals('file.beforeshare', $calledBeforeSharedEvent[0]); + $this->assertEquals('file.aftershare', $calledAfterSharedEvent[0]); + $this->assertArrayHasKey('sharedata', $calledBeforeSharedEvent[1]); + $this->assertArrayHasKey('sharedata', $calledAfterSharedEvent[1]); + $this->assertArrayHasKey('itemType', $calledBeforeSharedEvent[1]->getArgument('sharedata')); + $this->assertArrayHasKey('itemType', $calledAfterSharedEvent[1]->getArgument('sharedata')); \OC_User::setUserId($this->user2); try { diff --git a/tests/lib/Share20/ManagerTest.php b/tests/lib/Share20/ManagerTest.php index 67878706061f..e734288ac074 100644 --- a/tests/lib/Share20/ManagerTest.php +++ b/tests/lib/Share20/ManagerTest.php @@ -36,6 +36,7 @@ use OCP\Share\IProviderFactory; use OCP\Share\IShare; use OCP\Share\IShareProvider; +use Symfony\Component\EventDispatcher\GenericEvent; /** * Class ManagerTest @@ -231,7 +232,26 @@ public function testDelete($shareType, $sharedWith) { ->method('post') ->with($hookListnerExpectsPost); + $calledBeforeDeleteEvent = []; + $calledAfterDeleteEvent = []; + + \OC::$server->getEventDispatcher()->addListener('file.beforeunshare', + function (GenericEvent $event) use (&$calledBeforeDeleteEvent) { + $calledBeforeDeleteEvent[] = 'file.beforeunshare'; + $calledBeforeDeleteEvent[] = $event; + }); + \OC::$server->getEventDispatcher()->addListener('file.afterunshare', + function (GenericEvent $event) use (&$calledAfterDeleteEvent) { + $calledAfterDeleteEvent[] = 'file.afterunshare'; + $calledAfterDeleteEvent[] = $event; + }); $manager->deleteShare($share); + + $this->assertInstanceOf(GenericEvent::class, $calledBeforeDeleteEvent[1]); + $this->assertInstanceOf(GenericEvent::class, $calledAfterDeleteEvent[1]); + $this->assertEquals('file.beforeunshare', $calledBeforeDeleteEvent[0]); + $this->assertEquals('file.afterunshare', $calledAfterDeleteEvent[0]); + $this->assertArrayHasKey('share', $calledAfterDeleteEvent[1]); } public function testDeleteLazyShare() { @@ -310,7 +330,25 @@ public function testDeleteLazyShare() { ->method('post') ->with($hookListnerExpectsPost); + $calledBeforeDeleteEvent = []; + $calledAfterDeleteEvent = []; + \OC::$server->getEventDispatcher()->addListener('file.beforeunshare', + function (GenericEvent $event) use (&$calledBeforeDeleteEvent) { + $calledBeforeDeleteEvent[] = 'file.beforeunshare'; + $calledBeforeDeleteEvent[] = $event; + }); + \OC::$server->getEventDispatcher()->addListener('file.afterunshare', + function (GenericEvent $event) use (&$calledAfterDeleteEvent) { + $calledAfterDeleteEvent[] = 'file.afterunshare'; + $calledAfterDeleteEvent[] = $event; + }); $manager->deleteShare($share); + + $this->assertInstanceOf(GenericEvent::class, $calledBeforeDeleteEvent[1]); + $this->assertInstanceOf(GenericEvent::class, $calledAfterDeleteEvent[1]); + $this->assertEquals('file.afterunshare', $calledAfterDeleteEvent[0]); + $this->assertEquals('file.beforeunshare', $calledBeforeDeleteEvent[0]); + $this->assertArrayHasKey('share', $calledAfterDeleteEvent[1]); } public function testDeleteNested() { @@ -433,7 +471,25 @@ public function testDeleteNested() { ->method('post') ->with($hookListnerExpectsPost); + $calledBeforeDeleteEvent = []; + $calledAfterDeleteEvent = []; + \OC::$server->getEventDispatcher()->addListener('file.beforeunshare', + function (GenericEvent $event) use (&$calledBeforeDeleteEvent) { + $calledBeforeDeleteEvent[] = 'file.beforeunshare'; + $calledBeforeDeleteEvent[] = $event; + }); + \OC::$server->getEventDispatcher()->addListener('file.afterunshare', + function (GenericEvent $event) use (&$calledAfterDeleteEvent) { + $calledAfterDeleteEvent[] = 'file.afterunshare'; + $calledAfterDeleteEvent[] = $event; + }); $manager->deleteShare($share1); + + $this->assertInstanceOf(GenericEvent::class, $calledBeforeDeleteEvent[1]); + $this->assertInstanceOf(GenericEvent::class, $calledAfterDeleteEvent[1]); + $this->assertEquals('file.afterunshare', $calledAfterDeleteEvent[0]); + $this->assertEquals('file.beforeunshare', $calledBeforeDeleteEvent[0]); + $this->assertArrayHasKey('share', $calledAfterDeleteEvent[1]); } public function testDeleteChildren() { @@ -1662,7 +1718,27 @@ public function testCreateShareUser() { ->method('setTarget') ->with('/target'); + $calledBeforeCreateEvent = []; + $calledAfterCreateEvent = []; + \OC::$server->getEventDispatcher()->addListener('file.beforeshare', + function (GenericEvent $event) use (&$calledBeforeCreateEvent) { + $calledBeforeCreateEvent[] = 'file.beforeshare'; + $calledBeforeCreateEvent[] = $event; + }); + \OC::$server->getEventDispatcher()->addListener('file.aftershare', + function (GenericEvent $event) use (&$calledAfterCreateEvent) { + $calledAfterCreateEvent[] = 'file.aftershare'; + $calledAfterCreateEvent[] = $event; + }); + $manager->createShare($share); + + $this->assertInstanceOf(GenericEvent::class, $calledBeforeCreateEvent[1]); + $this->assertInstanceOf(GenericEvent::class, $calledAfterCreateEvent[1]); + $this->assertArrayHasKey('sharedata', $calledBeforeCreateEvent[1]); + $this->assertArrayHasKey('sharedata', $calledAfterCreateEvent[1]); + $this->assertEquals('file.beforeshare', $calledBeforeCreateEvent[0]); + $this->assertEquals('file.aftershare', $calledAfterCreateEvent[0]); } public function testCreateShareGroup() { @@ -1715,7 +1791,27 @@ public function testCreateShareGroup() { ->method('setTarget') ->with('/target'); + $calledBeforeCreateEvent = []; + $calledAfterCreateEvent = []; + \OC::$server->getEventDispatcher()->addListener('file.beforeshare', + function (GenericEvent $event) use (&$calledBeforeCreateEvent) { + $calledBeforeCreateEvent[] = 'file.beforeshare'; + $calledBeforeCreateEvent[] = $event; + }); + \OC::$server->getEventDispatcher()->addListener('file.aftershare', + function (GenericEvent $event) use (&$calledAfterCreateEvent) { + $calledAfterCreateEvent[] = 'file.aftershare'; + $calledAfterCreateEvent[] = $event; + }); + $manager->createShare($share); + + $this->assertInstanceOf(GenericEvent::class, $calledBeforeCreateEvent[1]); + $this->assertInstanceOf(GenericEvent::class, $calledAfterCreateEvent[1]); + $this->assertArrayHasKey('sharedata', $calledBeforeCreateEvent[1]); + $this->assertArrayHasKey('sharedata', $calledAfterCreateEvent[1]); + $this->assertEquals('file.beforeshare', $calledBeforeCreateEvent[0]); + $this->assertEquals('file.aftershare', $calledAfterCreateEvent[0]); } public function testCreateShareLink() { @@ -1978,7 +2074,27 @@ public function testCreateShareOfIncommingFederatedShare() { ->method('setTarget') ->with('/target'); + $calledBeforeCreateEvent = []; + $calledAfterCreateEvent = []; + \OC::$server->getEventDispatcher()->addListener('file.beforeshare', + function (GenericEvent $event) use (&$calledBeforeCreateEvent) { + $calledBeforeCreateEvent[] = 'file.beforeshare'; + $calledBeforeCreateEvent[] = $event; + }); + \OC::$server->getEventDispatcher()->addListener('file.aftershare', + function (GenericEvent $event) use (&$calledAfterCreateEvent) { + $calledAfterCreateEvent[] = 'file.aftershare'; + $calledAfterCreateEvent[] = $event; + }); + $manager->createShare($share); + + $this->assertInstanceOf(GenericEvent::class, $calledBeforeCreateEvent[1]); + $this->assertInstanceOf(GenericEvent::class, $calledAfterCreateEvent[1]); + $this->assertArrayHasKey('sharedata', $calledBeforeCreateEvent[1]); + $this->assertArrayHasKey('sharedata', $calledAfterCreateEvent[1]); + $this->assertEquals('file.beforeshare', $calledBeforeCreateEvent[0]); + $this->assertEquals('file.aftershare', $calledAfterCreateEvent[0]); } public function testGetAllSharesBy() {