diff options
Diffstat (limited to 'apps/files_sharing/tests/ApiTest.php')
-rw-r--r-- | apps/files_sharing/tests/ApiTest.php | 1501 |
1 files changed, 1501 insertions, 0 deletions
diff --git a/apps/files_sharing/tests/ApiTest.php b/apps/files_sharing/tests/ApiTest.php new file mode 100644 index 00000000000..960f29224bb --- /dev/null +++ b/apps/files_sharing/tests/ApiTest.php @@ -0,0 +1,1501 @@ +<?php + +/** + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only + */ +namespace OCA\Files_Sharing\Tests; + +use OC\Core\AppInfo\ConfigLexicon; +use OC\Files\Cache\Scanner; +use OC\Files\FileInfo; +use OC\Files\Filesystem; +use OC\Files\Storage\Temporary; +use OC\Files\View; +use OCA\Federation\TrustedServers; +use OCA\Files_Sharing\Controller\ShareAPIController; +use OCP\App\IAppManager; +use OCP\AppFramework\OCS\OCSBadRequestException; +use OCP\AppFramework\OCS\OCSException; +use OCP\AppFramework\OCS\OCSForbiddenException; +use OCP\AppFramework\OCS\OCSNotFoundException; +use OCP\Constants; +use OCP\Files\Folder; +use OCP\Files\IRootFolder; +use OCP\IAppConfig; +use OCP\IConfig; +use OCP\IDateTimeZone; +use OCP\IGroupManager; +use OCP\IL10N; +use OCP\IPreview; +use OCP\IRequest; +use OCP\ITagManager; +use OCP\IURLGenerator; +use OCP\IUserManager; +use OCP\Mail\IMailer; +use OCP\Server; +use OCP\Share\IProviderFactory; +use OCP\Share\IShare; +use OCP\UserStatus\IManager as IUserStatusManager; +use PHPUnit\Framework\MockObject\MockObject; +use Psr\Container\ContainerInterface; +use Psr\Log\LoggerInterface; + +/** + * Class ApiTest + * + * @group DB + * TODO: convert to real integration tests + */ +class ApiTest extends TestCase { + public const TEST_FOLDER_NAME = '/folder_share_api_test'; + public const APP_NAME = 'files_sharing'; + + private static $tempStorage; + + private Folder $userFolder; + private string $subsubfolder; + protected IAppConfig&MockObject $appConfig; + + protected function setUp(): void { + parent::setUp(); + + Server::get(IConfig::class)->setAppValue('core', 'shareapi_exclude_groups', 'no'); + Server::get(IConfig::class)->setAppValue('core', 'shareapi_expire_after_n_days', '7'); + + Filesystem::getLoader()->removeStorageWrapper('sharing_mask'); + + $this->folder = self::TEST_FOLDER_NAME; + $this->subfolder = '/subfolder_share_api_test'; + $this->subsubfolder = '/subsubfolder_share_api_test'; + + $this->filename = '/share-api-test.txt'; + + // save file with content + $this->view->file_put_contents($this->filename, $this->data); + $this->view->mkdir($this->folder); + $this->view->mkdir($this->folder . $this->subfolder); + $this->view->mkdir($this->folder . $this->subfolder . $this->subsubfolder); + $this->view->file_put_contents($this->folder . $this->filename, $this->data); + $this->view->file_put_contents($this->folder . $this->subfolder . $this->filename, $this->data); + $mount = $this->view->getMount($this->filename); + $mount->getStorage()->getScanner()->scan('', Scanner::SCAN_RECURSIVE); + + $this->userFolder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER1); + + $this->appConfig = $this->createMock(IAppConfig::class); + } + + protected function tearDown(): void { + if ($this->view instanceof View) { + $this->view->unlink($this->filename); + $this->view->deleteAll($this->folder); + } + + self::$tempStorage = null; + + parent::tearDown(); + } + + /** + * @param string $userId The userId of the caller + * @return ShareAPIController + */ + private function createOCS($userId) { + $l = $this->getMockBuilder(IL10N::class)->getMock(); + $l->method('t') + ->willReturnCallback(function ($text, $parameters = []) { + return vsprintf($text, $parameters); + }); + $config = $this->createMock(IConfig::class); + $appManager = $this->createMock(IAppManager::class); + $serverContainer = $this->createMock(ContainerInterface::class); + $userStatusManager = $this->createMock(IUserStatusManager::class); + $previewManager = $this->createMock(IPreview::class); + $dateTimeZone = $this->createMock(IDateTimeZone::class); + $logger = $this->createMock(LoggerInterface::class); + $providerFactory = $this->createMock(IProviderFactory::class); + $mailer = $this->createMock(IMailer::class); + $tagManager = $this->createMock(ITagManager::class); + $trustedServers = $this->createMock(TrustedServers::class); + $dateTimeZone->method('getTimeZone')->willReturn(new \DateTimeZone(date_default_timezone_get())); + + return new ShareAPIController( + self::APP_NAME, + $this->getMockBuilder(IRequest::class)->getMock(), + $this->shareManager, + Server::get(IGroupManager::class), + Server::get(IUserManager::class), + Server::get(IRootFolder::class), + Server::get(IURLGenerator::class), + $l, + $config, + $this->appConfig, + $appManager, + $serverContainer, + $userStatusManager, + $previewManager, + $dateTimeZone, + $logger, + $providerFactory, + $mailer, + $tagManager, + $trustedServers, + $userId, + ); + } + + public function testCreateShareUserFile(): void { + $this->setUp(); // for some reasons phpunit refuses to do this for us only for this test + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $result = $ocs->createShare($this->filename, Constants::PERMISSION_ALL, IShare::TYPE_USER, self::TEST_FILES_SHARING_API_USER2); + $ocs->cleanup(); + + $data = $result->getData(); + $this->assertEquals(19, $data['permissions']); + $this->assertEmpty($data['expiration']); + + $this->shareManager->getShareById('ocinternal:' . $data['id']); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $ocs->deleteShare($data['id']); + + $ocs->cleanup(); + } + + public function testCreateShareUserFolder(): void { + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $result = $ocs->createShare($this->folder, Constants::PERMISSION_ALL, IShare::TYPE_USER, self::TEST_FILES_SHARING_API_USER2); + $ocs->cleanup(); + + $data = $result->getData(); + $this->assertEquals(31, $data['permissions']); + $this->assertEmpty($data['expiration']); + + $this->shareManager->getShareById('ocinternal:' . $data['id']); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $ocs->deleteShare($data['id']); + $ocs->cleanup(); + } + + + public function testCreateShareGroupFile(): void { + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $result = $ocs->createShare($this->filename, Constants::PERMISSION_ALL, IShare::TYPE_GROUP, self::TEST_FILES_SHARING_API_GROUP1); + $ocs->cleanup(); + + $data = $result->getData(); + $this->assertEquals(19, $data['permissions']); + $this->assertEmpty($data['expiration']); + + $this->shareManager->getShareById('ocinternal:' . $data['id']); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $ocs->deleteShare($data['id']); + $ocs->cleanup(); + } + + public function testCreateShareGroupFolder(): void { + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $result = $ocs->createShare($this->folder, Constants::PERMISSION_ALL, IShare::TYPE_GROUP, self::TEST_FILES_SHARING_API_GROUP1); + $ocs->cleanup(); + + $data = $result->getData(); + $this->assertEquals(31, $data['permissions']); + $this->assertEmpty($data['expiration']); + + $this->shareManager->getShareById('ocinternal:' . $data['id']); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $ocs->deleteShare($data['id']); + $ocs->cleanup(); + } + + /** + * @group RoutingWeirdness + */ + public function testCreateShareLink(): void { + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $result = $ocs->createShare($this->folder, Constants::PERMISSION_ALL, IShare::TYPE_LINK); + $ocs->cleanup(); + + $data = $result->getData(); + $this->assertEquals(Constants::PERMISSION_ALL, + $data['permissions']); + $this->assertEmpty($data['expiration']); + $this->assertTrue(is_string($data['token'])); + + // check for correct link + $url = Server::get(IURLGenerator::class)->getAbsoluteURL('/index.php/s/' . $data['token']); + $this->assertEquals($url, $data['url']); + + $this->shareManager->getShareById('ocinternal:' . $data['id']); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $ocs->deleteShare($data['id']); + $ocs->cleanup(); + } + + /** + * @group RoutingWeirdness + * @dataProvider dataAllowFederationOnPublicShares + */ + public function testCreateShareLinkPublicUpload(array $appConfig, int $permissions): void { + $this->appConfig->method('getValueBool') + ->willReturnMap([$appConfig]); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $result = $ocs->createShare($this->folder, Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'true'); + $ocs->cleanup(); + + $data = $result->getData(); + $this->assertEquals( + Constants::PERMISSION_READ + | Constants::PERMISSION_CREATE + | Constants::PERMISSION_UPDATE + | Constants::PERMISSION_DELETE + | $permissions, + $data['permissions'] + ); + $this->assertEmpty($data['expiration']); + $this->assertTrue(is_string($data['token'])); + + // check for correct link + $url = Server::get(IURLGenerator::class)->getAbsoluteURL('/index.php/s/' . $data['token']); + $this->assertEquals($url, $data['url']); + + $this->shareManager->getShareById('ocinternal:' . $data['id']); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $ocs->deleteShare($data['id']); + $ocs->cleanup(); + } + + public function testEnforceLinkPassword(): void { + $password = md5(time()); + $config = Server::get(IConfig::class); + $config->setAppValue('core', 'shareapi_enforce_links_password', 'yes'); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + try { + $ocs->createShare($this->folder, Constants::PERMISSION_ALL, IShare::TYPE_LINK); + $this->fail(); + } catch (OCSForbiddenException $e) { + } + $ocs->cleanup(); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + try { + $ocs->createShare($this->folder, Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'false', ''); + $this->fail(); + } catch (OCSForbiddenException $e) { + } + $ocs->cleanup(); + + // share with password should succeed + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $result = $ocs->createShare($this->folder, Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'false', $password); + $ocs->cleanup(); + + $data = $result->getData(); + + // setting new password should succeed + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $ocs->updateShare($data['id'], null, $password); + $ocs->cleanup(); + + // removing password should fail + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + try { + $ocs->updateShare($data['id']); + $this->fail(); + } catch (OCSBadRequestException $e) { + } + $ocs->cleanup(); + + // cleanup + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $ocs->deleteShare($data['id']); + $ocs->cleanup(); + + $config->setAppValue('core', 'shareapi_enforce_links_password', 'no'); + $this->addToAssertionCount(1); + } + + /** + * @medium + */ + public function testSharePermissions(): void { + // sharing file to a user should work if shareapi_exclude_groups is set + // to no + Server::get(IConfig::class)->setAppValue('core', 'shareapi_exclude_groups', 'no'); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $result = $ocs->createShare($this->filename, Constants::PERMISSION_ALL, IShare::TYPE_USER, self::TEST_FILES_SHARING_API_USER2); + $ocs->cleanup(); + + $data = $result->getData(); + + $this->shareManager->getShareById('ocinternal:' . $data['id']); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $ocs->deleteShare($data['id']); + $ocs->cleanup(); + + // exclude groups, but not the group the user belongs to. Sharing should still work + Server::get(IConfig::class)->setAppValue('core', 'shareapi_exclude_groups', 'yes'); + Server::get(IConfig::class)->setAppValue('core', 'shareapi_exclude_groups_list', 'admin,group1,group2'); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $result = $ocs->createShare($this->filename, Constants::PERMISSION_ALL, IShare::TYPE_USER, self::TEST_FILES_SHARING_API_USER2); + $ocs->cleanup(); + + $data = $result->getData(); + + $this->shareManager->getShareById('ocinternal:' . $data['id']); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $ocs->deleteShare($data['id']); + $ocs->cleanup(); + + // now we exclude the group the user belongs to ('group'), sharing should fail now + Server::get(IConfig::class)->setAppValue('core', 'shareapi_exclude_groups_list', 'admin,group'); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $ocs->createShare($this->filename, Constants::PERMISSION_ALL, IShare::TYPE_USER, self::TEST_FILES_SHARING_API_USER2); + $ocs->cleanup(); + + // cleanup + Server::get(IConfig::class)->setAppValue('core', 'shareapi_exclude_groups', 'no'); + Server::get(IConfig::class)->setAppValue('core', 'shareapi_exclude_groups_list', ''); + + $this->addToAssertionCount(1); + } + + + /** + * @medium + */ + public function testGetAllShares(): void { + $node = $this->userFolder->get($this->filename); + + $share = $this->shareManager->newShare(); + $share->setNode($node) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER1) + ->setSharedWith(self::TEST_FILES_SHARING_API_USER2) + ->setShareType(IShare::TYPE_USER) + ->setPermissions(19); + + $share = $this->shareManager->createShare($share); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $result = $ocs->getShares(); + $ocs->cleanup(); + + $this->assertTrue(count($result->getData()) === 1); + + $this->shareManager->deleteShare($share); + } + + public function testGetAllSharesWithMe(): void { + $this->loginAsUser(self::TEST_FILES_SHARING_API_USER2); + $this->logout(); + + $node1 = $this->userFolder->get($this->filename); + $share1 = $this->shareManager->newShare(); + $share1->setNode($node1) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER1) + ->setSharedWith(self::TEST_FILES_SHARING_API_USER2) + ->setShareType(IShare::TYPE_USER) + ->setPermissions(19); + $share1 = $this->shareManager->createShare($share1); + $share1->setStatus(IShare::STATUS_ACCEPTED); + $this->shareManager->updateShare($share1); + + $node2 = $this->userFolder->get($this->folder); + $share2 = $this->shareManager->newShare(); + $share2->setNode($node2) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER1) + ->setSharedWith(self::TEST_FILES_SHARING_API_USER2) + ->setShareType(IShare::TYPE_USER) + ->setPermissions(31); + $share2 = $this->shareManager->createShare($share2); + $share2->setStatus(IShare::STATUS_ACCEPTED); + $this->shareManager->updateShare($share2); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER2); + $result = $ocs->getShares('true'); + $ocs->cleanup(); + + $this->assertCount(2, $result->getData()); + + $this->shareManager->deleteShare($share1); + $this->shareManager->deleteShare($share2); + } + + /** + * @medium + * @group RoutingWeirdness + */ + public function testPublicLinkUrl(): void { + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $result = $ocs->createShare($this->folder, Constants::PERMISSION_ALL, IShare::TYPE_LINK); + $ocs->cleanup(); + + $data = $result->getData(); + + // check if we have a token + $this->assertTrue(is_string($data['token'])); + $id = $data['id']; + + // check for correct link + $url = Server::get(IURLGenerator::class)->getAbsoluteURL('/index.php/s/' . $data['token']); + $this->assertEquals($url, $data['url']); + + // check for link in getall shares + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $result = $ocs->getShares(); + $ocs->cleanup(); + + $data = $result->getData(); + $this->assertEquals($url, current($data)['url']); + + // check for path + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $result = $ocs->getShares(); + $ocs->cleanup(); + + $data = $result->getData(); + $this->assertEquals($url, current($data)['url']); + + // check in share id + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $result = $ocs->getShare($id); + $ocs->cleanup(); + + $data = $result->getData(); + $this->assertEquals($url, current($data)['url']); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $ocs->deleteShare($id); + $ocs->cleanup(); + } + + /** + * @medium + * @depends testCreateShareUserFile + * @depends testCreateShareLink + */ + public function testGetShareFromSource(): void { + $node = $this->userFolder->get($this->filename); + $share = $this->shareManager->newShare(); + $share->setNode($node) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER1) + ->setSharedWith(self::TEST_FILES_SHARING_API_USER2) + ->setShareType(IShare::TYPE_USER) + ->setPermissions(19); + $share1 = $this->shareManager->createShare($share); + + $share = $this->shareManager->newShare(); + $share->setNode($node) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER1) + ->setShareType(IShare::TYPE_LINK) + ->setPermissions(1); + $share2 = $this->shareManager->createShare($share); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $result = $ocs->getShares(); + $ocs->cleanup(); + + // test should return one share created from testCreateShare() + $this->assertTrue(count($result->getData()) === 2); + + $this->shareManager->deleteShare($share1); + $this->shareManager->deleteShare($share2); + } + + /** + * @medium + * @depends testCreateShareUserFile + * @depends testCreateShareLink + */ + public function testGetShareFromSourceWithReshares(): void { + $node = $this->userFolder->get($this->filename); + $share1 = $this->shareManager->newShare(); + $share1->setNode($node) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER1) + ->setSharedWith(self::TEST_FILES_SHARING_API_USER2) + ->setShareType(IShare::TYPE_USER) + ->setPermissions(19); + $share1 = $this->shareManager->createShare($share1); + + $share2 = $this->shareManager->newShare(); + $share2->setNode($node) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER2) + ->setSharedWith(self::TEST_FILES_SHARING_API_USER3) + ->setShareType(IShare::TYPE_USER) + ->setPermissions(19); + $share2 = $this->shareManager->createShare($share2); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $result = $ocs->getShares(); + $ocs->cleanup(); + + // test should return one share + $this->assertTrue(count($result->getData()) === 1); + + // now also ask for the reshares + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $result = $ocs->getShares('false', 'true', 'false', $this->filename); + $ocs->cleanup(); + + // now we should get two shares, the initial share and the reshare + $this->assertCount(2, $result->getData()); + + $this->shareManager->deleteShare($share1); + $this->shareManager->deleteShare($share2); + } + + /** + * @medium + * @depends testCreateShareUserFile + */ + public function testGetShareFromId(): void { + $node = $this->userFolder->get($this->filename); + $share1 = $this->shareManager->newShare(); + $share1->setNode($node) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER1) + ->setSharedWith(self::TEST_FILES_SHARING_API_USER2) + ->setShareType(IShare::TYPE_USER) + ->setPermissions(19); + $share1 = $this->shareManager->createShare($share1); + + // call getShare() with share ID + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $result = $ocs->getShare($share1->getId()); + $ocs->cleanup(); + + // test should return one share created from testCreateShare() + $this->assertEquals(1, count($result->getData())); + + $this->shareManager->deleteShare($share1); + } + + /** + * @medium + */ + public function testGetShareFromFolder(): void { + $node1 = $this->userFolder->get($this->filename); + $share1 = $this->shareManager->newShare(); + $share1->setNode($node1) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER1) + ->setSharedWith(self::TEST_FILES_SHARING_API_USER2) + ->setShareType(IShare::TYPE_USER) + ->setPermissions(19); + $share1 = $this->shareManager->createShare($share1); + + $node2 = $this->userFolder->get($this->folder . '/' . $this->filename); + $share2 = $this->shareManager->newShare(); + $share2->setNode($node2) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER1) + ->setShareType(IShare::TYPE_LINK) + ->setPermissions(1); + $share2 = $this->shareManager->createShare($share2); + + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $result = $ocs->getShares('false', 'false', 'true', $this->folder); + $ocs->cleanup(); + + // test should return one share within $this->folder + $this->assertTrue(count($result->getData()) === 1); + + $this->shareManager->deleteShare($share1); + $this->shareManager->deleteShare($share2); + } + + public function testGetShareFromFolderWithFile(): void { + $node1 = $this->userFolder->get($this->filename); + $share1 = $this->shareManager->newShare(); + $share1->setNode($node1) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER1) + ->setSharedWith(self::TEST_FILES_SHARING_API_USER2) + ->setShareType(IShare::TYPE_USER) + ->setPermissions(19); + $share1 = $this->shareManager->createShare($share1); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + try { + $ocs->getShares('false', 'false', 'true', $this->filename); + $this->fail(); + } catch (OCSBadRequestException $e) { + $this->assertEquals('Not a directory', $e->getMessage()); + } + $ocs->cleanup(); + + $this->shareManager->deleteShare($share1); + } + + /** + * share a folder, than reshare a file within the shared folder and check if we construct the correct path + * @medium + */ + public function testGetShareFromFolderReshares(): void { + $node1 = $this->userFolder->get($this->folder); + $share1 = $this->shareManager->newShare(); + $share1->setNode($node1) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER1) + ->setSharedWith(self::TEST_FILES_SHARING_API_USER2) + ->setShareType(IShare::TYPE_USER) + ->setPermissions(31); + $share1 = $this->shareManager->createShare($share1); + $share1->setStatus(IShare::STATUS_ACCEPTED); + $this->shareManager->updateShare($share1); + + $node2 = $this->userFolder->get($this->folder . '/' . $this->filename); + $share2 = $this->shareManager->newShare(); + $share2->setNode($node2) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER2) + ->setShareType(IShare::TYPE_LINK) + ->setPermissions(1); + $share2 = $this->shareManager->createShare($share2); + $share2->setStatus(IShare::STATUS_ACCEPTED); + $this->shareManager->updateShare($share2); + + $node3 = $this->userFolder->get($this->folder . '/' . $this->subfolder . '/' . $this->filename); + $share3 = $this->shareManager->newShare(); + $share3->setNode($node3) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER2) + ->setShareType(IShare::TYPE_LINK) + ->setPermissions(1); + $share3 = $this->shareManager->createShare($share3); + $share3->setStatus(IShare::STATUS_ACCEPTED); + $this->shareManager->updateShare($share3); + + $testValues = [ + ['query' => $this->folder, + 'expectedResult' => $this->folder . $this->filename], + ['query' => $this->folder . $this->subfolder, + 'expectedResult' => $this->folder . $this->subfolder . $this->filename], + ]; + + foreach ($testValues as $value) { + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER2); + $result = $ocs->getShares('false', 'false', 'true', $value['query']); + $ocs->cleanup(); + + // test should return one share within $this->folder + $data = $result->getData(); + + $this->assertEquals($value['expectedResult'], $data[0]['path']); + } + + // cleanup + $this->shareManager->deleteShare($share1); + $this->shareManager->deleteShare($share2); + $this->shareManager->deleteShare($share3); + } + + /** + * reshare a sub folder and check if we get the correct path + * @medium + */ + public function testGetShareFromSubFolderReShares(): void { + $node1 = $this->userFolder->get($this->folder . $this->subfolder); + $share1 = $this->shareManager->newShare(); + $share1->setNode($node1) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER1) + ->setSharedWith(self::TEST_FILES_SHARING_API_USER2) + ->setShareType(IShare::TYPE_USER) + ->setPermissions(31); + $share1 = $this->shareManager->createShare($share1); + $share1->setStatus(IShare::STATUS_ACCEPTED); + $this->shareManager->updateShare($share1); + + $node2 = Server::get(IRootFolder::class)->getUserFolder(self::TEST_FILES_SHARING_API_USER2)->get($this->subfolder); + $share2 = $this->shareManager->newShare(); + $share2->setNode($node2) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER2) + ->setShareType(IShare::TYPE_LINK) + ->setPermissions(1); + $share2 = $this->shareManager->createShare($share2); + $share2->setStatus(IShare::STATUS_ACCEPTED); + $this->shareManager->updateShare($share2); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER2); + $result = $ocs->getShares(); + $ocs->cleanup(); + + // test should return one share within $this->folder + $data = $result->getData(); + + // we should get exactly one result + $this->assertCount(1, $data); + + $this->assertEquals($this->subfolder, $data[0]['path']); + + $this->shareManager->deleteShare($share2); + $this->shareManager->deleteShare($share1); + } + + /** + * test re-re-share of folder if the path gets constructed correctly + * @medium + */ + public function XtestGetShareFromFolderReReShares() { + $node1 = $this->userFolder->get($this->folder . $this->subfolder); + $share1 = $this->shareManager->newShare(); + $share1->setNode($node1) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER1) + ->setSharedWith(self::TEST_FILES_SHARING_API_USER2) + ->setShareType(IShare::TYPE_USER) + ->setPermissions(31); + $share1 = $this->shareManager->createShare($share1); + + $node2 = $this->userFolder->get($this->folder . $this->subfolder . $this->subsubfolder); + $share2 = $this->shareManager->newShare(); + $share2->setNode($node2) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER2) + ->setSharedWith(self::TEST_FILES_SHARING_API_USER3) + ->setShareType(IShare::TYPE_USER) + ->setPermissions(31); + $share2 = $this->shareManager->createShare($share2); + + $share3 = $this->shareManager->newShare(); + $share3->setNode($node2) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER3) + ->setShareType(IShare::TYPE_LINK) + ->setPermissions(1); + $share3 = $this->shareManager->createShare($share3); + + /* + * Test as recipient + */ + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER3); + $result = $ocs->getShares(); + $ocs->cleanup(); + + // test should return one share within $this->folder + $data = $result->getData(); + + // we should get exactly one result + $this->assertCount(1, $data); + $this->assertEquals($this->subsubfolder, $data[0]['path']); + + /* + * Test for first owner/initiator + */ + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $result = $ocs->getShares(); + $ocs->cleanup(); + + // test should return one share within $this->folder + $data = $result->getData(); + + // we should get exactly one result + $this->assertCount(1, $data); + $this->assertEquals($this->folder . $this->subfolder, $data[0]['path']); + + /* + * Test for second initiator + */ + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER2); + $result = $ocs->getShares(); + $ocs->cleanup(); + + // test should return one share within $this->folder + $data = $result->getData(); + + // we should get exactly one result + $this->assertCount(1, $data); + $this->assertEquals($this->subfolder . $this->subsubfolder, $data[0]['path']); + + $this->shareManager->deleteShare($share1); + $this->shareManager->deleteShare($share2); + $this->shareManager->deleteShare($share3); + } + + /** + * test multiple shared folder if the path gets constructed correctly + * @medium + */ + public function testGetShareMultipleSharedFolder(): void { + $this->setUp(); + $node1 = $this->userFolder->get($this->folder . $this->subfolder); + $share1 = $this->shareManager->newShare(); + $share1->setNode($node1) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER1) + ->setSharedWith(self::TEST_FILES_SHARING_API_USER2) + ->setShareType(IShare::TYPE_USER) + ->setPermissions(31); + $share1 = $this->shareManager->createShare($share1); + $share1->setStatus(IShare::STATUS_ACCEPTED); + $this->shareManager->updateShare($share1); + + $node2 = $this->userFolder->get($this->folder); + $share2 = $this->shareManager->newShare(); + $share2->setNode($node2) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER1) + ->setSharedWith(self::TEST_FILES_SHARING_API_USER2) + ->setShareType(IShare::TYPE_USER) + ->setPermissions(31); + $share2 = $this->shareManager->createShare($share2); + $share2->setStatus(IShare::STATUS_ACCEPTED); + $this->shareManager->updateShare($share2); + + $share3 = $this->shareManager->newShare(); + $share3->setNode($node1) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER2) + ->setShareType(IShare::TYPE_LINK) + ->setPermissions(1); + $share3 = $this->shareManager->createShare($share3); + $share3->setStatus(IShare::STATUS_ACCEPTED); + $this->shareManager->updateShare($share3); + + // $request = $this->createRequest(['path' => $this->subfolder]); + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER2); + $result1 = $ocs->getShares('false', 'false', 'false', $this->subfolder); + $ocs->cleanup(); + + // test should return one share within $this->folder + $data1 = $result1->getData(); + $this->assertCount(1, $data1); + $s1 = reset($data1); + + //$request = $this->createRequest(['path' => $this->folder.$this->subfolder]); + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER2); + $result2 = $ocs->getShares('false', 'false', 'false', $this->folder . $this->subfolder); + $ocs->cleanup(); + + // test should return one share within $this->folder + $data2 = $result2->getData(); + $this->assertCount(1, $data2); + $s2 = reset($data2); + + $this->assertEquals($this->subfolder, $s1['path']); + $this->assertEquals($this->folder . $this->subfolder, $s2['path']); + + $this->shareManager->deleteShare($share1); + $this->shareManager->deleteShare($share2); + $this->shareManager->deleteShare($share3); + } + + /** + * test re-re-share of folder if the path gets constructed correctly + * @medium + */ + public function testGetShareFromFileReReShares(): void { + $node1 = $this->userFolder->get($this->folder . $this->subfolder); + $share1 = $this->shareManager->newShare(); + $share1->setNode($node1) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER1) + ->setSharedWith(self::TEST_FILES_SHARING_API_USER2) + ->setShareType(IShare::TYPE_USER) + ->setPermissions(31); + $share1 = $this->shareManager->createShare($share1); + $share1->setStatus(IShare::STATUS_ACCEPTED); + $this->shareManager->updateShare($share1); + + $user2Folder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER2); + $node2 = $user2Folder->get($this->subfolder . $this->filename); + $share2 = $this->shareManager->newShare(); + $share2->setNode($node2) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER2) + ->setSharedWith(self::TEST_FILES_SHARING_API_USER3) + ->setShareType(IShare::TYPE_USER) + ->setPermissions(19); + $share2 = $this->shareManager->createShare($share2); + $share2->setStatus(IShare::STATUS_ACCEPTED); + $this->shareManager->updateShare($share2); + + $user3Folder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER3); + $node3 = $user3Folder->get($this->filename); + $share3 = $this->shareManager->newShare(); + $share3->setNode($node3) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER3) + ->setShareType(IShare::TYPE_LINK) + ->setPermissions(1); + $share3 = $this->shareManager->createShare($share3); + $share3->setStatus(IShare::STATUS_ACCEPTED); + $this->shareManager->updateShare($share3); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER3); + $result = $ocs->getShares(); + $ocs->cleanup(); + + // test should return one share within $this->folder + $data = $result->getData(); + + // we should get exactly one result + $this->assertCount(1, $data); + + $this->assertEquals($this->filename, $data[0]['path']); + + $this->shareManager->deleteShare($share1); + $this->shareManager->deleteShare($share2); + $this->shareManager->deleteShare($share3); + } + + /** + * @medium + */ + public function testGetShareFromUnknownId(): void { + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER3); + try { + $ocs->getShare(0); + $this->fail(); + } catch (OCSNotFoundException $e) { + $this->assertEquals('Wrong share ID, share does not exist', $e->getMessage()); + } + $ocs->cleanup(); + } + + /** + * @medium + * @depends testCreateShareUserFile + * @depends testCreateShareLink + */ + public function testUpdateShare(): void { + $password = md5(time()); + + $node1 = $this->userFolder->get($this->filename); + $share1 = $this->shareManager->newShare(); + $share1->setNode($node1) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER1) + ->setSharedWith(self::TEST_FILES_SHARING_API_USER2) + ->setShareType(IShare::TYPE_USER) + ->setPermissions(19) + ->setAttributes($this->shareManager->newShare()->newAttributes()); + + $this->assertNotNull($share1->getAttributes()); + $share1 = $this->shareManager->createShare($share1); + $this->assertEquals(19, $share1->getPermissions()); + + $share2 = $this->shareManager->newShare(); + $share2->setNode($node1) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER1) + ->setShareType(IShare::TYPE_LINK) + ->setPermissions(1); + $share2 = $this->shareManager->createShare($share2); + $this->assertEquals(1, $share2->getPermissions()); + + // update permissions + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $ocs->updateShare( + $share1->getId(), 1, null, null, null, null, null, null, null, + '[{"scope": "app1", "key": "attr1", "value": true}]' + ); + $ocs->cleanup(); + + $share1 = $this->shareManager->getShareById('ocinternal:' . $share1->getId()); + $this->assertEquals(1, $share1->getPermissions()); + $this->assertEquals(true, $share1->getAttributes()->getAttribute('app1', 'attr1')); + + // update password for link share + $this->assertNull($share2->getPassword()); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $ocs->updateShare($share2->getId(), null, $password); + $ocs->cleanup(); + + $share2 = $this->shareManager->getShareById('ocinternal:' . $share2->getId()); + $this->assertNotNull($share2->getPassword()); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $ocs->updateShare($share2->getId(), null, ''); + $ocs->cleanup(); + + $share2 = $this->shareManager->getShareById('ocinternal:' . $share2->getId()); + $this->assertNull($share2->getPassword()); + + $this->shareManager->deleteShare($share1); + $this->shareManager->deleteShare($share2); + } + + /** + * @medium + * @dataProvider dataAllowFederationOnPublicShares + */ + public function testUpdateShareUpload(array $appConfig, int $permissions): void { + $this->appConfig->method('getValueBool')->willReturnMap([ + $appConfig, + ]); + + $node1 = $this->userFolder->get($this->folder); + $share1 = $this->shareManager->newShare(); + $share1->setNode($node1) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER1) + ->setShareType(IShare::TYPE_LINK) + ->setPermissions(1); + $share1 = $this->shareManager->createShare($share1); + + // update public upload + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $ocs->updateShare($share1->getId(), null, null, null, 'true'); + $ocs->cleanup(); + + $share1 = $this->shareManager->getShareById($share1->getFullId()); + $this->assertEquals( + Constants::PERMISSION_READ + | Constants::PERMISSION_CREATE + | Constants::PERMISSION_UPDATE + | Constants::PERMISSION_DELETE + | $permissions, + $share1->getPermissions() + ); + + // cleanup + $this->shareManager->deleteShare($share1); + } + + public static function dataAllowFederationOnPublicShares(): array { + return [ + [['core', ConfigLexicon::SHAREAPI_ALLOW_FEDERATION_ON_PUBLIC_SHARES, false, false], 0], + [['core', ConfigLexicon::SHAREAPI_ALLOW_FEDERATION_ON_PUBLIC_SHARES, false, true], Constants::PERMISSION_SHARE], + ]; + } + + /** + * @medium + */ + public function testUpdateShareExpireDate(): void { + $node1 = $this->userFolder->get($this->folder); + $share1 = $this->shareManager->newShare(); + $share1->setNode($node1) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER1) + ->setShareType(IShare::TYPE_LINK) + ->setPermissions(1); + $share1 = $this->shareManager->createShare($share1); + $share1->setStatus(IShare::STATUS_ACCEPTED); + $this->shareManager->updateShare($share1); + + $config = Server::get(IConfig::class); + + // enforce expire date, by default 7 days after the file was shared + $config->setAppValue('core', 'shareapi_default_expire_date', 'yes'); + $config->setAppValue('core', 'shareapi_enforce_expire_date', 'yes'); + + $dateWithinRange = new \DateTime(); + $dateWithinRange->add(new \DateInterval('P6D')); + + $dateOutOfRange = new \DateTime(); + $dateOutOfRange->add(new \DateInterval('P8D')); + + // update expire date to a valid value + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $ocs->updateShare($share1->getId(), null, null, null, null, $dateWithinRange->format('Y-m-d')); + $ocs->cleanup(); + + $share1 = $this->shareManager->getShareById($share1->getFullId()); + + // date should be changed + $dateWithinRange->setTime(0, 0, 0); + $dateWithinRange->setTimezone(new \DateTimeZone(date_default_timezone_get())); + $this->assertEquals($dateWithinRange, $share1->getExpirationDate()); + + // update expire date to a value out of range + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + try { + $ocs->updateShare($share1->getId()); + $this->fail(); + } catch (OCSBadRequestException $e) { + } + $ocs->cleanup(); + + $share1 = $this->shareManager->getShareById($share1->getFullId()); + + // date shouldn't be changed + $this->assertEquals($dateWithinRange, $share1->getExpirationDate()); + + // Try to remove expire date + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + try { + $ocs->updateShare($share1->getId()); + $this->fail(); + } catch (OCSBadRequestException $e) { + } + $ocs->cleanup(); + + $share1 = $this->shareManager->getShareById($share1->getFullId()); + + + // date shouldn't be changed + $this->assertEquals($dateWithinRange, $share1->getExpirationDate()); + // cleanup + $config->setAppValue('core', 'shareapi_default_expire_date', 'no'); + $config->setAppValue('core', 'shareapi_enforce_expire_date', 'no'); + $this->shareManager->deleteShare($share1); + } + + /** + * @medium + * @depends testCreateShareUserFile + */ + public function testDeleteShare(): void { + $node1 = $this->userFolder->get($this->filename); + $share1 = $this->shareManager->newShare(); + $share1->setNode($node1) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER1) + ->setSharedWith(self::TEST_FILES_SHARING_API_USER2) + ->setShareType(IShare::TYPE_USER) + ->setPermissions(19); + $share1 = $this->shareManager->createShare($share1); + + $share2 = $this->shareManager->newShare(); + $share2->setNode($node1) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER1) + ->setShareType(IShare::TYPE_LINK) + ->setPermissions(1); + $share2 = $this->shareManager->createShare($share2); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $ocs->deleteShare($share1->getId()); + $ocs->cleanup(); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $ocs->deleteShare($share2->getId()); + $ocs->cleanup(); + + $this->assertEmpty($this->shareManager->getSharesBy(self::TEST_FILES_SHARING_API_USER2, IShare::TYPE_USER)); + $this->assertEmpty($this->shareManager->getSharesBy(self::TEST_FILES_SHARING_API_USER2, IShare::TYPE_LINK)); + } + + /** + * test unshare of a reshared file + */ + public function testDeleteReshare(): void { + $node1 = $this->userFolder->get($this->folder); + $share1 = $this->shareManager->newShare(); + $share1->setNode($node1) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER1) + ->setSharedWith(self::TEST_FILES_SHARING_API_USER2) + ->setShareType(IShare::TYPE_USER) + ->setPermissions(31); + $share1 = $this->shareManager->createShare($share1); + $share1->setStatus(IShare::STATUS_ACCEPTED); + $this->shareManager->updateShare($share1); + + $user2folder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER2); + $node2 = $user2folder->get($this->folder . '/' . $this->filename); + $share2 = $this->shareManager->newShare(); + $share2->setNode($node2) + ->setSharedBy(self::TEST_FILES_SHARING_API_USER2) + ->setShareType(IShare::TYPE_LINK) + ->setPermissions(1); + $share2 = $this->shareManager->createShare($share2); + $share2->setStatus(IShare::STATUS_ACCEPTED); + $this->shareManager->updateShare($share2); + + // test if we can unshare the link again + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER2); + $ocs->deleteShare($share2->getId()); + $ocs->cleanup(); + + $this->shareManager->deleteShare($share1); + $this->addToAssertionCount(1); + } + + /** + * share a folder which contains a share mount point, should be forbidden + */ + public function testShareFolderWithAMountPoint(): void { + // user 1 shares a folder with user2 + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + + $share = $this->share( + IShare::TYPE_USER, + $this->folder, + self::TEST_FILES_SHARING_API_USER1, + self::TEST_FILES_SHARING_API_USER2, + Constants::PERMISSION_ALL + ); + $share->setStatus(IShare::STATUS_ACCEPTED); + $this->shareManager->updateShare($share); + + // user2 shares a file from the folder as link + self::loginHelper(self::TEST_FILES_SHARING_API_USER2); + + $view = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files'); + $view->mkdir('localDir'); + + // move mount point to the folder "localDir" + $result = $view->rename($this->folder, 'localDir/' . $this->folder); + $this->assertTrue($result !== false); + + // try to share "localDir" + $fileInfo2 = $view->getFileInfo('localDir'); + + $this->assertTrue($fileInfo2 instanceof FileInfo); + + $pass = true; + try { + $this->share( + IShare::TYPE_USER, + 'localDir', + self::TEST_FILES_SHARING_API_USER2, + self::TEST_FILES_SHARING_API_USER3, + Constants::PERMISSION_ALL + ); + } catch (\Exception $e) { + $pass = false; + } + + $this->assertFalse($pass); + + //cleanup + + $result = $view->rename('localDir/' . $this->folder, $this->folder); + $this->assertTrue($result !== false); + $view->unlink('localDir'); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + + $this->shareManager->deleteShare($share); + } + + /** + * Post init mount points hook for mounting simulated ext storage + */ + public static function initTestMountPointsHook($data) { + if ($data['user'] === self::TEST_FILES_SHARING_API_USER1) { + Filesystem::mount(self::$tempStorage, [], '/' . self::TEST_FILES_SHARING_API_USER1 . '/files' . self::TEST_FOLDER_NAME); + } + } + + /** + * Tests mounting a folder that is an external storage mount point. + */ + public function testShareStorageMountPoint(): void { + $tempStorage = new Temporary([]); + $tempStorage->file_put_contents('test.txt', 'abcdef'); + $tempStorage->getScanner()->scan(''); + + $this->registerMount(self::TEST_FILES_SHARING_API_USER1, $tempStorage, self::TEST_FILES_SHARING_API_USER1 . '/files' . self::TEST_FOLDER_NAME); + + // logging in will auto-mount the temp storage for user1 as well + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + + // user 1 shares the mount point folder with user2 + $share = $this->share( + IShare::TYPE_USER, + $this->folder, + self::TEST_FILES_SHARING_API_USER1, + self::TEST_FILES_SHARING_API_USER2, + Constants::PERMISSION_ALL + ); + $share->setStatus(IShare::STATUS_ACCEPTED); + $this->shareManager->updateShare($share); + + // user2: check that mount point name appears correctly + self::loginHelper(self::TEST_FILES_SHARING_API_USER2); + + $view = new View('/' . self::TEST_FILES_SHARING_API_USER2 . '/files'); + + $this->assertTrue($view->file_exists($this->folder)); + $this->assertTrue($view->file_exists($this->folder . '/test.txt')); + + self::loginHelper(self::TEST_FILES_SHARING_API_USER1); + + $this->shareManager->deleteShare($share); + + \OC_Hook::clear('OC_Filesystem', 'post_initMountPoints'); + \OC_Hook::clear('\OCA\Files_Sharing\Tests\ApiTest', 'initTestMountPointsHook'); + } + + public static function datesProvider() { + $date = new \DateTime(); + $date->setTime(0, 0); + $date->add(new \DateInterval('P5D')); + $date->setTimezone(new \DateTimeZone(date_default_timezone_get())); + + return [ + [$date->format('Y-m-d H:i:s'), true], + ['abc', false], + [$date->format('Y-m-d H:i:s') . 'xyz', false], + ]; + } + + /** + * Make sure only ISO 8601 dates are accepted + * + * @group RoutingWeirdness + */ + #[\PHPUnit\Framework\Attributes\DataProvider('datesProvider')] + public function testPublicLinkExpireDate($date, $valid): void { + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + + try { + $result = $ocs->createShare($this->folder, Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'false', '', null, $date); + $this->assertTrue($valid); + } catch (OCSNotFoundException $e) { + $this->assertFalse($valid); + $this->assertEquals('Invalid date. Format must be YYYY-MM-DD', $e->getMessage()); + $ocs->cleanup(); + return; + } + $ocs->cleanup(); + + $data = $result->getData(); + $this->assertTrue(is_string($data['token'])); + $this->assertEquals(substr($date, 0, 10), substr($data['expiration'], 0, 10)); + + // check for correct link + $url = Server::get(IURLGenerator::class)->getAbsoluteURL('/index.php/s/' . $data['token']); + $this->assertEquals($url, $data['url']); + + $share = $this->shareManager->getShareById('ocinternal:' . $data['id']); + + $this->assertEquals($date, $share->getExpirationDate()->format('Y-m-d H:i:s')); + + $this->shareManager->deleteShare($share); + } + + /** + * @group RoutingWeirdness + */ + public function testCreatePublicLinkExpireDateValid(): void { + $config = Server::get(IConfig::class); + + // enforce expire date, by default 7 days after the file was shared + $config->setAppValue('core', 'shareapi_default_expire_date', 'yes'); + $config->setAppValue('core', 'shareapi_enforce_expire_date', 'yes'); + + $date = new \DateTime(); + $date->add(new \DateInterval('P5D')); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $result = $ocs->createShare($this->filename, Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'false', '', null, $date->format('Y-m-d')); + $ocs->cleanup(); + + $data = $result->getData(); + $this->assertTrue(is_string($data['token'])); + $this->assertEquals($date->format('Y-m-d 00:00:00'), $data['expiration']); + + // check for correct link + $url = Server::get(IURLGenerator::class)->getAbsoluteURL('/index.php/s/' . $data['token']); + $this->assertEquals($url, $data['url']); + + $share = $this->shareManager->getShareById('ocinternal:' . $data['id']); + $date->setTime(0, 0, 0); + $this->assertEquals($date, $share->getExpirationDate()); + + $this->shareManager->deleteShare($share); + + $config->setAppValue('core', 'shareapi_default_expire_date', 'no'); + $config->setAppValue('core', 'shareapi_enforce_expire_date', 'no'); + } + + public function testCreatePublicLinkExpireDateInvalidFuture(): void { + $config = Server::get(IConfig::class); + + // enforce expire date, by default 7 days after the file was shared + $config->setAppValue('core', 'shareapi_default_expire_date', 'yes'); + $config->setAppValue('core', 'shareapi_enforce_expire_date', 'yes'); + + $date = new \DateTime(); + $date->add(new \DateInterval('P8D')); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + + try { + $ocs->createShare($this->filename, Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'false', '', null, $date->format('Y-m-d')); + $this->fail(); + } catch (OCSException $e) { + $this->assertEquals(404, $e->getCode()); + $this->assertEquals('Cannot set expiration date more than 7 days in the future', $e->getMessage()); + } + $ocs->cleanup(); + + $config->setAppValue('core', 'shareapi_default_expire_date', 'no'); + $config->setAppValue('core', 'shareapi_enforce_expire_date', 'no'); + } + + public function XtestCreatePublicLinkExpireDateInvalidPast() { + $config = Server::get(IConfig::class); + + $date = new \DateTime(); + $date->sub(new \DateInterval('P8D')); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + + try { + $ocs->createShare($this->filename, Constants::PERMISSION_ALL, IShare::TYPE_LINK, null, 'false', '', null, $date->format('Y-m-d')); + $this->fail(); + } catch (OCSException $e) { + $this->assertEquals(404, $e->getCode()); + $this->assertEquals('Expiration date is in the past', $e->getMessage()); + } + $ocs->cleanup(); + + $config->setAppValue('core', 'shareapi_default_expire_date', 'no'); + $config->setAppValue('core', 'shareapi_enforce_expire_date', 'no'); + } + + /** + * test for no invisible shares + * See: https://github.com/owncloud/core/issues/22295 + */ + public function testInvisibleSharesUser(): void { + // simulate a post request + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $result = $ocs->createShare($this->folder, Constants::PERMISSION_ALL, IShare::TYPE_USER, self::TEST_FILES_SHARING_API_USER2); + $ocs->cleanup(); + $data = $result->getData(); + + $topId = $data['id']; + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER2); + $ocs->acceptShare($topId); + $ocs->cleanup(); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER2); + $ocs->createShare($this->folder, Constants::PERMISSION_ALL, IShare::TYPE_LINK); + $ocs->cleanup(); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $ocs->deleteShare($topId); + $ocs->cleanup(); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $result = $ocs->getShares(); + $ocs->cleanup(); + + $this->assertEmpty($result->getData()); + } + + /** + * test for no invisible shares + * See: https://github.com/owncloud/core/issues/22295 + */ + public function testInvisibleSharesGroup(): void { + // simulate a post request + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $result = $ocs->createShare($this->folder, Constants::PERMISSION_ALL, IShare::TYPE_GROUP, self::TEST_FILES_SHARING_API_GROUP1); + $ocs->cleanup(); + $data = $result->getData(); + + $topId = $data['id']; + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER2); + $ocs->acceptShare($topId); + $ocs->cleanup(); + + \OC_Util::tearDownFS(); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER2); + $ocs->createShare($this->folder, Constants::PERMISSION_ALL, IShare::TYPE_LINK); + $ocs->cleanup(); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $ocs->deleteShare($topId); + $ocs->cleanup(); + + $ocs = $this->createOCS(self::TEST_FILES_SHARING_API_USER1); + $result = $ocs->getShares(); + $ocs->cleanup(); + + $this->assertEmpty($result->getData()); + } +} |