From 98dea91493bc5a9f7c23be556b749a35eff5dbea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Mon, 2 Jul 2018 09:45:58 +0200 Subject: [PATCH 01/43] Add helper for ShareAPIController MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The methods of the helper class are called from the main \OCA\Files_Sharing\Controller\ShareAPIController class to perform actions or checks specific to room shares, thus keeping the main ShareAPIController of the server isolated from the Talk details. Signed-off-by: Daniel Calviño Sánchez --- lib/Share/Helper/ShareAPIController.php | 182 ++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 lib/Share/Helper/ShareAPIController.php diff --git a/lib/Share/Helper/ShareAPIController.php b/lib/Share/Helper/ShareAPIController.php new file mode 100644 index 00000000000..21087350eb5 --- /dev/null +++ b/lib/Share/Helper/ShareAPIController.php @@ -0,0 +1,182 @@ +. + * + */ + +namespace OCA\Spreed\Share\Helper; + +use OCA\Spreed\Exceptions\ParticipantNotFoundException; +use OCA\Spreed\Exceptions\RoomNotFoundException; +use OCA\Spreed\Manager; +use OCA\Spreed\Room; +use OCP\AppFramework\OCS\OCSNotFoundException; +use OCP\IL10N; +use OCP\IUserManager; +use OCP\Share\IShare; + +/** + * Helper of OCA\Files_Sharing\Controller\ShareAPIController for room shares. + * + * The methods of this class are called from the ShareAPIController to perform + * actions or checks specific to room shares. + */ +class ShareAPIController { + + /** @var string */ + private $userId; + + /** @var IUserManager */ + private $userManager; + + /** @var Manager */ + private $manager; + + /** @var IL10N */ + private $l; + + /** + * ShareAPIController constructor. + * + * @param string $UserId + * @param IUserManager $userManager + * @param Manager $manager + * @param IL10N $l10n + */ + public function __construct( + string $UserId, + IUserManager $userManager, + Manager $manager, + IL10N $l10n + ) { + $this->userId = $UserId; + $this->userManager = $userManager; + $this->manager = $manager; + $this->l = $l10n; + } + + /** + * Formats the specific fields of a room share for OCS output. + * + * The returned fields override those set by the main ShareAPIController. + * + * @param IShare $share + * @return array + */ + public function formatShare(IShare $share): array { + $result = []; + + try { + $room = $this->manager->getRoomByToken($share->getSharedWith()); + } catch (RoomNotFoundException $e) { + return $result; + } + + // The display name of one-to-one rooms is set to the display name of + // the other participant. + $roomName = $room->getName(); + if ($room->getType() === Room::ONE_TO_ONE_CALL) { + $participantsList = $room->getParticipants()['users']; + unset($participantsList[$this->userId]); + + $roomName = $this->userManager->get(key($participantsList))->getDisplayName(); + } + + $result['share_with_displayname'] = $roomName; + + return $result; + } + + /** + * Prepares the given share to be passed to OC\Share20\Manager::createShare. + * + * @param IShare $share + * @param string $shareWith + * @param int $permissions + * @param string $expireDate + */ + public function createShare(IShare $share, string $shareWith, int $permissions, string $expireDate) { + $share->setSharedWith($shareWith); + $share->setPermissions($permissions); + + if ($expireDate !== '') { + try { + $expireDate = $this->parseDate($expireDate); + $share->setExpirationDate($expireDate); + } catch (\Exception $e) { + throw new OCSNotFoundException($this->l->t('Invalid date, date format must be YYYY-MM-DD')); + } + } + } + + /** + * Make sure that the passed date is valid ISO 8601 + * So YYYY-MM-DD + * If not throw an exception + * + * Copied from \OCA\Files_Sharing\Controller\ShareAPIController::parseDate. + * + * @param string $expireDate + * @return \DateTime + * @throws \Exception + */ + private function parseDate(string $expireDate): \DateTime { + 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; + } + + /** + * Returns whether the given user can access the given room share or not. + * + * A user can access a room share only if she is a participant of the room. + * + * @param IShare $share + * @param string $user + * @return bool + */ + public function canAccessShare(IShare $share, string $user): bool { + try { + $room = $this->manager->getRoomByToken($share->getSharedWith()); + } catch (RoomNotFoundException $e) { + return false; + } + + try { + $room->getParticipant($user); + } catch (ParticipantNotFoundException $e) { + return false; + } + + return true; + } + +} From 47139121f0348e0762cd0d14e75d1dfed4e6a2a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Sun, 15 Jul 2018 21:37:48 +0200 Subject: [PATCH 02/43] Add helper for DeletedShareAPIController MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The methods of the helper class are called from the main \OCA\Files_Sharing\Controller\DeletedShareAPIController class to perform actions or checks specific to room shares, thus keeping the main DeletedShareAPIController of the server isolated from the Talk details. Signed-off-by: Daniel Calviño Sánchez --- .../Helper/DeletedShareAPIController.php | 101 ++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 lib/Share/Helper/DeletedShareAPIController.php diff --git a/lib/Share/Helper/DeletedShareAPIController.php b/lib/Share/Helper/DeletedShareAPIController.php new file mode 100644 index 00000000000..717ffd40a5d --- /dev/null +++ b/lib/Share/Helper/DeletedShareAPIController.php @@ -0,0 +1,101 @@ +. + * + */ + +namespace OCA\Spreed\Share\Helper; + +use OCA\Spreed\Exceptions\RoomNotFoundException; +use OCA\Spreed\Manager; +use OCA\Spreed\Room; +use OCP\IUserManager; +use OCP\Share\IShare; + +/** + * Helper of OCA\Files_Sharing\Controller\DeletedShareAPIController for room + * shares. + * + * The methods of this class are called from the DeletedShareAPIController to + * perform actions or checks specific to room shares. + */ +class DeletedShareAPIController { + + /** @var string */ + private $userId; + + /** @var IUserManager */ + private $userManager; + + /** @var Manager */ + private $manager; + + /** + * DeletedShareAPIController constructor. + * + * @param string $UserId + * @param IUserManager $userManager + * @param Manager $manager + */ + public function __construct( + string $UserId, + IUserManager $userManager, + Manager $manager + ) { + $this->userId = $UserId; + $this->userManager = $userManager; + $this->manager = $manager; + } + + /** + * Formats the specific fields of a room share for OCS output. + * + * The returned fields override those set by the main + * DeletedShareAPIController. + * + * @param IShare $share + * @return array + */ + public function formatShare(IShare $share): array { + $result = []; + + try { + $room = $this->manager->getRoomByToken($share->getSharedWith()); + } catch (RoomNotFoundException $e) { + return $result; + } + + // The display name of one-to-one rooms is set to the display name of + // the other participant. + $roomName = $room->getName(); + if ($room->getType() === Room::ONE_TO_ONE_CALL) { + $participantsList = $room->getParticipants()['users']; + unset($participantsList[$this->userId]); + + $roomName = $this->userManager->get(key($participantsList))->getDisplayName(); + } + + $result['share_with_displayname'] = $roomName; + + return $result; + } + +} From 648178643e302ce61e0d05b40b806199c4fa2e42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Mon, 2 Jul 2018 10:25:38 +0200 Subject: [PATCH 03/43] Delete created users and groups after each scenario MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This forces the users and groups to be created again from scratch as needed for each new scenario, thus preventing actions performed in a previous scenario, like creating a new folder, from affecting the following scenarios. Signed-off-by: Daniel Calviño Sánchez --- .../features/bootstrap/FeatureContext.php | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/tests/integration/features/bootstrap/FeatureContext.php b/tests/integration/features/bootstrap/FeatureContext.php index 4a091a42c7b..11934a9d33e 100644 --- a/tests/integration/features/bootstrap/FeatureContext.php +++ b/tests/integration/features/bootstrap/FeatureContext.php @@ -55,6 +55,12 @@ class FeatureContext implements Context, SnippetAcceptingContext { /** @var string */ protected $lastEtag; + /** @var array */ + protected $createdUsers = []; + + /** @var array */ + protected $createdGroups = []; + /** * FeatureContext constructor. */ @@ -63,6 +69,26 @@ public function __construct() { $this->baseUrl = getenv('TEST_SERVER_URL'); } + /** + * @BeforeScenario + */ + public function setUp() { + $this->createdUsers = []; + $this->createdGroups = []; + } + + /** + * @AfterScenario + */ + public function tearDown() { + foreach ($this->createdUsers as $user) { + $this->deleteUser($user); + } + foreach ($this->createdGroups as $group) { + $this->deleteGroup($group); + } + } + /** * @Then /^user "([^"]*)" is participant of the following rooms$/ * @@ -594,6 +620,22 @@ private function createUser($user) { ], ]; $client->send($client->createRequest('GET', $userProvisioningUrl . '/' . $user, $options2)); + + $this->createdUsers[] = $user; + } + + private function deleteUser($user) { + $userProvisioningUrl = $this->baseUrl . 'ocs/v2.php/cloud/users/' . $user; + $client = new Client(); + $options = [ + 'auth' => ['admin', 'admin'], + 'headers' => [ + 'OCS-APIREQUEST' => 'true', + ], + ]; + $client->send($client->createRequest('DELETE', $userProvisioningUrl, $options)); + + unset($this->createdUsers[array_search($user, $this->createdUsers)]); } private function setUserDisplayName($user) { @@ -650,6 +692,22 @@ private function createGroup($group) { ], ]; $client->send($client->createRequest('POST', $userProvisioningUrl, $options)); + + $this->createdGroups[] = $group; + } + + private function deleteGroup($group) { + $userProvisioningUrl = $this->baseUrl . 'ocs/v2.php/cloud/groups/' . $group; + $client = new Client(); + $options = [ + 'auth' => ['admin', 'admin'], + 'headers' => [ + 'OCS-APIREQUEST' => 'true', + ], + ]; + $client->send($client->createRequest('DELETE', $userProvisioningUrl, $options)); + + unset($this->createdGroups[array_search($group, $this->createdGroups)]); } /** From 220726000f546cd949029ec5767f698b134db794 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Mon, 2 Jul 2018 11:15:37 +0200 Subject: [PATCH 04/43] Add skeleton for RoomShareProvider MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- lib/Share/RoomShareProvider.php | 245 ++++++++++++++++++++++++++++++++ 1 file changed, 245 insertions(+) create mode 100644 lib/Share/RoomShareProvider.php diff --git a/lib/Share/RoomShareProvider.php b/lib/Share/RoomShareProvider.php new file mode 100644 index 00000000000..e5f19b24d8b --- /dev/null +++ b/lib/Share/RoomShareProvider.php @@ -0,0 +1,245 @@ +. + * + */ + +namespace OCA\Spreed\Share; + +use OCP\Files\Folder; +use OCP\Files\Node; +use OCP\Share\Exceptions\GenericShareException; +use OCP\Share\Exceptions\ShareNotFound; +use OCP\Share\IShare; +use OCP\Share\IShareProvider; + +/** + * Share provider for room shares. + * + * Files are shared with a room identified by its token; only users currently in + * the room can share with and access the shared files (although the access + * checks are not enforced by the provider, but done on a higher layer). + * + * Like in group shares, a recipient can move or delete a share without + * modifying the share for the other users in the room. + */ +class RoomShareProvider implements IShareProvider { + + /** + * Return the identifier of this provider. + * + * @return string Containing only [a-zA-Z0-9] + */ + public function identifier() { + return 'ocRoomShare'; + } + + /** + * Create a share + * + * @param IShare $share + * @return IShare The share object + */ + public function create(IShare $share) { + throw new \Exception("Not implemented"); + } + + /** + * Update a share + * + * @param IShare $share + * @return IShare The share object + */ + public function update(IShare $share) { + throw new \Exception("Not implemented"); + } + + /** + * Delete a share + * + * @param IShare $share + */ + public function delete(IShare $share) { + throw new \Exception("Not implemented"); + } + + /** + * Unshare a file from self as recipient. + * If a user unshares a room share from their self then the original room + * share should still exist. + * + * @param IShare $share + * @param string $recipient UserId of the recipient + */ + public function deleteFromSelf(IShare $share, $recipient) { + throw new \Exception("Not implemented"); + } + + /** + * Restore a share for a given recipient. The implementation could be provider independant. + * + * @param IShare $share + * @param string $recipient + * @return IShare The restored share object + * @throws GenericShareException In case the share could not be restored + */ + public function restore(IShare $share, string $recipient): IShare { + throw new \Exception("Not implemented"); + } + + /** + * Move a share as a recipient. + * This is updating the share target. Thus the mount point of the recipient. + * This may require special handling. If a user moves a group share + * the target should only be changed for them. + * + * @param IShare $share + * @param string $recipient userId of recipient + * @return IShare + */ + public function move(IShare $share, $recipient) { + throw new \Exception("Not implemented"); + } + + /** + * Get all shares by the given user in a folder + * + * @param string $userId + * @param Folder $node + * @param bool $reshares Also get the shares where $user is the owner instead of just the shares where $user is the initiator + * @return IShare[] + */ + public function getSharesInFolder($userId, Folder $node, $reshares) { + throw new \Exception("Not implemented"); + } + + /** + * Get all shares by the given user + * + * @param string $userId + * @param int $shareType + * @param Node|null $node + * @param bool $reshares Also get the shares where $user is the owner instead of just the shares where $user is the initiator + * @param int $limit The maximum number of shares to be returned, -1 for all shares + * @param int $offset + * @return IShare[] + */ + public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) { + throw new \Exception("Not implemented"); + } + + /** + * Get share by id + * + * @param int $id + * @param string|null $recipientId + * @return IShare + * @throws ShareNotFound + */ + public function getShareById($id, $recipientId = null) { + throw new \Exception("Not implemented"); + } + + /** + * Get shares for a given path + * + * @param Node $path + * @return IShare[] + */ + public function getSharesByPath(Node $path) { + throw new \Exception("Not implemented"); + } + + /** + * Get shared with the given user + * + * @param string $userId get shares where this user is the recipient + * @param int $shareType + * @param Node|null $node + * @param int $limit The max number of entries returned, -1 for all + * @param int $offset + * @return IShare[] + */ + public function getSharedWith($userId, $shareType, $node, $limit, $offset) { + throw new \Exception("Not implemented"); + } + + /** + * Get a share by token + * + * Note that token here refers to share token, not room token. + * + * @param string $token + * @return IShare + * @throws ShareNotFound + */ + public function getShareByToken($token) { + throw new \Exception("Not implemented"); + } + + /** + * A user is deleted from the system + * So clean up the relevant shares. + * + * @param string $uid + * @param int $shareType + */ + public function userDeleted($uid, $shareType) { + throw new \Exception("Not implemented"); + } + + /** + * A group is deleted from the system. + * We have to clean up all shares to this group. + * Providers not handling group shares should just return + * + * @param string $gid + */ + public function groupDeleted($gid) { + throw new \Exception("Not implemented"); + } + + /** + * A user is deleted from a group + * We have to clean up all the related user specific group shares + * Providers not handling group shares should just return + * + * @param string $uid + * @param string $gid + */ + public function userDeletedFromGroup($uid, $gid) { + throw new \Exception("Not implemented"); + } + + /** + * Get the access list to the array of provided nodes. + * + * @see IManager::getAccessList() for sample docs + * + * @param Node[] $nodes The list of nodes to get access for + * @param bool $currentAccess If current access is required (like for removed shares that might get revived later) + * @return array + */ + public function getAccessList($nodes, $currentAccess) { + throw new \Exception("Not implemented"); + } + +} From 06d2f0db6f915dfb85c630af966a9fe1a16d2abc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Mon, 2 Jul 2018 13:25:17 +0200 Subject: [PATCH 05/43] Add Behat context for integration tests of sharing rooms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- lib/Share/RoomShareProvider.php | 4 +- tests/integration/config/behat.yml | 6 + .../features/bootstrap/FeatureContext.php | 8 + .../features/bootstrap/SharingContext.php | 330 ++++++++++++++++++ .../lib/Controller/ApiController.php | 8 + 5 files changed, 355 insertions(+), 1 deletion(-) create mode 100644 tests/integration/features/bootstrap/SharingContext.php diff --git a/lib/Share/RoomShareProvider.php b/lib/Share/RoomShareProvider.php index e5f19b24d8b..c19b7247a03 100644 --- a/lib/Share/RoomShareProvider.php +++ b/lib/Share/RoomShareProvider.php @@ -83,6 +83,7 @@ public function delete(IShare $share) { /** * Unshare a file from self as recipient. + * * If a user unshares a room share from their self then the original room * share should still exist. * @@ -107,8 +108,9 @@ public function restore(IShare $share, string $recipient): IShare { /** * Move a share as a recipient. + * * This is updating the share target. Thus the mount point of the recipient. - * This may require special handling. If a user moves a group share + * This may require special handling. If a user moves a room share * the target should only be changed for them. * * @param IShare $share diff --git a/tests/integration/config/behat.yml b/tests/integration/config/behat.yml index 0fcead7a5ac..03d87d1e8f5 100644 --- a/tests/integration/config/behat.yml +++ b/tests/integration/config/behat.yml @@ -7,6 +7,12 @@ default: - %paths.base%/../features contexts: - FeatureContext + - SharingContext: + baseUrl: http://localhost:8080/ + admin: + - admin + - admin + regularUserPassword: 123456 extensions: jarnaiz\JUnitFormatter\JUnitFormatterExtension: diff --git a/tests/integration/features/bootstrap/FeatureContext.php b/tests/integration/features/bootstrap/FeatureContext.php index 11934a9d33e..2342663dc1f 100644 --- a/tests/integration/features/bootstrap/FeatureContext.php +++ b/tests/integration/features/bootstrap/FeatureContext.php @@ -61,6 +61,10 @@ class FeatureContext implements Context, SnippetAcceptingContext { /** @var array */ protected $createdGroups = []; + public static function getTokenForIdentifier(string $identifier) { + return self::$identifierToToken[$identifier]; + } + /** * FeatureContext constructor. */ @@ -73,6 +77,10 @@ public function __construct() { * @BeforeScenario */ public function setUp() { + self::$identifierToToken = []; + self::$tokenToIdentifier = []; + self::$sessionIdToUser = []; + $this->createdUsers = []; $this->createdGroups = []; } diff --git a/tests/integration/features/bootstrap/SharingContext.php b/tests/integration/features/bootstrap/SharingContext.php new file mode 100644 index 00000000000..ead74c99d5b --- /dev/null +++ b/tests/integration/features/bootstrap/SharingContext.php @@ -0,0 +1,330 @@ +. + * + */ + +use Behat\Behat\Context\Context; +use Behat\Gherkin\Node\TableNode; +use GuzzleHttp\Client; +use GuzzleHttp\Message\ResponseInterface; + +class SharingContext implements Context { + + /** @var string */ + private $baseUrl = ''; + + /** @var ResponseInterface */ + private $response = null; + + /** @var string */ + private $currentUser = ''; + + /** @var string */ + private $regularUserPassword; + + /** @var \SimpleXMLElement */ + private $lastCreatedShareData = null; + + public function __construct(string $baseUrl, array $admin, string $regularUserPassword) { + $this->baseUrl = $baseUrl; + $this->adminUser = $admin; + $this->regularUserPassword = $regularUserPassword; + + // in case of ci deployment we take the server url from the environment + $testServerUrl = getenv('TEST_SERVER_URL'); + if ($testServerUrl !== false) { + $this->baseUrl = $testServerUrl; + } + } + + /** + * @When user :user shares :path with user :sharee + * + * @param string $user + * @param string $path + * @param string $sharee + * @param TableNode|null $body + */ + public function userSharesWithUser(string $user, string $path, string $sharee, TableNode $body = null) { + $this->userSharesWith($user, $path, 0 /*Share::SHARE_TYPE_USER*/, $sharee, $body); + } + + /** + * @When user :user shares :path with user :sharee with OCS :statusCode + * + * @param string $user + * @param string $path + * @param string $sharee + * @param int $statusCode + */ + public function userSharesWithUserWithOcs(string $user, string $path, string $sharee, int $statusCode) { + $this->userSharesWithUser($user, $path, $sharee); + $this->theOCSStatusCodeShouldBe($statusCode); + } + + /** + * @When user :user shares :path with room :room + * + * @param string $user + * @param string $path + * @param string $room + * @param TableNode|null $body + */ + public function userSharesWithRoom(string $user, string $path, string $room, TableNode $body = null) { + $this->userSharesWith($user, $path, 10 /*Share::SHARE_TYPE_ROOM*/, FeatureContext::getTokenForIdentifier($room), $body); + } + + /** + * @When user :user shares :path with room :room with OCS :statusCode + * + * @param string $user + * @param string $path + * @param string $room + * @param int $statusCode + */ + public function userSharesWithRoomWithOcs(string $user, string $path, string $room, int $statusCode) { + $this->userSharesWithRoom($user, $path, $room); + $this->theOCSStatusCodeShouldBe($statusCode); + } + + /** + * @When user :user gets last share + */ + public function userGetsLastShare(string $user) { + $this->currentUser = $user; + + $url = '/apps/files_sharing/api/v1/shares/' . $this->getLastShareId(); + + $this->sendingTo('GET', $url); + } + + /** + * @When user :user gets all shares + * + * @param string $user + */ + public function userGetsAllShares(string $user) { + $this->currentUser = $user; + + $url = '/apps/files_sharing/api/v1/shares'; + + $this->sendingTo('GET', $url); + } + + /** + * @Then the OCS status code should be :statusCode + * + * @param int $statusCode + */ + public function theOCSStatusCodeShouldBe(int $statusCode) { + $meta = $this->getXmlResponse()->meta[0]; + + PHPUnit_Framework_Assert::assertEquals($statusCode, (int)$meta->statuscode, 'Response message: ' . (string)$meta->message); + } + + /** + * @Then the HTTP status code should be :statusCode + * + * @param int $statusCode + */ + public function theHTTPStatusCodeShouldBe(int $statusCode) { + PHPUnit_Framework_Assert::assertEquals($statusCode, $this->response->getStatusCode()); + } + + /** + * @Then the list of returned shares has :count shares + */ + public function theListOfReturnedSharesHasShares(int $count) { + $this->theHTTPStatusCodeShouldBe(200); + $this->theOCSStatusCodeShouldBe(100); + + $returnedShares = $this->getXmlResponse()->data[0]; + + PHPUnit_Framework_Assert::assertEquals($count, count($returnedShares->element)); + } + + /** + * @Then share is returned with + * + * @param TableNode $body + */ + public function shareIsReturnedWith(TableNode $body) { + $this->shareXIsReturnedWith(0, $body); + } + + /** + * @Then share :number is returned with + * + * @param int $number + * @param TableNode $body + */ + public function shareXIsReturnedWith(int $number, TableNode $body) { + $this->theHTTPStatusCodeShouldBe(200); + $this->theOCSStatusCodeShouldBe(100); + + if (!($body instanceof TableNode)) { + return; + } + + $returnedShare = $this->getXmlResponse()->data[0]; + if ($returnedShare->element) { + $returnedShare = $returnedShare->element[$number]; + } + + $defaultExpectedFields = [ + 'id' => 'A_NUMBER', + 'share_type' => '10', // Share::SHARE_TYPE_ROOM, + 'permissions' => '19', + 'stime' => 'A_NUMBER', + 'parent' => '', + 'expiration' => '', + 'token' => '', + 'storage' => 'A_NUMBER', + 'item_source' => 'A_NUMBER', + 'file_source' => 'A_NUMBER', + 'file_parent' => 'A_NUMBER', + 'mail_send' => '0' + ]; + $expectedFields = array_merge($defaultExpectedFields, $body->getRowsHash()); + + if (!array_key_exists('uid_file_owner', $expectedFields) && + array_key_exists('uid_owner', $expectedFields)) { + $expectedFields['uid_file_owner'] = $expectedFields['uid_owner']; + } + if (!array_key_exists('displayname_file_owner', $expectedFields) && + array_key_exists('displayname_owner', $expectedFields)) { + $expectedFields['displayname_file_owner'] = $expectedFields['displayname_owner']; + } + + if (array_key_exists('share_type', $expectedFields) && + $expectedFields['share_type'] == 10 /* Share::SHARE_TYPE_ROOM */ && + array_key_exists('share_with', $expectedFields)) { + $expectedFields['share_with'] = FeatureContext::getTokenForIdentifier($expectedFields['share_with']); + } + + foreach ($expectedFields as $field => $value) { + $this->assertFieldIsInReturnedShare($field, $value, $returnedShare); + } + } + + /** + * @param string $user + * @param string $path + * @param string $shareType + * @param string $shareWith + * @param TableNode|null $body + */ + private function userSharesWith(string $user, string $path, string $shareType, string $shareWith, TableNode $body = null) { + $this->currentUser = $user; + + $url = '/apps/files_sharing/api/v1/shares'; + + $parameters = []; + $parameters[] = 'path=' . $path; + $parameters[] = 'shareType=' . $shareType; + $parameters[] = 'shareWith=' . $shareWith; + + if ($body instanceof TableNode) { + foreach ($body->getRowsHash() as $key => $value) { + if ($key === 'expireDate' && $value !== 'invalid date'){ + $value = date('Y-m-d', strtotime($value)); + } + $parameters[] = $key . '=' . $value; + } + } + + $url .= '?' . implode('&', $parameters); + + $this->sendingTo('POST', $url); + + $this->lastCreatedShareData = $this->getXmlResponse(); + } + + /** + * @param string $verb + * @param string $url + * @param TableNode $body + */ + private function sendingTo(string $verb, string $url, TableNode $body = null) { + $fullUrl = $this->baseUrl . "ocs/v1.php" . $url; + $client = new Client(); + $options = []; + if ($this->currentUser === 'admin') { + $options['auth'] = $this->adminUser; + } else { + $options['auth'] = [$this->currentUser, $this->regularUserPassword]; + } + $options['headers'] = [ + 'OCS_APIREQUEST' => 'true' + ]; + if ($body instanceof TableNode) { + $fd = $body->getRowsHash(); + if (array_key_exists('expireDate', $fd)){ + $fd['expireDate'] = date('Y-m-d', strtotime($fd['expireDate'])); + } + $options['body'] = $fd; + } + + try { + $this->response = $client->send($client->createRequest($verb, $fullUrl, $options)); + } catch (GuzzleHttp\Exception\ClientException $ex) { + $this->response = $ex->getResponse(); + } + } + + /** + * @return string + */ + private function getLastShareId(): string { + return (string)$this->lastCreatedShareData->data[0]->id; + } + + /** + * @return SimpleXMLElement + */ + private function getXmlResponse(): \SimpleXMLElement { + return simplexml_load_string($this->response->getBody()); + } + + /** + * @param string $field + * @param string $contentExpected + * @param \SimpleXMLElement $returnedShare + */ + private function assertFieldIsInReturnedShare(string $field, string $contentExpected, \SimpleXMLElement $returnedShare){ + if (!array_key_exists($field, $returnedShare)) { + PHPUnit_Framework_Assert::fail("$field was not found in response"); + } + + if ($field === 'expiration' && !empty($contentExpected)){ + $contentExpected = date('Y-m-d', strtotime($contentExpected)) . " 00:00:00"; + } + + if ($contentExpected === 'A_NUMBER') { + PHPUnit_Framework_Assert::assertTrue(is_numeric((string)$returnedShare->$field), "Field '$field' is not a number: " . $returnedShare->$field); + } else if (strpos($contentExpected, 'REGEXP ') === 0) { + PHPUnit_Framework_Assert::assertRegExp(substr($contentExpected, strlen('REGEXP ')), (string)$returnedShare->$field, "Field '$field' does not match"); + } else { + PHPUnit_Framework_Assert::assertEquals($contentExpected, (string)$returnedShare->$field, "Field '$field' does not match"); + } + } + +} diff --git a/tests/integration/spreedcheats/lib/Controller/ApiController.php b/tests/integration/spreedcheats/lib/Controller/ApiController.php index 50a4e05290a..61aed6ef7c5 100644 --- a/tests/integration/spreedcheats/lib/Controller/ApiController.php +++ b/tests/integration/spreedcheats/lib/Controller/ApiController.php @@ -59,6 +59,14 @@ public function resetSpreed() { $query = $this->db->getQueryBuilder(); $query->delete('talk_participants')->execute(); + $query = $this->db->getQueryBuilder(); + $query->delete('share') + ->where($query->expr()->orX( + $query->expr()->eq('share_type', $query->createNamedParameter(\OCP\Share::SHARE_TYPE_ROOM)), + $query->expr()->eq('share_type', $query->createNamedParameter(11 /*RoomShareProvider::SHARE_TYPE_USERROOM*/)) + )) + ->execute(); + return new DataResponse(); } } From 1634f2c61eecc349c75eba8941ea6158ce45ba6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Mon, 2 Jul 2018 17:13:47 +0200 Subject: [PATCH 06/43] Implement creating room shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In order to keep the share manager as isolated as possible from room share specifics the validity checks are done in RoomShareManager. Getting room shares by path was also implemented, as it is needed to prevent creating again a share for the same path and room. Signed-off-by: Daniel Calviño Sánchez --- lib/Share/RoomShareProvider.php | 211 +++++++++++++++++++++++++++++++- 1 file changed, 209 insertions(+), 2 deletions(-) diff --git a/lib/Share/RoomShareProvider.php b/lib/Share/RoomShareProvider.php index c19b7247a03..c598c252c4e 100644 --- a/lib/Share/RoomShareProvider.php +++ b/lib/Share/RoomShareProvider.php @@ -24,10 +24,18 @@ namespace OCA\Spreed\Share; +use OCA\Spreed\Exceptions\ParticipantNotFoundException; +use OCA\Spreed\Exceptions\RoomNotFoundException; +use OCA\Spreed\Manager; use OCP\Files\Folder; +use OCP\Files\IRootFolder; use OCP\Files\Node; +use OCP\IDBConnection; +use OCP\IL10N; +use OCP\IUserManager; use OCP\Share\Exceptions\GenericShareException; use OCP\Share\Exceptions\ShareNotFound; +use OCP\Share\IManager as IShareManager; use OCP\Share\IShare; use OCP\Share\IShareProvider; @@ -43,6 +51,50 @@ */ class RoomShareProvider implements IShareProvider { + /** @var IDBConnection */ + private $dbConnection; + + /** @var IUserManager */ + private $userManager; + + /** @var IShareManager */ + private $shareManager; + + /** @var IRootFolder */ + private $rootFolder; + + /** @var IL10N */ + private $l; + + /** @var Manager */ + private $manager; + + /** + * RoomShareProvider constructor. + * + * @param IDBConnection $connection + * @param IUserManager $userManager + * @param IShareManager $shareManager + * @param IRootFolder $rootFolder + * @param IL10N $l10n + * @param Manager $manager + */ + public function __construct( + IDBConnection $connection, + IUserManager $userManager, + IShareManager $shareManager, + IRootFolder $rootFolder, + IL10N $l, + Manager $manager + ) { + $this->dbConnection = $connection; + $this->userManager = $userManager; + $this->shareManager = $shareManager; + $this->rootFolder = $rootFolder; + $this->l = $l; + $this->manager = $manager; + } + /** * Return the identifier of this provider. * @@ -57,9 +109,150 @@ public function identifier() { * * @param IShare $share * @return IShare The share object + * @throws GenericShareException */ public function create(IShare $share) { - throw new \Exception("Not implemented"); + try { + $room = $this->manager->getRoomByToken($share->getSharedWith()); + } catch (RoomNotFoundException $e) { + throw new GenericShareException("Room not found", $this->l->t('Conversation not found'), 404); + } + + try { + $room->getParticipant($share->getSharedBy()); + } catch (ParticipantNotFoundException $e) { + // If the sharer is not a participant of the room even if the room + // exists the error is still "Room not found". + throw new GenericShareException("Room not found", $this->l->t('Conversation not found'), 404); + } + + $existingShares = $this->getSharesByPath($share->getNode()); + foreach ($existingShares as $existingShare) { + if ($existingShare->getSharedWith() === $share->getSharedWith()) { + throw new GenericShareException("Already shared", $this->l->t('Path is already shared with this room'), 403); + } + } + + $shareId = $this->addShareToDB( + $share->getSharedWith(), + $share->getSharedBy(), + $share->getShareOwner(), + $share->getNodeType(), + $share->getNodeId(), + $share->getTarget(), + $share->getPermissions(), + $share->getExpirationDate() + ); + + $data = $this->getRawShare($shareId); + + return $this->createShareObject($data); + } + + /** + * Add share to the database and return the ID + * + * @param string $shareWith + * @param string $sharedBy + * @param string $shareOwner + * @param string $itemType + * @param int $itemSource + * @param string $target + * @param int $permissions + * @param \DateTime|null $expirationDate + * @return int + */ + private function addShareToDB( + string $shareWith, + string $sharedBy, + string $shareOwner, + string $itemType, + int $itemSource, + string $target, + int $permissions, + \DateTime $expirationDate = null + ): int { + $qb = $this->dbConnection->getQueryBuilder(); + $qb->insert('share') + ->setValue('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_ROOM)) + ->setValue('share_with', $qb->createNamedParameter($shareWith)) + ->setValue('uid_initiator', $qb->createNamedParameter($sharedBy)) + ->setValue('uid_owner', $qb->createNamedParameter($shareOwner)) + ->setValue('item_type', $qb->createNamedParameter($itemType)) + ->setValue('item_source', $qb->createNamedParameter($itemSource)) + ->setValue('file_source', $qb->createNamedParameter($itemSource)) + ->setValue('file_target', $qb->createNamedParameter($target)) + ->setValue('permissions', $qb->createNamedParameter($permissions)) + ->setValue('stime', $qb->createNamedParameter(time())); + + if ($expirationDate !== null) { + $qb->setValue('expiration', $qb->createNamedParameter($expirationDate, 'datetime')); + } + + $qb->execute(); + $id = $qb->getLastInsertId(); + + return (int)$id; + } + + /** + * Get database row of the given share + * + * @param int $id + * @return array + * @throws ShareNotFound + */ + private function getRawShare(int $id) { + $qb = $this->dbConnection->getQueryBuilder(); + $qb->select('*') + ->from('share') + ->where($qb->expr()->eq('id', $qb->createNamedParameter($id))); + + $cursor = $qb->execute(); + $data = $cursor->fetch(); + $cursor->closeCursor(); + + if ($data === false) { + throw new ShareNotFound(); + } + + return $data; + } + + /** + * Create a share object from a database row + * + * @param array $data + * @return IShare + */ + private function createShareObject($data) { + $share = $this->shareManager->newShare(); + $share->setId((int)$data['id']) + ->setShareType((int)$data['share_type']) + ->setPermissions((int)$data['permissions']) + ->setTarget($data['file_target']); + + $shareTime = new \DateTime(); + $shareTime->setTimestamp((int)$data['stime']); + $share->setShareTime($shareTime); + $share->setSharedWith($data['share_with']); + + $share->setSharedBy($data['uid_initiator']); + $share->setShareOwner($data['uid_owner']); + + if ($data['expiration'] !== null) { + $expiration = \DateTime::createFromFormat('Y-m-d H:i:s', $data['expiration']); + if ($expiration !== false) { + $share->setExpirationDate($expiration); + } + } + + $share->setNodeId((int)$data['file_source']); + $share->setNodeType($data['item_type']); + + $share->setProviderId($this->identifier()); + + return $share; } /** @@ -167,7 +360,21 @@ public function getShareById($id, $recipientId = null) { * @return IShare[] */ public function getSharesByPath(Node $path) { - throw new \Exception("Not implemented"); + $qb = $this->dbConnection->getQueryBuilder(); + + $cursor = $qb->select('*') + ->from('share') + ->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($path->getId()))) + ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_ROOM))) + ->execute(); + + $shares = []; + while ($data = $cursor->fetch()) { + $shares[] = $this->createShareObject($data); + } + $cursor->closeCursor(); + + return $shares; } /** From c51b6b954dd04b9f9d647b3edb42cdb3809c3c4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Mon, 2 Jul 2018 17:27:45 +0200 Subject: [PATCH 07/43] Implement getting room shares by user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- lib/Share/RoomShareProvider.php | 40 ++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/lib/Share/RoomShareProvider.php b/lib/Share/RoomShareProvider.php index c598c252c4e..a52eebce819 100644 --- a/lib/Share/RoomShareProvider.php +++ b/lib/Share/RoomShareProvider.php @@ -338,7 +338,45 @@ public function getSharesInFolder($userId, Folder $node, $reshares) { * @return IShare[] */ public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offset) { - throw new \Exception("Not implemented"); + $qb = $this->dbConnection->getQueryBuilder(); + $qb->select('*') + ->from('share'); + + $qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_ROOM))); + + /** + * Reshares for this user are shares where they are the owner. + */ + if ($reshares === false) { + $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))); + } else { + $qb->andWhere( + $qb->expr()->orX( + $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)), + $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)) + ) + ); + } + + if ($node !== null) { + $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId()))); + } + + if ($limit !== -1) { + $qb->setMaxResults($limit); + } + + $qb->setFirstResult($offset); + $qb->orderBy('id'); + + $cursor = $qb->execute(); + $shares = []; + while ($data = $cursor->fetch()) { + $shares[] = $this->createShareObject($data); + } + $cursor->closeCursor(); + + return $shares; } /** From 5638a233b8f22b8c5e64fcf7b8588b507e09bcee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Mon, 2 Jul 2018 18:00:14 +0200 Subject: [PATCH 08/43] Implement getting room shares by ID MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- lib/Share/RoomShareProvider.php | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/Share/RoomShareProvider.php b/lib/Share/RoomShareProvider.php index a52eebce819..3b1da6837e9 100644 --- a/lib/Share/RoomShareProvider.php +++ b/lib/Share/RoomShareProvider.php @@ -388,7 +388,22 @@ public function getSharesBy($userId, $shareType, $node, $reshares, $limit, $offs * @throws ShareNotFound */ public function getShareById($id, $recipientId = null) { - throw new \Exception("Not implemented"); + $qb = $this->dbConnection->getQueryBuilder(); + + $qb->select('*') + ->from('share') + ->where($qb->expr()->eq('id', $qb->createNamedParameter($id))) + ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_ROOM))); + + $cursor = $qb->execute(); + $data = $cursor->fetch(); + $cursor->closeCursor(); + + if ($data === false) { + throw new ShareNotFound(); + } + + return $this->createShareObject($data); } /** From 7a206b1062fd091cf18959d795d8a8b25a237c90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Tue, 3 Jul 2018 09:20:12 +0200 Subject: [PATCH 09/43] Implement getting room shares by recipient MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- lib/Share/RoomShareProvider.php | 57 ++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/lib/Share/RoomShareProvider.php b/lib/Share/RoomShareProvider.php index 3b1da6837e9..27c88e572d3 100644 --- a/lib/Share/RoomShareProvider.php +++ b/lib/Share/RoomShareProvider.php @@ -27,6 +27,8 @@ use OCA\Spreed\Exceptions\ParticipantNotFoundException; use OCA\Spreed\Exceptions\RoomNotFoundException; use OCA\Spreed\Manager; +use OCA\Spreed\Room; +use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\Files\Folder; use OCP\Files\IRootFolder; use OCP\Files\Node; @@ -441,7 +443,60 @@ public function getSharesByPath(Node $path) { * @return IShare[] */ public function getSharedWith($userId, $shareType, $node, $limit, $offset) { - throw new \Exception("Not implemented"); + $allRooms = $this->manager->getRoomsForParticipant($userId); + + /** @var IShare[] $shares */ + $shares = []; + + $start = 0; + while (true) { + $rooms = array_slice($allRooms, $start, 100); + $start += 100; + + if ($rooms === []) { + break; + } + + $qb = $this->dbConnection->getQueryBuilder(); + $qb->select('*') + ->from('share') + ->orderBy('id') + ->setFirstResult(0); + + if ($limit !== -1) { + $qb->setMaxResults($limit); + } + + // Filter by node if provided + if ($node !== null) { + $qb->andWhere($qb->expr()->eq('file_source', $qb->createNamedParameter($node->getId()))); + } + + $rooms = array_map(function(Room $room) { return $room->getToken(); }, $rooms); + + $qb->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_ROOM))) + ->andWhere($qb->expr()->in('share_with', $qb->createNamedParameter( + $rooms, + IQueryBuilder::PARAM_STR_ARRAY + ))) + ->andWhere($qb->expr()->orX( + $qb->expr()->eq('item_type', $qb->createNamedParameter('file')), + $qb->expr()->eq('item_type', $qb->createNamedParameter('folder')) + )); + + $cursor = $qb->execute(); + while ($data = $cursor->fetch()) { + if ($offset > 0) { + $offset--; + continue; + } + + $shares[] = $this->createShareObject($data); + } + $cursor->closeCursor(); + } + + return $shares; } /** From 6b4a090374bfdeaa1b6469656a84312df2bda37e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Tue, 3 Jul 2018 18:50:32 +0200 Subject: [PATCH 10/43] Add integration tests for creating room shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Note that these tests require some "getShareXXX" methods to be implemented in the provider, as even if they are not explicitly used they are required by the code paths to create shares. Signed-off-by: Daniel Calviño Sánchez --- .../features/sharing/create.feature | 301 ++++++++++++++++++ 1 file changed, 301 insertions(+) create mode 100644 tests/integration/features/sharing/create.feature diff --git a/tests/integration/features/sharing/create.feature b/tests/integration/features/sharing/create.feature new file mode 100644 index 00000000000..f4e66f59394 --- /dev/null +++ b/tests/integration/features/sharing/create.feature @@ -0,0 +1,301 @@ +Feature: create + + Background: + Given user "participant1" exists + Given user "participant2" exists + Given user "participant3" exists + + Scenario: create share with an owned one-to-one room + Given user "participant1" creates room "own one-to-one room" + | roomType | 1 | + | invite | participant2 | + When user "participant1" shares "welcome.txt" with room "own one-to-one room" + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | own one-to-one room | + | share_with_displayname | participant2-displayname | + + Scenario: create share with a one-to-one room invited to + Given user "participant2" creates room "one-to-one room invited to" + | roomType | 1 | + | invite | participant1 | + When user "participant1" shares "welcome.txt" with room "one-to-one room invited to" + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | one-to-one room invited to | + | share_with_displayname | participant2-displayname | + + Scenario: create share with a one-to-one room not invited to + Given user "participant2" creates room "one-to-one room not invited to" + | roomType | 1 | + | invite | participant3 | + When user "participant1" shares "welcome.txt" with room "one-to-one room not invited to" + Then the OCS status code should be "404" + And the HTTP status code should be "200" + + Scenario: create share with an owned group room + Given user "participant1" creates room "own group room" + | roomType | 2 | + And user "participant1" renames room "own group room" to "Own group room" with 200 + When user "participant1" shares "welcome.txt" with room "own group room" + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | own group room | + | share_with_displayname | Own group room | + + Scenario: create share with a group room invited to + Given user "participant2" creates room "group room invited to" + | roomType | 2 | + And user "participant2" renames room "group room invited to" to "Group room invited to" with 200 + And user "participant2" adds "participant1" to room "group room invited to" with 200 + When user "participant1" shares "welcome.txt" with room "group room invited to" + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + + Scenario: create share with a group room not invited to + Given user "participant2" creates room "group room not invited to" + | roomType | 2 | + When user "participant1" shares "welcome.txt" with room "group room not invited to" + Then the OCS status code should be "404" + And the HTTP status code should be "200" + + Scenario: create share with a group room no longer invited to + Given user "participant2" creates room "group room no longer invited to" + | roomType | 2 | + And user "participant2" adds "participant1" to room "group room no longer invited to" with 200 + And user "participant2" removes "participant1" from room "group room no longer invited to" with 200 + When user "participant1" shares "welcome.txt" with room "group room no longer invited to" + Then the OCS status code should be "404" + And the HTTP status code should be "200" + + Scenario: create share with an owned public room + Given user "participant1" creates room "own public room" + | roomType | 3 | + And user "participant1" renames room "own public room" to "Own public room" with 200 + When user "participant1" shares "welcome.txt" with room "own public room" + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | own public room | + | share_with_displayname | Own public room | + + Scenario: create share with a public room invited to + Given user "participant2" creates room "public room invited to" + | roomType | 3 | + And user "participant2" renames room "public room invited to" to "Public room invited to" with 200 + And user "participant2" adds "participant1" to room "public room invited to" with 200 + When user "participant1" shares "welcome.txt" with room "public room invited to" + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | public room invited to | + | share_with_displayname | Public room invited to | + + Scenario: create share with a public room self joined to + Given user "participant2" creates room "public room self joined to" + | roomType | 3 | + And user "participant2" renames room "public room self joined to" to "Public room self joined to" with 200 + And user "participant1" joins room "public room self joined to" with 200 + When user "participant1" shares "welcome.txt" with room "public room self joined to" + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | public room self joined to | + | share_with_displayname | Public room self joined to | + + Scenario: create share with a public room not joined to + Given user "participant2" creates room "public room not joined to" + | roomType | 3 | + When user "participant1" shares "welcome.txt" with room "public room not joined to" + Then the OCS status code should be "404" + And the HTTP status code should be "200" + + Scenario: create share with a public room no longer joined to + Given user "participant2" creates room "public room no longer joined to" + | roomType | 3 | + And user "participant1" joins room "public room no longer joined to" with 200 + And user "participant1" leaves room "public room no longer joined to" with 200 + When user "participant1" shares "welcome.txt" with room "public room no longer joined to" + Then the OCS status code should be "404" + And the HTTP status code should be "200" + + + + Scenario: create share with an expiration date + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + When user "participant1" shares "welcome.txt" with room "group room" + | expireDate | +3 days | + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + | expiration | +3 days | + + Scenario: create share with an invalid expiration date + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" adds "participant2" to room "group room" with 200 + When user "participant1" shares "welcome.txt" with room "group room" + | expireDate | invalid date | + Then the OCS status code should be "404" + And the HTTP status code should be "200" + + Scenario: create share with specific permissions + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + When user "participant1" shares "welcome.txt" with room "group room" + | permissions | 1 | + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + | permissions | 1 | + + + + Scenario: create share again with another room + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant1" creates room "another group room" + | roomType | 2 | + And user "participant1" renames room "another group room" to "Another group room" with 200 + When user "participant1" shares "welcome.txt" with room "another group room" + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | another group room | + | share_with_displayname | Another group room | + + Scenario: create share again with same room + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + When user "participant1" shares "welcome.txt" with room "group room" + Then the OCS status code should be "403" + And the HTTP status code should be "401" + + + + Scenario: create share with a room that includes a user who already received that share through another room + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant1" creates room "another group room" + | roomType | 2 | + And user "participant1" renames room "another group room" to "Another group room" with 200 + And user "participant1" adds "participant2" to room "another group room" with 200 + When user "participant1" shares "welcome.txt" with room "another group room" + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | another group room | + | share_with_displayname | Another group room | + + Scenario: create share with a user who already received that share through a room + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + When user "participant1" shares "welcome.txt" with user "participant2" + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | participant2 | + | share_with_displayname | participant2-displayname | + | share_type | 0 | + | mail_send | 1 | + + Scenario: create share with a room including a user who already received that share directly + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with user "participant2" with OCS 100 + When user "participant1" shares "welcome.txt" with room "group room" + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | From 8f3d493a09b28208e4d87e64686f58c2d2a96c03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Tue, 3 Jul 2018 19:37:12 +0200 Subject: [PATCH 11/43] Add integration tests for getting shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- .../features/sharing/create.feature | 46 +++++++++++++++ .../integration/features/sharing/get.feature | 56 +++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 tests/integration/features/sharing/get.feature diff --git a/tests/integration/features/sharing/create.feature b/tests/integration/features/sharing/create.feature index f4e66f59394..ee6661a45b2 100644 --- a/tests/integration/features/sharing/create.feature +++ b/tests/integration/features/sharing/create.feature @@ -44,6 +44,8 @@ Feature: create When user "participant1" shares "welcome.txt" with room "one-to-one room not invited to" Then the OCS status code should be "404" And the HTTP status code should be "200" + And user "participant1" gets all shares + And the list of returned shares has 0 shares Scenario: create share with an owned group room Given user "participant1" creates room "own group room" @@ -84,6 +86,8 @@ Feature: create When user "participant1" shares "welcome.txt" with room "group room not invited to" Then the OCS status code should be "404" And the HTTP status code should be "200" + And user "participant1" gets all shares + And the list of returned shares has 0 shares Scenario: create share with a group room no longer invited to Given user "participant2" creates room "group room no longer invited to" @@ -93,6 +97,8 @@ Feature: create When user "participant1" shares "welcome.txt" with room "group room no longer invited to" Then the OCS status code should be "404" And the HTTP status code should be "200" + And user "participant1" gets all shares + And the list of returned shares has 0 shares Scenario: create share with an owned public room Given user "participant1" creates room "own public room" @@ -150,6 +156,8 @@ Feature: create When user "participant1" shares "welcome.txt" with room "public room not joined to" Then the OCS status code should be "404" And the HTTP status code should be "200" + And user "participant1" gets all shares + And the list of returned shares has 0 shares Scenario: create share with a public room no longer joined to Given user "participant2" creates room "public room no longer joined to" @@ -159,6 +167,8 @@ Feature: create When user "participant1" shares "welcome.txt" with room "public room no longer joined to" Then the OCS status code should be "404" And the HTTP status code should be "200" + And user "participant1" gets all shares + And the list of returned shares has 0 shares @@ -188,6 +198,8 @@ Feature: create | expireDate | invalid date | Then the OCS status code should be "404" And the HTTP status code should be "200" + And user "participant1" gets all shares + And the list of returned shares has 0 shares Scenario: create share with specific permissions Given user "participant1" creates room "group room" @@ -228,6 +240,28 @@ Feature: create | file_target | /welcome.txt | | share_with | another group room | | share_with_displayname | Another group room | + And user "participant1" gets all shares + And the list of returned shares has 2 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + And share 1 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | another group room | + | share_with_displayname | Another group room | Scenario: create share again with same room Given user "participant1" creates room "group room" @@ -237,6 +271,18 @@ Feature: create When user "participant1" shares "welcome.txt" with room "group room" Then the OCS status code should be "403" And the HTTP status code should be "401" + And user "participant1" gets all shares + And the list of returned shares has 1 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | diff --git a/tests/integration/features/sharing/get.feature b/tests/integration/features/sharing/get.feature new file mode 100644 index 00000000000..3f40ecd5cd9 --- /dev/null +++ b/tests/integration/features/sharing/get.feature @@ -0,0 +1,56 @@ +Feature: get + + Background: + Given user "participant1" exists + Given user "participant2" exists + + + + Scenario: get a share + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + When user "participant1" gets last share + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + + + + Scenario: get a share using a user not invited to the room + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + When user "participant2" gets last share + Then the OCS status code should be "404" + And the HTTP status code should be "200" + + + + Scenario: get a share after changing the room name + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant1" renames room "group room" to "New room name" with 200 + When user "participant1" gets last share + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | New room name | From c673564a4ebb1130ec377509776d0339b2569cc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Wed, 4 Jul 2018 10:22:20 +0200 Subject: [PATCH 12/43] Implement moving room shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a recipient moves or deletes a room share the share should be moved or deleted only for that recipient and be left untouched for the other users in the room. Therefore, when a recipient moves or deletes a share a copy of the original share is added to keep the share status (permissions (to mark a share as deleted) and file target) from the point of view of the recipient; when the share is later accessed by the recipient RoomShareProvider returns it as seen by that recipient. Signed-off-by: Daniel Calviño Sánchez --- lib/Share/RoomShareProvider.php | 119 +++++++++++++++++++++++++++++++- 1 file changed, 117 insertions(+), 2 deletions(-) diff --git a/lib/Share/RoomShareProvider.php b/lib/Share/RoomShareProvider.php index 27c88e572d3..b51e3bc0eee 100644 --- a/lib/Share/RoomShareProvider.php +++ b/lib/Share/RoomShareProvider.php @@ -53,6 +53,9 @@ */ class RoomShareProvider implements IShareProvider { + // Special share type for user modified room shares + const SHARE_TYPE_USERROOM = 11; + /** @var IDBConnection */ private $dbConnection; @@ -313,7 +316,50 @@ public function restore(IShare $share, string $recipient): IShare { * @return IShare */ public function move(IShare $share, $recipient) { - throw new \Exception("Not implemented"); + // Check if there is a userroom share + $qb = $this->dbConnection->getQueryBuilder(); + $stmt = $qb->select('id') + ->from('share') + ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERROOM))) + ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient))) + ->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId()))) + ->andWhere($qb->expr()->orX( + $qb->expr()->eq('item_type', $qb->createNamedParameter('file')), + $qb->expr()->eq('item_type', $qb->createNamedParameter('folder')) + )) + ->setMaxResults(1) + ->execute(); + + $data = $stmt->fetch(); + $stmt->closeCursor(); + + if ($data === false) { + // No userroom share yet. Create one. + $qb = $this->dbConnection->getQueryBuilder(); + $qb->insert('share') + ->values([ + 'share_type' => $qb->createNamedParameter(self::SHARE_TYPE_USERROOM), + 'share_with' => $qb->createNamedParameter($recipient), + 'uid_owner' => $qb->createNamedParameter($share->getShareOwner()), + 'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()), + 'parent' => $qb->createNamedParameter($share->getId()), + 'item_type' => $qb->createNamedParameter($share->getNodeType()), + 'item_source' => $qb->createNamedParameter($share->getNodeId()), + 'file_source' => $qb->createNamedParameter($share->getNodeId()), + 'file_target' => $qb->createNamedParameter($share->getTarget()), + 'permissions' => $qb->createNamedParameter($share->getPermissions()), + 'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()), + ])->execute(); + } else { + // Already a userroom share. Update it. + $qb = $this->dbConnection->getQueryBuilder(); + $qb->update('share') + ->set('file_target', $qb->createNamedParameter($share->getTarget())) + ->where($qb->expr()->eq('id', $qb->createNamedParameter($data['id']))) + ->execute(); + } + + return $share; } /** @@ -405,7 +451,74 @@ public function getShareById($id, $recipientId = null) { throw new ShareNotFound(); } - return $this->createShareObject($data); + $share = $this->createShareObject($data); + + if ($recipientId !== null) { + $share = $this->resolveSharesForRecipient([$share], $recipientId)[0]; + } + + return $share; + } + + /** + * Returns each given share as seen by the given recipient. + * + * If the recipient has not modified the share the original one is returned + * instead. + * + * @param Share[] $shares + * @param string $userId + * @return Share[] + */ + private function resolveSharesForRecipient(array $shares, string $userId): array { + $result = []; + + $start = 0; + while (true) { + /** @var Share[] $shareSlice */ + $shareSlice = array_slice($shares, $start, 100); + $start += 100; + + if ($shareSlice === []) { + break; + } + + /** @var int[] $ids */ + $ids = []; + /** @var Share[] $shareMap */ + $shareMap = []; + + foreach ($shareSlice as $share) { + $ids[] = (int)$share->getId(); + $shareMap[$share->getId()] = $share; + } + + $qb = $this->dbConnection->getQueryBuilder(); + + $query = $qb->select('*') + ->from('share') + ->where($qb->expr()->in('parent', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY))) + ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($userId))) + ->andWhere($qb->expr()->orX( + $qb->expr()->eq('item_type', $qb->createNamedParameter('file')), + $qb->expr()->eq('item_type', $qb->createNamedParameter('folder')) + )); + + $stmt = $query->execute(); + + while ($data = $stmt->fetch()) { + $shareMap[$data['parent']]->setPermissions((int)$data['permissions']); + $shareMap[$data['parent']]->setTarget($data['file_target']); + } + + $stmt->closeCursor(); + + foreach ($shareMap as $share) { + $result[] = $share; + } + } + + return $result; } /** @@ -496,6 +609,8 @@ public function getSharedWith($userId, $shareType, $node, $limit, $offset) { $cursor->closeCursor(); } + $shares = $this->resolveSharesForRecipient($shares, $userId); + return $shares; } From 1ac8027594813908edd7c944e51af0401168e4bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Wed, 4 Jul 2018 11:35:19 +0200 Subject: [PATCH 13/43] Add integration tests for moving room shares into other folders MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- .../features/bootstrap/SharingContext.php | 79 +++++++++++++++ .../integration/features/sharing/move.feature | 95 +++++++++++++++++++ 2 files changed, 174 insertions(+) create mode 100644 tests/integration/features/sharing/move.feature diff --git a/tests/integration/features/bootstrap/SharingContext.php b/tests/integration/features/bootstrap/SharingContext.php index ead74c99d5b..c6a985a57e1 100644 --- a/tests/integration/features/bootstrap/SharingContext.php +++ b/tests/integration/features/bootstrap/SharingContext.php @@ -55,6 +55,53 @@ public function __construct(string $baseUrl, array $admin, string $regularUserPa } } + /** + * @Given user :user creates folder :destination + * + * @param string $user + * @param string $destination + */ + public function userCreatesFolder($user, $destination) { + $this->currentUser = $user; + + $url = "/$user/$destination/"; + + $this->sendingToDav('MKCOL', $url); + + $this->theHTTPStatusCodeShouldBe(201); + } + + /** + * @Given user :user moves file :source to :destination + * + * @param string $user + * @param string $source + * @param string $destination + */ + public function userMovesFileTo(string $user, string $source, string $destination) { + $this->currentUser = $user; + + $url = "/$user/$source"; + + $headers = []; + $headers['Destination'] = $this->baseUrl . "remote.php/dav/files/$user/" . $destination; + + $this->sendingToDav('MOVE', $url, $headers); + } + + /** + * @Given user :user moves file :source to :destination with :statusCode + * + * @param string $user + * @param string $source + * @param string $destination + * @param int statusCode + */ + public function userMovesFileToWith(string $user, string $source, string $destination, int $statusCode) { + $this->userMovesFileTo($user, $source, $destination); + $this->theHTTPStatusCodeShouldBe($statusCode); + } + /** * @When user :user shares :path with user :sharee * @@ -290,6 +337,38 @@ private function sendingTo(string $verb, string $url, TableNode $body = null) { } } + /** + * @param string $verb + * @param string $url + * @param array $headers + * @param string $body + */ + private function sendingToDav(string $verb, string $url, array $headers = null, string $body = null) { + $fullUrl = $this->baseUrl . "remote.php/dav/files" . $url; + $client = new Client(); + $options = []; + if ($this->currentUser === 'admin') { + $options['auth'] = $this->adminUser; + } else { + $options['auth'] = [$this->currentUser, $this->regularUserPassword]; + } + $options['headers'] = [ + 'OCS_APIREQUEST' => 'true' + ]; + if ($headers !== null) { + $options['headers'] = array_merge($options['headers'], $headers); + } + if ($body !== null) { + $options['body'] = $body; + } + + try { + $this->response = $client->send($client->createRequest($verb, $fullUrl, $options)); + } catch (GuzzleHttp\Exception\ClientException $ex) { + $this->response = $ex->getResponse(); + } + } + /** * @return string */ diff --git a/tests/integration/features/sharing/move.feature b/tests/integration/features/sharing/move.feature new file mode 100644 index 00000000000..472b362292c --- /dev/null +++ b/tests/integration/features/sharing/move.feature @@ -0,0 +1,95 @@ +Feature: move + + Background: + Given user "participant1" exists + Given user "participant2" exists + Given user "participant3" exists + Given user "participant4" exists + + Scenario: move share to another folder + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" adds "participant3" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant1" creates folder "/test" + When user "participant1" moves file "/welcome.txt" to "/test/renamed.txt" with 201 + Then user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /test/renamed.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + + + + Scenario: move received share to another folder + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" adds "participant3" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant2" creates folder "/test" + When user "participant2" moves file "/welcome (2).txt" to "/test/renamed.txt" with 201 + Then user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /test/renamed.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/test/renamed.txt | + | file_target | /test/renamed.txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | From 99aec02e585545ff5d1a12e5ed83a3faee8c0cbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Wed, 4 Jul 2018 16:55:07 +0200 Subject: [PATCH 14/43] Add integration tests for received shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As "welcome.txt" is part of the user skeleton every user has a file with that name. When a received share has the same name as an already existing file the share is renamed, in this case to "welcome (2).txt". Due to this these checks could not be added until now that moving shares is implemented. Signed-off-by: Daniel Calviño Sánchez --- .../features/bootstrap/SharingContext.php | 13 + .../features/sharing/create.feature | 262 ++++++++++++++++++ .../integration/features/sharing/get.feature | 11 + 3 files changed, 286 insertions(+) diff --git a/tests/integration/features/bootstrap/SharingContext.php b/tests/integration/features/bootstrap/SharingContext.php index c6a985a57e1..30848d1082d 100644 --- a/tests/integration/features/bootstrap/SharingContext.php +++ b/tests/integration/features/bootstrap/SharingContext.php @@ -176,6 +176,19 @@ public function userGetsAllShares(string $user) { $this->sendingTo('GET', $url); } + /** + * @When user :user gets all received shares + * + * @param string $user + */ + public function userGetsAllReceivedShares(string $user) { + $this->currentUser = $user; + + $url = '/apps/files_sharing/api/v1/shares?shared_with_me=true'; + + $this->sendingTo('GET', $url); + } + /** * @Then the OCS status code should be :statusCode * diff --git a/tests/integration/features/sharing/create.feature b/tests/integration/features/sharing/create.feature index ee6661a45b2..3492d2ca2d3 100644 --- a/tests/integration/features/sharing/create.feature +++ b/tests/integration/features/sharing/create.feature @@ -20,6 +20,17 @@ Feature: create | file_target | /welcome.txt | | share_with | own one-to-one room | | share_with_displayname | participant2-displayname | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | own one-to-one room | + | share_with_displayname | participant1-displayname | Scenario: create share with a one-to-one room invited to Given user "participant2" creates room "one-to-one room invited to" @@ -36,6 +47,17 @@ Feature: create | file_target | /welcome.txt | | share_with | one-to-one room invited to | | share_with_displayname | participant2-displayname | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | one-to-one room invited to | + | share_with_displayname | participant1-displayname | Scenario: create share with a one-to-one room not invited to Given user "participant2" creates room "one-to-one room not invited to" @@ -46,11 +68,16 @@ Feature: create And the HTTP status code should be "200" And user "participant1" gets all shares And the list of returned shares has 0 shares + And user "participant2" gets all received shares + And the list of returned shares has 0 shares + And user "participant3" gets all received shares + And the list of returned shares has 0 shares Scenario: create share with an owned group room Given user "participant1" creates room "own group room" | roomType | 2 | And user "participant1" renames room "own group room" to "Own group room" with 200 + And user "participant1" adds "participant2" to room "own group room" with 200 When user "participant1" shares "welcome.txt" with room "own group room" Then share is returned with | uid_owner | participant1 | @@ -62,6 +89,17 @@ Feature: create | file_target | /welcome.txt | | share_with | own group room | | share_with_displayname | Own group room | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | own group room | + | share_with_displayname | Own group room | Scenario: create share with a group room invited to Given user "participant2" creates room "group room invited to" @@ -79,6 +117,17 @@ Feature: create | file_target | /welcome.txt | | share_with | group room invited to | | share_with_displayname | Group room invited to | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | Scenario: create share with a group room not invited to Given user "participant2" creates room "group room not invited to" @@ -88,6 +137,8 @@ Feature: create And the HTTP status code should be "200" And user "participant1" gets all shares And the list of returned shares has 0 shares + And user "participant2" gets all received shares + And the list of returned shares has 0 shares Scenario: create share with a group room no longer invited to Given user "participant2" creates room "group room no longer invited to" @@ -99,11 +150,15 @@ Feature: create And the HTTP status code should be "200" And user "participant1" gets all shares And the list of returned shares has 0 shares + And user "participant2" gets all received shares + And the list of returned shares has 0 shares Scenario: create share with an owned public room Given user "participant1" creates room "own public room" | roomType | 3 | And user "participant1" renames room "own public room" to "Own public room" with 200 + And user "participant1" adds "participant2" to room "own public room" with 200 + And user "participant3" joins room "own public room" with 200 When user "participant1" shares "welcome.txt" with room "own public room" Then share is returned with | uid_owner | participant1 | @@ -115,12 +170,35 @@ Feature: create | file_target | /welcome.txt | | share_with | own public room | | share_with_displayname | Own public room | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | own public room | + | share_with_displayname | Own public room | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | own public room | + | share_with_displayname | Own public room | Scenario: create share with a public room invited to Given user "participant2" creates room "public room invited to" | roomType | 3 | And user "participant2" renames room "public room invited to" to "Public room invited to" with 200 And user "participant2" adds "participant1" to room "public room invited to" with 200 + And user "participant3" joins room "public room invited to" with 200 When user "participant1" shares "welcome.txt" with room "public room invited to" Then share is returned with | uid_owner | participant1 | @@ -132,12 +210,35 @@ Feature: create | file_target | /welcome.txt | | share_with | public room invited to | | share_with_displayname | Public room invited to | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | public room invited to | + | share_with_displayname | Public room invited to | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | public room invited to | + | share_with_displayname | Public room invited to | Scenario: create share with a public room self joined to Given user "participant2" creates room "public room self joined to" | roomType | 3 | And user "participant2" renames room "public room self joined to" to "Public room self joined to" with 200 And user "participant1" joins room "public room self joined to" with 200 + And user "participant3" joins room "public room self joined to" with 200 When user "participant1" shares "welcome.txt" with room "public room self joined to" Then share is returned with | uid_owner | participant1 | @@ -149,6 +250,28 @@ Feature: create | file_target | /welcome.txt | | share_with | public room self joined to | | share_with_displayname | Public room self joined to | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | public room self joined to | + | share_with_displayname | Public room self joined to | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | public room self joined to | + | share_with_displayname | Public room self joined to | Scenario: create share with a public room not joined to Given user "participant2" creates room "public room not joined to" @@ -158,6 +281,8 @@ Feature: create And the HTTP status code should be "200" And user "participant1" gets all shares And the list of returned shares has 0 shares + And user "participant2" gets all received shares + And the list of returned shares has 0 shares Scenario: create share with a public room no longer joined to Given user "participant2" creates room "public room no longer joined to" @@ -169,6 +294,8 @@ Feature: create And the HTTP status code should be "200" And user "participant1" gets all shares And the list of returned shares has 0 shares + And user "participant2" gets all received shares + And the list of returned shares has 0 shares @@ -176,6 +303,7 @@ Feature: create Given user "participant1" creates room "group room" | roomType | 2 | And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 When user "participant1" shares "welcome.txt" with room "group room" | expireDate | +3 days | Then share is returned with @@ -189,6 +317,18 @@ Feature: create | share_with | group room | | share_with_displayname | Group room | | expiration | +3 days | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + | expiration | +3 days | Scenario: create share with an invalid expiration date Given user "participant1" creates room "group room" @@ -200,11 +340,14 @@ Feature: create And the HTTP status code should be "200" And user "participant1" gets all shares And the list of returned shares has 0 shares + And user "participant2" gets all received shares + And the list of returned shares has 0 shares Scenario: create share with specific permissions Given user "participant1" creates room "group room" | roomType | 2 | And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 When user "participant1" shares "welcome.txt" with room "group room" | permissions | 1 | Then share is returned with @@ -218,6 +361,18 @@ Feature: create | share_with | group room | | share_with_displayname | Group room | | permissions | 1 | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + | permissions | 1 | @@ -225,10 +380,12 @@ Feature: create Given user "participant1" creates room "group room" | roomType | 2 | And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 And user "participant1" creates room "another group room" | roomType | 2 | And user "participant1" renames room "another group room" to "Another group room" with 200 + And user "participant1" adds "participant3" to room "another group room" with 200 When user "participant1" shares "welcome.txt" with room "another group room" Then share is returned with | uid_owner | participant1 | @@ -262,11 +419,36 @@ Feature: create | file_target | /welcome.txt | | share_with | another group room | | share_with_displayname | Another group room | + And user "participant2" gets all received shares + And the list of returned shares has 1 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant3" gets all received shares + And the list of returned shares has 1 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | another group room | + | share_with_displayname | Another group room | Scenario: create share again with same room Given user "participant1" creates room "group room" | roomType | 2 | And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 When user "participant1" shares "welcome.txt" with room "group room" Then the OCS status code should be "403" @@ -283,6 +465,18 @@ Feature: create | file_target | /welcome.txt | | share_with | group room | | share_with_displayname | Group room | + And user "participant2" gets all received shares + And the list of returned shares has 1 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | @@ -307,6 +501,28 @@ Feature: create | file_target | /welcome.txt | | share_with | another group room | | share_with_displayname | Another group room | + And user "participant2" gets all received shares + And the list of returned shares has 2 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + And share 1 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | another group room | + | share_with_displayname | Another group room | Scenario: create share with a user who already received that share through a room Given user "participant1" creates room "group room" @@ -327,6 +543,29 @@ Feature: create | share_with_displayname | participant2-displayname | | share_type | 0 | | mail_send | 1 | + And user "participant2" gets all received shares + And the list of returned shares has 2 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | participant2 | + | share_with_displayname | participant2-displayname | + | share_type | 0 | + And share 1 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | Scenario: create share with a room including a user who already received that share directly Given user "participant1" creates room "group room" @@ -345,3 +584,26 @@ Feature: create | file_target | /welcome.txt | | share_with | group room | | share_with_displayname | Group room | + And user "participant2" gets all received shares + And the list of returned shares has 2 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | participant2 | + | share_with_displayname | participant2-displayname | + | share_type | 0 | + And share 1 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | diff --git a/tests/integration/features/sharing/get.feature b/tests/integration/features/sharing/get.feature index 3f40ecd5cd9..99c7d2a86a9 100644 --- a/tests/integration/features/sharing/get.feature +++ b/tests/integration/features/sharing/get.feature @@ -54,3 +54,14 @@ Feature: get | file_target | /welcome.txt | | share_with | group room | | share_with_displayname | New room name | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | New room name | From 17e25bcd7b4a8d7ad6896d5833135e20810542ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Wed, 4 Jul 2018 17:42:48 +0200 Subject: [PATCH 15/43] Add integration tests for creating and getting reshares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- .../features/sharing/create.feature | 162 ++++++++++++++++++ .../integration/features/sharing/get.feature | 18 ++ 2 files changed, 180 insertions(+) diff --git a/tests/integration/features/sharing/create.feature b/tests/integration/features/sharing/create.feature index 3492d2ca2d3..2657db98c3d 100644 --- a/tests/integration/features/sharing/create.feature +++ b/tests/integration/features/sharing/create.feature @@ -299,6 +299,132 @@ Feature: create + Scenario: create share with a room of a received share whose owner is in the room + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" adds "participant3" to room "group room" with 200 + And user "participant2" shares "welcome.txt" with user "participant1" with OCS 100 + When user "participant1" shares "welcome (2).txt" with room "group room" + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | uid_file_owner | participant2 | + | displayname_file_owner | participant2-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | uid_file_owner | participant2 | + | displayname_file_owner | participant2-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant2 | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | uid_file_owner | participant2 | + | displayname_file_owner | participant2-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + + Scenario: create share with a room of a received share whose owner is not in the room + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant3" to room "group room" with 200 + And user "participant2" shares "welcome.txt" with user "participant1" with OCS 100 + When user "participant1" shares "welcome (2).txt" with room "group room" + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | uid_file_owner | participant2 | + | displayname_file_owner | participant2-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | uid_file_owner | participant2 | + | displayname_file_owner | participant2-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant2 | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | uid_file_owner | participant2 | + | displayname_file_owner | participant2-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + + Scenario: create share with a room of a received share without reshare permissions + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" adds "participant3" to room "group room" with 200 + And user "participant2" shares "welcome.txt" with user "participant1" + | permissions | 1 | + And share is returned with + | permissions | 1 | + | share_type | 0 | + | mail_send | 1 | + When user "participant1" shares "welcome (2).txt" with room "group room" + Then the OCS status code should be "404" + And the HTTP status code should be "200" + And user "participant1" gets all shares + And the list of returned shares has 0 shares + And user "participant1" gets all received shares + And the list of returned shares has 1 shares + And share 0 is returned with + | permissions | 1 | + | share_type | 0 | + And user "participant2" gets all shares + And the list of returned shares has 1 shares + And share 0 is returned with + | permissions | 1 | + | share_type | 0 | + And user "participant2" gets all received shares + And the list of returned shares has 0 shares + And user "participant3" gets all received shares + And the list of returned shares has 0 shares + + + Scenario: create share with an expiration date Given user "participant1" creates room "group room" | roomType | 2 | @@ -478,6 +604,42 @@ Feature: create | share_with | group room | | share_with_displayname | Group room | + Scenario: create share again with same room by a sharee + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + When user "participant2" shares "welcome (2).txt" with room "group room" + Then the OCS status code should be "403" + And the HTTP status code should be "401" + And user "participant1" gets all shares + And the list of returned shares has 1 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant2" gets all shares + And the list of returned shares has 0 shares + And user "participant2" gets all received shares + And the list of returned shares has 1 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + Scenario: create share with a room that includes a user who already received that share through another room diff --git a/tests/integration/features/sharing/get.feature b/tests/integration/features/sharing/get.feature index 99c7d2a86a9..fba0a8a56ce 100644 --- a/tests/integration/features/sharing/get.feature +++ b/tests/integration/features/sharing/get.feature @@ -23,6 +23,24 @@ Feature: get | share_with | group room | | share_with_displayname | Group room | + Scenario: get a received share + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + When user "participant2" gets last share + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + Scenario: get a share using a user not invited to the room From f4a5048c5002e09dffb40f5f47995d1e2b18a972 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Thu, 5 Jul 2018 11:23:04 +0200 Subject: [PATCH 16/43] Add integration tests for getting shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- .../features/bootstrap/SharingContext.php | 69 +++ .../integration/features/sharing/get.feature | 441 ++++++++++++++++++ 2 files changed, 510 insertions(+) diff --git a/tests/integration/features/bootstrap/SharingContext.php b/tests/integration/features/bootstrap/SharingContext.php index 30848d1082d..40cc5697fff 100644 --- a/tests/integration/features/bootstrap/SharingContext.php +++ b/tests/integration/features/bootstrap/SharingContext.php @@ -176,6 +176,61 @@ public function userGetsAllShares(string $user) { $this->sendingTo('GET', $url); } + /** + * @When user :user gets all shares and reshares + * + * @param string $user + */ + public function userGetsAllSharesAndReshares(string $user) { + $this->currentUser = $user; + + $url = '/apps/files_sharing/api/v1/shares?reshares=true'; + + $this->sendingTo('GET', $url); + } + + /** + * @When user :user gets all shares for :path + * + * @param string $user + * @param string $path + */ + public function userGetsAllSharesFor(string $user, string $path) { + $this->currentUser = $user; + + $url = '/apps/files_sharing/api/v1/shares?path=' . $path; + + $this->sendingTo('GET', $url); + } + + /** + * @When user :user gets all shares and reshares for :path + * + * @param string $user + * @param string $path + */ + public function userGetsAllSharesAndResharesFor(string $user, string $path) { + $this->currentUser = $user; + + $url = '/apps/files_sharing/api/v1/shares?reshares=true&path=' . $path; + + $this->sendingTo('GET', $url); + } + + /** + * @When user :user gets all shares for :path and its subfiles + * + * @param string $user + * @param string $path + */ + public function userGetsAllSharesForAndItsSubfiles(string $user, string $path) { + $this->currentUser = $user; + + $url = '/apps/files_sharing/api/v1/shares?subfiles=true&path=' . $path; + + $this->sendingTo('GET', $url); + } + /** * @When user :user gets all received shares * @@ -189,6 +244,20 @@ public function userGetsAllReceivedShares(string $user) { $this->sendingTo('GET', $url); } + /** + * @When user :user gets all received shares for :path + * + * @param string $user + * @param string $path + */ + public function userGetsAllReceivedSharesFor(string $user, string $path) { + $this->currentUser = $user; + + $url = '/apps/files_sharing/api/v1/shares?shared_with_me=true&path=' . $path; + + $this->sendingTo('GET', $url); + } + /** * @Then the OCS status code should be :statusCode * diff --git a/tests/integration/features/sharing/get.feature b/tests/integration/features/sharing/get.feature index fba0a8a56ce..3fed205d2df 100644 --- a/tests/integration/features/sharing/get.feature +++ b/tests/integration/features/sharing/get.feature @@ -3,6 +3,8 @@ Feature: get Background: Given user "participant1" exists Given user "participant2" exists + Given user "participant3" exists + Given user "participant4" exists @@ -83,3 +85,442 @@ Feature: get | file_target | /welcome (2).txt | | share_with | group room | | share_with_displayname | New room name | + + + + Scenario: get all shares of a user + Given user "participant1" creates room "own group room" + | roomType | 2 | + And user "participant1" renames room "own group room" to "Own group room" with 200 + And user "participant2" creates room "group room invited to" + | roomType | 2 | + And user "participant2" renames room "group room invited to" to "Group room invited to" with 200 + And user "participant2" adds "participant1" to room "group room invited to" with 200 + And user "participant1" creates room "own one-to-one room" + | roomType | 1 | + | invite | participant3 | + And user "participant3" creates room "one-to-one room not invited to" + | roomType | 1 | + | invite | participant4 | + And user "participant1" creates folder "/test" + And user "participant1" shares "welcome.txt" with room "own group room" with OCS 100 + And user "participant1" shares "test" with room "group room invited to" with OCS 100 + And user "participant1" shares "welcome.txt" with room "group room invited to" with OCS 100 + And user "participant1" shares "test" with room "own one-to-one room" with OCS 100 + And user "participant2" shares "welcome (2).txt" with user "participant3" with OCS 100 + And user "participant3" shares "welcome (2).txt" with room "one-to-one room not invited to" with OCS 100 + When user "participant1" gets all shares + Then the list of returned shares has 4 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | own group room | + | share_with_displayname | Own group room | + And share 1 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /test | + | item_type | folder | + | mimetype | httpd/unix-directory | + | storage_id | home::participant1 | + | file_target | /test | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + | permissions | 31 | + And share 2 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + And share 3 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /test | + | item_type | folder | + | mimetype | httpd/unix-directory | + | storage_id | home::participant1 | + | file_target | /test | + | share_with | own one-to-one room | + | share_with_displayname | participant3-displayname | + | permissions | 31 | + + Scenario: get all shares and reshares of a user + Given user "participant1" creates room "own group room" + | roomType | 2 | + And user "participant1" renames room "own group room" to "Own group room" with 200 + And user "participant2" creates room "group room invited to" + | roomType | 2 | + And user "participant2" renames room "group room invited to" to "Group room invited to" with 200 + And user "participant2" adds "participant1" to room "group room invited to" with 200 + And user "participant1" creates room "own one-to-one room" + | roomType | 1 | + | invite | participant3 | + And user "participant3" creates room "one-to-one room not invited to" + | roomType | 1 | + | invite | participant4 | + And user "participant1" creates folder "/test" + And user "participant1" shares "welcome.txt" with room "own group room" with OCS 100 + And user "participant1" shares "test" with room "group room invited to" with OCS 100 + And user "participant1" shares "welcome.txt" with room "group room invited to" with OCS 100 + And user "participant1" shares "test" with room "own one-to-one room" with OCS 100 + And user "participant2" shares "welcome (2).txt" with user "participant3" with OCS 100 + And user "participant3" shares "welcome (2).txt" with room "one-to-one room not invited to" with OCS 100 + When user "participant1" gets all shares and reshares + Then the list of returned shares has 6 shares + And share 0 is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | uid_file_owner | participant1 | + | displayname_file_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome (2).txt | + | share_with | participant3 | + | share_with_displayname | participant3-displayname | + | share_type | 0 | + And share 1 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | own group room | + | share_with_displayname | Own group room | + And share 2 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /test | + | item_type | folder | + | mimetype | httpd/unix-directory | + | storage_id | home::participant1 | + | file_target | /test | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + | permissions | 31 | + And share 3 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + And share 4 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /test | + | item_type | folder | + | mimetype | httpd/unix-directory | + | storage_id | home::participant1 | + | file_target | /test | + | share_with | own one-to-one room | + | share_with_displayname | participant3-displayname | + | permissions | 31 | + And share 5 is returned with + | uid_owner | participant3 | + | displayname_owner | participant3-displayname | + | uid_file_owner | participant1 | + | displayname_file_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome (2).txt | + | share_with | one-to-one room not invited to | + | share_with_displayname | participant3-displayname | + + Scenario: get all shares of a file + Given user "participant1" creates room "own group room" + | roomType | 2 | + And user "participant1" renames room "own group room" to "Own group room" with 200 + And user "participant2" creates room "group room invited to" + | roomType | 2 | + And user "participant2" renames room "group room invited to" to "Group room invited to" with 200 + And user "participant2" adds "participant1" to room "group room invited to" with 200 + And user "participant1" creates room "own one-to-one room" + | roomType | 1 | + | invite | participant3 | + And user "participant3" creates room "one-to-one room not invited to" + | roomType | 1 | + | invite | participant4 | + And user "participant1" creates folder "/test" + And user "participant1" shares "welcome.txt" with room "own group room" with OCS 100 + And user "participant1" shares "test" with room "group room invited to" with OCS 100 + And user "participant1" shares "welcome.txt" with room "group room invited to" with OCS 100 + And user "participant1" shares "test" with room "own one-to-one room" with OCS 100 + And user "participant2" shares "welcome (2).txt" with user "participant3" with OCS 100 + And user "participant3" shares "welcome (2).txt" with room "one-to-one room not invited to" with OCS 100 + When user "participant1" gets all shares for "/welcome.txt" + Then the list of returned shares has 2 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | own group room | + | share_with_displayname | Own group room | + And share 1 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + + Scenario: get all shares and reshares of a file + Given user "participant1" creates room "own group room" + | roomType | 2 | + And user "participant1" renames room "own group room" to "Own group room" with 200 + And user "participant2" creates room "group room invited to" + | roomType | 2 | + And user "participant2" renames room "group room invited to" to "Group room invited to" with 200 + And user "participant2" adds "participant1" to room "group room invited to" with 200 + And user "participant1" creates room "own one-to-one room" + | roomType | 1 | + | invite | participant3 | + And user "participant3" creates room "one-to-one room not invited to" + | roomType | 1 | + | invite | participant4 | + And user "participant1" creates folder "/test" + And user "participant1" shares "welcome.txt" with room "own group room" with OCS 100 + And user "participant1" shares "test" with room "group room invited to" with OCS 100 + And user "participant1" shares "welcome.txt" with room "group room invited to" with OCS 100 + And user "participant1" shares "test" with room "own one-to-one room" with OCS 100 + And user "participant2" shares "welcome (2).txt" with user "participant3" with OCS 100 + And user "participant3" shares "welcome (2).txt" with room "one-to-one room not invited to" with OCS 100 + When user "participant1" gets all shares and reshares for "/welcome.txt" + Then the list of returned shares has 4 shares + And share 0 is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | uid_file_owner | participant1 | + | displayname_file_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome (2).txt | + | share_with | participant3 | + | share_with_displayname | participant3-displayname | + | share_type | 0 | + And share 1 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | own group room | + | share_with_displayname | Own group room | + And share 2 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + And share 3 is returned with + | uid_owner | participant3 | + | displayname_owner | participant3-displayname | + | uid_file_owner | participant1 | + | displayname_file_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome (2).txt | + | share_with | one-to-one room not invited to | + | share_with_displayname | participant3-displayname | + + Scenario: get all shares of a folder + Given user "participant1" creates room "own group room" + | roomType | 2 | + And user "participant1" renames room "own group room" to "Own group room" with 200 + And user "participant2" creates room "group room invited to" + | roomType | 2 | + And user "participant2" renames room "group room invited to" to "Group room invited to" with 200 + And user "participant2" adds "participant1" to room "group room invited to" with 200 + And user "participant1" creates room "own one-to-one room" + | roomType | 1 | + | invite | participant3 | + And user "participant3" creates room "one-to-one room not invited to" + | roomType | 1 | + | invite | participant4 | + And user "participant1" creates folder "/test" + And user "participant1" creates folder "/test/subfolder" + And user "participant1" creates folder "/test/subfolder/subsubfolder" + And user "participant1" creates folder "/test2" + And user "participant1" shares "welcome.txt" with room "own group room" with OCS 100 + And user "participant1" shares "test/subfolder" with room "group room invited to" with OCS 100 + And user "participant1" shares "test/subfolder/subsubfolder" with room "group room invited to" with OCS 100 + And user "participant1" shares "welcome.txt" with room "group room invited to" with OCS 100 + And user "participant1" shares "test2" with room "own one-to-one room" with OCS 100 + And user "participant1" moves file "/welcome.txt" to "/test/renamed.txt" with 201 + And user "participant2" shares "subfolder" with user "participant3" with OCS 100 + And user "participant3" shares "subfolder" with room "one-to-one room not invited to" with OCS 100 + # Only direct children are taken into account + When user "participant1" gets all shares for "/test" and its subfiles + Then the list of returned shares has 3 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /test/renamed.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | own group room | + | share_with_displayname | Own group room | + And share 1 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /test/renamed.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + And share 2 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /test/subfolder | + | item_type | folder | + | mimetype | httpd/unix-directory | + | storage_id | home::participant1 | + | file_target | /subfolder | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + | permissions | 31 | + + + + Scenario: get all received shares of a user + Given user "participant1" creates room "own group room" + | roomType | 2 | + And user "participant1" renames room "own group room" to "Own group room" with 200 + And user "participant1" adds "participant2" to room "own group room" with 200 + And user "participant2" creates room "group room invited to" + | roomType | 2 | + And user "participant2" renames room "group room invited to" to "Group room invited to" with 200 + And user "participant2" adds "participant1" to room "group room invited to" with 200 + And user "participant2" adds "participant3" to room "group room invited to" with 200 + And user "participant1" creates room "own one-to-one room" + | roomType | 1 | + | invite | participant3 | + And user "participant3" creates folder "/test" + And user "participant2" shares "welcome.txt" with room "own group room" with OCS 100 + And user "participant3" shares "test" with room "group room invited to" with OCS 100 + And user "participant2" shares "welcome.txt" with room "group room invited to" with OCS 100 + And user "participant3" shares "test" with room "own one-to-one room" with OCS 100 + When user "participant1" gets all received shares + Then the list of returned shares has 4 shares + And share 0 is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | own group room | + | share_with_displayname | Own group room | + And share 1 is returned with + | uid_owner | participant3 | + | displayname_owner | participant3-displayname | + | path | /test | + | item_type | folder | + | mimetype | httpd/unix-directory | + | storage_id | shared::/test | + | file_target | /test | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + | permissions | 31 | + And share 2 is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + And share 3 is returned with + | uid_owner | participant3 | + | displayname_owner | participant3-displayname | + | path | /test | + | item_type | folder | + | mimetype | httpd/unix-directory | + | storage_id | shared::/test | + | file_target | /test | + | share_with | own one-to-one room | + | share_with_displayname | participant3-displayname | + | permissions | 31 | + + Scenario: get all received shares of a file + Given user "participant1" creates room "own group room" + | roomType | 2 | + And user "participant1" renames room "own group room" to "Own group room" with 200 + And user "participant1" adds "participant2" to room "own group room" with 200 + And user "participant2" creates room "group room invited to" + | roomType | 2 | + And user "participant2" renames room "group room invited to" to "Group room invited to" with 200 + And user "participant2" adds "participant1" to room "group room invited to" with 200 + And user "participant2" adds "participant3" to room "group room invited to" with 200 + And user "participant1" creates room "own one-to-one room" + | roomType | 1 | + | invite | participant3 | + And user "participant3" creates folder "/test" + And user "participant2" shares "welcome.txt" with room "own group room" with OCS 100 + And user "participant3" shares "test" with room "group room invited to" with OCS 100 + And user "participant2" shares "welcome.txt" with room "group room invited to" with OCS 100 + And user "participant3" shares "test" with room "own one-to-one room" with OCS 100 + When user "participant1" gets all received shares for "/welcome (2).txt" + Then the list of returned shares has 2 shares + And share 0 is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | own group room | + | share_with_displayname | Own group room | + And share 1 is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | From c32c697fe6475fd0919be100d5c5b62436569acd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Thu, 5 Jul 2018 12:13:14 +0200 Subject: [PATCH 17/43] Implement updating room shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a share is updated the share itself and all the copies that store the share from the point of view of the recipients are updated. The only exception are the permissions of shares deleted by the recipient, as 0 will be used to mark them as deleted. Signed-off-by: Daniel Calviño Sánchez --- lib/Share/RoomShareProvider.php | 36 ++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/lib/Share/RoomShareProvider.php b/lib/Share/RoomShareProvider.php index b51e3bc0eee..fbf14a70ce2 100644 --- a/lib/Share/RoomShareProvider.php +++ b/lib/Share/RoomShareProvider.php @@ -267,7 +267,41 @@ private function createShareObject($data) { * @return IShare The share object */ public function update(IShare $share) { - throw new \Exception("Not implemented"); + $qb = $this->dbConnection->getQueryBuilder(); + $qb->update('share') + ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId()))) + ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner())) + ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy())) + ->set('permissions', $qb->createNamedParameter($share->getPermissions())) + ->set('item_source', $qb->createNamedParameter($share->getNode()->getId())) + ->set('file_source', $qb->createNamedParameter($share->getNode()->getId())) + ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE)) + ->execute(); + + /* + * Update all user defined group shares + */ + $qb = $this->dbConnection->getQueryBuilder(); + $qb->update('share') + ->where($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId()))) + ->set('uid_owner', $qb->createNamedParameter($share->getShareOwner())) + ->set('uid_initiator', $qb->createNamedParameter($share->getSharedBy())) + ->set('item_source', $qb->createNamedParameter($share->getNode()->getId())) + ->set('file_source', $qb->createNamedParameter($share->getNode()->getId())) + ->set('expiration', $qb->createNamedParameter($share->getExpirationDate(), IQueryBuilder::PARAM_DATE)) + ->execute(); + + /* + * Now update the permissions for all children that have not set it to 0 + */ + $qb = $this->dbConnection->getQueryBuilder(); + $qb->update('share') + ->where($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId()))) + ->andWhere($qb->expr()->neq('permissions', $qb->createNamedParameter(0))) + ->set('permissions', $qb->createNamedParameter($share->getPermissions())) + ->execute(); + + return $share; } /** From 9d1d1a169ef31de2ed473534e5e35bffcf2ef174 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Thu, 5 Jul 2018 20:05:44 +0200 Subject: [PATCH 18/43] Add integration tests for updating room shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- .../features/bootstrap/SharingContext.php | 14 + .../features/sharing/update.feature | 1101 +++++++++++++++++ 2 files changed, 1115 insertions(+) create mode 100644 tests/integration/features/sharing/update.feature diff --git a/tests/integration/features/bootstrap/SharingContext.php b/tests/integration/features/bootstrap/SharingContext.php index 40cc5697fff..d792aa194b4 100644 --- a/tests/integration/features/bootstrap/SharingContext.php +++ b/tests/integration/features/bootstrap/SharingContext.php @@ -152,6 +152,20 @@ public function userSharesWithRoomWithOcs(string $user, string $path, string $ro $this->theOCSStatusCodeShouldBe($statusCode); } + /** + * @When user :user updates last share with + * + * @param string $user + * @param TableNode $body + */ + public function userUpdatesLastShareWith(string $user, TableNode $body) { + $this->currentUser = $user; + + $url = '/apps/files_sharing/api/v1/shares/' . $this->getLastShareId(); + + $this->sendingTo('PUT', $url, $body); + } + /** * @When user :user gets last share */ diff --git a/tests/integration/features/sharing/update.feature b/tests/integration/features/sharing/update.feature new file mode 100644 index 00000000000..b72a85b3f27 --- /dev/null +++ b/tests/integration/features/sharing/update.feature @@ -0,0 +1,1101 @@ +Feature: update + + Background: + Given user "participant1" exists + Given user "participant2" exists + Given user "participant3" exists + + Scenario: update share with an owned one-to-one room + Given user "participant1" creates room "own one-to-one room" + | roomType | 1 | + | invite | participant2 | + And user "participant1" shares "welcome.txt" with room "own one-to-one room" with OCS 100 + When user "participant1" updates last share with + | permissions | 1 | + | expireDate | +3 days | + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | own one-to-one room | + | share_with_displayname | participant2-displayname | + | permissions | 1 | + | expiration | +3 days | + And user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | own one-to-one room | + | share_with_displayname | participant2-displayname | + | permissions | 1 | + | expiration | +3 days | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | own one-to-one room | + | share_with_displayname | participant1-displayname | + | permissions | 1 | + | expiration | +3 days | + + Scenario: update share with a one-to-one room invited to + Given user "participant2" creates room "one-to-one room invited to" + | roomType | 1 | + | invite | participant1 | + And user "participant1" shares "welcome.txt" with room "one-to-one room invited to" with OCS 100 + When user "participant1" updates last share with + | permissions | 1 | + | expireDate | +3 days | + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | one-to-one room invited to | + | share_with_displayname | participant2-displayname | + | permissions | 1 | + | expiration | +3 days | + And user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | one-to-one room invited to | + | share_with_displayname | participant2-displayname | + | permissions | 1 | + | expiration | +3 days | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | one-to-one room invited to | + | share_with_displayname | participant1-displayname | + | permissions | 1 | + | expiration | +3 days | + + Scenario: update share with an owned group room + Given user "participant1" creates room "own group room" + | roomType | 2 | + And user "participant1" renames room "own group room" to "Own group room" with 200 + And user "participant1" adds "participant2" to room "own group room" with 200 + And user "participant1" shares "welcome.txt" with room "own group room" with OCS 100 + When user "participant1" updates last share with + | permissions | 1 | + | expireDate | +3 days | + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | own group room | + | share_with_displayname | Own group room | + | permissions | 1 | + | expiration | +3 days | + And user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | own group room | + | share_with_displayname | Own group room | + | permissions | 1 | + | expiration | +3 days | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | own group room | + | share_with_displayname | Own group room | + | permissions | 1 | + | expiration | +3 days | + + Scenario: update share with a group room invited to + Given user "participant2" creates room "group room invited to" + | roomType | 2 | + And user "participant2" renames room "group room invited to" to "Group room invited to" with 200 + And user "participant2" adds "participant1" to room "group room invited to" with 200 + And user "participant1" shares "welcome.txt" with room "group room invited to" with OCS 100 + When user "participant1" updates last share with + | permissions | 1 | + | expireDate | +3 days | + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + | permissions | 1 | + | expiration | +3 days | + And user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + | permissions | 1 | + | expiration | +3 days | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + | permissions | 1 | + | expiration | +3 days | + + Scenario: update share with an owned public room + Given user "participant1" creates room "own public room" + | roomType | 3 | + And user "participant1" renames room "own public room" to "Own public room" with 200 + And user "participant1" adds "participant2" to room "own public room" with 200 + And user "participant3" joins room "own public room" with 200 + And user "participant1" shares "welcome.txt" with room "own public room" with OCS 100 + When user "participant1" updates last share with + | permissions | 1 | + | expireDate | +3 days | + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | own public room | + | share_with_displayname | Own public room | + | permissions | 1 | + | expiration | +3 days | + And user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | own public room | + | share_with_displayname | Own public room | + | permissions | 1 | + | expiration | +3 days | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | own public room | + | share_with_displayname | Own public room | + | permissions | 1 | + | expiration | +3 days | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | own public room | + | share_with_displayname | Own public room | + | permissions | 1 | + | expiration | +3 days | + + Scenario: update share with a public room invited to + Given user "participant2" creates room "public room invited to" + | roomType | 3 | + And user "participant2" renames room "public room invited to" to "Public room invited to" with 200 + And user "participant2" adds "participant1" to room "public room invited to" with 200 + And user "participant3" joins room "public room invited to" with 200 + And user "participant1" shares "welcome.txt" with room "public room invited to" with OCS 100 + When user "participant1" updates last share with + | permissions | 1 | + | expireDate | +3 days | + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | public room invited to | + | share_with_displayname | Public room invited to | + | permissions | 1 | + | expiration | +3 days | + And user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | public room invited to | + | share_with_displayname | Public room invited to | + | permissions | 1 | + | expiration | +3 days | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | public room invited to | + | share_with_displayname | Public room invited to | + | permissions | 1 | + | expiration | +3 days | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | public room invited to | + | share_with_displayname | Public room invited to | + | permissions | 1 | + | expiration | +3 days | + + Scenario: update share with a public room self joined to + Given user "participant2" creates room "public room self joined to" + | roomType | 3 | + And user "participant2" renames room "public room self joined to" to "Public room self joined to" with 200 + And user "participant1" joins room "public room self joined to" with 200 + And user "participant3" joins room "public room self joined to" with 200 + And user "participant1" shares "welcome.txt" with room "public room self joined to" with OCS 100 + When user "participant1" updates last share with + | permissions | 1 | + | expireDate | +3 days | + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | public room self joined to | + | share_with_displayname | Public room self joined to | + | permissions | 1 | + | expiration | +3 days | + And user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | public room self joined to | + | share_with_displayname | Public room self joined to | + | permissions | 1 | + | expiration | +3 days | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | public room self joined to | + | share_with_displayname | Public room self joined to | + | permissions | 1 | + | expiration | +3 days | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | public room self joined to | + | share_with_displayname | Public room self joined to | + | permissions | 1 | + | expiration | +3 days | + + + + Scenario: update (unknown) share with a one-to-one room not invited to + Given user "participant2" creates room "one-to-one room not invited to" + | roomType | 1 | + | invite | participant3 | + And user "participant2" shares "welcome.txt" with room "one-to-one room not invited to" with OCS 100 + When user "participant1" updates last share with + | permissions | 1 | + | expireDate | +3 days | + Then the OCS status code should be "404" + And the HTTP status code should be "200" + And user "participant2" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant2 | + | file_target | /welcome.txt | + | share_with | one-to-one room not invited to | + | share_with_displayname | participant3-displayname | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | one-to-one room not invited to | + | share_with_displayname | participant2-displayname | + + Scenario: update (unknown) share with a group room not invited to + Given user "participant2" creates room "group room not invited to" + | roomType | 2 | + And user "participant2" renames room "group room not invited to" to "Group room not invited to" with 200 + And user "participant2" adds "participant3" to room "group room not invited to" with 200 + And user "participant2" shares "welcome.txt" with room "group room not invited to" with OCS 100 + When user "participant1" updates last share with + | permissions | 1 | + | expireDate | +3 days | + Then the OCS status code should be "404" + And the HTTP status code should be "200" + And user "participant2" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant2 | + | file_target | /welcome.txt | + | share_with | group room not invited to | + | share_with_displayname | Group room not invited to | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room not invited to | + | share_with_displayname | Group room not invited to | + + Scenario: update (unknown) share with a public room not joined to + Given user "participant2" creates room "public room not joined to" + | roomType | 3 | + And user "participant2" renames room "public room not joined to" to "Public room not joined to" with 200 + And user "participant2" adds "participant3" to room "public room not joined to" with 200 + And user "participant2" shares "welcome.txt" with room "public room not joined to" with OCS 100 + When user "participant1" updates last share with + | permissions | 1 | + | expireDate | +3 days | + Then the OCS status code should be "404" + And the HTTP status code should be "200" + And user "participant2" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant2 | + | file_target | /welcome.txt | + | share_with | public room not joined to | + | share_with_displayname | Public room not joined to | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | public room not joined to | + | share_with_displayname | Public room not joined to | + + + + Scenario: update received share with an owned one-to-one room + Given user "participant2" creates room "own one-to-one room" + | roomType | 1 | + | invite | participant1 | + And user "participant1" shares "welcome.txt" with room "own one-to-one room" with OCS 100 + When user "participant2" updates last share with + | permissions | 1 | + | expireDate | +3 days | + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | own one-to-one room | + | share_with_displayname | participant1-displayname | + | permissions | 1 | + | expiration | +3 days | + And user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | own one-to-one room | + | share_with_displayname | participant2-displayname | + | permissions | 1 | + | expiration | +3 days | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | own one-to-one room | + | share_with_displayname | participant1-displayname | + | permissions | 1 | + | expiration | +3 days | + + Scenario: update received share with a one-to-one room invited to + Given user "participant1" creates room "one-to-one room invited to" + | roomType | 1 | + | invite | participant2 | + And user "participant1" shares "welcome.txt" with room "one-to-one room invited to" with OCS 100 + When user "participant2" updates last share with + | permissions | 1 | + | expireDate | +3 days | + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | one-to-one room invited to | + | share_with_displayname | participant1-displayname | + | permissions | 1 | + | expiration | +3 days | + And user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | one-to-one room invited to | + | share_with_displayname | participant2-displayname | + | permissions | 1 | + | expiration | +3 days | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | one-to-one room invited to | + | share_with_displayname | participant1-displayname | + | permissions | 1 | + | expiration | +3 days | + + Scenario: update received share with an owned group room + Given user "participant2" creates room "own group room" + | roomType | 2 | + And user "participant2" renames room "own group room" to "Own group room" with 200 + And user "participant2" adds "participant1" to room "own group room" with 200 + And user "participant1" shares "welcome.txt" with room "own group room" with OCS 100 + When user "participant2" updates last share with + | permissions | 1 | + | expireDate | +3 days | + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | own group room | + | share_with_displayname | Own group room | + | permissions | 1 | + | expiration | +3 days | + And user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | own group room | + | share_with_displayname | Own group room | + | permissions | 1 | + | expiration | +3 days | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | own group room | + | share_with_displayname | Own group room | + | permissions | 1 | + | expiration | +3 days | + + Scenario: update received share with a group room invited to + Given user "participant1" creates room "group room invited to" + | roomType | 2 | + And user "participant1" renames room "group room invited to" to "Group room invited to" with 200 + And user "participant1" adds "participant2" to room "group room invited to" with 200 + And user "participant1" adds "participant3" to room "group room invited to" with 200 + And user "participant1" shares "welcome.txt" with room "group room invited to" with OCS 100 + When user "participant2" updates last share with + | permissions | 1 | + | expireDate | +3 days | + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + | permissions | 1 | + | expiration | +3 days | + And user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + | permissions | 1 | + | expiration | +3 days | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + | permissions | 1 | + | expiration | +3 days | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + | permissions | 1 | + | expiration | +3 days | + + Scenario: update received share with a group room no longer invited to + Given user "participant1" creates room "group room no longer invited to" + | roomType | 2 | + And user "participant1" renames room "group room no longer invited to" to "Group room no longer invited to" with 200 + And user "participant1" adds "participant2" to room "group room no longer invited to" with 200 + And user "participant1" adds "participant3" to room "group room no longer invited to" with 200 + And user "participant1" shares "welcome.txt" with room "group room no longer invited to" with OCS 100 + And user "participant1" removes "participant2" from room "group room no longer invited to" with 200 + When user "participant2" updates last share with + | permissions | 1 | + | expiration | +3 days | + Then the OCS status code should be "404" + And the HTTP status code should be "200" + And user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room no longer invited to | + | share_with_displayname | Group room no longer invited to | + And user "participant2" gets last share + And the OCS status code should be "404" + And the HTTP status code should be "200" + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room no longer invited to | + | share_with_displayname | Group room no longer invited to | + + Scenario: update received share with an owned public room + Given user "participant2" creates room "own public room" + | roomType | 3 | + And user "participant2" renames room "own public room" to "Own public room" with 200 + And user "participant2" adds "participant1" to room "own public room" with 200 + And user "participant3" joins room "own public room" with 200 + And user "participant1" shares "welcome.txt" with room "own public room" with OCS 100 + When user "participant2" updates last share with + | permissions | 1 | + | expireDate | +3 days | + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | own public room | + | share_with_displayname | Own public room | + | permissions | 1 | + | expiration | +3 days | + And user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | own public room | + | share_with_displayname | Own public room | + | permissions | 1 | + | expiration | +3 days | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | own public room | + | share_with_displayname | Own public room | + | permissions | 1 | + | expiration | +3 days | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | own public room | + | share_with_displayname | Own public room | + | permissions | 1 | + | expiration | +3 days | + + Scenario: update received share with a public room invited to + Given user "participant1" creates room "public room invited to" + | roomType | 3 | + And user "participant1" renames room "public room invited to" to "Public room invited to" with 200 + And user "participant1" adds "participant2" to room "public room invited to" with 200 + And user "participant3" joins room "public room invited to" with 200 + And user "participant1" shares "welcome.txt" with room "public room invited to" with OCS 100 + When user "participant2" updates last share with + | permissions | 1 | + | expireDate | +3 days | + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | public room invited to | + | share_with_displayname | Public room invited to | + | permissions | 1 | + | expiration | +3 days | + And user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | public room invited to | + | share_with_displayname | Public room invited to | + | permissions | 1 | + | expiration | +3 days | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | public room invited to | + | share_with_displayname | Public room invited to | + | permissions | 1 | + | expiration | +3 days | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | public room invited to | + | share_with_displayname | Public room invited to | + | permissions | 1 | + | expiration | +3 days | + + Scenario: update received share with a public room self joined to + Given user "participant1" creates room "public room self joined to" + | roomType | 3 | + And user "participant1" renames room "public room self joined to" to "Public room self joined to" with 200 + And user "participant2" joins room "public room self joined to" with 200 + And user "participant3" joins room "public room self joined to" with 200 + And user "participant1" shares "welcome.txt" with room "public room self joined to" with OCS 100 + When user "participant2" updates last share with + | permissions | 1 | + | expireDate | +3 days | + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | public room self joined to | + | share_with_displayname | Public room self joined to | + | permissions | 1 | + | expiration | +3 days | + And user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | public room self joined to | + | share_with_displayname | Public room self joined to | + | permissions | 1 | + | expiration | +3 days | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | public room self joined to | + | share_with_displayname | Public room self joined to | + | permissions | 1 | + | expiration | +3 days | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | public room self joined to | + | share_with_displayname | Public room self joined to | + | permissions | 1 | + | expiration | +3 days | + + Scenario: update received share with a public room no longer joined to + Given user "participant1" creates room "public room no longer joined to" + | roomType | 3 | + And user "participant1" renames room "public room no longer joined to" to "Public room no longer joined to" with 200 + And user "participant2" joins room "public room no longer joined to" with 200 + And user "participant3" joins room "public room no longer joined to" with 200 + And user "participant1" shares "welcome.txt" with room "public room no longer joined to" with OCS 100 + And user "participant2" leaves room "public room no longer joined to" with 200 + When user "participant2" updates last share with + | permissions | 1 | + | expiration | +3 days | + Then the OCS status code should be "404" + And the HTTP status code should be "200" + And user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | public room no longer joined to | + | share_with_displayname | Public room no longer joined to | + And user "participant2" gets last share + And the OCS status code should be "404" + And the HTTP status code should be "200" + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | public room no longer joined to | + | share_with_displayname | Public room no longer joined to | + + + + Scenario: update received share after moving it + Given user "participant1" creates room "group room invited to" + | roomType | 2 | + And user "participant1" renames room "group room invited to" to "Group room invited to" with 200 + And user "participant1" adds "participant2" to room "group room invited to" with 200 + And user "participant1" adds "participant3" to room "group room invited to" with 200 + And user "participant1" shares "welcome.txt" with room "group room invited to" with OCS 100 + And user "participant2" creates folder "/test" + And user "participant2" moves file "/welcome (2).txt" to "/test/renamed.txt" with 201 + When user "participant2" updates last share with + | permissions | 1 | + | expireDate | +3 days | + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /test/renamed.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/test/renamed.txt | + | file_target | /test/renamed.txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + | permissions | 1 | + | expiration | +3 days | + And user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + | permissions | 1 | + | expiration | +3 days | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /test/renamed.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/test/renamed.txt | + | file_target | /test/renamed.txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + | permissions | 1 | + | expiration | +3 days | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + | permissions | 1 | + | expiration | +3 days | + + Scenario: update received share with a room no longer invited to after moving it + Given user "participant1" creates room "group room invited to" + | roomType | 2 | + And user "participant1" renames room "group room invited to" to "Group room invited to" with 200 + And user "participant1" adds "participant2" to room "group room invited to" with 200 + And user "participant1" adds "participant3" to room "group room invited to" with 200 + And user "participant1" shares "welcome.txt" with room "group room invited to" with OCS 100 + And user "participant2" creates folder "/test" + And user "participant2" moves file "/welcome (2).txt" to "/test/renamed.txt" with 201 + And user "participant1" removes "participant2" from room "group room invited to" with 200 + When user "participant2" updates last share with + | permissions | 1 | + | expireDate | +3 days | + Then the OCS status code should be "404" + And the HTTP status code should be "200" + And user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + And user "participant2" gets last share + And the OCS status code should be "404" + And the HTTP status code should be "200" + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + + + + Scenario: update received share with increased permissions + Given user "participant1" creates room "group room invited to" + | roomType | 2 | + And user "participant1" renames room "group room invited to" to "Group room invited to" with 200 + And user "participant1" adds "participant2" to room "group room invited to" with 200 + And user "participant1" shares "welcome.txt" with room "group room invited to" with OCS 100 + And user "participant1" updates last share with + | permissions | 1 | + When user "participant2" updates last share with + | permissions | 19 | + Then the OCS status code should be "404" + And the HTTP status code should be "200" + And user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + | permissions | 1 | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + | permissions | 1 | From 46d755b66cd2ca433aec2694aa4b8e3a174fc623 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Thu, 5 Jul 2018 20:55:24 +0200 Subject: [PATCH 19/43] Add integration tests for moving shares into other shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When an own share is moved into a received shared folder the ownership of the share is handed over to the folder owner. Due to this those tests could not be added until now that updating shares is implemented. Signed-off-by: Daniel Calviño Sánchez --- .../integration/features/sharing/move.feature | 263 ++++++++++++++++++ 1 file changed, 263 insertions(+) diff --git a/tests/integration/features/sharing/move.feature b/tests/integration/features/sharing/move.feature index 472b362292c..3f4e7157959 100644 --- a/tests/integration/features/sharing/move.feature +++ b/tests/integration/features/sharing/move.feature @@ -51,6 +51,163 @@ Feature: move + # When an own share is moved into a received shared folder the ownership of + # the share is handed over to the folder owner. + Scenario: move share to received shared folder from a user in the room + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" adds "participant3" to room "group room" with 200 + And user "participant3" creates folder "/test" + And user "participant3" shares "/test" with user "participant1" with OCS 100 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + When user "participant1" moves file "/welcome.txt" to "/test/renamed.txt" with 201 + Then user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | uid_file_owner | participant3 | + | displayname_file_owner | participant3-displayname | + | path | /test/renamed.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/test | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | uid_file_owner | participant3 | + | displayname_file_owner | participant3-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | uid_file_owner | participant3 | + | displayname_file_owner | participant3-displayname | + | path | /test/renamed.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant3 | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + + Scenario: move share to received shared folder from a user not in the room + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" adds "participant3" to room "group room" with 200 + And user "participant4" creates folder "/test" + And user "participant4" shares "/test" with user "participant1" with OCS 100 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + When user "participant1" moves file "/welcome.txt" to "/test/renamed.txt" with 201 + Then user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | uid_file_owner | participant4 | + | displayname_file_owner | participant4-displayname | + | path | /test/renamed.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/test | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | uid_file_owner | participant4 | + | displayname_file_owner | participant4-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | uid_file_owner | participant4 | + | displayname_file_owner | participant4-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + + Scenario: move share to received shared folder which is also a received shared folder + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant3" creates folder "/test" + And user "participant3" shares "/test" with user "participant4" with OCS 100 + And user "participant4" shares "/test" with user "participant1" with OCS 100 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + When user "participant1" moves file "/welcome.txt" to "/test/renamed.txt" with 201 + Then user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | uid_file_owner | participant3 | + | displayname_file_owner | participant3-displayname | + | path | /test/renamed.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/test | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | uid_file_owner | participant3 | + | displayname_file_owner | participant3-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | uid_file_owner | participant3 | + | displayname_file_owner | participant3-displayname | + | path | /test/renamed.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant3 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant4" gets last share + Then the OCS status code should be "404" + And the HTTP status code should be "200" + + + Scenario: move received share to another folder Given user "participant1" creates room "group room" | roomType | 2 | @@ -93,3 +250,109 @@ Feature: move | file_target | /welcome (2).txt | | share_with | group room | | share_with_displayname | Group room | + + + + # Received shares can not be moved into other shares (general limitation of + # the sharing system, not related to room shares). + Scenario: move received share to shared folder + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" adds "participant3" to room "group room" with 200 + And user "participant3" creates folder "/test" + And user "participant3" shares "/test" with user "participant2" with OCS 100 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + When user "participant3" moves file "/welcome (2).txt" to "/test/renamed.txt" + Then the HTTP status code should be "403" + + # Received shares can be moved into other received shares, though. However, + # they are moved back to the default share folder. + Scenario: move received share to received shared folder from a user in the room + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" adds "participant3" to room "group room" with 200 + And user "participant3" creates folder "/test" + And user "participant3" shares "/test" with user "participant2" with OCS 100 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + When user "participant2" moves file "/welcome (2).txt" to "/test/renamed.txt" + Then user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /renamed.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/renamed.txt | + | file_target | /renamed.txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + + Scenario: move received share to received shared folder from a user not in the room + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" adds "participant3" to room "group room" with 200 + And user "participant4" creates folder "/test" + And user "participant4" shares "/test" with user "participant2" with OCS 100 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + When user "participant2" moves file "/welcome (2).txt" to "/test/renamed.txt" + Then user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /renamed.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/renamed.txt | + | file_target | /renamed.txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | From 1b3fdb14e41db19486729aa7df31b1f7b873397a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Fri, 6 Jul 2018 09:37:11 +0200 Subject: [PATCH 20/43] Implement deleting room shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- lib/Share/RoomShareProvider.php | 35 ++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/lib/Share/RoomShareProvider.php b/lib/Share/RoomShareProvider.php index fbf14a70ce2..0a30bd52a2c 100644 --- a/lib/Share/RoomShareProvider.php +++ b/lib/Share/RoomShareProvider.php @@ -310,7 +310,13 @@ public function update(IShare $share) { * @param IShare $share */ public function delete(IShare $share) { - throw new \Exception("Not implemented"); + $qb = $this->dbConnection->getQueryBuilder(); + $qb->delete('share') + ->where($qb->expr()->eq('id', $qb->createNamedParameter($share->getId()))); + + $qb->orWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId()))); + + $qb->execute(); } /** @@ -708,4 +714,31 @@ public function getAccessList($nodes, $currentAccess) { throw new \Exception("Not implemented"); } + /** + * Get all children of this share + * + * Not part of IShareProvider API, but needed by OC\Share20\Manager. + * + * @param IShare $parent + * @return IShare[] + */ + public function getChildren(IShare $parent) { + $children = []; + + $qb = $this->dbConnection->getQueryBuilder(); + $qb->select('*') + ->from('share') + ->where($qb->expr()->eq('parent', $qb->createNamedParameter($parent->getId()))) + ->andWhere($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_ROOM))) + ->orderBy('id'); + + $cursor = $qb->execute(); + while ($data = $cursor->fetch()) { + $children[] = $this->createShareObject($data); + } + $cursor->closeCursor(); + + return $children; + } + } From 4fe537d31ac853096343f3bc30bf8c3d15630adf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Fri, 6 Jul 2018 12:17:08 +0200 Subject: [PATCH 21/43] Add integration tests for deleting shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- .../features/bootstrap/SharingContext.php | 24 ++ .../features/sharing/delete.feature | 251 ++++++++++++++++++ 2 files changed, 275 insertions(+) create mode 100644 tests/integration/features/sharing/delete.feature diff --git a/tests/integration/features/bootstrap/SharingContext.php b/tests/integration/features/bootstrap/SharingContext.php index d792aa194b4..951933268f5 100644 --- a/tests/integration/features/bootstrap/SharingContext.php +++ b/tests/integration/features/bootstrap/SharingContext.php @@ -166,6 +166,30 @@ public function userUpdatesLastShareWith(string $user, TableNode $body) { $this->sendingTo('PUT', $url, $body); } + /** + * @When user :user deletes last share + * + * @param string $user + */ + public function userDeletesLastShare(string $user) { + $this->currentUser = $user; + + $url = '/apps/files_sharing/api/v1/shares/' . $this->getLastShareId(); + + $this->sendingTo('DELETE', $url); + } + + /** + * @When user :user deletes last share with OCS :statusCode + * + * @param string $user + * @param int $statusCode + */ + public function userDeletesLastShareWithOcs(string $user, int $statusCode) { + $this->userDeletesLastShare($user); + $this->theOCSStatusCodeShouldBe($statusCode); + } + /** * @When user :user gets last share */ diff --git a/tests/integration/features/sharing/delete.feature b/tests/integration/features/sharing/delete.feature new file mode 100644 index 00000000000..818b4a849f9 --- /dev/null +++ b/tests/integration/features/sharing/delete.feature @@ -0,0 +1,251 @@ +Feature: delete + + Background: + Given user "participant1" exists + Given user "participant2" exists + Given user "participant3" exists + + Scenario: delete share with an owned one-to-one room + Given user "participant1" creates room "own one-to-one room" + | roomType | 1 | + | invite | participant2 | + And user "participant1" shares "welcome.txt" with room "own one-to-one room" with OCS 100 + When user "participant1" deletes last share + Then the OCS status code should be "100" + And the HTTP status code should be "200" + And user "participant1" gets last share + And the OCS status code should be "404" + And user "participant2" gets last share + And the OCS status code should be "404" + + Scenario: delete share with a one-to-one room invited to + Given user "participant2" creates room "one-to-one room invited to" + | roomType | 1 | + | invite | participant1 | + And user "participant1" shares "welcome.txt" with room "one-to-one room invited to" with OCS 100 + When user "participant1" deletes last share + Then the OCS status code should be "100" + And the HTTP status code should be "200" + And user "participant1" gets last share + And the OCS status code should be "404" + And user "participant2" gets last share + And the OCS status code should be "404" + + Scenario: delete share with an owned group room + Given user "participant1" creates room "own group room" + | roomType | 2 | + And user "participant1" adds "participant2" to room "own group room" with 200 + And user "participant1" shares "welcome.txt" with room "own group room" with OCS 100 + When user "participant1" deletes last share + Then the OCS status code should be "100" + And the HTTP status code should be "200" + And user "participant1" gets last share + And the OCS status code should be "404" + And user "participant2" gets last share + And the OCS status code should be "404" + + Scenario: delete share with a group room invited to + Given user "participant2" creates room "group room invited to" + | roomType | 2 | + And user "participant2" adds "participant1" to room "group room invited to" with 200 + And user "participant1" shares "welcome.txt" with room "group room invited to" with OCS 100 + When user "participant1" deletes last share + Then the OCS status code should be "100" + And the HTTP status code should be "200" + And user "participant1" gets last share + And the OCS status code should be "404" + And user "participant2" gets last share + And the OCS status code should be "404" + + Scenario: delete share with an owned public room + Given user "participant1" creates room "own public room" + | roomType | 3 | + And user "participant1" adds "participant2" to room "own public room" with 200 + And user "participant3" joins room "own public room" with 200 + And user "participant1" shares "welcome.txt" with room "own public room" with OCS 100 + When user "participant1" deletes last share + Then the OCS status code should be "100" + And the HTTP status code should be "200" + And user "participant1" gets last share + And the OCS status code should be "404" + And user "participant2" gets last share + And the OCS status code should be "404" + And user "participant3" gets last share + And the OCS status code should be "404" + + Scenario: delete share with a public room invited to + Given user "participant2" creates room "public room invited to" + | roomType | 3 | + And user "participant2" adds "participant1" to room "public room invited to" with 200 + And user "participant3" joins room "public room invited to" with 200 + And user "participant1" shares "welcome.txt" with room "public room invited to" with OCS 100 + When user "participant1" deletes last share + Then the OCS status code should be "100" + And the HTTP status code should be "200" + And user "participant1" gets last share + And the OCS status code should be "404" + And user "participant2" gets last share + And the OCS status code should be "404" + And user "participant3" gets last share + And the OCS status code should be "404" + + Scenario: delete share with a public room self joined to + Given user "participant2" creates room "public room self joined to" + | roomType | 3 | + And user "participant1" joins room "public room self joined to" with 200 + And user "participant3" joins room "public room self joined to" with 200 + And user "participant1" shares "welcome.txt" with room "public room self joined to" with OCS 100 + When user "participant1" deletes last share + Then the OCS status code should be "100" + And the HTTP status code should be "200" + And user "participant1" gets last share + And the OCS status code should be "404" + And user "participant2" gets last share + And the OCS status code should be "404" + And user "participant3" gets last share + And the OCS status code should be "404" + + + + Scenario: delete (unknown) share with a one-to-one room not invited to + Given user "participant2" creates room "one-to-one room not invited to" + | roomType | 1 | + | invite | participant3 | + And user "participant2" shares "welcome.txt" with room "one-to-one room not invited to" with OCS 100 + When user "participant1" deletes last share + Then the OCS status code should be "404" + And the HTTP status code should be "200" + And user "participant2" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant2 | + | file_target | /welcome.txt | + | share_with | one-to-one room not invited to | + | share_with_displayname | participant3-displayname | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | one-to-one room not invited to | + | share_with_displayname | participant2-displayname | + + Scenario: delete (unknown) share with a group room not invited to + Given user "participant2" creates room "group room not invited to" + | roomType | 2 | + And user "participant2" renames room "group room not invited to" to "Group room not invited to" with 200 + And user "participant2" adds "participant3" to room "group room not invited to" with 200 + And user "participant2" shares "welcome.txt" with room "group room not invited to" with OCS 100 + When user "participant1" deletes last share + Then the OCS status code should be "404" + And the HTTP status code should be "200" + And user "participant2" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant2 | + | file_target | /welcome.txt | + | share_with | group room not invited to | + | share_with_displayname | Group room not invited to | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room not invited to | + | share_with_displayname | Group room not invited to | + + Scenario: delete (unknown) share with a public room not joined to + Given user "participant2" creates room "public room not joined to" + | roomType | 3 | + And user "participant2" renames room "public room not joined to" to "Public room not joined to" with 200 + And user "participant2" adds "participant3" to room "public room not joined to" with 200 + And user "participant2" shares "welcome.txt" with room "public room not joined to" with OCS 100 + When user "participant1" deletes last share + Then the OCS status code should be "404" + And the HTTP status code should be "200" + And user "participant2" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant2 | + | file_target | /welcome.txt | + | share_with | public room not joined to | + | share_with_displayname | Public room not joined to | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | public room not joined to | + | share_with_displayname | Public room not joined to | + + + + Scenario: delete share with a user who also received that share through a room + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant1" shares "welcome.txt" with user "participant2" with OCS 100 + When user "participant1" deletes last share + Then the OCS status code should be "100" + And the HTTP status code should be "200" + And user "participant2" gets all received shares + And the list of returned shares has 1 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + + Scenario: delete share with a room including a user who also received that share directly + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with user "participant2" with OCS 100 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + When user "participant1" deletes last share + Then the OCS status code should be "100" + And the HTTP status code should be "200" + And user "participant2" gets all received shares + And the list of returned shares has 1 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | participant2 | + | share_with_displayname | participant2-displayname | + | share_type | 0 | From dfa6e26a70192a4ffa174d9ffe1e3b5755d67139 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Fri, 6 Jul 2018 12:47:22 +0200 Subject: [PATCH 22/43] Implement deleting received room shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- lib/Share/RoomShareProvider.php | 42 ++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/lib/Share/RoomShareProvider.php b/lib/Share/RoomShareProvider.php index 0a30bd52a2c..f3cddfdab76 100644 --- a/lib/Share/RoomShareProvider.php +++ b/lib/Share/RoomShareProvider.php @@ -329,7 +329,47 @@ public function delete(IShare $share) { * @param string $recipient UserId of the recipient */ public function deleteFromSelf(IShare $share, $recipient) { - throw new \Exception("Not implemented"); + // Check if there is a userroom share + $qb = $this->dbConnection->getQueryBuilder(); + $stmt = $qb->select(['id', 'permissions']) + ->from('share') + ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERROOM))) + ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($recipient))) + ->andWhere($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId()))) + ->andWhere($qb->expr()->orX( + $qb->expr()->eq('item_type', $qb->createNamedParameter('file')), + $qb->expr()->eq('item_type', $qb->createNamedParameter('folder')) + )) + ->execute(); + + $data = $stmt->fetch(); + $stmt->closeCursor(); + + if ($data === false) { + // No userroom share yet. Create one. + $qb = $this->dbConnection->getQueryBuilder(); + $qb->insert('share') + ->values([ + 'share_type' => $qb->createNamedParameter(self::SHARE_TYPE_USERROOM), + 'share_with' => $qb->createNamedParameter($recipient), + 'uid_owner' => $qb->createNamedParameter($share->getShareOwner()), + 'uid_initiator' => $qb->createNamedParameter($share->getSharedBy()), + 'parent' => $qb->createNamedParameter($share->getId()), + 'item_type' => $qb->createNamedParameter($share->getNodeType()), + 'item_source' => $qb->createNamedParameter($share->getNodeId()), + 'file_source' => $qb->createNamedParameter($share->getNodeId()), + 'file_target' => $qb->createNamedParameter($share->getTarget()), + 'permissions' => $qb->createNamedParameter(0), + 'stime' => $qb->createNamedParameter($share->getShareTime()->getTimestamp()), + ])->execute(); + } else if ($data['permissions'] !== 0) { + // Already a userroom share. Update it. + $qb = $this->dbConnection->getQueryBuilder(); + $qb->update('share') + ->set('permissions', $qb->createNamedParameter(0)) + ->where($qb->expr()->eq('id', $qb->createNamedParameter($data['id']))) + ->execute(); + } } /** From bdf09a300eabef11f73f25a6125e0c067fef1b62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Fri, 6 Jul 2018 14:26:33 +0200 Subject: [PATCH 23/43] Add integration tests for deleting received room shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- .../features/sharing/delete.feature | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) diff --git a/tests/integration/features/sharing/delete.feature b/tests/integration/features/sharing/delete.feature index 818b4a849f9..527796c0628 100644 --- a/tests/integration/features/sharing/delete.feature +++ b/tests/integration/features/sharing/delete.feature @@ -249,3 +249,91 @@ Feature: delete | share_with | participant2 | | share_with_displayname | participant2-displayname | | share_type | 0 | + + + + Scenario: delete received share + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" adds "participant3" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + When user "participant2" deletes last share + Then the OCS status code should be "100" + And the HTTP status code should be "200" + And user "participant2" gets last share + And the OCS status code should be "404" + And user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + + + + Scenario: delete share received directly and through a room + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" adds "participant3" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with user "participant2" with OCS 100 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + When user "participant2" deletes last share + Then the OCS status code should be "100" + And the HTTP status code should be "200" + And user "participant2" gets last share + And the OCS status code should be "404" + And user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant2" gets all received shares + And the list of returned shares has 1 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | participant2 | + | share_with_displayname | participant2-displayname | + | share_type | 0 | From 836e4541a8f8de5e01cd141a9efe2fcb4b6b694e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Fri, 6 Jul 2018 15:16:17 +0200 Subject: [PATCH 24/43] Add integration tests for getting expired shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When an expierd share is got that share is deleted. Due to this these tests could not be added until now that deleting shares is implemented. Signed-off-by: Daniel Calviño Sánchez --- .../integration/features/sharing/get.feature | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/tests/integration/features/sharing/get.feature b/tests/integration/features/sharing/get.feature index 3fed205d2df..346bf1367d1 100644 --- a/tests/integration/features/sharing/get.feature +++ b/tests/integration/features/sharing/get.feature @@ -88,6 +88,60 @@ Feature: get + Scenario: get an expired share + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" + | expireDate | -3 days | + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + | expiration | -3 days | + When user "participant1" gets last share + Then the OCS status code should be "404" + And the HTTP status code should be "200" + And user "participant2" gets last share + And the OCS status code should be "404" + And the HTTP status code should be "200" + + Scenario: get an expired share moved by the sharee + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant2" moves file "/welcome (2).txt" to "/renamed.txt" with 201 + And user "participant1" updates last share with + | expireDate | -3 days | + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + | expiration | -3 days | + When user "participant1" gets last share + Then the OCS status code should be "404" + And the HTTP status code should be "200" + And user "participant2" gets last share + And the OCS status code should be "404" + And the HTTP status code should be "200" + + + Scenario: get all shares of a user Given user "participant1" creates room "own group room" | roomType | 2 | From 8fb35e05dcb3d337946a15405ecf391f01f533a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Fri, 6 Jul 2018 15:56:29 +0200 Subject: [PATCH 25/43] Add integration tests for updating a deleted share MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- .../features/sharing/update.feature | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/tests/integration/features/sharing/update.feature b/tests/integration/features/sharing/update.feature index b72a85b3f27..d861380dedf 100644 --- a/tests/integration/features/sharing/update.feature +++ b/tests/integration/features/sharing/update.feature @@ -1099,3 +1099,69 @@ Feature: update | share_with | group room invited to | | share_with_displayname | Group room invited to | | permissions | 1 | + + + + Scenario: update share after sharee deleted it + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant2" deletes last share with OCS 100 + When user "participant1" updates last share with + | permissions | 1 | + | expireDate | +3 days | + Then share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + | permissions | 1 | + | expiration | +3 days | + And user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + | permissions | 1 | + | expiration | +3 days | + And user "participant2" gets last share + And the OCS status code should be "404" + + Scenario: update received share after deleting it + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant2" deletes last share with OCS 100 + When user "participant2" updates last share with + | permissions | 1 | + | expireDate | +3 days | + Then the OCS status code should be "404" + And the HTTP status code should be "200" + And user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant2" gets last share + And the OCS status code should be "404" From ce162a50ae91664630c5ab22cdd3c6bd5430b75b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Sun, 15 Jul 2018 21:39:19 +0200 Subject: [PATCH 26/43] Implement restoring deleted room shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- lib/Share/RoomShareProvider.php | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/lib/Share/RoomShareProvider.php b/lib/Share/RoomShareProvider.php index f3cddfdab76..6ddd1df79f7 100644 --- a/lib/Share/RoomShareProvider.php +++ b/lib/Share/RoomShareProvider.php @@ -381,7 +381,32 @@ public function deleteFromSelf(IShare $share, $recipient) { * @throws GenericShareException In case the share could not be restored */ public function restore(IShare $share, string $recipient): IShare { - throw new \Exception("Not implemented"); + $qb = $this->dbConnection->getQueryBuilder(); + $qb->select('permissions') + ->from('share') + ->where( + $qb->expr()->eq('id', $qb->createNamedParameter($share->getId())) + ); + $cursor = $qb->execute(); + $data = $cursor->fetch(); + $cursor->closeCursor(); + + $originalPermission = $data['permissions']; + + $qb = $this->dbConnection->getQueryBuilder(); + $qb->update('share') + ->set('permissions', $qb->createNamedParameter($originalPermission)) + ->where( + $qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())) + )->andWhere( + $qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERROOM)) + )->andWhere( + $qb->expr()->eq('share_with', $qb->createNamedParameter($recipient)) + ); + + $qb->execute(); + + return $this->getShareById($share->getId(), $recipient); } /** From 4cfded458d0cbf04283c24a7315f18459894d46a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Sun, 15 Jul 2018 21:41:06 +0200 Subject: [PATCH 27/43] Add integration tests for getting deleted room shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- .../features/bootstrap/SharingContext.php | 17 ++++++++ .../integration/features/sharing/get.feature | 41 +++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/tests/integration/features/bootstrap/SharingContext.php b/tests/integration/features/bootstrap/SharingContext.php index 951933268f5..46c5c3b7b5b 100644 --- a/tests/integration/features/bootstrap/SharingContext.php +++ b/tests/integration/features/bootstrap/SharingContext.php @@ -296,6 +296,19 @@ public function userGetsAllReceivedSharesFor(string $user, string $path) { $this->sendingTo('GET', $url); } + /** + * @When user :user gets deleted shares + * + * @param string $user + */ + public function userGetsDeletedShares(string $user) { + $this->currentUser = $user; + + $url = '/apps/files_sharing/api/v1/deletedshares'; + + $this->sendingTo('GET', $url); + } + /** * @Then the OCS status code should be :statusCode * @@ -509,6 +522,10 @@ private function getXmlResponse(): \SimpleXMLElement { * @param \SimpleXMLElement $returnedShare */ private function assertFieldIsInReturnedShare(string $field, string $contentExpected, \SimpleXMLElement $returnedShare){ + if ($contentExpected === 'IGNORE') { + return; + } + if (!array_key_exists($field, $returnedShare)) { PHPUnit_Framework_Assert::fail("$field was not found in response"); } diff --git a/tests/integration/features/sharing/get.feature b/tests/integration/features/sharing/get.feature index 346bf1367d1..1b3718a9680 100644 --- a/tests/integration/features/sharing/get.feature +++ b/tests/integration/features/sharing/get.feature @@ -578,3 +578,44 @@ Feature: get | file_target | /welcome (2).txt | | share_with | group room invited to | | share_with_displayname | Group room invited to | + + + + Scenario: get deleted shares when deleting an own share + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant1" deletes last share + When user "participant1" gets deleted shares + Then the list of returned shares has 0 shares + And user "participant2" gets deleted shares + And the list of returned shares has 0 shares + + Scenario: get deleted shares when deleting a received share + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" adds "participant3" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant2" deletes last share + When user "participant2" gets deleted shares + Then the list of returned shares has 1 shares + And share 0 is returned with + | id | REGEXP /ocRoomShare:[0-9]+/ | + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + | permissions | 0 | + | mail_send | IGNORE | + And user "participant1" gets deleted shares + And the list of returned shares has 0 shares + And user "participant3" gets deleted shares + And the list of returned shares has 0 shares From 452e2f113c6d8841b8e033975c08732c77667ae3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Sun, 15 Jul 2018 21:42:10 +0200 Subject: [PATCH 28/43] Add integration tests for restoring deleted room shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- .../features/bootstrap/SharingContext.php | 13 ++ .../features/sharing/restore.feature | 153 ++++++++++++++++++ 2 files changed, 166 insertions(+) create mode 100644 tests/integration/features/sharing/restore.feature diff --git a/tests/integration/features/bootstrap/SharingContext.php b/tests/integration/features/bootstrap/SharingContext.php index 46c5c3b7b5b..cd466d186c5 100644 --- a/tests/integration/features/bootstrap/SharingContext.php +++ b/tests/integration/features/bootstrap/SharingContext.php @@ -190,6 +190,19 @@ public function userDeletesLastShareWithOcs(string $user, int $statusCode) { $this->theOCSStatusCodeShouldBe($statusCode); } + /** + * @When user :user restores last share + * + * @param string $user + */ + public function userRestoresLastShareWithOcs(string $user) { + $this->currentUser = $user; + + $url = '/apps/files_sharing/api/v1/deletedshares/ocRoomShare:' . $this->getLastShareId(); + + $this->sendingTo('POST', $url); + } + /** * @When user :user gets last share */ diff --git a/tests/integration/features/sharing/restore.feature b/tests/integration/features/sharing/restore.feature new file mode 100644 index 00000000000..295ca41ed02 --- /dev/null +++ b/tests/integration/features/sharing/restore.feature @@ -0,0 +1,153 @@ +Feature: delete + + Background: + Given user "participant1" exists + Given user "participant2" exists + Given user "participant3" exists + + Scenario: restore deleted share + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" adds "participant3" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant2" deletes last share + When user "participant2" restores last share + Then the OCS status code should be "100" + And the HTTP status code should be "200" + And user "participant2" gets deleted shares + And the list of returned shares has 0 shares + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + + Scenario: restore share deleted after moving it + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" adds "participant3" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant2" moves file "/welcome (2).txt" to "/renamed.txt" with 201 + And user "participant2" deletes last share + When user "participant2" restores last share + Then the OCS status code should be "100" + And the HTTP status code should be "200" + And user "participant2" gets deleted shares + And the list of returned shares has 0 shares + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /renamed.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/renamed.txt | + | file_target | /renamed.txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + + Scenario: restore deleted share after owner updated it + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" adds "participant3" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant2" deletes last share + And user "participant1" updates last share with + | permissions | 1 | + When user "participant2" restores last share + Then the OCS status code should be "100" + And the HTTP status code should be "200" + And user "participant2" gets deleted shares + And the list of returned shares has 0 shares + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + | permissions | 1 | + And user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + | permissions | 1 | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + | permissions | 1 | From 19186045f5f0177b19a65956b43c2d516dbc37ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Fri, 6 Jul 2018 18:01:12 +0200 Subject: [PATCH 29/43] Implement hooks for deleting shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a user is removed from a room by any means all the shares owned and received by that user are removed. When a room is deleted all the shares in that room are deleted. Signed-off-by: Daniel Calviño Sánchez --- lib/AppInfo/Application.php | 36 ++++++++++++++ lib/Share/RoomShareProvider.php | 86 +++++++++++++++++++++++++++++++-- 2 files changed, 119 insertions(+), 3 deletions(-) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 654b6e7dd2e..4b97a4945ce 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -29,6 +29,7 @@ use OCA\Spreed\GuestManager; use OCA\Spreed\HookListener; use OCA\Spreed\Notification\Notifier; +use OCA\Spreed\Participant; use OCA\Spreed\Room; use OCA\Spreed\Settings\Personal; use OCA\Spreed\Signaling\BackendNotifier; @@ -70,6 +71,7 @@ public function register() { $this->registerRoomInvitationHook($dispatcher); $this->registerCallNotificationHook($dispatcher); $this->registerChatHooks($dispatcher); + $this->registerRoomHooks($dispatcher); $this->registerClientLinks($server); /** @var Listener $systemMessageListener */ @@ -321,4 +323,38 @@ protected function registerChatHooks(EventDispatcherInterface $dispatcher) { }; $dispatcher->addListener(Room::class . '::postDeleteRoom', $listener); } + + protected function registerRoomHooks(EventDispatcherInterface $dispatcher) { + $listener = function(GenericEvent $event) { + /** @var Room $room */ + $room = $event->getSubject(); + + if ($event->getArgument('selfJoin')) { + /** @var \OCA\Spreed\Share\RoomShareProvider $roomShareProvider */ + $roomShareProvider = $this->getContainer()->query(\OCA\Spreed\Share\RoomShareProvider::class); + $roomShareProvider->deleteInRoom($room->getToken(), $event->getArgument('userId')); + } + }; + $dispatcher->addListener(Room::class . '::postUserDisconnectRoom', $listener); + + $listener = function(GenericEvent $event) { + /** @var Room $room */ + $room = $event->getSubject(); + + /** @var \OCA\Spreed\Share\RoomShareProvider $roomShareProvider */ + $roomShareProvider = $this->getContainer()->query(\OCA\Spreed\Share\RoomShareProvider::class); + $roomShareProvider->deleteInRoom($room->getToken(), $event->getArgument('user')->getUID()); + }; + $dispatcher->addListener(Room::class . '::postRemoveUser', $listener); + + $listener = function(GenericEvent $event) { + /** @var Room $room */ + $room = $event->getSubject(); + + /** @var \OCA\Spreed\Share\RoomShareProvider $roomShareProvider */ + $roomShareProvider = $this->getContainer()->query(\OCA\Spreed\Share\RoomShareProvider::class); + $roomShareProvider->deleteInRoom($room->getToken()); + }; + $dispatcher->addListener(Room::class . '::postDeleteRoom', $listener); + } } diff --git a/lib/Share/RoomShareProvider.php b/lib/Share/RoomShareProvider.php index 6ddd1df79f7..724fc30e89a 100644 --- a/lib/Share/RoomShareProvider.php +++ b/lib/Share/RoomShareProvider.php @@ -740,7 +740,8 @@ public function getShareByToken($token) { * @param int $shareType */ public function userDeleted($uid, $shareType) { - throw new \Exception("Not implemented"); + // A deleted user is handled automatically by the room hooks due to the + // user being removed from the room. } /** @@ -751,7 +752,6 @@ public function userDeleted($uid, $shareType) { * @param string $gid */ public function groupDeleted($gid) { - throw new \Exception("Not implemented"); } /** @@ -763,7 +763,6 @@ public function groupDeleted($gid) { * @param string $gid */ public function userDeletedFromGroup($uid, $gid) { - throw new \Exception("Not implemented"); } /** @@ -806,4 +805,85 @@ public function getChildren(IShare $parent) { return $children; } + /** + * Delete all shares in a room, or only those from the given user. + * + * When a user is given all her shares are removed, both own shares and + * received shares. + * + * Not part of IShareProvider API, but needed by the hooks in + * OCA\Spreed\AppInfo\Application + * + * @param string $roomToken + * @param string|null $user + */ + public function deleteInRoom(string $roomToken, string $user = null) { + //First delete all custom room shares for the original shares to be removed + $qb = $this->dbConnection->getQueryBuilder(); + $qb->select('id') + ->from('share') + ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_ROOM))) + ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($roomToken))); + + if ($user !== null) { + $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($user))); + } + + $cursor = $qb->execute(); + $ids = []; + while($row = $cursor->fetch()) { + $ids[] = (int)$row['id']; + } + $cursor->closeCursor(); + + if (!empty($ids)) { + $chunks = array_chunk($ids, 100); + foreach ($chunks as $chunk) { + $qb->delete('share') + ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERROOM))) + ->andWhere($qb->expr()->in('parent', $qb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY))); + $qb->execute(); + } + } + + // Now delete all the original room shares + $qb = $this->dbConnection->getQueryBuilder(); + $qb->delete('share') + ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_ROOM))) + ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($roomToken))); + + if ($user !== null) { + $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($user))); + } + + $qb->execute(); + + // Finally delete all custom room shares leftovers for the given user + if ($user !== null) { + $qb = $this->dbConnection->getQueryBuilder(); + $qb->select('id') + ->from('share') + ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_ROOM))) + ->andWhere($qb->expr()->eq('share_with', $qb->createNamedParameter($roomToken))); + + $cursor = $qb->execute(); + $ids = []; + while($row = $cursor->fetch()) { + $ids[] = (int)$row['id']; + } + $cursor->closeCursor(); + + if (!empty($ids)) { + $chunks = array_chunk($ids, 100); + foreach ($chunks as $chunk) { + $qb->delete('share') + ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERROOM))) + ->andWhere($qb->expr()->in('share_with', $qb->createNamedParameter($user))) + ->andWhere($qb->expr()->in('parent', $qb->createNamedParameter($chunk, IQueryBuilder::PARAM_INT_ARRAY))); + $qb->execute(); + } + } + } + } + } From 4dd51ccf923855006ce87245da6bbd1af2e22837 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Fri, 6 Jul 2018 21:12:55 +0200 Subject: [PATCH 30/43] Add integration tests for room shares when removing participants MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- .../features/sharing/hooks.feature | 421 ++++++++++++++++++ 1 file changed, 421 insertions(+) create mode 100644 tests/integration/features/sharing/hooks.feature diff --git a/tests/integration/features/sharing/hooks.feature b/tests/integration/features/sharing/hooks.feature new file mode 100644 index 00000000000..ede30208ec7 --- /dev/null +++ b/tests/integration/features/sharing/hooks.feature @@ -0,0 +1,421 @@ +Feature: hooks + + Background: + Given user "participant1" exists + Given user "participant2" exists + Given user "participant3" exists + Given user "participant4" exists + + # Entering a room does not really require any hook to work, but conceptually + # these tests belong here. + Scenario: invite user to group room after a file was shared + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + When user "participant1" adds "participant2" to room "group room" with 200 + Then user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + + Scenario: join public room after a file was shared + Given user "participant1" creates room "public room" + | roomType | 3 | + And user "participant1" renames room "public room" to "Public room" with 200 + And user "participant1" shares "welcome.txt" with room "public room" with OCS 100 + And user "participant2" joins room "public room" with 200 + Then user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | public room | + | share_with_displayname | Public room | + + + + Scenario: remove sharer from group room after sharing a file + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant2" shares "welcome.txt" with room "group room" with OCS 100 + When user "participant1" removes "participant2" from room "group room" with 200 + Then user "participant1" gets last share + And the OCS status code should be "404" + And user "participant2" gets last share + And the OCS status code should be "404" + + Scenario: remove herself from group room after sharing a file + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant2" shares "welcome.txt" with room "group room" with OCS 100 + When user "participant2" removes themselves from room "group room" with 200 + Then user "participant1" gets last share + And the OCS status code should be "404" + And user "participant2" gets last share + And the OCS status code should be "404" + + Scenario: leave group room after sharing a file + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant2" shares "welcome.txt" with room "group room" with OCS 100 + When user "participant2" leaves room "group room" with 200 + Then user "participant1" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant2 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + + Scenario: leave public room invited to after sharing a file + Given user "participant1" creates room "public room" + | roomType | 3 | + And user "participant1" renames room "public room" to "Public room" with 200 + And user "participant1" adds "participant2" to room "public room" with 200 + And user "participant2" shares "welcome.txt" with room "public room" with OCS 100 + When user "participant2" leaves room "public room" with 200 + Then user "participant1" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | public room | + | share_with_displayname | Public room | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant2 | + | file_target | /welcome.txt | + | share_with | public room | + | share_with_displayname | Public room | + + Scenario: leave public room self joined to after sharing a file + Given user "participant1" creates room "public room" + | roomType | 3 | + And user "participant2" joins room "public room" with 200 + And user "participant2" shares "welcome.txt" with room "public room" with OCS 100 + When user "participant2" leaves room "public room" with 200 + Then user "participant1" gets last share + And the OCS status code should be "404" + And user "participant2" gets last share + And the OCS status code should be "404" + + Scenario: remove sharer from group room with other shares after sharing a file + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" creates folder "test" + And user "participant1" shares "test" with room "group room" with OCS 100 + And user "participant2" shares "welcome.txt" with room "group room" with OCS 100 + When user "participant1" removes "participant2" from room "group room" with 200 + Then user "participant1" gets last share + And the OCS status code should be "404" + And user "participant2" gets last share + And the OCS status code should be "404" + And user "participant1" gets all shares + And the list of returned shares has 1 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | uid_file_owner | participant1 | + | displayname_file_owner | participant1-displayname | + | path | /test | + | item_type | folder | + | mimetype | httpd/unix-directory | + | storage_id | home::participant1 | + | file_target | /test | + | share_with | group room | + | share_with_displayname | Group room | + | permissions | 31 | + + + + Scenario: remove sharer from group room after sharing a file and a receiver reshared it + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant2" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant1" shares "welcome (2).txt" with user "participant3" with OCS 100 + When user "participant1" removes "participant2" from room "group room" with 200 + Then user "participant1" gets last share + And the OCS status code should be "404" + And user "participant1" gets all shares + And the list of returned shares has 0 shares + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | uid_file_owner | participant2 | + | displayname_file_owner | participant2-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant2 | + | file_target | /welcome (2).txt | + | share_with | participant3 | + | share_with_displayname | participant3-displayname | + | share_type | 0 | + And user "participant2" gets all shares + And the list of returned shares has 0 shares + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | uid_file_owner | participant2 | + | displayname_file_owner | participant2-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | participant3 | + | share_with_displayname | participant3-displayname | + | share_type | 0 | + + + + Scenario: remove sharee from group room after a file was shared + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + When user "participant1" removes "participant2" from room "group room" with 200 + Then user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant2" gets last share + And the OCS status code should be "404" + + Scenario: remove sharee from group room after a file was shared and the sharee moved it + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant2" moves file "welcome (2).txt" to "renamed.txt" + When user "participant1" removes "participant2" from room "group room" with 200 + Then user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant2" gets last share + And the OCS status code should be "404" + + Scenario: remove herself from group room after a file was shared + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + When user "participant2" removes themselves from room "group room" with 200 + Then user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant2" gets last share + And the OCS status code should be "404" + + Scenario: remove herself from group room after a file was shared and the sharee moved it + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant2" moves file "welcome (2).txt" to "renamed.txt" + When user "participant2" removes themselves from room "group room" with 200 + Then user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant2" gets last share + And the OCS status code should be "404" + + Scenario: leave public room self joined to after a file was shared + Given user "participant1" creates room "public room" + | roomType | 3 | + And user "participant1" renames room "public room" to "Public room" with 200 + And user "participant2" joins room "public room" with 200 + And user "participant1" shares "welcome.txt" with room "public room" with OCS 100 + When user "participant2" leaves room "public room" with 200 + Then user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | public room | + | share_with_displayname | Public room | + And user "participant2" gets last share + And the OCS status code should be "404" + + Scenario: leave public room self joined to after a file was shared and the sharee moved it + Given user "participant1" creates room "public room" + | roomType | 3 | + And user "participant1" renames room "public room" to "Public room" with 200 + And user "participant2" joins room "public room" with 200 + And user "participant1" shares "welcome.txt" with room "public room" with OCS 100 + And user "participant2" moves file "welcome (2).txt" to "renamed.txt" + When user "participant2" leaves room "public room" with 200 + Then user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | public room | + | share_with_displayname | Public room | + And user "participant2" gets last share + And the OCS status code should be "404" + + Scenario: remove sharee from group room with other sharees after a file was shared and the sharees moved it + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" adds "participant3" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant2" moves file "welcome (2).txt" to "renamed.txt" + And user "participant3" moves file "welcome (2).txt" to "renamed too.txt" + When user "participant1" removes "participant2" from room "group room" with 200 + Then user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant2" gets last share + And the OCS status code should be "404" + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /renamed too.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/renamed too.txt | + | file_target | /renamed too.txt | + | share_with | group room | + | share_with_displayname | Group room | + + + + Scenario: remove sharee from group room after a file was shared and the sharee reshared it + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant2" shares "welcome (2).txt" with user "participant3" with OCS 100 + When user "participant1" removes "participant2" from room "group room" with 200 + Then user "participant1" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | uid_file_owner | participant1 | + | displayname_file_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome (2).txt | + | share_with | participant3 | + | share_with_displayname | participant3-displayname | + | share_type | 0 | + And user "participant2" gets last share + And the OCS status code should be "404" + And user "participant2" gets all shares + And the list of returned shares has 0 shares + And user "participant3" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | uid_file_owner | participant1 | + | displayname_file_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | participant3 | + | share_with_displayname | participant3-displayname | + | share_type | 0 | From 8e55f0b37148281d6cdd6f9def73a0996a4b4db7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Fri, 6 Jul 2018 22:26:15 +0200 Subject: [PATCH 31/43] Add integration tests for room shares when adding participants back MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- .../features/sharing/hooks.feature | 267 ++++++++++++++++++ 1 file changed, 267 insertions(+) diff --git a/tests/integration/features/sharing/hooks.feature b/tests/integration/features/sharing/hooks.feature index ede30208ec7..2aa7aa35c5b 100644 --- a/tests/integration/features/sharing/hooks.feature +++ b/tests/integration/features/sharing/hooks.feature @@ -419,3 +419,270 @@ Feature: hooks | share_with | participant3 | | share_with_displayname | participant3-displayname | | share_type | 0 | + + + + Scenario: add sharer again to group room after sharing a file and the sharer was removed from the room + Given user "participant2" creates room "group room" + | roomType | 2 | + And user "participant2" adds "participant1" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant2" removes "participant1" from room "group room" with 200 + When user "participant2" adds "participant1" to room "group room" with 200 + Then user "participant1" gets all shares + And the list of returned shares has 0 shares + And user "participant2" gets all received shares + And the list of returned shares has 0 shares + + Scenario: add sharer again to group room after sharing a file and the sharer removed herself from the room + Given user "participant2" creates room "group room" + | roomType | 2 | + And user "participant2" adds "participant1" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant1" removes themselves from room "group room" with 200 + When user "participant2" adds "participant1" to room "group room" with 200 + Then user "participant1" gets all shares + And the list of returned shares has 0 shares + And user "participant2" gets all received shares + And the list of returned shares has 0 shares + + Scenario: join public room again after sharing a file and the sharer left the room + Given user "participant2" creates room "public room" + | roomType | 3 | + And user "participant1" joins room "public room" with 200 + And user "participant1" shares "welcome.txt" with room "public room" with OCS 100 + And user "participant1" leaves room "public room" with 200 + When user "participant1" joins room "public room" with 200 + Then user "participant1" gets all shares + And the list of returned shares has 0 shares + And user "participant2" gets all received shares + And the list of returned shares has 0 shares + + + + Scenario: add sharer again to group room after sharing a file and a receiver reshared it and the sharer was removed from the room + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant2" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant1" shares "welcome (2).txt" with user "participant3" with OCS 100 + And user "participant1" removes "participant2" from room "group room" with 200 + When user "participant1" adds "participant2" to room "group room" with 200 + Then user "participant1" gets last share + And the OCS status code should be "404" + And user "participant1" gets all shares + And the list of returned shares has 0 shares + And user "participant2" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | uid_file_owner | participant2 | + | displayname_file_owner | participant2-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant2 | + | file_target | /welcome (2).txt | + | share_with | participant3 | + | share_with_displayname | participant3-displayname | + | share_type | 0 | + And user "participant2" gets all shares + And the list of returned shares has 0 shares + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | uid_file_owner | participant2 | + | displayname_file_owner | participant2-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | participant3 | + | share_with_displayname | participant3-displayname | + | share_type | 0 | + + + + Scenario: add sharee again to group room after a file was shared and the sharee was removed from the room + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant1" removes "participant2" from room "group room" with 200 + When user "participant1" adds "participant2" to room "group room" with 200 + Then user "participant2" gets all received shares + And the list of returned shares has 1 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + + Scenario: add sharee again to group room after a file was shared and moved by the sharee and the sharee was removed from the room + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant2" moves file "welcome (2).txt" to "renamed.txt" + And user "participant1" removes "participant2" from room "group room" with 200 + When user "participant1" adds "participant2" to room "group room" with 200 + Then user "participant2" gets all received shares + And the list of returned shares has 1 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + + Scenario: add sharee again to group room after a file was shared and the sharee removed herself from the room + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant2" removes themselves from room "group room" with 200 + When user "participant1" adds "participant2" to room "group room" with 200 + Then user "participant2" gets all received shares + And the list of returned shares has 1 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + + Scenario: add sharee again to group room after a file was shared and moved by the sharee and the sharee removed herself from the room + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant2" moves file "welcome (2).txt" to "renamed.txt" + And user "participant2" removes themselves from room "group room" with 200 + When user "participant1" adds "participant2" to room "group room" with 200 + Then user "participant2" gets all received shares + And the list of returned shares has 1 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + + Scenario: join sharee again to public room after a file was shared and the sharee left the room + Given user "participant1" creates room "public room" + | roomType | 3 | + And user "participant1" renames room "public room" to "Public room" with 200 + And user "participant2" joins room "public room" with 200 + And user "participant1" shares "welcome.txt" with room "public room" with OCS 100 + And user "participant2" leaves room "public room" with 200 + When user "participant2" joins room "public room" with 200 + Then user "participant2" gets all received shares + And the list of returned shares has 1 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | public room | + | share_with_displayname | Public room | + + Scenario: join sharee again to public room after a file was shared and moved by the sharee and the sharee left the room + Given user "participant1" creates room "public room" + | roomType | 3 | + And user "participant1" renames room "public room" to "Public room" with 200 + And user "participant2" joins room "public room" with 200 + And user "participant1" shares "welcome.txt" with room "public room" with OCS 100 + And user "participant2" moves file "welcome (2).txt" to "renamed.txt" + And user "participant2" leaves room "public room" with 200 + When user "participant2" joins room "public room" with 200 + Then user "participant2" gets all received shares + And the list of returned shares has 1 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | public room | + | share_with_displayname | Public room | + + + + Scenario: add sharee again to group room after a file was shared and the sharee reshared it and the sharee was removed from the room + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant2" shares "welcome (2).txt" with user "participant3" with OCS 100 + And user "participant1" removes "participant2" from room "group room" with 200 + When user "participant1" adds "participant2" to room "group room" with 200 + Then user "participant1" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | uid_file_owner | participant1 | + | displayname_file_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome (2).txt | + | share_with | participant3 | + | share_with_displayname | participant3-displayname | + | share_type | 0 | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | uid_file_owner | participant1 | + | displayname_file_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | participant3 | + | share_with_displayname | participant3-displayname | + | share_type | 0 | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | uid_file_owner | participant1 | + | displayname_file_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | participant3 | + | share_with_displayname | participant3-displayname | + | share_type | 0 | From 2f21a84d5497f01d7fdb9b19f359ce0ec021b48c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Sat, 7 Jul 2018 16:16:48 +0200 Subject: [PATCH 32/43] Add integration tests for room shares when deleting rooms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- .../features/sharing/hooks.feature | 171 ++++++++++++++++++ 1 file changed, 171 insertions(+) diff --git a/tests/integration/features/sharing/hooks.feature b/tests/integration/features/sharing/hooks.feature index 2aa7aa35c5b..9d0e5eb03f9 100644 --- a/tests/integration/features/sharing/hooks.feature +++ b/tests/integration/features/sharing/hooks.feature @@ -686,3 +686,174 @@ Feature: hooks | share_with | participant3 | | share_with_displayname | participant3-displayname | | share_type | 0 | + + + + Scenario: delete one-to-one room after sharing a file + Given user "participant1" creates room "own one-to-one room" + | roomType | 1 | + | invite | participant2 | + And user "participant1" shares "welcome.txt" with room "own one-to-one room" with OCS 100 + When user "participant1" deletes room "own one-to-one room" with 200 + Then user "participant1" gets last share + And the OCS status code should be "404" + And user "participant2" gets last share + And the OCS status code should be "404" + + Scenario: delete group room after sharing a file + Given user "participant1" creates room "own group room" + | roomType | 2 | + And user "participant1" adds "participant2" to room "own group room" with 200 + And user "participant1" shares "welcome.txt" with room "own group room" with OCS 100 + When user "participant1" deletes room "own group room" with 200 + Then user "participant1" gets last share + And the OCS status code should be "404" + And user "participant2" gets last share + And the OCS status code should be "404" + + Scenario: delete public room after sharing a file + Given user "participant1" creates room "own public room" + | roomType | 3 | + And user "participant1" adds "participant2" to room "own public room" with 200 + And user "participant3" joins room "own public room" with 200 + And user "participant1" shares "welcome.txt" with room "own public room" with OCS 100 + When user "participant1" deletes room "own public room" with 200 + Then user "participant1" gets last share + And the OCS status code should be "404" + And user "participant2" gets last share + And the OCS status code should be "404" + And user "participant3" gets last share + And the OCS status code should be "404" + + Scenario: delete room after a file was shared and the sharee moved it + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant2" moves file "welcome (2).txt" to "renamed.txt" + When user "participant1" deletes room "group room" with 200 + Then user "participant1" gets last share + And the OCS status code should be "404" + And user "participant2" gets last share + And the OCS status code should be "404" + + Scenario: delete room after a file was shared and the sharee reshared it + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant2" shares "welcome (2).txt" with user "participant3" with OCS 100 + When user "participant1" deletes room "group room" with 200 + Then user "participant1" gets all shares + And the list of returned shares has 0 shares + And user "participant2" gets all shares + And the list of returned shares has 0 shares + And user "participant2" gets all received shares + And the list of returned shares has 0 shares + And user "participant3" gets all received shares + And the list of returned shares has 1 shares + And share 0 is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | uid_file_owner | participant1 | + | displayname_file_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | participant3 | + | share_with_displayname | participant3-displayname | + | share_type | 0 | + + Scenario: delete room after a file was shared and the sharee moved and reshared it + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant2" moves file "welcome (2).txt" to "renamed.txt" + And user "participant2" shares "renamed.txt" with user "participant3" with OCS 100 + When user "participant1" deletes room "group room" with 200 + Then user "participant1" gets all shares + And the list of returned shares has 0 shares + And user "participant2" gets all shares + And the list of returned shares has 0 shares + And user "participant2" gets all received shares + And the list of returned shares has 0 shares + And user "participant3" gets all received shares + And the list of returned shares has 1 shares + And share 0 is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | uid_file_owner | participant1 | + | displayname_file_owner | participant1-displayname | + | path | /renamed.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/renamed.txt | + | file_target | /renamed.txt | + | share_with | participant3 | + | share_with_displayname | participant3-displayname | + | share_type | 0 | + + Scenario: delete room after sharing a file with several rooms + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" creates room "another group room" + | roomType | 2 | + And user "participant1" renames room "another group room" to "Another group room" with 200 + And user "participant1" creates room "yet another group room" + | roomType | 2 | + And user "participant1" renames room "yet another group room" to "Yet another group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" adds "participant2" to room "another group room" with 200 + And user "participant1" adds "participant2" to room "yet another group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant1" shares "welcome.txt" with room "another group room" with OCS 100 + And user "participant1" shares "welcome.txt" with room "yet another group room" with OCS 100 + When user "participant1" deletes room "group room" with 200 + Then user "participant1" gets all shares + And the list of returned shares has 2 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | another group room | + | share_with_displayname | Another group room | + And share 1 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | yet another group room | + | share_with_displayname | Yet another group room | + And user "participant2" gets all received shares + And the list of returned shares has 2 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | another group room | + | share_with_displayname | Another group room | + And share 1 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | yet another group room | + | share_with_displayname | Yet another group room | From 14ef81667f40e42d8c04e7bd227484bb7a15c300 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Sat, 7 Jul 2018 17:56:23 +0200 Subject: [PATCH 33/43] Add integration tests for room shares when deleting users MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- .../features/bootstrap/FeatureContext.php | 19 +++ .../features/sharing/hooks.feature | 139 ++++++++++++++++++ 2 files changed, 158 insertions(+) diff --git a/tests/integration/features/bootstrap/FeatureContext.php b/tests/integration/features/bootstrap/FeatureContext.php index 2342663dc1f..e2cb45ae081 100644 --- a/tests/integration/features/bootstrap/FeatureContext.php +++ b/tests/integration/features/bootstrap/FeatureContext.php @@ -632,6 +632,25 @@ private function createUser($user) { $this->createdUsers[] = $user; } + /** + * @Given /^user "([^"]*)" is deleted$/ + * @param string $user + */ + public function userIsDeleted($user) { + $deleted = false; + + $this->deleteUser($user); + try { + $this->userExists($user); + } catch (\GuzzleHttp\Exception\ClientException $ex) { + $deleted = true; + } + + if (!$deleted) { + PHPUnit_Framework_Assert::fail("User $user exists"); + } + } + private function deleteUser($user) { $userProvisioningUrl = $this->baseUrl . 'ocs/v2.php/cloud/users/' . $user; $client = new Client(); diff --git a/tests/integration/features/sharing/hooks.feature b/tests/integration/features/sharing/hooks.feature index 9d0e5eb03f9..8a4d9ef37c3 100644 --- a/tests/integration/features/sharing/hooks.feature +++ b/tests/integration/features/sharing/hooks.feature @@ -857,3 +857,142 @@ Feature: hooks | file_target | /welcome (2).txt | | share_with | yet another group room | | share_with_displayname | Yet another group room | + + + + Scenario: delete user after sharing a file + Given user "participant1" creates room "group room invited to" + | roomType | 2 | + And user "participant1" adds "participant2" to room "group room invited to" with 200 + And user "participant2" shares "welcome.txt" with room "group room invited to" with OCS 100 + When user "participant2" is deleted + Then user "participant1" gets last share + And the OCS status code should be "404" + + Scenario: delete user after receiving a shared a file + Given user "participant1" creates room "group room invited to" + | roomType | 2 | + And user "participant1" renames room "group room invited to" to "Group room invited to" with 200 + And user "participant1" adds "participant2" to room "group room invited to" with 200 + And user "participant1" adds "participant3" to room "group room invited to" with 200 + And user "participant1" shares "welcome.txt" with room "group room invited to" with OCS 100 + When user "participant2" is deleted + Then user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + + Scenario: delete user after receiving and moving a shared a file + Given user "participant1" creates room "group room invited to" + | roomType | 2 | + And user "participant1" renames room "group room invited to" to "Group room invited to" with 200 + And user "participant1" adds "participant2" to room "group room invited to" with 200 + And user "participant1" adds "participant3" to room "group room invited to" with 200 + And user "participant1" shares "welcome.txt" with room "group room invited to" with OCS 100 + And user "participant2" moves file "welcome (2).txt" to "renamed.txt" + When user "participant2" is deleted + Then user "participant1" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + + Scenario: delete user after resharing a file + Given user "participant1" creates room "group room invited to" + | roomType | 2 | + And user "participant1" renames room "group room invited to" to "Group room invited to" with 200 + And user "participant1" adds "participant2" to room "group room invited to" with 200 + And user "participant1" adds "participant3" to room "group room invited to" with 200 + And user "participant1" shares "welcome.txt" with room "group room invited to" with OCS 100 + And user "participant2" shares "welcome (2).txt" with user "participant4" with OCS 100 + When user "participant2" is deleted + Then user "participant1" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2 | + | uid_file_owner | participant1 | + | displayname_file_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome (2).txt | + | share_with | participant4 | + | share_with_displayname | participant4-displayname | + | share_type | 0 | + And user "participant1" gets all shares + And the list of returned shares has 1 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant1 | + | file_target | /welcome.txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + And user "participant3" gets last share + And the OCS status code should be "404" + And the HTTP status code should be "200" + And user "participant3" gets all received shares + And the list of returned shares has 1 shares + And share 0 is returned with + | uid_owner | participant1 | + | displayname_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room invited to | + | share_with_displayname | Group room invited to | + And user "participant4" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2 | + | uid_file_owner | participant1 | + | displayname_file_owner | participant1-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | participant4 | + | share_with_displayname | participant4-displayname | + | share_type | 0 | From c25dc2cf8736f73f5112449fd558f5ce0698888e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Sun, 8 Jul 2018 13:06:11 +0200 Subject: [PATCH 34/43] Implement getting room shares in folder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- lib/Share/RoomShareProvider.php | 39 ++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/lib/Share/RoomShareProvider.php b/lib/Share/RoomShareProvider.php index 724fc30e89a..383da9ddba4 100644 --- a/lib/Share/RoomShareProvider.php +++ b/lib/Share/RoomShareProvider.php @@ -476,7 +476,44 @@ public function move(IShare $share, $recipient) { * @return IShare[] */ public function getSharesInFolder($userId, Folder $node, $reshares) { - throw new \Exception("Not implemented"); + $qb = $this->dbConnection->getQueryBuilder(); + $qb->select('*') + ->from('share', 's') + ->andWhere($qb->expr()->orX( + $qb->expr()->eq('item_type', $qb->createNamedParameter('file')), + $qb->expr()->eq('item_type', $qb->createNamedParameter('folder')) + )) + ->andWhere( + $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_ROOM)) + ); + + /** + * Reshares for this user are shares where they are the owner. + */ + if ($reshares === false) { + $qb->andWhere($qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId))); + } else { + $qb->andWhere( + $qb->expr()->orX( + $qb->expr()->eq('uid_owner', $qb->createNamedParameter($userId)), + $qb->expr()->eq('uid_initiator', $qb->createNamedParameter($userId)) + ) + ); + } + + $qb->innerJoin('s', 'filecache' ,'f', $qb->expr()->eq('s.file_source', 'f.fileid')); + $qb->andWhere($qb->expr()->eq('f.parent', $qb->createNamedParameter($node->getId()))); + + $qb->orderBy('id'); + + $cursor = $qb->execute(); + $shares = []; + while ($data = $cursor->fetch()) { + $shares[$data['fileid']][] = $this->createShareObject($data); + } + $cursor->closeCursor(); + + return $shares; } /** From 97e5a8844d43ba5a6d1b45beb523a9e06eea9e54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Sun, 8 Jul 2018 14:16:21 +0200 Subject: [PATCH 35/43] Add integration tests for getting DAV properties of room shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Besides the SharesPlugin for DAV, these tests exercise getting room shares in a folder (as that plugin is the only place where that is used). Signed-off-by: Daniel Calviño Sánchez --- .../features/bootstrap/SharingContext.php | 48 ++++++++ .../integration/features/sharing/get.feature | 112 ++++++++++++++++++ 2 files changed, 160 insertions(+) diff --git a/tests/integration/features/bootstrap/SharingContext.php b/tests/integration/features/bootstrap/SharingContext.php index cd466d186c5..61c145d3067 100644 --- a/tests/integration/features/bootstrap/SharingContext.php +++ b/tests/integration/features/bootstrap/SharingContext.php @@ -322,6 +322,30 @@ public function userGetsDeletedShares(string $user) { $this->sendingTo('GET', $url); } + /** + * @When user :user gets the share-type DAV property for :path + * + * @param string $user + * @param string $path + */ + public function userGetsTheShareTypeDavPropertyFor(string $user, string $path) { + $this->currentUser = $user; + + $url = "/$user/$path"; + + $headers = null; + + $body = '' . + ' ' . + ' ' . + ' ' . + ''; + + $this->sendingToDav('PROPFIND', $url, $headers, $body); + + $this->theHTTPStatusCodeShouldBe(207); + } + /** * @Then the OCS status code should be :statusCode * @@ -418,6 +442,30 @@ public function shareXIsReturnedWith(int $number, TableNode $body) { } } + /** + * @Then the response contains a share-types DAV property with + * + * @param TableNode|null $table + */ + public function theResponseContainsAShareTypesDavPropertyWith(TableNode $table = null) { + $xmlResponse = $this->getXmlResponse(); + $xmlResponse->registerXPathNamespace('oc', 'http://owncloud.org/ns'); + + $shareTypes = []; + foreach ($xmlResponse->xpath('//oc:share-types/oc:share-type') as $shareType) { + $shareTypes[] = (int)$shareType; + } + + $expectedShareTypes = []; + if ($table !== null) { + foreach ($table->getRows() as $row) { + $expectedShareTypes[] = (int)$row[0]; + } + } + + PHPUnit_Framework_Assert::assertEquals($expectedShareTypes, $shareTypes); + } + /** * @param string $user * @param string $path diff --git a/tests/integration/features/sharing/get.feature b/tests/integration/features/sharing/get.feature index 1b3718a9680..6df5db7e54d 100644 --- a/tests/integration/features/sharing/get.feature +++ b/tests/integration/features/sharing/get.feature @@ -619,3 +619,115 @@ Feature: get And the list of returned shares has 0 shares And user "participant3" gets deleted shares And the list of returned shares has 0 shares + + + + Scenario: get DAV properties for a share + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + When user "participant1" gets the share-type DAV property for "/welcome.txt" + Then the response contains a share-types DAV property with + | 10 | + + Scenario: get DAV properties for a folder with a share + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" creates folder "/test" + And user "participant1" moves file "/welcome.txt" to "/test/renamed.txt" with 201 + And user "participant1" shares "/test/renamed.txt" with room "group room" with OCS 100 + When user "participant1" gets the share-type DAV property for "/test" + Then the response contains a share-types DAV property with + | 10 | + + Scenario: get DAV properties for a received share + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + When user "participant2" gets the share-type DAV property for "/welcome (2).txt" + Then the response contains a share-types DAV property with + + Scenario: get DAV properties for a room share reshared with a user + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant2" creates room "another group room" + | roomType | 2 | + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant2" shares "welcome (2).txt" with user "participant3" with OCS 100 + When user "participant1" gets the share-type DAV property for "/welcome.txt" + Then the response contains a share-types DAV property with + | 10 | + + Scenario: get DAV properties for a user share reshared with a room + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant2" creates room "another group room" + | roomType | 2 | + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with user "participant2" with OCS 100 + And user "participant2" shares "welcome (2).txt" with room "group room" with OCS 100 + When user "participant1" gets the share-type DAV property for "/welcome.txt" + Then the response contains a share-types DAV property with + | 0 | + + Scenario: get DAV properties for a room share reshared with a user as the resharer + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant2" creates room "another group room" + | roomType | 2 | + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant2" shares "welcome (2).txt" with user "participant3" with OCS 100 + When user "participant2" gets the share-type DAV property for "/welcome (2).txt" + Then the response contains a share-types DAV property with + | 0 | + + Scenario: get DAV properties for a user share reshared with a room as the resharer + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant2" creates room "another group room" + | roomType | 2 | + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with user "participant2" with OCS 100 + And user "participant2" shares "welcome (2).txt" with room "group room" with OCS 100 + When user "participant2" gets the share-type DAV property for "/welcome (2).txt" + Then the response contains a share-types DAV property with + | 10 | + + # Reshares are taken into account only for the files in the folder, not the + # folder itself. + Scenario: get DAV properties for a reshared folder + Given user "participant2" creates room "group room" + | roomType | 2 | + And user "participant1" creates folder "/test" + And user "participant1" shares "/test" with user "participant2" with OCS 100 + And user "participant2" shares "/test" with room "group room" with OCS 100 + When user "participant1" gets the share-type DAV property for "/test" + Then the response contains a share-types DAV property with + | 0 | + + Scenario: get DAV properties for a folder with a reshare + Given user "participant2" creates room "group room" + | roomType | 2 | + And user "participant1" creates folder "/test" + And user "participant1" moves file "/welcome.txt" to "/test/renamed.txt" with 201 + And user "participant1" shares "/test/renamed.txt" with user "participant2" with OCS 100 + And user "participant2" shares "renamed.txt" with room "group room" with OCS 100 + When user "participant1" gets the share-type DAV property for "/test" + Then the response contains a share-types DAV property with + | 0 | + | 10 | + + Scenario: get DAV properties for a folder with a reshared folder + Given user "participant2" creates room "group room" + | roomType | 2 | + And user "participant1" creates folder "/test" + And user "participant1" creates folder "/test/subfolder" + And user "participant1" shares "/test/subfolder" with user "participant2" with OCS 100 + And user "participant2" shares "subfolder" with room "group room" with OCS 100 + When user "participant1" gets the share-type DAV property for "/test" + Then the response contains a share-types DAV property with + | 0 | + | 10 | From a34984a6f5f3c1d4dd25cf0cb5e5ca4416c09fae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Sun, 8 Jul 2018 14:22:01 +0200 Subject: [PATCH 36/43] Implement getting room shares by token MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Room shares have no token, so it is not possible to get a room share by token. Signed-off-by: Daniel Calviño Sánchez --- lib/Share/RoomShareProvider.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Share/RoomShareProvider.php b/lib/Share/RoomShareProvider.php index 383da9ddba4..eda9b351212 100644 --- a/lib/Share/RoomShareProvider.php +++ b/lib/Share/RoomShareProvider.php @@ -766,7 +766,7 @@ public function getSharedWith($userId, $shareType, $node, $limit, $offset) { * @throws ShareNotFound */ public function getShareByToken($token) { - throw new \Exception("Not implemented"); + throw new ShareNotFound(); } /** From 31cc43600b55122aaf5cce82e33856782a778c1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Mon, 9 Jul 2018 12:00:46 +0200 Subject: [PATCH 37/43] Implement getting access list for room shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- lib/Share/RoomShareProvider.php | 94 ++++++++++++++++++++++++++++++++- 1 file changed, 93 insertions(+), 1 deletion(-) diff --git a/lib/Share/RoomShareProvider.php b/lib/Share/RoomShareProvider.php index eda9b351212..ca4dccff9c5 100644 --- a/lib/Share/RoomShareProvider.php +++ b/lib/Share/RoomShareProvider.php @@ -812,7 +812,99 @@ public function userDeletedFromGroup($uid, $gid) { * @return array */ public function getAccessList($nodes, $currentAccess) { - throw new \Exception("Not implemented"); + $ids = []; + foreach ($nodes as $node) { + $ids[] = $node->getId(); + } + + $qb = $this->dbConn->getQueryBuilder(); + + $or = $qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_ROOM)); + + if ($currentAccess) { + $or->add($qb->expr()->eq('share_type', $qb->createNamedParameter(self::SHARE_TYPE_USERROOM))); + } + + $qb->select('id', 'parent', 'share_type', 'share_with', 'file_source', 'file_target', 'permissions') + ->from('share') + ->where( + $or + ) + ->andWhere($qb->expr()->in('file_source', $qb->createNamedParameter($ids, IQueryBuilder::PARAM_INT_ARRAY))) + ->andWhere($qb->expr()->orX( + $qb->expr()->eq('item_type', $qb->createNamedParameter('file')), + $qb->expr()->eq('item_type', $qb->createNamedParameter('folder')) + )); + $cursor = $qb->execute(); + + $users = []; + while($row = $cursor->fetch()) { + $type = (int)$row['share_type']; + if ($type === \OCP\Share::SHARE_TYPE_ROOM) { + $roomToken = $row['share_with']; + try { + $room = $this->manager->getRoomByToken($roomToken); + } catch (RoomNotFoundException $e) { + continue; + } + + $userList = $room->getParticipants()['users']; + foreach ($userList as $uid => $participantData) { + $users[$uid] = isset($users[$uid]) ? $users[$uid] : []; + $users[$uid][$row['id']] = $row; + } + } else if ($type === self::SHARE_TYPE_USERROOM && $currentAccess === true) { + $uid = $row['share_with']; + $users[$uid] = isset($users[$uid]) ? $users[$uid] : []; + $users[$uid][$row['id']] = $row; + } + } + $cursor->closeCursor(); + + if ($currentAccess === true) { + $users = array_map([$this, 'filterSharesOfUser'], $users); + $users = array_filter($users); + } else { + $users = array_keys($users); + } + + return ['users' => $users]; + } + + /** + * For each user the path with the fewest slashes is returned + * @param array $shares + * @return array + */ + protected function filterSharesOfUser(array $shares) { + // Room shares when the user has a share exception + foreach ($shares as $id => $share) { + $type = (int) $share['share_type']; + $permissions = (int) $share['permissions']; + + if ($type === self::SHARE_TYPE_USERROOM) { + unset($shares[$share['parent']]); + + if ($permissions === 0) { + unset($shares[$id]); + } + } + } + + $best = []; + $bestDepth = 0; + foreach ($shares as $id => $share) { + $depth = substr_count($share['file_target'], '/'); + if (empty($best) || $depth < $bestDepth) { + $bestDepth = $depth; + $best = [ + 'node_id' => $share['file_source'], + 'node_path' => $share['file_target'], + ]; + } + } + + return $best; } /** From 0b8b745c5b1cc2b0b1e8ad5f43f6ba492ceb9e28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Sat, 14 Jul 2018 09:35:12 +0200 Subject: [PATCH 38/43] Add integration tests for getting the recent files including room shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These tests do not check anything new in the RoomShareProvider, but on other code paths. Signed-off-by: Daniel Calviño Sánchez --- .../features/bootstrap/SharingContext.php | 124 ++++++++++++++++++ .../integration/features/sharing/get.feature | 18 +++ 2 files changed, 142 insertions(+) diff --git a/tests/integration/features/bootstrap/SharingContext.php b/tests/integration/features/bootstrap/SharingContext.php index 61c145d3067..41d5fed568c 100644 --- a/tests/integration/features/bootstrap/SharingContext.php +++ b/tests/integration/features/bootstrap/SharingContext.php @@ -24,6 +24,7 @@ use Behat\Behat\Context\Context; use Behat\Gherkin\Node\TableNode; use GuzzleHttp\Client; +use GuzzleHttp\Cookie\CookieJar; use GuzzleHttp\Message\ResponseInterface; class SharingContext implements Context { @@ -346,6 +347,21 @@ public function userGetsTheShareTypeDavPropertyFor(string $user, string $path) { $this->theHTTPStatusCodeShouldBe(207); } + /** + * @When user :user gets recent files + * + * @param string $user + */ + public function userGetsRecentFiles(string $user) { + // Recents endpoint is not an OCS endpoint, so a request token must be + // provided. + list($requestToken, $cookieJar) = $this->loggingInUsingWebAs($user); + + $url = '/index.php/apps/files/api/v1/recent'; + + $this->sendingToWithRequestToken('GET', $url, $requestToken, $cookieJar); + } + /** * @Then the OCS status code should be :statusCode * @@ -466,6 +482,43 @@ public function theResponseContainsAShareTypesDavPropertyWith(TableNode $table = PHPUnit_Framework_Assert::assertEquals($expectedShareTypes, $shareTypes); } + /** + * @Then the response contains a share-types file property for :path with + * + * @param string $path + * @param TableNode|null $table + */ + public function theResponseContainsAShareTypesFilesPropertyForWith(string $path, TableNode $table = null) { + $response = json_decode($this->response->getBody()); + + $fileForPath = array_filter($response->files, function($file) use ($path) { + $filePath = $file->path . (substr($file->path, -1) === '/'? '': '/'); + return ($filePath . $file->name) === $path; + }); + + if (empty($fileForPath)) { + PHPUnit_Framework_Assert::fail("$path not found in the response"); + } + + $fileForPath = array_shift($fileForPath); + + $shareTypes = []; + if (property_exists($fileForPath, 'shareTypes')) { + foreach ($fileForPath->shareTypes as $shareType) { + $shareTypes[] = (int)$shareType; + } + } + + $expectedShareTypes = []; + if ($table !== null) { + foreach ($table->getRows() as $row) { + $expectedShareTypes[] = (int)$row[0]; + } + } + + PHPUnit_Framework_Assert::assertEquals($expectedShareTypes, $shareTypes); + } + /** * @param string $user * @param string $path @@ -563,6 +616,77 @@ private function sendingToDav(string $verb, string $url, array $headers = null, } } + /** + * @param string $verb + * @param string $url + * @param string $requestToken + * @param CookieJar $cookieJar + */ + private function sendingToWithRequestToken(string $verb, string $url, string $requestToken, CookieJar $cookieJar) { + $fullUrl = $this->baseUrl . $url; + + $client = new Client(); + try { + $this->response = $client->send($client->createRequest( + $verb, + $fullUrl, + [ + 'cookies' => $cookieJar, + 'headers' => [ + 'requesttoken' => $requestToken + ] + ] + )); + } catch (GuzzleHttp\Exception\ClientException $e) { + $this->response = $e->getResponse(); + } + } + + /** + * @param ResponseInterface $response + * @return string + */ + private function extractRequestTokenFromResponse(ResponseInterface $response): string { + return substr(preg_replace('/(.*)data-requesttoken="(.*)">(.*)/sm', '\2', $response->getBody()->getContents()), 0, 89); + } + + /** + * @param string $user + */ + private function loggingInUsingWebAs(string $user) { + $loginUrl = $this->baseUrl . '/login'; + + $cookieJar = new CookieJar(); + + // Request a new session and extract CSRF token + $client = new Client(); + $response = $client->get( + $loginUrl, + [ + 'cookies' => $cookieJar, + ] + ); + $requestToken = $this->extractRequestTokenFromResponse($response); + + // Login and extract new token + $password = ($user === 'admin') ? $this->adminUser[1] : $this->regularUserPassword; + $client = new Client(); + $response = $client->post( + $loginUrl, + [ + 'body' => [ + 'user' => $user, + 'password' => $password, + 'requesttoken' => $requestToken, + ], + 'cookies' => $cookieJar, + ] + ); + $requestToken = $this->extractRequestTokenFromResponse($response); + + return [$requestToken, $cookieJar]; + } + /** * @return string */ diff --git a/tests/integration/features/sharing/get.feature b/tests/integration/features/sharing/get.feature index 6df5db7e54d..4e043af6ec1 100644 --- a/tests/integration/features/sharing/get.feature +++ b/tests/integration/features/sharing/get.feature @@ -731,3 +731,21 @@ Feature: get Then the response contains a share-types DAV property with | 0 | | 10 | + + + + Scenario: get recent files including a share + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" creates folder "/test" + And user "participant1" creates folder "/test/subfolder" + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + And user "participant1" shares "test/subfolder" with room "group room" with OCS 100 + And user "participant1" shares "test/subfolder" with user "participant3" with OCS 100 + When user "participant1" gets recent files + Then the response contains a share-types file property for "/welcome.txt" with + | 10 | + And the response contains a share-types file property for "/test" with + And the response contains a share-types file property for "/test/subfolder" with + | 0 | + | 10 | From b2885788f60f8a4cb9249d47415760ba94bb4625 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Sat, 14 Jul 2018 10:51:33 +0200 Subject: [PATCH 39/43] Add integration tests for transfering ownership of room shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These tests do not check anything new in the RoomShareProvider, but on other code paths. Signed-off-by: Daniel Calviño Sánchez --- .../features/bootstrap/SharingContext.php | 32 ++++ .../sharing/transfer-ownership.feature | 140 ++++++++++++++++++ 2 files changed, 172 insertions(+) create mode 100644 tests/integration/features/sharing/transfer-ownership.feature diff --git a/tests/integration/features/bootstrap/SharingContext.php b/tests/integration/features/bootstrap/SharingContext.php index 41d5fed568c..86d80a9fa6c 100644 --- a/tests/integration/features/bootstrap/SharingContext.php +++ b/tests/integration/features/bootstrap/SharingContext.php @@ -362,6 +362,38 @@ public function userGetsRecentFiles(string $user) { $this->sendingToWithRequestToken('GET', $url, $requestToken, $cookieJar); } + /** + * @When transfering ownership from :user1 to :user2 + * + * @param string $user1 + * @param string $user2 + */ + public function transferingOwnershipFromTo(string $user1, string $user2) { + $args = ['files:transfer-ownership', $user1, $user2]; + + $args = array_map(function($arg) { + return escapeshellarg($arg); + }, $args); + $args[] = '--no-ansi'; + $args = implode(' ', $args); + + $descriptor = [ + 0 => ['pipe', 'r'], + 1 => ['pipe', 'w'], + 2 => ['pipe', 'w'], + ]; + $process = proc_open('php console.php ' . $args, $descriptor, $pipes, '../../../../'); + $lastStdOut = stream_get_contents($pipes[1]); + $lastStdErr = stream_get_contents($pipes[2]); + $lastCode = proc_close($process); + + // Clean opcode cache + $client = new GuzzleHttp\Client(); + $client->send($client->createRequest('GET', $this->baseUrl . '/apps/testing/clean_opcode_cache.php')); + + PHPUnit_Framework_Assert::assertEquals(0, $lastCode); + } + /** * @Then the OCS status code should be :statusCode * diff --git a/tests/integration/features/sharing/transfer-ownership.feature b/tests/integration/features/sharing/transfer-ownership.feature new file mode 100644 index 00000000000..4c1b1d98805 --- /dev/null +++ b/tests/integration/features/sharing/transfer-ownership.feature @@ -0,0 +1,140 @@ +Feature: transfer-ownership + + Background: + Given user "participant1" exists + Given user "participant2" exists + Given user "participant3" exists + + Scenario: transfer ownership of a file shared with a room to a user in the room + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" adds "participant3" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + When transfering ownership from "participant1" to "participant2" + Then user "participant1" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome.txt | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | path | REGEXP /\/transferred from participant1 on .*\/welcome.txt/ | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant2 | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + + Scenario: transfer ownership of a file reshared with a room to a user in the room + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant2" to room "group room" with 200 + And user "participant1" adds "participant3" to room "group room" with 200 + And user "participant3" shares "welcome.txt" with user "participant1" with OCS 100 + And user "participant1" shares "welcome (2).txt" with room "group room" with OCS 100 + When transfering ownership from "participant1" to "participant2" + Then user "participant1" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | uid_file_owner | participant3 | + | displayname_file_owner | participant3-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | uid_file_owner | participant3 | + | displayname_file_owner | participant3-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | uid_file_owner | participant3 | + | displayname_file_owner | participant3-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant3 | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | + + # This is a special case in which even if the (now) sharer is not in a room + # the room share is valid and other participants can access that share. + Scenario: transfer ownership of a file shared with a room to a user not in the room + Given user "participant1" creates room "group room" + | roomType | 2 | + And user "participant1" renames room "group room" to "Group room" with 200 + And user "participant1" adds "participant3" to room "group room" with 200 + And user "participant1" shares "welcome.txt" with room "group room" with OCS 100 + When transfering ownership from "participant1" to "participant2" + Then user "participant1" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | path | /welcome.txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome.txt | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant2" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | path | REGEXP /\/transferred from participant1 on .*\/welcome.txt/ | + | item_type | file | + | mimetype | text/plain | + | storage_id | home::participant2 | + | file_target | /welcome.txt | + | share_with | group room | + | share_with_displayname | Group room | + And user "participant3" gets last share + And share is returned with + | uid_owner | participant2 | + | displayname_owner | participant2-displayname | + | path | /welcome (2).txt | + | item_type | file | + | mimetype | text/plain | + | storage_id | shared::/welcome (2).txt | + | file_target | /welcome (2).txt | + | share_with | group room | + | share_with_displayname | Group room | From 2ca4e1af8818e97cbf65b42adf3c092ff791033e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Sat, 14 Jul 2018 10:59:10 +0200 Subject: [PATCH 40/43] Add reference to original sources in licence MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Daniel Calviño Sánchez --- lib/Share/RoomShareProvider.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/Share/RoomShareProvider.php b/lib/Share/RoomShareProvider.php index ca4dccff9c5..94aafde258e 100644 --- a/lib/Share/RoomShareProvider.php +++ b/lib/Share/RoomShareProvider.php @@ -5,6 +5,10 @@ * * @copyright Copyright (c) 2018, Daniel Calviño Sánchez (danxuliu@gmail.com) * + * Code copied from "lib/private/Share20/DefaultShareProvider.php" and + * "apps/sharebymail/lib/ShareByMailProvider.php" at d805959e819e64 in Nextcloud + * server repository. + * * @license GNU AGPL version 3 or any later version * * This program is free software: you can redistribute it and/or modify From 1dc87c7f8695823a4769e54176f4e92e1aa02eea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Wed, 1 Aug 2018 19:30:31 +0200 Subject: [PATCH 41/43] Add tokens to room shares MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Tokens allow guest users to download the files shared with a public room; although every room share has a token only those with public rooms can be accessed using the token. Signed-off-by: Daniel Calviño Sánchez --- lib/Share/RoomShareProvider.php | 48 +++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) diff --git a/lib/Share/RoomShareProvider.php b/lib/Share/RoomShareProvider.php index 94aafde258e..2f46d1c1c82 100644 --- a/lib/Share/RoomShareProvider.php +++ b/lib/Share/RoomShareProvider.php @@ -39,6 +39,7 @@ use OCP\IDBConnection; use OCP\IL10N; use OCP\IUserManager; +use OCP\Security\ISecureRandom; use OCP\Share\Exceptions\GenericShareException; use OCP\Share\Exceptions\ShareNotFound; use OCP\Share\IManager as IShareManager; @@ -63,6 +64,9 @@ class RoomShareProvider implements IShareProvider { /** @var IDBConnection */ private $dbConnection; + /** @var ISecureRandom */ + private $secureRandom; + /** @var IUserManager */ private $userManager; @@ -82,6 +86,7 @@ class RoomShareProvider implements IShareProvider { * RoomShareProvider constructor. * * @param IDBConnection $connection + * @param ISecureRandom $secureRandom * @param IUserManager $userManager * @param IShareManager $shareManager * @param IRootFolder $rootFolder @@ -90,6 +95,7 @@ class RoomShareProvider implements IShareProvider { */ public function __construct( IDBConnection $connection, + ISecureRandom $secureRandom, IUserManager $userManager, IShareManager $shareManager, IRootFolder $rootFolder, @@ -97,6 +103,7 @@ public function __construct( Manager $manager ) { $this->dbConnection = $connection; + $this->secureRandom = $secureRandom; $this->userManager = $userManager; $this->shareManager = $shareManager; $this->rootFolder = $rootFolder; @@ -142,6 +149,13 @@ public function create(IShare $share) { } } + $share->setToken( + $this->secureRandom->generate( + 15, // \OC\Share\Constants::TOKEN_LENGTH + \OCP\Security\ISecureRandom::CHAR_HUMAN_READABLE + ) + ); + $shareId = $this->addShareToDB( $share->getSharedWith(), $share->getSharedBy(), @@ -150,6 +164,7 @@ public function create(IShare $share) { $share->getNodeId(), $share->getTarget(), $share->getPermissions(), + $share->getToken(), $share->getExpirationDate() ); @@ -168,6 +183,7 @@ public function create(IShare $share) { * @param int $itemSource * @param string $target * @param int $permissions + * @param string $token * @param \DateTime|null $expirationDate * @return int */ @@ -179,6 +195,7 @@ private function addShareToDB( int $itemSource, string $target, int $permissions, + string $token, \DateTime $expirationDate = null ): int { $qb = $this->dbConnection->getQueryBuilder(); @@ -192,6 +209,7 @@ private function addShareToDB( ->setValue('file_source', $qb->createNamedParameter($itemSource)) ->setValue('file_target', $qb->createNamedParameter($target)) ->setValue('permissions', $qb->createNamedParameter($permissions)) + ->setValue('token', $qb->createNamedParameter($token)) ->setValue('stime', $qb->createNamedParameter(time())); if ($expirationDate !== null) { @@ -239,7 +257,8 @@ private function createShareObject($data) { $share->setId((int)$data['id']) ->setShareType((int)$data['share_type']) ->setPermissions((int)$data['permissions']) - ->setTarget($data['file_target']); + ->setTarget($data['file_target']) + ->setToken($data['token']); $shareTime = new \DateTime(); $shareTime->setTimestamp((int)$data['stime']); @@ -770,7 +789,32 @@ public function getSharedWith($userId, $shareType, $node, $limit, $offset) { * @throws ShareNotFound */ public function getShareByToken($token) { - throw new ShareNotFound(); + $qb = $this->dbConnection->getQueryBuilder(); + + $cursor = $qb->select('*') + ->from('share') + ->where($qb->expr()->eq('share_type', $qb->createNamedParameter(\OCP\Share::SHARE_TYPE_ROOM))) + ->andWhere($qb->expr()->eq('token', $qb->createNamedParameter($token))) + ->execute(); + + $data = $cursor->fetch(); + + if ($data === false) { + throw new ShareNotFound(); + } + + $roomToken = $data['share_with']; + try { + $room = $this->manager->getRoomByToken($roomToken); + } catch (RoomNotFoundException $e) { + throw new ShareNotFound(); + } + + if ($room->getType() !== Room::PUBLIC_CALL) { + throw new ShareNotFound(); + } + + return $this->createShareObject($data); } /** From e273ac4a59f2ca2b1004d815696097bfb591fb55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Calvi=C3=B1o=20S=C3=A1nchez?= Date: Wed, 8 Aug 2018 17:15:35 +0200 Subject: [PATCH 42/43] Include the token of shares with public rooms in share API responses MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Only shares with public rooms can be accessed using the token, so there is no point in returning the token for shares with other types of rooms. Signed-off-by: Daniel Calviño Sánchez --- lib/Share/Helper/ShareAPIController.php | 4 +++ .../features/bootstrap/SharingContext.php | 4 +++ .../features/sharing/create.feature | 9 ++++++ .../features/sharing/delete.feature | 2 ++ .../features/sharing/hooks.feature | 7 +++++ .../features/sharing/update.feature | 28 +++++++++++++++++++ 6 files changed, 54 insertions(+) diff --git a/lib/Share/Helper/ShareAPIController.php b/lib/Share/Helper/ShareAPIController.php index 21087350eb5..e46c3019b58 100644 --- a/lib/Share/Helper/ShareAPIController.php +++ b/lib/Share/Helper/ShareAPIController.php @@ -102,6 +102,10 @@ public function formatShare(IShare $share): array { $result['share_with_displayname'] = $roomName; + if ($room->getType() === Room::PUBLIC_CALL) { + $result['token'] = $share->getToken(); + } + return $result; } diff --git a/tests/integration/features/bootstrap/SharingContext.php b/tests/integration/features/bootstrap/SharingContext.php index 86d80a9fa6c..9e2b1616f71 100644 --- a/tests/integration/features/bootstrap/SharingContext.php +++ b/tests/integration/features/bootstrap/SharingContext.php @@ -753,6 +753,10 @@ private function assertFieldIsInReturnedShare(string $field, string $contentExpe if ($contentExpected === 'A_NUMBER') { PHPUnit_Framework_Assert::assertTrue(is_numeric((string)$returnedShare->$field), "Field '$field' is not a number: " . $returnedShare->$field); + } else if ($contentExpected === 'A_TOKEN') { + // A token is composed by 15 characters from + // ISecureRandom::CHAR_HUMAN_READABLE. + PHPUnit_Framework_Assert::assertRegExp('/^[abcdefgijkmnopqrstwxyzABCDEFGHJKLMNPQRSTWXYZ23456789]{15}$/', (string)$returnedShare->$field, "Field '$field' is not a token"); } else if (strpos($contentExpected, 'REGEXP ') === 0) { PHPUnit_Framework_Assert::assertRegExp(substr($contentExpected, strlen('REGEXP ')), (string)$returnedShare->$field, "Field '$field' does not match"); } else { diff --git a/tests/integration/features/sharing/create.feature b/tests/integration/features/sharing/create.feature index 2657db98c3d..80ba025daf4 100644 --- a/tests/integration/features/sharing/create.feature +++ b/tests/integration/features/sharing/create.feature @@ -170,6 +170,7 @@ Feature: create | file_target | /welcome.txt | | share_with | own public room | | share_with_displayname | Own public room | + | token | A_TOKEN | And user "participant2" gets last share And share is returned with | uid_owner | participant1 | @@ -181,6 +182,7 @@ Feature: create | file_target | /welcome (2).txt | | share_with | own public room | | share_with_displayname | Own public room | + | token | A_TOKEN | And user "participant3" gets last share And share is returned with | uid_owner | participant1 | @@ -192,6 +194,7 @@ Feature: create | file_target | /welcome (2).txt | | share_with | own public room | | share_with_displayname | Own public room | + | token | A_TOKEN | Scenario: create share with a public room invited to Given user "participant2" creates room "public room invited to" @@ -210,6 +213,7 @@ Feature: create | file_target | /welcome.txt | | share_with | public room invited to | | share_with_displayname | Public room invited to | + | token | A_TOKEN | And user "participant2" gets last share And share is returned with | uid_owner | participant1 | @@ -221,6 +225,7 @@ Feature: create | file_target | /welcome (2).txt | | share_with | public room invited to | | share_with_displayname | Public room invited to | + | token | A_TOKEN | And user "participant3" gets last share And share is returned with | uid_owner | participant1 | @@ -232,6 +237,7 @@ Feature: create | file_target | /welcome (2).txt | | share_with | public room invited to | | share_with_displayname | Public room invited to | + | token | A_TOKEN | Scenario: create share with a public room self joined to Given user "participant2" creates room "public room self joined to" @@ -250,6 +256,7 @@ Feature: create | file_target | /welcome.txt | | share_with | public room self joined to | | share_with_displayname | Public room self joined to | + | token | A_TOKEN | And user "participant2" gets last share And share is returned with | uid_owner | participant1 | @@ -261,6 +268,7 @@ Feature: create | file_target | /welcome (2).txt | | share_with | public room self joined to | | share_with_displayname | Public room self joined to | + | token | A_TOKEN | And user "participant3" gets last share And share is returned with | uid_owner | participant1 | @@ -272,6 +280,7 @@ Feature: create | file_target | /welcome (2).txt | | share_with | public room self joined to | | share_with_displayname | Public room self joined to | + | token | A_TOKEN | Scenario: create share with a public room not joined to Given user "participant2" creates room "public room not joined to" diff --git a/tests/integration/features/sharing/delete.feature b/tests/integration/features/sharing/delete.feature index 527796c0628..9c3a52bd10d 100644 --- a/tests/integration/features/sharing/delete.feature +++ b/tests/integration/features/sharing/delete.feature @@ -190,6 +190,7 @@ Feature: delete | file_target | /welcome.txt | | share_with | public room not joined to | | share_with_displayname | Public room not joined to | + | token | A_TOKEN | And user "participant3" gets last share And share is returned with | uid_owner | participant2 | @@ -201,6 +202,7 @@ Feature: delete | file_target | /welcome (2).txt | | share_with | public room not joined to | | share_with_displayname | Public room not joined to | + | token | A_TOKEN | diff --git a/tests/integration/features/sharing/hooks.feature b/tests/integration/features/sharing/hooks.feature index 8a4d9ef37c3..e07fe11fab1 100644 --- a/tests/integration/features/sharing/hooks.feature +++ b/tests/integration/features/sharing/hooks.feature @@ -43,6 +43,7 @@ Feature: hooks | file_target | /welcome (2).txt | | share_with | public room | | share_with_displayname | Public room | + | token | A_TOKEN | @@ -116,6 +117,7 @@ Feature: hooks | file_target | /welcome (2).txt | | share_with | public room | | share_with_displayname | Public room | + | token | A_TOKEN | And user "participant2" gets last share And share is returned with | uid_owner | participant2 | @@ -127,6 +129,7 @@ Feature: hooks | file_target | /welcome.txt | | share_with | public room | | share_with_displayname | Public room | + | token | A_TOKEN | Scenario: leave public room self joined to after sharing a file Given user "participant1" creates room "public room" @@ -318,6 +321,7 @@ Feature: hooks | file_target | /welcome.txt | | share_with | public room | | share_with_displayname | Public room | + | token | A_TOKEN | And user "participant2" gets last share And the OCS status code should be "404" @@ -340,6 +344,7 @@ Feature: hooks | file_target | /welcome.txt | | share_with | public room | | share_with_displayname | Public room | + | token | A_TOKEN | And user "participant2" gets last share And the OCS status code should be "404" @@ -611,6 +616,7 @@ Feature: hooks | file_target | /welcome (2).txt | | share_with | public room | | share_with_displayname | Public room | + | token | A_TOKEN | Scenario: join sharee again to public room after a file was shared and moved by the sharee and the sharee left the room Given user "participant1" creates room "public room" @@ -633,6 +639,7 @@ Feature: hooks | file_target | /welcome (2).txt | | share_with | public room | | share_with_displayname | Public room | + | token | A_TOKEN | diff --git a/tests/integration/features/sharing/update.feature b/tests/integration/features/sharing/update.feature index d861380dedf..f03a5a6f087 100644 --- a/tests/integration/features/sharing/update.feature +++ b/tests/integration/features/sharing/update.feature @@ -215,6 +215,7 @@ Feature: update | file_target | /welcome.txt | | share_with | own public room | | share_with_displayname | Own public room | + | token | A_TOKEN | | permissions | 1 | | expiration | +3 days | And user "participant1" gets last share @@ -228,6 +229,7 @@ Feature: update | file_target | /welcome.txt | | share_with | own public room | | share_with_displayname | Own public room | + | token | A_TOKEN | | permissions | 1 | | expiration | +3 days | And user "participant2" gets last share @@ -241,6 +243,7 @@ Feature: update | file_target | /welcome (2).txt | | share_with | own public room | | share_with_displayname | Own public room | + | token | A_TOKEN | | permissions | 1 | | expiration | +3 days | And user "participant3" gets last share @@ -254,6 +257,7 @@ Feature: update | file_target | /welcome (2).txt | | share_with | own public room | | share_with_displayname | Own public room | + | token | A_TOKEN | | permissions | 1 | | expiration | +3 days | @@ -277,6 +281,7 @@ Feature: update | file_target | /welcome.txt | | share_with | public room invited to | | share_with_displayname | Public room invited to | + | token | A_TOKEN | | permissions | 1 | | expiration | +3 days | And user "participant1" gets last share @@ -290,6 +295,7 @@ Feature: update | file_target | /welcome.txt | | share_with | public room invited to | | share_with_displayname | Public room invited to | + | token | A_TOKEN | | permissions | 1 | | expiration | +3 days | And user "participant2" gets last share @@ -303,6 +309,7 @@ Feature: update | file_target | /welcome (2).txt | | share_with | public room invited to | | share_with_displayname | Public room invited to | + | token | A_TOKEN | | permissions | 1 | | expiration | +3 days | And user "participant3" gets last share @@ -316,6 +323,7 @@ Feature: update | file_target | /welcome (2).txt | | share_with | public room invited to | | share_with_displayname | Public room invited to | + | token | A_TOKEN | | permissions | 1 | | expiration | +3 days | @@ -339,6 +347,7 @@ Feature: update | file_target | /welcome.txt | | share_with | public room self joined to | | share_with_displayname | Public room self joined to | + | token | A_TOKEN | | permissions | 1 | | expiration | +3 days | And user "participant1" gets last share @@ -352,6 +361,7 @@ Feature: update | file_target | /welcome.txt | | share_with | public room self joined to | | share_with_displayname | Public room self joined to | + | token | A_TOKEN | | permissions | 1 | | expiration | +3 days | And user "participant2" gets last share @@ -365,6 +375,7 @@ Feature: update | file_target | /welcome (2).txt | | share_with | public room self joined to | | share_with_displayname | Public room self joined to | + | token | A_TOKEN | | permissions | 1 | | expiration | +3 days | And user "participant3" gets last share @@ -378,6 +389,7 @@ Feature: update | file_target | /welcome (2).txt | | share_with | public room self joined to | | share_with_displayname | Public room self joined to | + | token | A_TOKEN | | permissions | 1 | | expiration | +3 days | @@ -472,6 +484,7 @@ Feature: update | file_target | /welcome.txt | | share_with | public room not joined to | | share_with_displayname | Public room not joined to | + | token | A_TOKEN | And user "participant3" gets last share And share is returned with | uid_owner | participant2 | @@ -483,6 +496,7 @@ Feature: update | file_target | /welcome (2).txt | | share_with | public room not joined to | | share_with_displayname | Public room not joined to | + | token | A_TOKEN | @@ -749,6 +763,7 @@ Feature: update | file_target | /welcome (2).txt | | share_with | own public room | | share_with_displayname | Own public room | + | token | A_TOKEN | | permissions | 1 | | expiration | +3 days | And user "participant1" gets last share @@ -762,6 +777,7 @@ Feature: update | file_target | /welcome.txt | | share_with | own public room | | share_with_displayname | Own public room | + | token | A_TOKEN | | permissions | 1 | | expiration | +3 days | And user "participant2" gets last share @@ -775,6 +791,7 @@ Feature: update | file_target | /welcome (2).txt | | share_with | own public room | | share_with_displayname | Own public room | + | token | A_TOKEN | | permissions | 1 | | expiration | +3 days | And user "participant3" gets last share @@ -788,6 +805,7 @@ Feature: update | file_target | /welcome (2).txt | | share_with | own public room | | share_with_displayname | Own public room | + | token | A_TOKEN | | permissions | 1 | | expiration | +3 days | @@ -811,6 +829,7 @@ Feature: update | file_target | /welcome (2).txt | | share_with | public room invited to | | share_with_displayname | Public room invited to | + | token | A_TOKEN | | permissions | 1 | | expiration | +3 days | And user "participant1" gets last share @@ -824,6 +843,7 @@ Feature: update | file_target | /welcome.txt | | share_with | public room invited to | | share_with_displayname | Public room invited to | + | token | A_TOKEN | | permissions | 1 | | expiration | +3 days | And user "participant2" gets last share @@ -837,6 +857,7 @@ Feature: update | file_target | /welcome (2).txt | | share_with | public room invited to | | share_with_displayname | Public room invited to | + | token | A_TOKEN | | permissions | 1 | | expiration | +3 days | And user "participant3" gets last share @@ -850,6 +871,7 @@ Feature: update | file_target | /welcome (2).txt | | share_with | public room invited to | | share_with_displayname | Public room invited to | + | token | A_TOKEN | | permissions | 1 | | expiration | +3 days | @@ -873,6 +895,7 @@ Feature: update | file_target | /welcome (2).txt | | share_with | public room self joined to | | share_with_displayname | Public room self joined to | + | token | A_TOKEN | | permissions | 1 | | expiration | +3 days | And user "participant1" gets last share @@ -886,6 +909,7 @@ Feature: update | file_target | /welcome.txt | | share_with | public room self joined to | | share_with_displayname | Public room self joined to | + | token | A_TOKEN | | permissions | 1 | | expiration | +3 days | And user "participant2" gets last share @@ -899,6 +923,7 @@ Feature: update | file_target | /welcome (2).txt | | share_with | public room self joined to | | share_with_displayname | Public room self joined to | + | token | A_TOKEN | | permissions | 1 | | expiration | +3 days | And user "participant3" gets last share @@ -912,6 +937,7 @@ Feature: update | file_target | /welcome (2).txt | | share_with | public room self joined to | | share_with_displayname | Public room self joined to | + | token | A_TOKEN | | permissions | 1 | | expiration | +3 days | @@ -939,6 +965,7 @@ Feature: update | file_target | /welcome.txt | | share_with | public room no longer joined to | | share_with_displayname | Public room no longer joined to | + | token | A_TOKEN | And user "participant2" gets last share And the OCS status code should be "404" And the HTTP status code should be "200" @@ -953,6 +980,7 @@ Feature: update | file_target | /welcome (2).txt | | share_with | public room no longer joined to | | share_with_displayname | Public room no longer joined to | + | token | A_TOKEN | From 57bf6e6c1d19ec55f6c29a352ec04bc6d3b81d9d Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 24 Aug 2018 16:41:02 +0200 Subject: [PATCH 43/43] Add a system message for "file shared into room" Signed-off-by: Joas Schilling --- js/richobjectstringparser.js | 2 +- lib/Chat/SystemMessage/Listener.php | 19 +++++++++- lib/Chat/SystemMessage/Parser.php | 58 ++++++++++++++++++++++++++++- 3 files changed, 76 insertions(+), 3 deletions(-) diff --git a/js/richobjectstringparser.js b/js/richobjectstringparser.js index 169fa6bba8a..3cd7ce15e90 100644 --- a/js/richobjectstringparser.js +++ b/js/richobjectstringparser.js @@ -16,7 +16,7 @@ _userLocalTemplate: '@{{name}}', _unknownTemplate: '{{name}}', - _unknownLinkTemplate: '{{name}}', + _unknownLinkTemplate: '{{name}}', /** * @param {string} subject diff --git a/lib/Chat/SystemMessage/Listener.php b/lib/Chat/SystemMessage/Listener.php index 1ea295cde65..3037ee353a9 100644 --- a/lib/Chat/SystemMessage/Listener.php +++ b/lib/Chat/SystemMessage/Listener.php @@ -23,11 +23,14 @@ use OCA\Spreed\Chat\ChatManager; +use OCA\Spreed\Manager; use OCA\Spreed\Participant; use OCA\Spreed\Room; use OCA\Spreed\TalkSession; use OCP\IUser; use OCP\IUserSession; +use OCP\Share; +use OCP\Share\IShare; use Symfony\Component\EventDispatcher\EventDispatcherInterface; use Symfony\Component\EventDispatcher\GenericEvent; @@ -37,14 +40,17 @@ class Listener { protected $dispatcher; /** @var ChatManager */ protected $chatManager; + /** @var Manager */ + protected $roomManager; /** @var TalkSession */ protected $talkSession; /** @var IUserSession */ protected $userSession; - public function __construct(EventDispatcherInterface $dispatcher, ChatManager $chatManager, TalkSession $talkSession, IUserSession $userSession) { + public function __construct(EventDispatcherInterface $dispatcher, ChatManager $chatManager, Manager $roomManager, TalkSession $talkSession, IUserSession $userSession) { $this->dispatcher = $dispatcher; $this->chatManager = $chatManager; + $this->roomManager = $roomManager; $this->talkSession = $talkSession; $this->userSession = $userSession; } @@ -129,6 +135,17 @@ public function register() { $this->sendSystemMessage($room, 'moderator_demoted', ['user' => $event->getArgument('user')]); } }); + $this->dispatcher->addListener('OCP\Share::postShare', function(GenericEvent $event) { + /** @var IShare $share */ + $share = $event->getSubject(); + + if ($share->getShareType() !== Share::SHARE_TYPE_ROOM) { + return; + } + + $room = $this->roomManager->getRoomByToken($share->getSharedWith()); + $this->sendSystemMessage($room, 'file_shared', ['share' => $share->getId()]); + }); } protected function sendSystemMessage(Room $room, string $message, array $parameters = []) { diff --git a/lib/Chat/SystemMessage/Parser.php b/lib/Chat/SystemMessage/Parser.php index dc9e3b91b48..918c360b0ac 100644 --- a/lib/Chat/SystemMessage/Parser.php +++ b/lib/Chat/SystemMessage/Parser.php @@ -24,8 +24,10 @@ use OCA\Spreed\Exceptions\ParticipantNotFoundException; use OCA\Spreed\GuestManager; +use OCA\Spreed\Share\RoomShareProvider; use OCP\Comments\IComment; use OCP\IL10N; +use OCP\IURLGenerator; use OCP\IUser; use OCP\IUserManager; use OCP\IUserSession; @@ -38,6 +40,10 @@ class Parser { protected $guestManager; /** @var IUserSession */ protected $userSession; + /** @var RoomShareProvider */ + protected $shareProvider; + /** @var IURLGenerator */ + protected $url; /** @var IL10N */ protected $l; @@ -46,10 +52,17 @@ class Parser { /** @var string[] */ protected $guestNames = []; - public function __construct(IUserManager $userManager, GuestManager $guestManager, IUserSession $userSession, IL10N $l) { + public function __construct(IUserManager $userManager, + GuestManager $guestManager, + IUserSession $userSession, + RoomShareProvider $shareProvider, + IURLGenerator $url, + IL10N $l) { $this->userManager = $userManager; $this->guestManager = $guestManager; $this->userSession = $userSession; + $this->shareProvider = $shareProvider; + $this->url = $url; $this->l = $l; } @@ -146,6 +159,19 @@ public function parseMessage(IComment $comment, string $displayName): array { } else if ($currentUser instanceof IUser && $currentUser->getUID() === $parsedParameters['user']['id']) { $parsedMessage = $this->l->t('{actor} demoted you from moderator'); } + } else if ($message === 'file_shared') { + try { + $parsedParameters['file'] = $this->getFileFromShare($parameters['share']); + $parsedMessage = $this->l->t('{actor} shared {file} into the conversation'); + if ($currentUserIsActor) { + $parsedMessage = $this->l->t('You shared {file} into the conversation'); + } + } catch (\Exception $e) { + $parsedMessage = $this->l->t('{actor} shared a file which is no longer available'); + if ($currentUserIsActor) { + $parsedMessage = $this->l->t('You shared a file which is no longer available'); + } + } } $comment->setMessage($message); @@ -161,6 +187,36 @@ protected function getActor(IComment $comment): array { return $this->getUser($comment->getActorId()); } + /** + * @param string $shareId + * @return array + * @throws \OCP\Files\InvalidPathException + * @throws \OCP\Files\NotFoundException + * @throws \OCP\Share\Exceptions\ShareNotFound + */ + protected function getFileFromShare(string $shareId): array { + $share = $this->shareProvider->getShareById($shareId); + $node = $share->getNode(); + + + if ($this->userSession->isLoggedIn()) { + $url = $this->url->linkToRouteAbsolute('files.viewcontroller.showFile', [ + 'fileid' => $node->getId(), + ]); + } else { + $url = $this->url->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', [ + 'token' => $share->getToken(), + ]); + } + + return [ + 'type' => 'file', + 'id' => $shareId, + 'name' => $node->getName(), + 'link' => $url, + ]; + } + protected function getUser(string $uid): array { if (!isset($this->displayNames[$uid])) { $this->displayNames[$uid] = $this->getDisplayName($uid);