ApplicationTest.php 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-License-Identifier: AGPL-3.0-or-later
  5. */
  6. namespace OCA\Files_Sharing\Tests;
  7. use OCA\Files_Sharing\AppInfo\Application;
  8. use OCA\Files_Sharing\Listener\BeforeDirectFileDownloadListener;
  9. use OCA\Files_Sharing\Listener\BeforeZipCreatedListener;
  10. use OCA\Files_Sharing\SharedStorage;
  11. use OCP\Files\Events\BeforeDirectFileDownloadEvent;
  12. use OCP\Files\Events\BeforeZipCreatedEvent;
  13. use OCP\Files\File;
  14. use OCP\Files\Folder;
  15. use OCP\Files\IRootFolder;
  16. use OCP\Files\Storage\IStorage;
  17. use OCP\IUser;
  18. use OCP\IUserSession;
  19. use OCP\Share\IAttributes;
  20. use OCP\Share\IShare;
  21. use Test\TestCase;
  22. class ApplicationTest extends TestCase {
  23. private Application $application;
  24. /** @var IUserSession */
  25. private $userSession;
  26. /** @var IRootFolder */
  27. private $rootFolder;
  28. protected function setUp(): void {
  29. parent::setUp();
  30. $this->application = new Application([]);
  31. $this->userSession = $this->createMock(IUserSession::class);
  32. $this->rootFolder = $this->createMock(IRootFolder::class);
  33. }
  34. public function providesDataForCanGet(): array {
  35. // normal file (sender) - can download directly
  36. $senderFileStorage = $this->createMock(IStorage::class);
  37. $senderFileStorage->method('instanceOfStorage')->with(SharedStorage::class)->willReturn(false);
  38. $senderFile = $this->createMock(File::class);
  39. $senderFile->method('getStorage')->willReturn($senderFileStorage);
  40. $senderUserFolder = $this->createMock(Folder::class);
  41. $senderUserFolder->method('get')->willReturn($senderFile);
  42. $result[] = [ '/bar.txt', $senderUserFolder, true ];
  43. // shared file (receiver) with attribute secure-view-enabled set false -
  44. // can download directly
  45. $receiverFileShareAttributes = $this->createMock(IAttributes::class);
  46. $receiverFileShareAttributes->method('getAttribute')->with('permissions', 'download')->willReturn(true);
  47. $receiverFileShare = $this->createMock(IShare::class);
  48. $receiverFileShare->method('getAttributes')->willReturn($receiverFileShareAttributes);
  49. $receiverFileStorage = $this->createMock(SharedStorage::class);
  50. $receiverFileStorage->method('instanceOfStorage')->with(SharedStorage::class)->willReturn(true);
  51. $receiverFileStorage->method('getShare')->willReturn($receiverFileShare);
  52. $receiverFile = $this->createMock(File::class);
  53. $receiverFile->method('getStorage')->willReturn($receiverFileStorage);
  54. $receiverUserFolder = $this->createMock(Folder::class);
  55. $receiverUserFolder->method('get')->willReturn($receiverFile);
  56. $result[] = [ '/share-bar.txt', $receiverUserFolder, true ];
  57. // shared file (receiver) with attribute secure-view-enabled set true -
  58. // cannot download directly
  59. $secureReceiverFileShareAttributes = $this->createMock(IAttributes::class);
  60. $secureReceiverFileShareAttributes->method('getAttribute')->with('permissions', 'download')->willReturn(false);
  61. $secureReceiverFileShare = $this->createMock(IShare::class);
  62. $secureReceiverFileShare->method('getAttributes')->willReturn($secureReceiverFileShareAttributes);
  63. $secureReceiverFileStorage = $this->createMock(SharedStorage::class);
  64. $secureReceiverFileStorage->method('instanceOfStorage')->with(SharedStorage::class)->willReturn(true);
  65. $secureReceiverFileStorage->method('getShare')->willReturn($secureReceiverFileShare);
  66. $secureReceiverFile = $this->createMock(File::class);
  67. $secureReceiverFile->method('getStorage')->willReturn($secureReceiverFileStorage);
  68. $secureReceiverUserFolder = $this->createMock(Folder::class);
  69. $secureReceiverUserFolder->method('get')->willReturn($secureReceiverFile);
  70. $result[] = [ '/secure-share-bar.txt', $secureReceiverUserFolder, false ];
  71. return $result;
  72. }
  73. /**
  74. * @dataProvider providesDataForCanGet
  75. */
  76. public function testCheckDirectCanBeDownloaded(string $path, Folder $userFolder, bool $run): void {
  77. $user = $this->createMock(IUser::class);
  78. $user->method('getUID')->willReturn('test');
  79. $this->userSession->method('getUser')->willReturn($user);
  80. $this->userSession->method('isLoggedIn')->willReturn(true);
  81. $this->rootFolder->method('getUserFolder')->willReturn($userFolder);
  82. // Simulate direct download of file
  83. $event = new BeforeDirectFileDownloadEvent($path);
  84. $listener = new BeforeDirectFileDownloadListener(
  85. $this->userSession,
  86. $this->rootFolder
  87. );
  88. $listener->handle($event);
  89. $this->assertEquals($run, $event->isSuccessful());
  90. }
  91. public function providesDataForCanZip(): array {
  92. // Mock: Normal file/folder storage
  93. $nonSharedStorage = $this->createMock(IStorage::class);
  94. $nonSharedStorage->method('instanceOfStorage')->with(SharedStorage::class)->willReturn(false);
  95. // Mock: Secure-view file/folder shared storage
  96. $secureReceiverFileShareAttributes = $this->createMock(IAttributes::class);
  97. $secureReceiverFileShareAttributes->method('getAttribute')->with('permissions', 'download')->willReturn(false);
  98. $secureReceiverFileShare = $this->createMock(IShare::class);
  99. $secureReceiverFileShare->method('getAttributes')->willReturn($secureReceiverFileShareAttributes);
  100. $secureSharedStorage = $this->createMock(SharedStorage::class);
  101. $secureSharedStorage->method('instanceOfStorage')->with(SharedStorage::class)->willReturn(true);
  102. $secureSharedStorage->method('getShare')->willReturn($secureReceiverFileShare);
  103. // 1. can download zipped 2 non-shared files inside non-shared folder
  104. // 2. can download zipped non-shared folder
  105. $sender1File = $this->createMock(File::class);
  106. $sender1File->method('getStorage')->willReturn($nonSharedStorage);
  107. $sender1Folder = $this->createMock(Folder::class);
  108. $sender1Folder->method('getStorage')->willReturn($nonSharedStorage);
  109. $sender1Folder->method('getDirectoryListing')->willReturn([$sender1File, $sender1File]);
  110. $sender1RootFolder = $this->createMock(Folder::class);
  111. $sender1RootFolder->method('getStorage')->willReturn($nonSharedStorage);
  112. $sender1RootFolder->method('getDirectoryListing')->willReturn([$sender1Folder]);
  113. $sender1UserFolder = $this->createMock(Folder::class);
  114. $sender1UserFolder->method('get')->willReturn($sender1RootFolder);
  115. $return[] = [ '/folder', ['bar1.txt', 'bar2.txt'], $sender1UserFolder, true ];
  116. $return[] = [ '/', ['folder'], $sender1UserFolder, true ];
  117. // 3. cannot download zipped 1 non-shared file and 1 secure-shared inside non-shared folder
  118. $receiver1File = $this->createMock(File::class);
  119. $receiver1File->method('getStorage')->willReturn($nonSharedStorage);
  120. $receiver1SecureFile = $this->createMock(File::class);
  121. $receiver1SecureFile->method('getStorage')->willReturn($secureSharedStorage);
  122. $receiver1Folder = $this->createMock(Folder::class);
  123. $receiver1Folder->method('getStorage')->willReturn($nonSharedStorage);
  124. $receiver1Folder->method('getDirectoryListing')->willReturn([$receiver1File, $receiver1SecureFile]);
  125. $receiver1RootFolder = $this->createMock(Folder::class);
  126. $receiver1RootFolder->method('getStorage')->willReturn($nonSharedStorage);
  127. $receiver1RootFolder->method('getDirectoryListing')->willReturn([$receiver1Folder]);
  128. $receiver1UserFolder = $this->createMock(Folder::class);
  129. $receiver1UserFolder->method('get')->willReturn($receiver1RootFolder);
  130. $return[] = [ '/folder', ['secured-bar1.txt', 'bar2.txt'], $receiver1UserFolder, false ];
  131. // 4. cannot download zipped secure-shared folder
  132. $receiver2Folder = $this->createMock(Folder::class);
  133. $receiver2Folder->method('getStorage')->willReturn($secureSharedStorage);
  134. $receiver2RootFolder = $this->createMock(Folder::class);
  135. $receiver2RootFolder->method('getStorage')->willReturn($nonSharedStorage);
  136. $receiver2RootFolder->method('getDirectoryListing')->willReturn([$receiver2Folder]);
  137. $receiver2UserFolder = $this->createMock(Folder::class);
  138. $receiver2UserFolder->method('get')->willReturn($receiver2RootFolder);
  139. $return[] = [ '/', ['secured-folder'], $receiver2UserFolder, false ];
  140. return $return;
  141. }
  142. /**
  143. * @dataProvider providesDataForCanZip
  144. */
  145. public function testCheckZipCanBeDownloaded(string $dir, array $files, Folder $userFolder, bool $run): void {
  146. $user = $this->createMock(IUser::class);
  147. $user->method('getUID')->willReturn('test');
  148. $this->userSession->method('getUser')->willReturn($user);
  149. $this->userSession->method('isLoggedIn')->willReturn(true);
  150. $this->rootFolder->method('getUserFolder')->with('test')->willReturn($userFolder);
  151. // Simulate zip download of folder folder
  152. $event = new BeforeZipCreatedEvent($dir, $files);
  153. $listener = new BeforeZipCreatedListener(
  154. $this->userSession,
  155. $this->rootFolder
  156. );
  157. $listener->handle($event);
  158. $this->assertEquals($run, $event->isSuccessful());
  159. $this->assertEquals($run, $event->getErrorMessage() === null);
  160. }
  161. public function testCheckFileUserNotFound(): void {
  162. $this->userSession->method('isLoggedIn')->willReturn(false);
  163. // Simulate zip download of folder folder
  164. $event = new BeforeZipCreatedEvent('/test', ['test.txt']);
  165. $listener = new BeforeZipCreatedListener(
  166. $this->userSession,
  167. $this->rootFolder
  168. );
  169. $listener->handle($event);
  170. // It should run as this would restrict e.g. share links otherwise
  171. $this->assertTrue($event->isSuccessful());
  172. $this->assertEquals(null, $event->getErrorMessage());
  173. }
  174. }