1
0

ShareByMailProviderTest.php 74 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-License-Identifier: AGPL-3.0-or-later
  5. */
  6. namespace OCA\ShareByMail\Tests;
  7. use DateTime;
  8. use OC\Mail\Message;
  9. use OCA\ShareByMail\Settings\SettingsManager;
  10. use OCA\ShareByMail\ShareByMailProvider;
  11. use OCP\Activity\IManager as IActivityManager;
  12. use OCP\Defaults;
  13. use OCP\EventDispatcher\IEventDispatcher;
  14. use OCP\Files\File;
  15. use OCP\Files\IRootFolder;
  16. use OCP\Files\Node;
  17. use OCP\IConfig;
  18. use OCP\IDBConnection;
  19. use OCP\IL10N;
  20. use OCP\IURLGenerator;
  21. use OCP\IUser;
  22. use OCP\IUserManager;
  23. use OCP\Mail\IEMailTemplate;
  24. use OCP\Mail\IMailer;
  25. use OCP\Mail\IMessage;
  26. use OCP\Security\Events\GenerateSecurePasswordEvent;
  27. use OCP\Security\IHasher;
  28. use OCP\Security\ISecureRandom;
  29. use OCP\Security\PasswordContext;
  30. use OCP\Share\IAttributes;
  31. use OCP\Share\IManager;
  32. use OCP\Share\IShare;
  33. use PHPUnit\Framework\MockObject\MockObject;
  34. use Psr\Log\LoggerInterface;
  35. use Test\TestCase;
  36. /**
  37. * Class ShareByMailProviderTest
  38. *
  39. * @package OCA\ShareByMail\Tests
  40. * @group DB
  41. */
  42. class ShareByMailProviderTest extends TestCase {
  43. private IDBConnection $connection;
  44. private IL10N&MockObject $l;
  45. private IShare&MockObject $share;
  46. private IConfig&MockObject $config;
  47. private IMailer&MockObject $mailer;
  48. private IHasher&MockObject $hasher;
  49. private Defaults&MockObject $defaults;
  50. private IManager&MockObject $shareManager;
  51. private LoggerInterface&MockObject $logger;
  52. private IRootFolder&MockObject $rootFolder;
  53. private IUserManager&MockObject $userManager;
  54. private ISecureRandom&MockObject $secureRandom;
  55. private IURLGenerator&MockObject $urlGenerator;
  56. private SettingsManager&MockObject $settingsManager;
  57. private IActivityManager&MockObject $activityManager;
  58. private IEventDispatcher&MockObject $eventDispatcher;
  59. protected function setUp(): void {
  60. parent::setUp();
  61. $this->connection = \OCP\Server::get(IDBConnection::class);
  62. $this->l = $this->getMockBuilder(IL10N::class)->getMock();
  63. $this->l->method('t')
  64. ->willReturnCallback(function ($text, $parameters = []) {
  65. return vsprintf($text, $parameters);
  66. });
  67. $this->config = $this->getMockBuilder(IConfig::class)->getMock();
  68. $this->logger = $this->getMockBuilder(LoggerInterface::class)->getMock();
  69. $this->rootFolder = $this->getMockBuilder('OCP\Files\IRootFolder')->getMock();
  70. $this->userManager = $this->getMockBuilder(IUserManager::class)->getMock();
  71. $this->secureRandom = $this->getMockBuilder('\OCP\Security\ISecureRandom')->getMock();
  72. $this->mailer = $this->getMockBuilder('\OCP\Mail\IMailer')->getMock();
  73. $this->urlGenerator = $this->getMockBuilder(IURLGenerator::class)->getMock();
  74. $this->share = $this->getMockBuilder(IShare::class)->getMock();
  75. $this->activityManager = $this->getMockBuilder('OCP\Activity\IManager')->getMock();
  76. $this->settingsManager = $this->getMockBuilder(SettingsManager::class)->disableOriginalConstructor()->getMock();
  77. $this->defaults = $this->createMock(Defaults::class);
  78. $this->hasher = $this->getMockBuilder(IHasher::class)->getMock();
  79. $this->eventDispatcher = $this->getMockBuilder(IEventDispatcher::class)->getMock();
  80. $this->shareManager = $this->getMockBuilder(IManager::class)->getMock();
  81. $this->userManager->expects($this->any())->method('userExists')->willReturn(true);
  82. $this->config->expects($this->any())->method('getAppValue')->with('core', 'enforce_strict_email_check')->willReturn('yes');
  83. }
  84. /**
  85. * get instance of Mocked ShareByMailProvider
  86. *
  87. * @param array $mockedMethods internal methods which should be mocked
  88. * @return \PHPUnit\Framework\MockObject\MockObject | ShareByMailProvider
  89. */
  90. private function getInstance(array $mockedMethods = []) {
  91. if (!empty($mockedMethods)) {
  92. return $this->getMockBuilder('OCA\ShareByMail\ShareByMailProvider')
  93. ->setConstructorArgs([
  94. $this->config,
  95. $this->connection,
  96. $this->secureRandom,
  97. $this->userManager,
  98. $this->rootFolder,
  99. $this->l,
  100. $this->logger,
  101. $this->mailer,
  102. $this->urlGenerator,
  103. $this->activityManager,
  104. $this->settingsManager,
  105. $this->defaults,
  106. $this->hasher,
  107. $this->eventDispatcher,
  108. $this->shareManager
  109. ])
  110. ->setMethods($mockedMethods)
  111. ->getMock();
  112. }
  113. return new ShareByMailProvider(
  114. $this->config,
  115. $this->connection,
  116. $this->secureRandom,
  117. $this->userManager,
  118. $this->rootFolder,
  119. $this->l,
  120. $this->logger,
  121. $this->mailer,
  122. $this->urlGenerator,
  123. $this->activityManager,
  124. $this->settingsManager,
  125. $this->defaults,
  126. $this->hasher,
  127. $this->eventDispatcher,
  128. $this->shareManager
  129. );
  130. }
  131. protected function tearDown(): void {
  132. $this->connection
  133. ->getQueryBuilder()
  134. ->delete('share')
  135. ->executeStatement();
  136. parent::tearDown();
  137. }
  138. public function testCreate(): void {
  139. $expectedShare = $this->createMock(IShare::class);
  140. $share = $this->getMockBuilder(IShare::class)->getMock();
  141. $share->expects($this->any())->method('getSharedWith')->willReturn('user1');
  142. $node = $this->getMockBuilder(File::class)->getMock();
  143. $node->expects($this->any())->method('getName')->willReturn('filename');
  144. $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'sendEmail', 'sendPassword']);
  145. $instance->expects($this->once())->method('getSharedWith')->willReturn([]);
  146. $instance->expects($this->once())->method('createMailShare')->with($share)->willReturn(42);
  147. $instance->expects($this->once())->method('createShareActivity')->with($share);
  148. $instance->expects($this->once())->method('getRawShare')->with(42)->willReturn(['rawShare']);
  149. $instance->expects($this->once())->method('createShareObject')->with(['rawShare'])->willReturn($expectedShare);
  150. $share->expects($this->any())->method('getNode')->willReturn($node);
  151. // As share api link password is not enforced, the password will not be generated.
  152. $this->shareManager->expects($this->once())->method('shareApiLinkEnforcePassword')->willReturn(false);
  153. $this->settingsManager->expects($this->never())->method('sendPasswordByMail');
  154. // Mail notification is triggered by the share manager.
  155. $instance->expects($this->never())->method('sendEmail');
  156. $instance->expects($this->never())->method('sendPassword');
  157. $this->assertSame($expectedShare, $instance->create($share));
  158. }
  159. public function testCreateSendPasswordByMailWithoutEnforcedPasswordProtection(): void {
  160. $expectedShare = $this->createMock(IShare::class);
  161. $node = $this->getMockBuilder(File::class)->getMock();
  162. $node->expects($this->any())->method('getName')->willReturn('filename');
  163. $share = $this->getMockBuilder(IShare::class)->getMock();
  164. $share->expects($this->any())->method('getSharedWith')->willReturn('receiver@examplelölöl.com');
  165. $share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(false);
  166. $share->expects($this->any())->method('getSharedBy')->willReturn('owner');
  167. $share->expects($this->any())->method('getNode')->willReturn($node);
  168. $share->expects($this->any())->method('getId')->willReturn(42);
  169. $share->expects($this->any())->method('getNote')->willReturn('');
  170. $share->expects($this->any())->method('getToken')->willReturn('token');
  171. // Assume the mail address is valid.
  172. $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true);
  173. $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity', 'sendEmail', 'sendPassword', 'sendPasswordToOwner']);
  174. $instance->expects($this->once())->method('getSharedWith')->willReturn([]);
  175. $instance->expects($this->once())->method('createMailShare')->with($share)->willReturn(42);
  176. $instance->expects($this->once())->method('createShareActivity')->with($share);
  177. $instance->expects($this->once())->method('getRawShare')->with(42)->willReturn(['rawShare']);
  178. $instance->expects($this->once())->method('createShareObject')->with(['rawShare'])->willReturn($expectedShare);
  179. $share->expects($this->any())->method('getNode')->willReturn($node);
  180. // The autogenerated password should not be mailed.
  181. $this->shareManager->expects($this->any())->method('shareApiLinkEnforcePassword')->willReturn(false);
  182. $this->settingsManager->expects($this->any())->method('sendPasswordByMail')->willReturn(true);
  183. $instance->expects($this->never())->method('autoGeneratePassword');
  184. // No password is set and no password sent via talk is requested
  185. $instance->expects($this->once())->method('sendEmail')->with($share, ['receiver@examplelölöl.com']);
  186. $instance->expects($this->never())->method('sendPassword');
  187. $instance->expects($this->never())->method('sendPasswordToOwner');
  188. // The manager sends the mail notification.
  189. // For the sake of testing simplicity, we will handle it ourselves.
  190. $this->assertSame($expectedShare, $instance->create($share));
  191. $instance->sendMailNotification($share);
  192. }
  193. public function testCreateSendPasswordByMailWithPasswordAndWithoutEnforcedPasswordProtectionWithPermanentPassword(): void {
  194. $expectedShare = $this->createMock(IShare::class);
  195. $node = $this->getMockBuilder(File::class)->getMock();
  196. $node->expects($this->any())->method('getName')->willReturn('filename');
  197. $share = $this->getMockBuilder(IShare::class)->getMock();
  198. $share->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com');
  199. $share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(false);
  200. $share->expects($this->any())->method('getSharedBy')->willReturn('owner');
  201. $share->expects($this->any())->method('getNode')->willReturn($node);
  202. $share->expects($this->any())->method('getId')->willReturn(42);
  203. $share->expects($this->any())->method('getNote')->willReturn('');
  204. $share->expects($this->any())->method('getToken')->willReturn('token');
  205. // Assume the mail address is valid.
  206. $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true);
  207. $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity', 'sendEmail', 'sendPassword', 'sendPasswordToOwner']);
  208. $instance->expects($this->once())->method('getSharedWith')->willReturn([]);
  209. $instance->expects($this->once())->method('createMailShare')->with($share)->willReturn(42);
  210. $instance->expects($this->once())->method('createShareActivity')->with($share);
  211. $instance->expects($this->once())->method('getRawShare')->with(42)->willReturn(['rawShare', 'password' => 'password']);
  212. $instance->expects($this->once())->method('createShareObject')->with(['rawShare', 'password' => 'password'])->willReturn($expectedShare);
  213. $share->expects($this->any())->method('getNode')->willReturn($node);
  214. $share->expects($this->any())->method('getPassword')->willReturn('password');
  215. $this->hasher->expects($this->once())->method('hash')->with('password')->willReturn('passwordHashed');
  216. $share->expects($this->once())->method('setPassword')->with('passwordHashed');
  217. // The given password (but not the autogenerated password) should not be
  218. // mailed to the receiver of the share because permanent passwords are not enforced.
  219. $this->shareManager->expects($this->any())->method('shareApiLinkEnforcePassword')->willReturn(false);
  220. $this->config->expects($this->once())->method('getSystemValue')->with('sharing.enable_mail_link_password_expiration')->willReturn(false);
  221. $instance->expects($this->never())->method('autoGeneratePassword');
  222. // A password is set but no password sent via talk has been requested
  223. $instance->expects($this->once())->method('sendEmail')->with($share, ['receiver@example.com']);
  224. $instance->expects($this->once())->method('sendPassword')->with($share, 'password');
  225. $instance->expects($this->never())->method('sendPasswordToOwner');
  226. $this->assertSame($expectedShare, $instance->create($share));
  227. $instance->sendMailNotification($share);
  228. }
  229. public function testCreateSendPasswordByMailWithPasswordAndWithoutEnforcedPasswordProtectionWithoutPermanentPassword(): void {
  230. $expectedShare = $this->createMock(IShare::class);
  231. $node = $this->getMockBuilder(File::class)->getMock();
  232. $node->expects($this->any())->method('getName')->willReturn('filename');
  233. $share = $this->getMockBuilder(IShare::class)->getMock();
  234. $share->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com');
  235. $share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(false);
  236. $share->expects($this->any())->method('getSharedBy')->willReturn('owner');
  237. $share->expects($this->any())->method('getNode')->willReturn($node);
  238. $share->expects($this->any())->method('getId')->willReturn(42);
  239. $share->expects($this->any())->method('getNote')->willReturn('');
  240. $share->expects($this->any())->method('getToken')->willReturn('token');
  241. // Assume the mail address is valid.
  242. $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true);
  243. $instance = $this->getInstance([
  244. 'getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject',
  245. 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity',
  246. 'sendEmail', 'sendPassword', 'sendPasswordToOwner',
  247. ]);
  248. $instance->expects($this->once())->method('getSharedWith')->willReturn([]);
  249. $instance->expects($this->once())->method('createMailShare')->with($share)->willReturn(42);
  250. $instance->expects($this->once())->method('createShareActivity')->with($share);
  251. $instance->expects($this->once())->method('getRawShare')->with(42)->willReturn(['rawShare', 'password' => 'password']);
  252. $instance->expects($this->once())->method('createShareObject')->with(['rawShare', 'password' => 'password'])->willReturn($expectedShare);
  253. $share->expects($this->any())->method('getNode')->willReturn($node);
  254. $share->expects($this->any())->method('getPassword')->willReturn('password');
  255. $this->hasher->expects($this->once())->method('hash')->with('password')->willReturn('passwordHashed');
  256. $share->expects($this->once())->method('setPassword')->with('passwordHashed');
  257. // No password is generated, so no emails need to be sent
  258. // aside from the main email notification.
  259. $this->shareManager->expects($this->any())->method('shareApiLinkEnforcePassword')->willReturn(false);
  260. $instance->expects($this->never())->method('autoGeneratePassword');
  261. $this->config->expects($this->once())->method('getSystemValue')
  262. ->with('sharing.enable_mail_link_password_expiration')
  263. ->willReturn(true);
  264. // No password has been set and no password sent via talk has been requested,
  265. // but password has been enforced for the whole instance and will be generated.
  266. $instance->expects($this->once())->method('sendEmail')->with($share, ['receiver@example.com']);
  267. $instance->expects($this->never())->method('sendPassword');
  268. $instance->expects($this->never())->method('sendPasswordToOwner');
  269. $this->assertSame($expectedShare, $instance->create($share));
  270. $instance->sendMailNotification($share);
  271. }
  272. public function testCreateSendPasswordByMailWithEnforcedPasswordProtectionWithPermanentPassword(): void {
  273. $expectedShare = $this->createMock(IShare::class);
  274. $node = $this->getMockBuilder(File::class)->getMock();
  275. $node->expects($this->any())->method('getName')->willReturn('filename');
  276. $share = $this->getMockBuilder(IShare::class)->getMock();
  277. $share->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com');
  278. $share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(false);
  279. $share->expects($this->any())->method('getSharedBy')->willReturn('owner');
  280. $share->expects($this->any())->method('getNode')->willReturn($node);
  281. $share->expects($this->any())->method('getId')->willReturn(42);
  282. $share->expects($this->any())->method('getNote')->willReturn('');
  283. $share->expects($this->any())->method('getToken')->willReturn('token');
  284. $this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute')
  285. ->with('files_sharing.sharecontroller.showShare', ['token' => 'token'])
  286. ->willReturn('https://example.com/file.txt');
  287. $this->secureRandom->expects($this->once())
  288. ->method('generate')
  289. ->with(8, ISecureRandom::CHAR_HUMAN_READABLE)
  290. ->willReturn('autogeneratedPassword');
  291. $this->eventDispatcher->expects($this->once())
  292. ->method('dispatchTyped')
  293. ->with(new GenerateSecurePasswordEvent(PasswordContext::SHARING));
  294. // Assume the mail address is valid.
  295. $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true);
  296. $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'createPasswordSendActivity', 'sendPasswordToOwner']);
  297. $instance->expects($this->once())->method('getSharedWith')->willReturn([]);
  298. $instance->expects($this->once())->method('createMailShare')->with($share)->willReturn(42);
  299. $instance->expects($this->once())->method('createShareActivity')->with($share);
  300. $instance->expects($this->once())->method('getRawShare')->with(42)->willReturn(['rawShare', 'password' => 'autogeneratedPassword']);
  301. $instance->expects($this->once())->method('createShareObject')->with(['rawShare', 'password' => 'autogeneratedPassword'])->willReturn($expectedShare);
  302. // Initially not set, but will be set by the autoGeneratePassword method.
  303. $share->expects($this->exactly(3))->method('getPassword')->willReturnOnConsecutiveCalls(null, 'autogeneratedPassword', 'autogeneratedPassword');
  304. $this->hasher->expects($this->once())->method('hash')->with('autogeneratedPassword')->willReturn('autogeneratedPasswordHashed');
  305. $share->expects($this->once())->method('setPassword')->with('autogeneratedPasswordHashed');
  306. // The autogenerated password should be mailed to the receiver of the share because permanent passwords are enforced.
  307. $this->shareManager->expects($this->any())->method('shareApiLinkEnforcePassword')->willReturn(true);
  308. $this->config->expects($this->any())->method('getSystemValue')->with('sharing.enable_mail_link_password_expiration')->willReturn(false);
  309. $this->settingsManager->expects($this->any())->method('sendPasswordByMail')->willReturn(true);
  310. $message = $this->createMock(IMessage::class);
  311. $message->expects($this->exactly(2))->method('setTo')->with(['receiver@example.com']);
  312. $this->mailer->expects($this->exactly(2))->method('createMessage')->willReturn($message);
  313. $this->mailer->expects($this->exactly(2))->method('createEMailTemplate')
  314. ->withConsecutive([
  315. 'sharebymail.RecipientNotification', [
  316. 'filename' => 'filename',
  317. 'link' => 'https://example.com/file.txt',
  318. 'initiator' => 'owner',
  319. 'expiration' => null,
  320. 'shareWith' => 'receiver@example.com',
  321. 'note' => ''
  322. ]
  323. ],
  324. [
  325. 'sharebymail.RecipientPasswordNotification', [
  326. 'filename' => 'filename',
  327. 'password' => 'autogeneratedPassword',
  328. 'initiator' => 'owner',
  329. 'initiatorEmail' => null,
  330. 'shareWith' => 'receiver@example.com',
  331. ]
  332. ]);
  333. // Main email notification is sent as well as the password
  334. // to the recipient because shareApiLinkEnforcePassword is enabled.
  335. $this->mailer->expects($this->exactly(2))->method('send');
  336. $instance->expects($this->never())->method('sendPasswordToOwner');
  337. $this->assertSame($expectedShare, $instance->create($share));
  338. $instance->sendMailNotification($share);
  339. }
  340. public function testCreateSendPasswordByMailWithPasswordAndWithEnforcedPasswordProtectionWithPermanentPassword(): void {
  341. $expectedShare = $this->createMock(IShare::class);
  342. $node = $this->getMockBuilder(File::class)->getMock();
  343. $node->expects($this->any())->method('getName')->willReturn('filename');
  344. $share = $this->getMockBuilder(IShare::class)->getMock();
  345. $share->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com');
  346. $share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(false);
  347. $share->expects($this->any())->method('getSharedBy')->willReturn('owner');
  348. $share->expects($this->any())->method('getNode')->willReturn($node);
  349. $share->expects($this->any())->method('getId')->willReturn(42);
  350. $share->expects($this->any())->method('getNote')->willReturn('');
  351. $share->expects($this->any())->method('getToken')->willReturn('token');
  352. $this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute')
  353. ->with('files_sharing.sharecontroller.showShare', ['token' => 'token'])
  354. ->willReturn('https://example.com/file.txt');
  355. // Assume the mail address is valid.
  356. $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true);
  357. $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity', 'sendPasswordToOwner']);
  358. $instance->expects($this->once())->method('getSharedWith')->willReturn([]);
  359. $instance->expects($this->once())->method('createMailShare')->with($share)->willReturn(42);
  360. $instance->expects($this->once())->method('createShareActivity')->with($share);
  361. $instance->expects($this->once())->method('getRawShare')->with(42)->willReturn(['rawShare', 'password' => 'password']);
  362. $instance->expects($this->once())->method('createShareObject')->with(['rawShare', 'password' => 'password'])->willReturn($expectedShare);
  363. $share->expects($this->exactly(3))->method('getPassword')->willReturn('password');
  364. $this->hasher->expects($this->once())->method('hash')->with('password')->willReturn('passwordHashed');
  365. $share->expects($this->once())->method('setPassword')->with('passwordHashed');
  366. // The given password (but not the autogenerated password) should be
  367. // mailed to the receiver of the share.
  368. $this->shareManager->expects($this->any())->method('shareApiLinkEnforcePassword')->willReturn(true);
  369. $this->config->expects($this->any())->method('getSystemValue')->with('sharing.enable_mail_link_password_expiration')->willReturn(false);
  370. $this->settingsManager->expects($this->any())->method('sendPasswordByMail')->willReturn(true);
  371. $instance->expects($this->never())->method('autoGeneratePassword');
  372. $message = $this->createMock(IMessage::class);
  373. $message->expects($this->exactly(2))->method('setTo')->with(['receiver@example.com']);
  374. $this->mailer->expects($this->exactly(2))->method('createMessage')->willReturn($message);
  375. $this->mailer->expects($this->exactly(2))->method('createEMailTemplate')
  376. ->withConsecutive([
  377. 'sharebymail.RecipientNotification', [
  378. 'filename' => 'filename',
  379. 'link' => 'https://example.com/file.txt',
  380. 'initiator' => 'owner',
  381. 'expiration' => null,
  382. 'shareWith' => 'receiver@example.com',
  383. 'note' => ''
  384. ]
  385. ],
  386. [
  387. 'sharebymail.RecipientPasswordNotification', [
  388. 'filename' => 'filename',
  389. 'password' => 'password',
  390. 'initiator' => 'owner',
  391. 'initiatorEmail' => null,
  392. 'shareWith' => 'receiver@example.com',
  393. ]
  394. ]);
  395. // Main email notification is sent as well as the password
  396. // to the recipient because the password is set.
  397. $this->mailer->expects($this->exactly(2))->method('send');
  398. $instance->expects($this->never())->method('sendPasswordToOwner');
  399. $this->assertSame($expectedShare, $instance->create($share));
  400. $instance->sendMailNotification($share);
  401. }
  402. public function testCreateSendPasswordByTalkWithEnforcedPasswordProtectionWithPermanentPassword(): void {
  403. $expectedShare = $this->createMock(IShare::class);
  404. // The owner of the share.
  405. $owner = $this->getMockBuilder(IUser::class)->getMock();
  406. $this->userManager->expects($this->any())->method('get')->with('owner')->willReturn($owner);
  407. $owner->expects($this->any())->method('getEMailAddress')->willReturn('owner@example.com');
  408. $owner->expects($this->any())->method('getDisplayName')->willReturn('owner');
  409. $node = $this->getMockBuilder(File::class)->getMock();
  410. $node->expects($this->any())->method('getName')->willReturn('filename');
  411. $share = $this->getMockBuilder(IShare::class)->getMock();
  412. $share->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com');
  413. $share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(true);
  414. $share->expects($this->any())->method('getSharedBy')->willReturn('owner');
  415. $share->expects($this->any())->method('getNode')->willReturn($node);
  416. $share->expects($this->any())->method('getId')->willReturn(42);
  417. $share->expects($this->any())->method('getNote')->willReturn('');
  418. $share->expects($this->any())->method('getToken')->willReturn('token');
  419. $this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute')
  420. ->with('files_sharing.sharecontroller.showShare', ['token' => 'token'])
  421. ->willReturn('https://example.com/file.txt');
  422. // Assume the mail address is valid.
  423. $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true);
  424. $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity']);
  425. $instance->expects($this->once())->method('getSharedWith')->willReturn([]);
  426. $instance->expects($this->once())->method('createMailShare')->with($share)->willReturn(42);
  427. $instance->expects($this->once())->method('createShareActivity')->with($share);
  428. $instance->expects($this->once())->method('getRawShare')->with(42)->willReturn(['rawShare', 'password' => 'autogeneratedPassword']);
  429. $instance->expects($this->once())->method('createShareObject')->with(['rawShare', 'password' => 'autogeneratedPassword'])->willReturn($expectedShare);
  430. $share->expects($this->exactly(4))->method('getPassword')->willReturnOnConsecutiveCalls(null, 'autogeneratedPassword', 'autogeneratedPassword', 'autogeneratedPassword');
  431. $this->hasher->expects($this->once())->method('hash')->with('autogeneratedPassword')->willReturn('autogeneratedPasswordHashed');
  432. $share->expects($this->once())->method('setPassword')->with('autogeneratedPasswordHashed');
  433. // The autogenerated password should be mailed to the owner of the share.
  434. $this->shareManager->expects($this->any())->method('shareApiLinkEnforcePassword')->willReturn(true);
  435. $this->config->expects($this->any())->method('getSystemValue')->with('sharing.enable_mail_link_password_expiration')->willReturn(false);
  436. $this->settingsManager->expects($this->any())->method('sendPasswordByMail')->willReturn(true);
  437. $instance->expects($this->once())->method('autoGeneratePassword')->with($share)->willReturn('autogeneratedPassword');
  438. $message = $this->createMock(IMessage::class);
  439. $message->expects($this->exactly(2))->method('setTo')->withConsecutive([['receiver@example.com']], [['owner@example.com' => 'owner']]);
  440. $this->mailer->expects($this->exactly(2))->method('createMessage')->willReturn($message);
  441. $this->mailer->expects($this->exactly(2))->method('createEMailTemplate')
  442. ->withConsecutive([
  443. 'sharebymail.RecipientNotification', [
  444. 'filename' => 'filename',
  445. 'link' => 'https://example.com/file.txt',
  446. 'initiator' => 'owner',
  447. 'expiration' => null,
  448. 'shareWith' => 'receiver@example.com',
  449. 'note' => ''
  450. ]
  451. ],
  452. [
  453. 'sharebymail.OwnerPasswordNotification', [
  454. 'filename' => 'filename',
  455. 'password' => 'autogeneratedPassword',
  456. 'initiator' => 'owner',
  457. 'initiatorEmail' => 'owner@example.com',
  458. 'shareWith' => 'receiver@example.com',
  459. ]
  460. ]);
  461. // Main email notification is sent as well as the password to owner
  462. // because the password is set and SendPasswordByTalk is enabled.
  463. $this->mailer->expects($this->exactly(2))->method('send');
  464. $this->assertSame($expectedShare, $instance->create($share));
  465. $instance->sendMailNotification($share);
  466. }
  467. // If attributes is set to multiple emails, use them as BCC
  468. public function sendNotificationToMultipleEmails() {
  469. $expectedShare = $this->createMock(IShare::class);
  470. $node = $this->getMockBuilder(File::class)->getMock();
  471. $node->expects($this->any())->method('getName')->willReturn('filename');
  472. $share = $this->getMockBuilder(IShare::class)->getMock();
  473. $share->expects($this->any())->method('getSharedWith')->willReturn('');
  474. $share->expects($this->any())->method('getSendPasswordByTalk')->willReturn(false);
  475. $share->expects($this->any())->method('getSharedBy')->willReturn('owner');
  476. $share->expects($this->any())->method('getNode')->willReturn($node);
  477. $share->expects($this->any())->method('getId')->willReturn(42);
  478. $share->expects($this->any())->method('getNote')->willReturn('');
  479. $share->expects($this->any())->method('getToken')->willReturn('token');
  480. $attributes = $this->getMockBuilder(IAttributes::class)->getMock();
  481. $share->expects($this->any())->method('getAttributes')->willReturn($attributes);
  482. $attributes->expects($this->any())->method('getAttribute')->with('shareWith', 'emails')->willReturn([
  483. 'receiver1@example.com',
  484. 'receiver2@example.com',
  485. 'receiver3@example.com',
  486. ]);
  487. // Assume the mail address is valid.
  488. $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true);
  489. $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject', 'createShareActivity', 'autoGeneratePassword', 'createPasswordSendActivity', 'sendEmail', 'sendPassword', 'sendPasswordToOwner']);
  490. $instance->expects($this->once())->method('getSharedWith')->willReturn([]);
  491. $instance->expects($this->once())->method('createMailShare')->with($share)->willReturn(42);
  492. $instance->expects($this->once())->method('createShareActivity')->with($share);
  493. $instance->expects($this->once())->method('getRawShare')->with(42)->willReturn(['rawShare', 'password' => 'password']);
  494. $instance->expects($this->once())->method('createShareObject')->with(['rawShare', 'password' => 'password'])->willReturn($expectedShare);
  495. $share->expects($this->any())->method('getNode')->willReturn($node);
  496. $share->expects($this->any())->method('getPassword')->willReturn('password');
  497. $this->hasher->expects($this->once())->method('hash')->with('password')->willReturn('passwordHashed');
  498. $share->expects($this->once())->method('setPassword')->with('passwordHashed');
  499. // The given password (but not the autogenerated password) should not be
  500. // mailed to the receiver of the share because permanent passwords are not enforced.
  501. $this->shareManager->expects($this->any())->method('shareApiLinkEnforcePassword')->willReturn(false);
  502. $this->config->expects($this->once())->method('getSystemValue')->with('sharing.enable_mail_link_password_expiration')->willReturn(false);
  503. $instance->expects($this->never())->method('autoGeneratePassword');
  504. // A password is set but no password sent via talk has been requested
  505. $instance->expects($this->once())->method('sendEmail')
  506. ->with($share, ['receiver1@example.com', 'receiver2@example.com', 'receiver3@example.com']);
  507. $instance->expects($this->once())->method('sendPassword')->with($share, 'password');
  508. $instance->expects($this->never())->method('sendPasswordToOwner');
  509. $message = $this->createMock(IMessage::class);
  510. $message->expects($this->never())->method('setTo');
  511. $message->expects($this->exactly(2))->method('setBcc')->with(['receiver1@example.com', 'receiver2@example.com', 'receiver3@example.com']);
  512. $this->mailer->expects($this->exactly(2))->method('createMessage')->willReturn($message);
  513. // Main email notification is sent as well as the password
  514. // to recipients because the password is set.
  515. $this->mailer->expects($this->exactly(2))->method('send');
  516. $this->assertSame($expectedShare, $instance->create($share));
  517. $instance->sendMailNotification($share);
  518. }
  519. public function testCreateFailed(): void {
  520. $this->expectException(\Exception::class);
  521. $this->share->expects($this->once())->method('getSharedWith')->willReturn('user1');
  522. $node = $this->getMockBuilder('OCP\Files\Node')->getMock();
  523. $node->expects($this->any())->method('getName')->willReturn('fileName');
  524. $this->share->expects($this->any())->method('getNode')->willReturn($node);
  525. $instance = $this->getInstance(['getSharedWith', 'createMailShare', 'getRawShare', 'createShareObject']);
  526. $instance->expects($this->once())->method('getSharedWith')->willReturn(['found']);
  527. $instance->expects($this->never())->method('createMailShare');
  528. $instance->expects($this->never())->method('getRawShare');
  529. $instance->expects($this->never())->method('createShareObject');
  530. $this->assertSame('shareObject',
  531. $instance->create($this->share)
  532. );
  533. }
  534. public function testCreateMailShare(): void {
  535. $this->share->expects($this->any())->method('getToken')->willReturn('token');
  536. $this->share->expects($this->once())->method('setToken')->with('token');
  537. $this->share->expects($this->any())->method('getSharedBy')->willReturn('validby@valid.com');
  538. $this->share->expects($this->any())->method('getSharedWith')->willReturn('validwith@valid.com');
  539. $this->share->expects($this->any())->method('getNote')->willReturn('Check this!');
  540. $this->share->expects($this->any())->method('getMailSend')->willReturn(true);
  541. $node = $this->getMockBuilder('OCP\Files\Node')->getMock();
  542. $node->expects($this->any())->method('getName')->willReturn('fileName');
  543. $this->share->expects($this->any())->method('getNode')->willReturn($node);
  544. $instance = $this->getInstance(['generateToken', 'addShareToDB', 'sendMailNotification']);
  545. $instance->expects($this->once())->method('generateToken')->willReturn('token');
  546. $instance->expects($this->once())->method('addShareToDB')->willReturn(42);
  547. // The manager handle the mail sending
  548. $instance->expects($this->never())->method('sendMailNotification');
  549. $this->assertSame(42,
  550. $this->invokePrivate($instance, 'createMailShare', [$this->share])
  551. );
  552. }
  553. public function testGenerateToken(): void {
  554. $instance = $this->getInstance();
  555. $this->secureRandom->expects($this->once())->method('generate')->willReturn('token');
  556. $this->assertSame('token',
  557. $this->invokePrivate($instance, 'generateToken')
  558. );
  559. }
  560. public function testAddShareToDB(): void {
  561. $itemSource = 11;
  562. $itemType = 'file';
  563. $shareWith = 'user@server.com';
  564. $sharedBy = 'user1';
  565. $uidOwner = 'user2';
  566. $permissions = 1;
  567. $token = 'token';
  568. $password = 'password';
  569. $sendPasswordByTalk = true;
  570. $hideDownload = true;
  571. $label = 'label';
  572. $expiration = new \DateTime();
  573. $passwordExpirationTime = new \DateTime();
  574. $instance = $this->getInstance();
  575. $id = $this->invokePrivate(
  576. $instance,
  577. 'addShareToDB',
  578. [
  579. $itemSource,
  580. $itemType,
  581. $shareWith,
  582. $sharedBy,
  583. $uidOwner,
  584. $permissions,
  585. $token,
  586. $password,
  587. $passwordExpirationTime,
  588. $sendPasswordByTalk,
  589. $hideDownload,
  590. $label,
  591. $expiration
  592. ]
  593. );
  594. $qb = $this->connection->getQueryBuilder();
  595. $qb->select('*')
  596. ->from('share')
  597. ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
  598. $qResult = $qb->execute();
  599. $result = $qResult->fetchAll();
  600. $qResult->closeCursor();
  601. $this->assertSame(1, count($result));
  602. $this->assertSame($itemSource, (int)$result[0]['item_source']);
  603. $this->assertSame($itemType, $result[0]['item_type']);
  604. $this->assertSame($shareWith, $result[0]['share_with']);
  605. $this->assertSame($sharedBy, $result[0]['uid_initiator']);
  606. $this->assertSame($uidOwner, $result[0]['uid_owner']);
  607. $this->assertSame($permissions, (int)$result[0]['permissions']);
  608. $this->assertSame($token, $result[0]['token']);
  609. $this->assertSame($password, $result[0]['password']);
  610. $this->assertSame($passwordExpirationTime->getTimestamp(), \DateTime::createFromFormat('Y-m-d H:i:s', $result[0]['password_expiration_time'])->getTimestamp());
  611. $this->assertSame($sendPasswordByTalk, (bool)$result[0]['password_by_talk']);
  612. $this->assertSame($hideDownload, (bool)$result[0]['hide_download']);
  613. $this->assertSame($label, $result[0]['label']);
  614. $this->assertSame($expiration->getTimestamp(), \DateTime::createFromFormat('Y-m-d H:i:s', $result[0]['expiration'])->getTimestamp());
  615. }
  616. public function testUpdate(): void {
  617. $itemSource = 11;
  618. $itemType = 'file';
  619. $shareWith = 'user@server.com';
  620. $sharedBy = 'user1';
  621. $uidOwner = 'user2';
  622. $permissions = 1;
  623. $token = 'token';
  624. $note = 'personal note';
  625. $instance = $this->getInstance();
  626. $id = $this->createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, $token, $note);
  627. $this->share->expects($this->once())->method('getPermissions')->willReturn($permissions + 1);
  628. $this->share->expects($this->once())->method('getShareOwner')->willReturn($uidOwner);
  629. $this->share->expects($this->once())->method('getSharedBy')->willReturn($sharedBy);
  630. $this->share->expects($this->any())->method('getNote')->willReturn($note);
  631. $this->share->expects($this->atLeastOnce())->method('getId')->willReturn($id);
  632. $this->assertSame($this->share,
  633. $instance->update($this->share)
  634. );
  635. $qb = $this->connection->getQueryBuilder();
  636. $qb->select('*')
  637. ->from('share')
  638. ->where($qb->expr()->eq('id', $qb->createNamedParameter($id)));
  639. $qResult = $qb->execute();
  640. $result = $qResult->fetchAll();
  641. $qResult->closeCursor();
  642. $this->assertSame(1, count($result));
  643. $this->assertSame($itemSource, (int)$result[0]['item_source']);
  644. $this->assertSame($itemType, $result[0]['item_type']);
  645. $this->assertSame($shareWith, $result[0]['share_with']);
  646. $this->assertSame($sharedBy, $result[0]['uid_initiator']);
  647. $this->assertSame($uidOwner, $result[0]['uid_owner']);
  648. $this->assertSame($permissions + 1, (int)$result[0]['permissions']);
  649. $this->assertSame($token, $result[0]['token']);
  650. $this->assertSame($note, $result[0]['note']);
  651. }
  652. public function dataUpdateSendPassword() {
  653. return [
  654. ['password', 'hashed', 'hashed new', false, false, true],
  655. ['', 'hashed', 'hashed new', false, false, false],
  656. [null, 'hashed', 'hashed new', false, false, false],
  657. ['password', 'hashed', 'hashed', false, false, false],
  658. ['password', 'hashed', 'hashed new', false, true, false],
  659. ['password', 'hashed', 'hashed new', true, false, true],
  660. ['password', 'hashed', 'hashed', true, false, true],
  661. ];
  662. }
  663. /**
  664. * @dataProvider dataUpdateSendPassword
  665. *
  666. * @param string|null plainTextPassword
  667. * @param string originalPassword
  668. * @param string newPassword
  669. * @param string originalSendPasswordByTalk
  670. * @param string newSendPasswordByTalk
  671. * @param bool sendMail
  672. */
  673. public function testUpdateSendPassword($plainTextPassword, string $originalPassword, string $newPassword, $originalSendPasswordByTalk, $newSendPasswordByTalk, bool $sendMail): void {
  674. $node = $this->createMock(File::class);
  675. $node->expects($this->any())->method('getName')->willReturn('filename');
  676. $this->settingsManager->method('sendPasswordByMail')->willReturn(true);
  677. $originalShare = $this->getMockBuilder(IShare::class)->getMock();
  678. $originalShare->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com');
  679. $originalShare->expects($this->any())->method('getNode')->willReturn($node);
  680. $originalShare->expects($this->any())->method('getId')->willReturn(42);
  681. $originalShare->expects($this->any())->method('getPassword')->willReturn($originalPassword);
  682. $originalShare->expects($this->any())->method('getSendPasswordByTalk')->willReturn($originalSendPasswordByTalk);
  683. $share = $this->getMockBuilder(IShare::class)->getMock();
  684. $share->expects($this->any())->method('getSharedWith')->willReturn('receiver@example.com');
  685. $share->expects($this->any())->method('getNode')->willReturn($node);
  686. $share->expects($this->any())->method('getId')->willReturn(42);
  687. $share->expects($this->any())->method('getPassword')->willReturn($newPassword);
  688. $share->expects($this->any())->method('getSendPasswordByTalk')->willReturn($newSendPasswordByTalk);
  689. if ($sendMail) {
  690. $this->mailer->expects($this->once())->method('createEMailTemplate')->with('sharebymail.RecipientPasswordNotification', [
  691. 'filename' => 'filename',
  692. 'password' => $plainTextPassword,
  693. 'initiator' => null,
  694. 'initiatorEmail' => null,
  695. 'shareWith' => 'receiver@example.com',
  696. ]);
  697. $this->mailer->expects($this->once())->method('send');
  698. } else {
  699. $this->mailer->expects($this->never())->method('send');
  700. }
  701. $instance = $this->getInstance(['getShareById', 'createPasswordSendActivity']);
  702. $instance->expects($this->once())->method('getShareById')->willReturn($originalShare);
  703. $this->assertSame($share,
  704. $instance->update($share, $plainTextPassword)
  705. );
  706. }
  707. public function testDelete(): void {
  708. $instance = $this->getInstance(['removeShareFromTable', 'createShareActivity']);
  709. $this->share->expects($this->once())->method('getId')->willReturn(42);
  710. $instance->expects($this->once())->method('removeShareFromTable')->with(42);
  711. $instance->expects($this->once())->method('createShareActivity')->with($this->share, 'unshare');
  712. $instance->delete($this->share);
  713. }
  714. public function testGetShareById(): void {
  715. $instance = $this->getInstance(['createShareObject']);
  716. $itemSource = 11;
  717. $itemType = 'file';
  718. $shareWith = 'user@server.com';
  719. $sharedBy = 'user1';
  720. $uidOwner = 'user2';
  721. $permissions = 1;
  722. $token = 'token';
  723. $this->createDummyShare($itemType, $itemSource, $shareWith, 'user1wrong', 'user2wrong', $permissions, $token);
  724. $id2 = $this->createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, $token);
  725. $instance->expects($this->once())->method('createShareObject')
  726. ->willReturnCallback(
  727. function ($data) use ($uidOwner, $sharedBy, $id2) {
  728. $this->assertSame($uidOwner, $data['uid_owner']);
  729. $this->assertSame($sharedBy, $data['uid_initiator']);
  730. $this->assertSame($id2, (int)$data['id']);
  731. return $this->share;
  732. }
  733. );
  734. $result = $instance->getShareById($id2);
  735. $this->assertInstanceOf('OCP\Share\IShare', $result);
  736. }
  737. public function testGetShareByIdFailed(): void {
  738. $this->expectException(\OCP\Share\Exceptions\ShareNotFound::class);
  739. $instance = $this->getInstance(['createShareObject']);
  740. $itemSource = 11;
  741. $itemType = 'file';
  742. $shareWith = 'user@server.com';
  743. $sharedBy = 'user1';
  744. $uidOwner = 'user2';
  745. $permissions = 1;
  746. $token = 'token';
  747. $id = $this->createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, $token);
  748. $instance->getShareById($id + 1);
  749. }
  750. public function testGetShareByPath(): void {
  751. $itemSource = 11;
  752. $itemType = 'file';
  753. $shareWith = 'user@server.com';
  754. $sharedBy = 'user1';
  755. $uidOwner = 'user2';
  756. $permissions = 1;
  757. $token = 'token';
  758. $node = $this->createMock(Node::class);
  759. $node->expects($this->once())->method('getId')->willReturn($itemSource);
  760. $instance = $this->getInstance(['createShareObject']);
  761. $this->createDummyShare($itemType, 111, $shareWith, $sharedBy, $uidOwner, $permissions, $token);
  762. $id = $this->createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, $token);
  763. $instance->expects($this->once())->method('createShareObject')
  764. ->willReturnCallback(
  765. function ($data) use ($uidOwner, $sharedBy, $id) {
  766. $this->assertSame($uidOwner, $data['uid_owner']);
  767. $this->assertSame($sharedBy, $data['uid_initiator']);
  768. $this->assertSame($id, (int)$data['id']);
  769. return $this->share;
  770. }
  771. );
  772. $result = $instance->getSharesByPath($node);
  773. $this->assertTrue(is_array($result));
  774. $this->assertSame(1, count($result));
  775. $this->assertInstanceOf('OCP\Share\IShare', $result[0]);
  776. }
  777. public function testGetShareByToken(): void {
  778. $itemSource = 11;
  779. $itemType = 'file';
  780. $shareWith = 'user@server.com';
  781. $sharedBy = 'user1';
  782. $uidOwner = 'user2';
  783. $permissions = 1;
  784. $token = 'token';
  785. $instance = $this->getInstance(['createShareObject']);
  786. $idMail = $this->createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, $token);
  787. $idPublic = $this->createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, $token, '', IShare::TYPE_LINK);
  788. $this->assertTrue($idMail !== $idPublic);
  789. $instance->expects($this->once())->method('createShareObject')
  790. ->willReturnCallback(
  791. function ($data) use ($idMail) {
  792. $this->assertSame($idMail, (int)$data['id']);
  793. return $this->share;
  794. }
  795. );
  796. $result = $instance->getShareByToken('token');
  797. $this->assertInstanceOf('OCP\Share\IShare', $result);
  798. }
  799. public function testGetShareByTokenFailed(): void {
  800. $this->expectException(\OCP\Share\Exceptions\ShareNotFound::class);
  801. $itemSource = 11;
  802. $itemType = 'file';
  803. $shareWith = 'user@server.com';
  804. $sharedBy = 'user1';
  805. $uidOwner = 'user2';
  806. $permissions = 1;
  807. $token = 'token';
  808. $instance = $this->getInstance(['createShareObject']);
  809. $idMail = $this->createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, $token);
  810. $idPublic = $this->createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, 'token2', '', IShare::TYPE_LINK);
  811. $this->assertTrue($idMail !== $idPublic);
  812. $this->assertInstanceOf('OCP\Share\IShare',
  813. $instance->getShareByToken('token2')
  814. );
  815. }
  816. public function testRemoveShareFromTable(): void {
  817. $itemSource = 11;
  818. $itemType = 'file';
  819. $shareWith = 'user@server.com';
  820. $sharedBy = 'user1';
  821. $uidOwner = 'user2';
  822. $permissions = 1;
  823. $token = 'token';
  824. $instance = $this->getInstance();
  825. $id = $this->createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, $token);
  826. $query = $this->connection->getQueryBuilder();
  827. $query->select('*')->from('share')
  828. ->where($query->expr()->eq('id', $query->createNamedParameter($id)));
  829. $result = $query->execute();
  830. $before = $result->fetchAll();
  831. $result->closeCursor();
  832. $this->assertTrue(is_array($before));
  833. $this->assertSame(1, count($before));
  834. $this->invokePrivate($instance, 'removeShareFromTable', [$id]);
  835. $query = $this->connection->getQueryBuilder();
  836. $query->select('*')->from('share')
  837. ->where($query->expr()->eq('id', $query->createNamedParameter($id)));
  838. $result = $query->execute();
  839. $after = $result->fetchAll();
  840. $result->closeCursor();
  841. $this->assertTrue(is_array($after));
  842. $this->assertEmpty($after);
  843. }
  844. public function testUserDeleted(): void {
  845. $itemSource = 11;
  846. $itemType = 'file';
  847. $shareWith = 'user@server.com';
  848. $sharedBy = 'user1';
  849. $uidOwner = 'user2';
  850. $permissions = 1;
  851. $token = 'token';
  852. $this->createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, $token);
  853. $id = $this->createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, 'user2Wrong', $permissions, $token);
  854. $query = $this->connection->getQueryBuilder();
  855. $query->select('*')->from('share');
  856. $result = $query->execute();
  857. $before = $result->fetchAll();
  858. $result->closeCursor();
  859. $this->assertTrue(is_array($before));
  860. $this->assertSame(2, count($before));
  861. $instance = $this->getInstance();
  862. $instance->userDeleted($uidOwner, IShare::TYPE_EMAIL);
  863. $query = $this->connection->getQueryBuilder();
  864. $query->select('*')->from('share');
  865. $result = $query->execute();
  866. $after = $result->fetchAll();
  867. $result->closeCursor();
  868. $this->assertTrue(is_array($after));
  869. $this->assertSame(1, count($after));
  870. $this->assertSame($id, (int)$after[0]['id']);
  871. }
  872. public function testGetRawShare(): void {
  873. $itemSource = 11;
  874. $itemType = 'file';
  875. $shareWith = 'user@server.com';
  876. $sharedBy = 'user1';
  877. $uidOwner = 'user2';
  878. $permissions = 1;
  879. $token = 'token';
  880. $instance = $this->getInstance();
  881. $id = $this->createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, $token);
  882. $result = $this->invokePrivate($instance, 'getRawShare', [$id]);
  883. $this->assertTrue(is_array($result));
  884. $this->assertSame($itemSource, (int)$result['item_source']);
  885. $this->assertSame($itemType, $result['item_type']);
  886. $this->assertSame($shareWith, $result['share_with']);
  887. $this->assertSame($sharedBy, $result['uid_initiator']);
  888. $this->assertSame($uidOwner, $result['uid_owner']);
  889. $this->assertSame($permissions, (int)$result['permissions']);
  890. $this->assertSame($token, $result['token']);
  891. }
  892. public function testGetRawShareFailed(): void {
  893. $this->expectException(\OCP\Share\Exceptions\ShareNotFound::class);
  894. $itemSource = 11;
  895. $itemType = 'file';
  896. $shareWith = 'user@server.com';
  897. $sharedBy = 'user1';
  898. $uidOwner = 'user2';
  899. $permissions = 1;
  900. $token = 'token';
  901. $instance = $this->getInstance();
  902. $id = $this->createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, $token);
  903. $this->invokePrivate($instance, 'getRawShare', [$id + 1]);
  904. }
  905. private function createDummyShare($itemType, $itemSource, $shareWith, $sharedBy, $uidOwner, $permissions, $token, $note = '', $shareType = IShare::TYPE_EMAIL) {
  906. $qb = $this->connection->getQueryBuilder();
  907. $qb->insert('share')
  908. ->setValue('share_type', $qb->createNamedParameter($shareType))
  909. ->setValue('item_type', $qb->createNamedParameter($itemType))
  910. ->setValue('item_source', $qb->createNamedParameter($itemSource))
  911. ->setValue('file_source', $qb->createNamedParameter($itemSource))
  912. ->setValue('share_with', $qb->createNamedParameter($shareWith))
  913. ->setValue('uid_owner', $qb->createNamedParameter($uidOwner))
  914. ->setValue('uid_initiator', $qb->createNamedParameter($sharedBy))
  915. ->setValue('permissions', $qb->createNamedParameter($permissions))
  916. ->setValue('token', $qb->createNamedParameter($token))
  917. ->setValue('note', $qb->createNamedParameter($note))
  918. ->setValue('stime', $qb->createNamedParameter(time()));
  919. /*
  920. * Added to fix https://github.com/owncloud/core/issues/22215
  921. * Can be removed once we get rid of ajax/share.php
  922. */
  923. $qb->setValue('file_target', $qb->createNamedParameter(''));
  924. $qb->execute();
  925. $id = $qb->getLastInsertId();
  926. return (int)$id;
  927. }
  928. public function testGetSharesInFolder(): void {
  929. $userManager = \OC::$server->getUserManager();
  930. $rootFolder = \OC::$server->getRootFolder();
  931. $this->shareManager->expects($this->any())
  932. ->method('newShare')
  933. ->willReturn(new \OC\Share20\Share($rootFolder, $userManager));
  934. $provider = $this->getInstance(['sendMailNotification', 'createShareActivity']);
  935. $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true);
  936. $u1 = $userManager->createUser('testFed', md5(time()));
  937. $u2 = $userManager->createUser('testFed2', md5(time()));
  938. $folder1 = $rootFolder->getUserFolder($u1->getUID())->newFolder('foo');
  939. $file1 = $folder1->newFile('bar1');
  940. $file2 = $folder1->newFile('bar2');
  941. $share1 = $this->shareManager->newShare();
  942. $share1->setSharedWith('user@server.com')
  943. ->setSharedBy($u1->getUID())
  944. ->setShareOwner($u1->getUID())
  945. ->setPermissions(\OCP\Constants::PERMISSION_READ)
  946. ->setNode($file1);
  947. $provider->create($share1);
  948. $share2 = $this->shareManager->newShare();
  949. $share2->setSharedWith('user@server.com')
  950. ->setSharedBy($u2->getUID())
  951. ->setShareOwner($u1->getUID())
  952. ->setPermissions(\OCP\Constants::PERMISSION_READ)
  953. ->setNode($file2);
  954. $provider->create($share2);
  955. $result = $provider->getSharesInFolder($u1->getUID(), $folder1, false);
  956. $this->assertCount(1, $result);
  957. $this->assertCount(1, $result[$file1->getId()]);
  958. $result = $provider->getSharesInFolder($u1->getUID(), $folder1, true);
  959. $this->assertCount(2, $result);
  960. $this->assertCount(1, $result[$file1->getId()]);
  961. $this->assertCount(1, $result[$file2->getId()]);
  962. $u1->delete();
  963. $u2->delete();
  964. }
  965. public function testGetAccessList(): void {
  966. $userManager = \OC::$server->getUserManager();
  967. $rootFolder = \OC::$server->getRootFolder();
  968. $this->shareManager->expects($this->any())
  969. ->method('newShare')
  970. ->willReturn(new \OC\Share20\Share($rootFolder, $userManager));
  971. $provider = $this->getInstance(['sendMailNotification', 'createShareActivity']);
  972. $this->mailer->expects($this->any())->method('validateMailAddress')->willReturn(true);
  973. $u1 = $userManager->createUser('testFed', md5(time()));
  974. $u2 = $userManager->createUser('testFed2', md5(time()));
  975. $folder = $rootFolder->getUserFolder($u1->getUID())->newFolder('foo');
  976. $accessList = $provider->getAccessList([$folder], true);
  977. $this->assertArrayHasKey('public', $accessList);
  978. $this->assertFalse($accessList['public']);
  979. $accessList = $provider->getAccessList([$folder], false);
  980. $this->assertArrayHasKey('public', $accessList);
  981. $this->assertFalse($accessList['public']);
  982. $share1 = $this->shareManager->newShare();
  983. $share1->setSharedWith('user@server.com')
  984. ->setSharedBy($u1->getUID())
  985. ->setShareOwner($u1->getUID())
  986. ->setPermissions(\OCP\Constants::PERMISSION_READ)
  987. ->setNode($folder);
  988. $share1 = $provider->create($share1);
  989. $share2 = $this->shareManager->newShare();
  990. $share2->setSharedWith('user2@server.com')
  991. ->setSharedBy($u2->getUID())
  992. ->setShareOwner($u1->getUID())
  993. ->setPermissions(\OCP\Constants::PERMISSION_READ)
  994. ->setNode($folder);
  995. $share2 = $provider->create($share2);
  996. $accessList = $provider->getAccessList([$folder], true);
  997. $this->assertArrayHasKey('public', $accessList);
  998. $this->assertTrue($accessList['public']);
  999. $accessList = $provider->getAccessList([$folder], false);
  1000. $this->assertArrayHasKey('public', $accessList);
  1001. $this->assertTrue($accessList['public']);
  1002. $provider->delete($share2);
  1003. $accessList = $provider->getAccessList([$folder], true);
  1004. $this->assertArrayHasKey('public', $accessList);
  1005. $this->assertTrue($accessList['public']);
  1006. $accessList = $provider->getAccessList([$folder], false);
  1007. $this->assertArrayHasKey('public', $accessList);
  1008. $this->assertTrue($accessList['public']);
  1009. $provider->delete($share1);
  1010. $accessList = $provider->getAccessList([$folder], true);
  1011. $this->assertArrayHasKey('public', $accessList);
  1012. $this->assertFalse($accessList['public']);
  1013. $accessList = $provider->getAccessList([$folder], false);
  1014. $this->assertArrayHasKey('public', $accessList);
  1015. $this->assertFalse($accessList['public']);
  1016. $u1->delete();
  1017. $u2->delete();
  1018. }
  1019. public function testSendMailNotificationWithSameUserAndUserEmail(): void {
  1020. $provider = $this->getInstance();
  1021. $user = $this->createMock(IUser::class);
  1022. $this->settingsManager->expects($this->any())->method('replyToInitiator')->willReturn(true);
  1023. $this->userManager
  1024. ->expects($this->once())
  1025. ->method('get')
  1026. ->with('OwnerUser')
  1027. ->willReturn($user);
  1028. $user
  1029. ->expects($this->once())
  1030. ->method('getDisplayName')
  1031. ->willReturn('Mrs. Owner User');
  1032. $message = $this->createMock(Message::class);
  1033. $this->mailer
  1034. ->expects($this->once())
  1035. ->method('createMessage')
  1036. ->willReturn($message);
  1037. $template = $this->createMock(IEMailTemplate::class);
  1038. $this->mailer
  1039. ->expects($this->once())
  1040. ->method('createEMailTemplate')
  1041. ->willReturn($template);
  1042. $template
  1043. ->expects($this->once())
  1044. ->method('addHeader');
  1045. $template
  1046. ->expects($this->once())
  1047. ->method('addHeading')
  1048. ->with('Mrs. Owner User shared file.txt with you');
  1049. $template
  1050. ->expects($this->once())
  1051. ->method('addBodyText')
  1052. ->with(
  1053. 'Mrs. Owner User shared file.txt with you. Click the button below to open it.',
  1054. 'Mrs. Owner User shared file.txt with you.'
  1055. );
  1056. $template
  1057. ->expects($this->once())
  1058. ->method('addBodyButton')
  1059. ->with(
  1060. 'Open file.txt',
  1061. 'https://example.com/file.txt'
  1062. );
  1063. $message
  1064. ->expects($this->once())
  1065. ->method('setTo')
  1066. ->with(['john@doe.com']);
  1067. $this->defaults
  1068. ->expects($this->once())
  1069. ->method('getName')
  1070. ->willReturn('UnitTestCloud');
  1071. $message
  1072. ->expects($this->once())
  1073. ->method('setFrom')
  1074. ->with([
  1075. \OCP\Util::getDefaultEmailAddress('UnitTestCloud') => 'Mrs. Owner User via UnitTestCloud'
  1076. ]);
  1077. $user
  1078. ->expects($this->once())
  1079. ->method('getEMailAddress')
  1080. ->willReturn('owner@example.com');
  1081. $message
  1082. ->expects($this->once())
  1083. ->method('setReplyTo')
  1084. ->with(['owner@example.com' => 'Mrs. Owner User']);
  1085. $this->defaults
  1086. ->expects($this->exactly(2))
  1087. ->method('getSlogan')
  1088. ->willReturn('Testing like 1990');
  1089. $template
  1090. ->expects($this->once())
  1091. ->method('addFooter')
  1092. ->with('UnitTestCloud - Testing like 1990');
  1093. $template
  1094. ->expects($this->once())
  1095. ->method('setSubject')
  1096. ->with('Mrs. Owner User shared file.txt with you');
  1097. $message
  1098. ->expects($this->once())
  1099. ->method('useTemplate')
  1100. ->with($template);
  1101. $this->mailer->expects($this->once())
  1102. ->method('validateMailAddress')
  1103. ->willReturn(true);
  1104. $this->mailer
  1105. ->expects($this->once())
  1106. ->method('send')
  1107. ->with($message);
  1108. $this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute')
  1109. ->with('files_sharing.sharecontroller.showShare', ['token' => 'token'])
  1110. ->willReturn('https://example.com/file.txt');
  1111. $node = $this->getMockBuilder(File::class)->getMock();
  1112. $node->expects($this->any())->method('getName')->willReturn('file.txt');
  1113. $share = $this->getMockBuilder(IShare::class)->getMock();
  1114. $share->expects($this->any())->method('getSharedBy')->willReturn('OwnerUser');
  1115. $share->expects($this->any())->method('getSharedWith')->willReturn('john@doe.com');
  1116. $share->expects($this->any())->method('getNode')->willReturn($node);
  1117. $share->expects($this->any())->method('getId')->willReturn(42);
  1118. $share->expects($this->any())->method('getNote')->willReturn('');
  1119. $share->expects($this->any())->method('getToken')->willReturn('token');
  1120. self::invokePrivate(
  1121. $provider,
  1122. 'sendMailNotification',
  1123. [$share]
  1124. );
  1125. }
  1126. public function testSendMailNotificationWithSameUserAndUserEmailAndNote(): void {
  1127. $provider = $this->getInstance();
  1128. $user = $this->createMock(IUser::class);
  1129. $this->settingsManager->expects($this->any())->method('replyToInitiator')->willReturn(true);
  1130. $this->userManager
  1131. ->expects($this->once())
  1132. ->method('get')
  1133. ->with('OwnerUser')
  1134. ->willReturn($user);
  1135. $user
  1136. ->expects($this->once())
  1137. ->method('getDisplayName')
  1138. ->willReturn('Mrs. Owner User');
  1139. $message = $this->createMock(Message::class);
  1140. $this->mailer
  1141. ->expects($this->once())
  1142. ->method('createMessage')
  1143. ->willReturn($message);
  1144. $template = $this->createMock(IEMailTemplate::class);
  1145. $this->mailer
  1146. ->expects($this->once())
  1147. ->method('createEMailTemplate')
  1148. ->willReturn($template);
  1149. $template
  1150. ->expects($this->once())
  1151. ->method('addHeader');
  1152. $template
  1153. ->expects($this->once())
  1154. ->method('addHeading')
  1155. ->with('Mrs. Owner User shared file.txt with you');
  1156. $template
  1157. ->expects($this->once())
  1158. ->method('addBodyText')
  1159. ->with('Mrs. Owner User shared file.txt with you. Click the button below to open it.', 'Mrs. Owner User shared file.txt with you.');
  1160. $this->urlGenerator->expects($this->once())->method('imagePath')
  1161. ->with('core', 'caldav/description.png')
  1162. ->willReturn('core/img/caldav/description.png');
  1163. $this->urlGenerator->expects($this->once())->method('getAbsoluteURL')
  1164. ->with('core/img/caldav/description.png')
  1165. ->willReturn('https://example.com/core/img/caldav/description.png');
  1166. $template
  1167. ->expects($this->once())
  1168. ->method('addBodyListItem')
  1169. ->with(
  1170. 'This is a note to the recipient',
  1171. 'Note:',
  1172. 'https://example.com/core/img/caldav/description.png',
  1173. 'This is a note to the recipient'
  1174. );
  1175. $template
  1176. ->expects($this->once())
  1177. ->method('addBodyButton')
  1178. ->with(
  1179. 'Open file.txt',
  1180. 'https://example.com/file.txt'
  1181. );
  1182. $message
  1183. ->expects($this->once())
  1184. ->method('setTo')
  1185. ->with(['john@doe.com']);
  1186. $this->defaults
  1187. ->expects($this->once())
  1188. ->method('getName')
  1189. ->willReturn('UnitTestCloud');
  1190. $message
  1191. ->expects($this->once())
  1192. ->method('setFrom')
  1193. ->with([
  1194. \OCP\Util::getDefaultEmailAddress('UnitTestCloud') => 'Mrs. Owner User via UnitTestCloud'
  1195. ]);
  1196. $user
  1197. ->expects($this->once())
  1198. ->method('getEMailAddress')
  1199. ->willReturn('owner@example.com');
  1200. $message
  1201. ->expects($this->once())
  1202. ->method('setReplyTo')
  1203. ->with(['owner@example.com' => 'Mrs. Owner User']);
  1204. $this->defaults
  1205. ->expects($this->exactly(2))
  1206. ->method('getSlogan')
  1207. ->willReturn('Testing like 1990');
  1208. $template
  1209. ->expects($this->once())
  1210. ->method('addFooter')
  1211. ->with('UnitTestCloud - Testing like 1990');
  1212. $template
  1213. ->expects($this->once())
  1214. ->method('setSubject')
  1215. ->with('Mrs. Owner User shared file.txt with you');
  1216. $message
  1217. ->expects($this->once())
  1218. ->method('useTemplate')
  1219. ->with($template);
  1220. $this->mailer->expects($this->once())
  1221. ->method('validateMailAddress')
  1222. ->willReturn(true);
  1223. $this->mailer
  1224. ->expects($this->once())
  1225. ->method('send')
  1226. ->with($message);
  1227. $this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute')
  1228. ->with('files_sharing.sharecontroller.showShare', ['token' => 'token'])
  1229. ->willReturn('https://example.com/file.txt');
  1230. $node = $this->getMockBuilder(File::class)->getMock();
  1231. $node->expects($this->any())->method('getName')->willReturn('file.txt');
  1232. $share = $this->getMockBuilder(IShare::class)->getMock();
  1233. $share->expects($this->any())->method('getSharedBy')->willReturn('OwnerUser');
  1234. $share->expects($this->any())->method('getSharedWith')->willReturn('john@doe.com');
  1235. $share->expects($this->any())->method('getNode')->willReturn($node);
  1236. $share->expects($this->any())->method('getId')->willReturn(42);
  1237. $share->expects($this->any())->method('getNote')->willReturn('This is a note to the recipient');
  1238. $share->expects($this->any())->method('getToken')->willReturn('token');
  1239. self::invokePrivate(
  1240. $provider,
  1241. 'sendMailNotification',
  1242. [$share]
  1243. );
  1244. }
  1245. public function testSendMailNotificationWithSameUserAndUserEmailAndExpiration(): void {
  1246. $provider = $this->getInstance();
  1247. $user = $this->createMock(IUser::class);
  1248. $this->settingsManager->expects($this->any())->method('replyToInitiator')->willReturn(true);
  1249. $this->userManager
  1250. ->expects($this->once())
  1251. ->method('get')
  1252. ->with('OwnerUser')
  1253. ->willReturn($user);
  1254. $user
  1255. ->expects($this->once())
  1256. ->method('getDisplayName')
  1257. ->willReturn('Mrs. Owner User');
  1258. $message = $this->createMock(Message::class);
  1259. $this->mailer
  1260. ->expects($this->once())
  1261. ->method('createMessage')
  1262. ->willReturn($message);
  1263. $template = $this->createMock(IEMailTemplate::class);
  1264. $this->mailer
  1265. ->expects($this->once())
  1266. ->method('createEMailTemplate')
  1267. ->willReturn($template);
  1268. $template
  1269. ->expects($this->once())
  1270. ->method('addHeader');
  1271. $template
  1272. ->expects($this->once())
  1273. ->method('addHeading')
  1274. ->with('Mrs. Owner User shared file.txt with you');
  1275. $template
  1276. ->expects($this->once())
  1277. ->method('addBodyText')
  1278. ->with('Mrs. Owner User shared file.txt with you. Click the button below to open it.', 'Mrs. Owner User shared file.txt with you.');
  1279. $expiration = new DateTime('2001-01-01');
  1280. $this->l->expects($this->once())
  1281. ->method('l')
  1282. ->with('date', $expiration, ['width' => 'medium'])
  1283. ->willReturn('2001-01-01');
  1284. $this->urlGenerator->expects($this->once())->method('imagePath')
  1285. ->with('core', 'caldav/time.png')
  1286. ->willReturn('core/img/caldav/time.png');
  1287. $this->urlGenerator->expects($this->once())->method('getAbsoluteURL')
  1288. ->with('core/img/caldav/time.png')
  1289. ->willReturn('https://example.com/core/img/caldav/time.png');
  1290. $template
  1291. ->expects($this->once())
  1292. ->method('addBodyListItem')
  1293. ->with(
  1294. 'This share is valid until 2001-01-01 at midnight',
  1295. 'Expiration:',
  1296. 'https://example.com/core/img/caldav/time.png',
  1297. );
  1298. $template
  1299. ->expects($this->once())
  1300. ->method('addBodyButton')
  1301. ->with(
  1302. 'Open file.txt',
  1303. 'https://example.com/file.txt'
  1304. );
  1305. $message
  1306. ->expects($this->once())
  1307. ->method('setTo')
  1308. ->with(['john@doe.com']);
  1309. $this->defaults
  1310. ->expects($this->once())
  1311. ->method('getName')
  1312. ->willReturn('UnitTestCloud');
  1313. $message
  1314. ->expects($this->once())
  1315. ->method('setFrom')
  1316. ->with([
  1317. \OCP\Util::getDefaultEmailAddress('UnitTestCloud') => 'Mrs. Owner User via UnitTestCloud'
  1318. ]);
  1319. $user
  1320. ->expects($this->once())
  1321. ->method('getEMailAddress')
  1322. ->willReturn('owner@example.com');
  1323. $message
  1324. ->expects($this->once())
  1325. ->method('setReplyTo')
  1326. ->with(['owner@example.com' => 'Mrs. Owner User']);
  1327. $this->defaults
  1328. ->expects($this->exactly(2))
  1329. ->method('getSlogan')
  1330. ->willReturn('Testing like 1990');
  1331. $template
  1332. ->expects($this->once())
  1333. ->method('addFooter')
  1334. ->with('UnitTestCloud - Testing like 1990');
  1335. $template
  1336. ->expects($this->once())
  1337. ->method('setSubject')
  1338. ->with('Mrs. Owner User shared file.txt with you');
  1339. $message
  1340. ->expects($this->once())
  1341. ->method('useTemplate')
  1342. ->with($template);
  1343. $this->mailer->expects($this->once())
  1344. ->method('validateMailAddress')
  1345. ->willReturn(true);
  1346. $this->mailer
  1347. ->expects($this->once())
  1348. ->method('send')
  1349. ->with($message);
  1350. $this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute')
  1351. ->with('files_sharing.sharecontroller.showShare', ['token' => 'token'])
  1352. ->willReturn('https://example.com/file.txt');
  1353. $node = $this->getMockBuilder(File::class)->getMock();
  1354. $node->expects($this->any())->method('getName')->willReturn('file.txt');
  1355. $share = $this->getMockBuilder(IShare::class)->getMock();
  1356. $share->expects($this->any())->method('getSharedBy')->willReturn('OwnerUser');
  1357. $share->expects($this->any())->method('getSharedWith')->willReturn('john@doe.com');
  1358. $share->expects($this->any())->method('getNode')->willReturn($node);
  1359. $share->expects($this->any())->method('getId')->willReturn(42);
  1360. $share->expects($this->any())->method('getNote')->willReturn('');
  1361. $share->expects($this->any())->method('getExpirationDate')->willReturn($expiration);
  1362. $share->expects($this->any())->method('getToken')->willReturn('token');
  1363. self::invokePrivate(
  1364. $provider,
  1365. 'sendMailNotification',
  1366. [$share]
  1367. );
  1368. }
  1369. public function testSendMailNotificationWithDifferentUserAndNoUserEmail(): void {
  1370. $provider = $this->getInstance();
  1371. $initiatorUser = $this->createMock(IUser::class);
  1372. $this->settingsManager->expects($this->any())->method('replyToInitiator')->willReturn(true);
  1373. $this->userManager
  1374. ->expects($this->once())
  1375. ->method('get')
  1376. ->with('InitiatorUser')
  1377. ->willReturn($initiatorUser);
  1378. $initiatorUser
  1379. ->expects($this->once())
  1380. ->method('getDisplayName')
  1381. ->willReturn('Mr. Initiator User');
  1382. $message = $this->createMock(Message::class);
  1383. $this->mailer
  1384. ->expects($this->once())
  1385. ->method('createMessage')
  1386. ->willReturn($message);
  1387. $template = $this->createMock(IEMailTemplate::class);
  1388. $this->mailer
  1389. ->expects($this->once())
  1390. ->method('createEMailTemplate')
  1391. ->willReturn($template);
  1392. $template
  1393. ->expects($this->once())
  1394. ->method('addHeader');
  1395. $template
  1396. ->expects($this->once())
  1397. ->method('addHeading')
  1398. ->with('Mr. Initiator User shared file.txt with you');
  1399. $template
  1400. ->expects($this->once())
  1401. ->method('addBodyText')
  1402. ->with(
  1403. 'Mr. Initiator User shared file.txt with you. Click the button below to open it.',
  1404. 'Mr. Initiator User shared file.txt with you.'
  1405. );
  1406. $template
  1407. ->expects($this->once())
  1408. ->method('addBodyButton')
  1409. ->with(
  1410. 'Open file.txt',
  1411. 'https://example.com/file.txt'
  1412. );
  1413. $message
  1414. ->expects($this->once())
  1415. ->method('setTo')
  1416. ->with(['john@doe.com']);
  1417. $this->defaults
  1418. ->expects($this->once())
  1419. ->method('getName')
  1420. ->willReturn('UnitTestCloud');
  1421. $message
  1422. ->expects($this->once())
  1423. ->method('setFrom')
  1424. ->with([
  1425. \OCP\Util::getDefaultEmailAddress('UnitTestCloud') => 'Mr. Initiator User via UnitTestCloud'
  1426. ]);
  1427. $message
  1428. ->expects($this->never())
  1429. ->method('setReplyTo');
  1430. $template
  1431. ->expects($this->once())
  1432. ->method('addFooter')
  1433. ->with('');
  1434. $template
  1435. ->expects($this->once())
  1436. ->method('setSubject')
  1437. ->with('Mr. Initiator User shared file.txt with you');
  1438. $message
  1439. ->expects($this->once())
  1440. ->method('useTemplate')
  1441. ->with($template);
  1442. $this->mailer->expects($this->once())
  1443. ->method('validateMailAddress')
  1444. ->willReturn(true);
  1445. $this->mailer
  1446. ->expects($this->once())
  1447. ->method('send')
  1448. ->with($message);
  1449. $this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute')
  1450. ->with('files_sharing.sharecontroller.showShare', ['token' => 'token'])
  1451. ->willReturn('https://example.com/file.txt');
  1452. $node = $this->getMockBuilder(File::class)->getMock();
  1453. $node->expects($this->any())->method('getName')->willReturn('file.txt');
  1454. $share = $this->getMockBuilder(IShare::class)->getMock();
  1455. $share->expects($this->any())->method('getSharedBy')->willReturn('InitiatorUser');
  1456. $share->expects($this->any())->method('getSharedWith')->willReturn('john@doe.com');
  1457. $share->expects($this->any())->method('getNode')->willReturn($node);
  1458. $share->expects($this->any())->method('getId')->willReturn(42);
  1459. $share->expects($this->any())->method('getNote')->willReturn('');
  1460. $share->expects($this->any())->method('getToken')->willReturn('token');
  1461. self::invokePrivate(
  1462. $provider,
  1463. 'sendMailNotification',
  1464. [$share]
  1465. );
  1466. }
  1467. public function testSendMailNotificationWithSameUserAndUserEmailAndReplyToDesactivate(): void {
  1468. $provider = $this->getInstance();
  1469. $user = $this->createMock(IUser::class);
  1470. $this->settingsManager->expects($this->any())->method('replyToInitiator')->willReturn(false);
  1471. $this->userManager
  1472. ->expects($this->once())
  1473. ->method('get')
  1474. ->with('OwnerUser')
  1475. ->willReturn($user);
  1476. $user
  1477. ->expects($this->once())
  1478. ->method('getDisplayName')
  1479. ->willReturn('Mrs. Owner User');
  1480. $message = $this->createMock(Message::class);
  1481. $this->mailer
  1482. ->expects($this->once())
  1483. ->method('createMessage')
  1484. ->willReturn($message);
  1485. $template = $this->createMock(IEMailTemplate::class);
  1486. $this->mailer
  1487. ->expects($this->once())
  1488. ->method('createEMailTemplate')
  1489. ->willReturn($template);
  1490. $template
  1491. ->expects($this->once())
  1492. ->method('addHeader');
  1493. $template
  1494. ->expects($this->once())
  1495. ->method('addHeading')
  1496. ->with('Mrs. Owner User shared file.txt with you');
  1497. $template
  1498. ->expects($this->once())
  1499. ->method('addBodyText')
  1500. ->with(
  1501. 'Mrs. Owner User shared file.txt with you. Click the button below to open it.',
  1502. 'Mrs. Owner User shared file.txt with you.'
  1503. );
  1504. $template
  1505. ->expects($this->once())
  1506. ->method('addBodyButton')
  1507. ->with(
  1508. 'Open file.txt',
  1509. 'https://example.com/file.txt'
  1510. );
  1511. $message
  1512. ->expects($this->once())
  1513. ->method('setTo')
  1514. ->with(['john@doe.com']);
  1515. $this->defaults
  1516. ->expects($this->once())
  1517. ->method('getName')
  1518. ->willReturn('UnitTestCloud');
  1519. $message
  1520. ->expects($this->once())
  1521. ->method('setFrom')
  1522. ->with([
  1523. \OCP\Util::getDefaultEmailAddress('UnitTestCloud') => 'UnitTestCloud'
  1524. ]);
  1525. // Since replyToInitiator is false, we never get the initiator email address
  1526. $user
  1527. ->expects($this->never())
  1528. ->method('getEMailAddress');
  1529. $message
  1530. ->expects($this->never())
  1531. ->method('setReplyTo');
  1532. $template
  1533. ->expects($this->once())
  1534. ->method('addFooter')
  1535. ->with('');
  1536. $template
  1537. ->expects($this->once())
  1538. ->method('setSubject')
  1539. ->with('Mrs. Owner User shared file.txt with you');
  1540. $message
  1541. ->expects($this->once())
  1542. ->method('useTemplate')
  1543. ->with($template);
  1544. $this->mailer->expects($this->once())
  1545. ->method('validateMailAddress')
  1546. ->willReturn(true);
  1547. $this->mailer
  1548. ->expects($this->once())
  1549. ->method('send')
  1550. ->with($message);
  1551. $this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute')
  1552. ->with('files_sharing.sharecontroller.showShare', ['token' => 'token'])
  1553. ->willReturn('https://example.com/file.txt');
  1554. $node = $this->getMockBuilder(File::class)->getMock();
  1555. $node->expects($this->any())->method('getName')->willReturn('file.txt');
  1556. $share = $this->getMockBuilder(IShare::class)->getMock();
  1557. $share->expects($this->any())->method('getSharedBy')->willReturn('OwnerUser');
  1558. $share->expects($this->any())->method('getSharedWith')->willReturn('john@doe.com');
  1559. $share->expects($this->any())->method('getNode')->willReturn($node);
  1560. $share->expects($this->any())->method('getId')->willReturn(42);
  1561. $share->expects($this->any())->method('getNote')->willReturn('');
  1562. $share->expects($this->any())->method('getToken')->willReturn('token');
  1563. self::invokePrivate(
  1564. $provider,
  1565. 'sendMailNotification',
  1566. [$share]
  1567. );
  1568. }
  1569. public function testSendMailNotificationWithDifferentUserAndNoUserEmailAndReplyToDesactivate(): void {
  1570. $provider = $this->getInstance();
  1571. $initiatorUser = $this->createMock(IUser::class);
  1572. $this->settingsManager->expects($this->any())->method('replyToInitiator')->willReturn(false);
  1573. $this->userManager
  1574. ->expects($this->once())
  1575. ->method('get')
  1576. ->with('InitiatorUser')
  1577. ->willReturn($initiatorUser);
  1578. $initiatorUser
  1579. ->expects($this->once())
  1580. ->method('getDisplayName')
  1581. ->willReturn('Mr. Initiator User');
  1582. $message = $this->createMock(Message::class);
  1583. $this->mailer
  1584. ->expects($this->once())
  1585. ->method('createMessage')
  1586. ->willReturn($message);
  1587. $template = $this->createMock(IEMailTemplate::class);
  1588. $this->mailer
  1589. ->expects($this->once())
  1590. ->method('createEMailTemplate')
  1591. ->willReturn($template);
  1592. $template
  1593. ->expects($this->once())
  1594. ->method('addHeader');
  1595. $template
  1596. ->expects($this->once())
  1597. ->method('addHeading')
  1598. ->with('Mr. Initiator User shared file.txt with you');
  1599. $template
  1600. ->expects($this->once())
  1601. ->method('addBodyText')
  1602. ->with(
  1603. 'Mr. Initiator User shared file.txt with you. Click the button below to open it.',
  1604. 'Mr. Initiator User shared file.txt with you.'
  1605. );
  1606. $template
  1607. ->expects($this->once())
  1608. ->method('addBodyButton')
  1609. ->with(
  1610. 'Open file.txt',
  1611. 'https://example.com/file.txt'
  1612. );
  1613. $message
  1614. ->expects($this->once())
  1615. ->method('setTo')
  1616. ->with(['john@doe.com']);
  1617. $this->defaults
  1618. ->expects($this->once())
  1619. ->method('getName')
  1620. ->willReturn('UnitTestCloud');
  1621. $message
  1622. ->expects($this->once())
  1623. ->method('setFrom')
  1624. ->with([
  1625. \OCP\Util::getDefaultEmailAddress('UnitTestCloud') => 'UnitTestCloud'
  1626. ]);
  1627. $message
  1628. ->expects($this->never())
  1629. ->method('setReplyTo');
  1630. $template
  1631. ->expects($this->once())
  1632. ->method('addFooter')
  1633. ->with('');
  1634. $template
  1635. ->expects($this->once())
  1636. ->method('setSubject')
  1637. ->with('Mr. Initiator User shared file.txt with you');
  1638. $message
  1639. ->expects($this->once())
  1640. ->method('useTemplate')
  1641. ->with($template);
  1642. $this->mailer->expects($this->once())
  1643. ->method('validateMailAddress')
  1644. ->willReturn(true);
  1645. $this->mailer
  1646. ->expects($this->once())
  1647. ->method('send')
  1648. ->with($message);
  1649. $this->urlGenerator->expects($this->once())->method('linkToRouteAbsolute')
  1650. ->with('files_sharing.sharecontroller.showShare', ['token' => 'token'])
  1651. ->willReturn('https://example.com/file.txt');
  1652. $node = $this->getMockBuilder(File::class)->getMock();
  1653. $node->expects($this->any())->method('getName')->willReturn('file.txt');
  1654. $share = $this->getMockBuilder(IShare::class)->getMock();
  1655. $share->expects($this->any())->method('getSharedBy')->willReturn('InitiatorUser');
  1656. $share->expects($this->any())->method('getSharedWith')->willReturn('john@doe.com');
  1657. $share->expects($this->any())->method('getNode')->willReturn($node);
  1658. $share->expects($this->any())->method('getId')->willReturn(42);
  1659. $share->expects($this->any())->method('getNote')->willReturn('');
  1660. $share->expects($this->any())->method('getToken')->willReturn('token');
  1661. self::invokePrivate(
  1662. $provider,
  1663. 'sendMailNotification',
  1664. [$share]
  1665. );
  1666. }
  1667. }