MailPluginTest.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2017 Arthur Schiwon <blizzz@arthur-schiwon.de>
  4. *
  5. * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
  6. *
  7. * @license GNU AGPL version 3 or any later version
  8. *
  9. * This program is free software: you can redistribute it and/or modify
  10. * it under the terms of the GNU Affero General Public License as
  11. * published by the Free Software Foundation, either version 3 of the
  12. * License, or (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU Affero General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU Affero General Public License
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. *
  22. */
  23. namespace Test\Collaboration\Collaborators;
  24. use OC\Collaboration\Collaborators\MailPlugin;
  25. use OC\Collaboration\Collaborators\SearchResult;
  26. use OC\Federation\CloudIdManager;
  27. use OCP\Collaboration\Collaborators\SearchResultType;
  28. use OCP\Contacts\IManager;
  29. use OCP\Federation\ICloudIdManager;
  30. use OCP\IConfig;
  31. use OCP\IGroupManager;
  32. use OCP\IUser;
  33. use OCP\IUserSession;
  34. use OCP\Share;
  35. use Test\TestCase;
  36. class MailPluginTest extends TestCase {
  37. /** @var IConfig|\PHPUnit_Framework_MockObject_MockObject */
  38. protected $config;
  39. /** @var IManager|\PHPUnit_Framework_MockObject_MockObject */
  40. protected $contactsManager;
  41. /** @var ICloudIdManager|\PHPUnit_Framework_MockObject_MockObject */
  42. protected $cloudIdManager;
  43. /** @var MailPlugin */
  44. protected $plugin;
  45. /** @var SearchResult */
  46. protected $searchResult;
  47. /** @var IGroupManager|\PHPUnit_Framework_MockObject_MockObject */
  48. protected $groupManager;
  49. /** @var IUserSession|\PHPUnit_Framework_MockObject_MockObject */
  50. protected $userSession;
  51. public function setUp() {
  52. parent::setUp();
  53. $this->config = $this->createMock(IConfig::class);
  54. $this->contactsManager = $this->createMock(IManager::class);
  55. $this->groupManager = $this->createMock(IGroupManager::class);
  56. $this->userSession = $this->createMock(IUserSession::class);
  57. $this->cloudIdManager = new CloudIdManager();
  58. $this->searchResult = new SearchResult();
  59. }
  60. public function instantiatePlugin() {
  61. $this->plugin = new MailPlugin($this->contactsManager, $this->cloudIdManager, $this->config, $this->groupManager, $this->userSession);
  62. }
  63. /**
  64. * @dataProvider dataGetEmail
  65. *
  66. * @param string $searchTerm
  67. * @param array $contacts
  68. * @param bool $shareeEnumeration
  69. * @param array $expected
  70. * @param bool $reachedEnd
  71. */
  72. public function testSearch($searchTerm, $contacts, $shareeEnumeration, $expected, $exactIdMatch, $reachedEnd) {
  73. $this->config->expects($this->any())
  74. ->method('getAppValue')
  75. ->willReturnCallback(
  76. function($appName, $key, $default)
  77. use ($shareeEnumeration)
  78. {
  79. if ($appName === 'core' && $key === 'shareapi_allow_share_dialog_user_enumeration') {
  80. return $shareeEnumeration ? 'yes' : 'no';
  81. }
  82. return $default;
  83. }
  84. );
  85. $this->instantiatePlugin();
  86. $currentUser = $this->createMock(IUser::class);
  87. $currentUser->method('getUID')
  88. ->willReturn('current');
  89. $this->userSession->method('getUser')
  90. ->willReturn($currentUser);
  91. $this->contactsManager->expects($this->any())
  92. ->method('search')
  93. ->with($searchTerm, ['EMAIL', 'FN'])
  94. ->willReturn($contacts);
  95. $moreResults = $this->plugin->search($searchTerm, 2, 0, $this->searchResult);
  96. $result = $this->searchResult->asArray();
  97. $this->assertSame($exactIdMatch, $this->searchResult->hasExactIdMatch(new SearchResultType('emails')));
  98. $this->assertEquals($expected, $result);
  99. $this->assertSame($reachedEnd, $moreResults);
  100. }
  101. public function dataGetEmail() {
  102. return [
  103. ['test', [], true, ['emails' => [], 'exact' => ['emails' => []]], false, false],
  104. ['test', [], false, ['emails' => [], 'exact' => ['emails' => []]], false, false],
  105. [
  106. 'test@remote.com',
  107. [],
  108. true,
  109. ['emails' => [], 'exact' => ['emails' => [['label' => 'test@remote.com', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]],
  110. false,
  111. false,
  112. ],
  113. [ // no valid email address
  114. 'test@remote',
  115. [],
  116. true,
  117. ['emails' => [], 'exact' => ['emails' => []]],
  118. false,
  119. false,
  120. ],
  121. [
  122. 'test@remote.com',
  123. [],
  124. false,
  125. ['emails' => [], 'exact' => ['emails' => [['label' => 'test@remote.com', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]],
  126. false,
  127. false,
  128. ],
  129. [
  130. 'test',
  131. [
  132. [
  133. 'FN' => 'User3 @ Localhost',
  134. ],
  135. [
  136. 'FN' => 'User2 @ Localhost',
  137. 'EMAIL' => [
  138. ],
  139. ],
  140. [
  141. 'FN' => 'User @ Localhost',
  142. 'EMAIL' => [
  143. 'username@localhost',
  144. ],
  145. ],
  146. ],
  147. true,
  148. ['emails' => [['label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'username@localhost']]], 'exact' => ['emails' => []]],
  149. false,
  150. false,
  151. ],
  152. [
  153. 'test',
  154. [
  155. [
  156. 'FN' => 'User3 @ Localhost',
  157. ],
  158. [
  159. 'FN' => 'User2 @ Localhost',
  160. 'EMAIL' => [
  161. ],
  162. ],
  163. [
  164. 'FN' => 'User @ Localhost',
  165. 'EMAIL' => [
  166. 'username@localhost',
  167. ],
  168. ],
  169. ],
  170. false,
  171. ['emails' => [], 'exact' => ['emails' => []]],
  172. false,
  173. false,
  174. ],
  175. [
  176. 'test@remote.com',
  177. [
  178. [
  179. 'FN' => 'User3 @ Localhost',
  180. ],
  181. [
  182. 'FN' => 'User2 @ Localhost',
  183. 'EMAIL' => [
  184. ],
  185. ],
  186. [
  187. 'FN' => 'User @ Localhost',
  188. 'EMAIL' => [
  189. 'username@localhost',
  190. ],
  191. ],
  192. ],
  193. true,
  194. ['emails' => [['label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'username@localhost']]], 'exact' => ['emails' => [['label' => 'test@remote.com', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]],
  195. false,
  196. false,
  197. ],
  198. [
  199. 'test@remote.com',
  200. [
  201. [
  202. 'FN' => 'User3 @ Localhost',
  203. ],
  204. [
  205. 'FN' => 'User2 @ Localhost',
  206. 'EMAIL' => [
  207. ],
  208. ],
  209. [
  210. 'FN' => 'User @ Localhost',
  211. 'EMAIL' => [
  212. 'username@localhost',
  213. ],
  214. ],
  215. ],
  216. false,
  217. ['emails' => [], 'exact' => ['emails' => [['label' => 'test@remote.com', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'test@remote.com']]]]],
  218. false,
  219. false,
  220. ],
  221. [
  222. 'username@localhost',
  223. [
  224. [
  225. 'FN' => 'User3 @ Localhost',
  226. ],
  227. [
  228. 'FN' => 'User2 @ Localhost',
  229. 'EMAIL' => [
  230. ],
  231. ],
  232. [
  233. 'FN' => 'User @ Localhost',
  234. 'EMAIL' => [
  235. 'username@localhost',
  236. ],
  237. ],
  238. ],
  239. true,
  240. ['emails' => [], 'exact' => ['emails' => [['label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'username@localhost']]]]],
  241. true,
  242. false,
  243. ],
  244. [
  245. 'username@localhost',
  246. [
  247. [
  248. 'FN' => 'User3 @ Localhost',
  249. ],
  250. [
  251. 'FN' => 'User2 @ Localhost',
  252. 'EMAIL' => [
  253. ],
  254. ],
  255. [
  256. 'FN' => 'User @ Localhost',
  257. 'EMAIL' => [
  258. 'username@localhost',
  259. ],
  260. ],
  261. ],
  262. false,
  263. ['emails' => [], 'exact' => ['emails' => [['label' => 'User @ Localhost (username@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'username@localhost']]]]],
  264. true,
  265. false,
  266. ],
  267. // contact with space
  268. [
  269. 'user name@localhost',
  270. [
  271. [
  272. 'FN' => 'User3 @ Localhost',
  273. ],
  274. [
  275. 'FN' => 'User2 @ Localhost',
  276. 'EMAIL' => [
  277. ],
  278. ],
  279. [
  280. 'FN' => 'User Name @ Localhost',
  281. 'EMAIL' => [
  282. 'user name@localhost',
  283. ],
  284. ],
  285. ],
  286. false,
  287. ['emails' => [], 'exact' => ['emails' => [['label' => 'User Name @ Localhost (user name@localhost)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'user name@localhost']]]]],
  288. true,
  289. false,
  290. ],
  291. // remote with space, no contact
  292. [
  293. 'user space@remote.com',
  294. [
  295. [
  296. 'FN' => 'User3 @ Localhost',
  297. ],
  298. [
  299. 'FN' => 'User2 @ Localhost',
  300. 'EMAIL' => [
  301. ],
  302. ],
  303. [
  304. 'FN' => 'User @ Localhost',
  305. 'EMAIL' => [
  306. 'username@localhost',
  307. ],
  308. ],
  309. ],
  310. false,
  311. ['emails' => [], 'exact' => ['emails' => []]],
  312. false,
  313. false,
  314. ],
  315. // Local user found by email
  316. [
  317. 'test@example.com',
  318. [
  319. [
  320. 'FN' => 'User',
  321. 'EMAIL' => ['test@example.com'],
  322. 'CLOUD' => ['test@localhost'],
  323. 'isLocalSystemBook' => true,
  324. ]
  325. ],
  326. false,
  327. ['users' => [], 'exact' => ['users' => [['label' => 'User (test@example.com)','value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test'],]]]],
  328. true,
  329. false,
  330. ],
  331. // Current local user found by email => no result
  332. [
  333. 'test@example.com',
  334. [
  335. [
  336. 'FN' => 'User',
  337. 'EMAIL' => ['test@example.com'],
  338. 'CLOUD' => ['current@localhost'],
  339. 'isLocalSystemBook' => true,
  340. ]
  341. ],
  342. true,
  343. ['exact' => []],
  344. false,
  345. false,
  346. ],
  347. // Pagination and "more results" for user matches byyyyyyy emails
  348. [
  349. 'test@example',
  350. [
  351. [
  352. 'FN' => 'User1',
  353. 'EMAIL' => ['test@example.com'],
  354. 'CLOUD' => ['test1@localhost'],
  355. 'isLocalSystemBook' => true,
  356. ],
  357. [
  358. 'FN' => 'User2',
  359. 'EMAIL' => ['test@example.de'],
  360. 'CLOUD' => ['test2@localhost'],
  361. 'isLocalSystemBook' => true,
  362. ],
  363. [
  364. 'FN' => 'User3',
  365. 'EMAIL' => ['test@example.org'],
  366. 'CLOUD' => ['test3@localhost'],
  367. 'isLocalSystemBook' => true,
  368. ],
  369. [
  370. 'FN' => 'User4',
  371. 'EMAIL' => ['test@example.net'],
  372. 'CLOUD' => ['test4@localhost'],
  373. 'isLocalSystemBook' => true,
  374. ],
  375. ],
  376. true,
  377. ['users' => [
  378. ['label' => 'User1 (test@example.com)', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test1']],
  379. ['label' => 'User2 (test@example.de)', 'value' => ['shareType' => Share::SHARE_TYPE_USER, 'shareWith' => 'test2']],
  380. ], 'emails' => [], 'exact' => ['users' => [], 'emails' => []]],
  381. false,
  382. true,
  383. ],
  384. // Pagination and "more results" for normal emails
  385. [
  386. 'test@example',
  387. [
  388. [
  389. 'FN' => 'User1',
  390. 'EMAIL' => ['test@example.com'],
  391. 'CLOUD' => ['test1@localhost'],
  392. ],
  393. [
  394. 'FN' => 'User2',
  395. 'EMAIL' => ['test@example.de'],
  396. 'CLOUD' => ['test2@localhost'],
  397. ],
  398. [
  399. 'FN' => 'User3',
  400. 'EMAIL' => ['test@example.org'],
  401. 'CLOUD' => ['test3@localhost'],
  402. ],
  403. [
  404. 'FN' => 'User4',
  405. 'EMAIL' => ['test@example.net'],
  406. 'CLOUD' => ['test4@localhost'],
  407. ],
  408. ],
  409. true,
  410. ['emails' => [
  411. ['label' => 'User1 (test@example.com)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'test@example.com']],
  412. ['label' => 'User2 (test@example.de)', 'value' => ['shareType' => Share::SHARE_TYPE_EMAIL, 'shareWith' => 'test@example.de']],
  413. ], 'exact' => ['emails' => []]],
  414. false,
  415. true,
  416. ],
  417. ];
  418. }
  419. /**
  420. * @dataProvider dataGetEmailGroupsOnly
  421. *
  422. * @param string $searchTerm
  423. * @param array $contacts
  424. * @param array $expected
  425. * @param bool $exactIdMatch
  426. * @param bool $reachedEnd
  427. * @param array groups
  428. */
  429. public function testSearchGroupsOnly($searchTerm, $contacts, $expected, $exactIdMatch, $reachedEnd, $userToGroupMapping) {
  430. $this->config->expects($this->any())
  431. ->method('getAppValue')
  432. ->willReturnCallback(
  433. function($appName, $key, $default) {
  434. if ($appName === 'core' && $key === 'shareapi_allow_share_dialog_user_enumeration') {
  435. return 'yes';
  436. } else if ($appName === 'core' && $key === 'shareapi_only_share_with_group_members') {
  437. return 'yes';
  438. }
  439. return $default;
  440. }
  441. );
  442. $this->instantiatePlugin();
  443. /** @var \OCP\IUser | \PHPUnit_Framework_MockObject_MockObject */
  444. $currentUser = $this->createMock('\OCP\IUser');
  445. $currentUser->expects($this->any())
  446. ->method('getUID')
  447. ->willReturn('currentUser');
  448. $this->contactsManager->expects($this->any())
  449. ->method('search')
  450. ->with($searchTerm, ['EMAIL', 'FN'])
  451. ->willReturn($contacts);
  452. $this->userSession->expects($this->any())
  453. ->method('getUser')
  454. ->willReturn($currentUser);
  455. $this->groupManager->expects($this->any())
  456. ->method('getUserGroupIds')
  457. ->willReturnCallback(function(\OCP\IUser $user) use ($userToGroupMapping) {
  458. return $userToGroupMapping[$user->getUID()];
  459. });
  460. $this->groupManager->expects($this->any())
  461. ->method('isInGroup')
  462. ->willReturnCallback(function($userId, $group) use ($userToGroupMapping) {
  463. return in_array($group, $userToGroupMapping[$userId]);
  464. });
  465. $moreResults = $this->plugin->search($searchTerm, 2, 0, $this->searchResult);
  466. $result = $this->searchResult->asArray();
  467. $this->assertSame($exactIdMatch, $this->searchResult->hasExactIdMatch(new SearchResultType('emails')));
  468. $this->assertEquals($expected, $result);
  469. $this->assertSame($reachedEnd, $moreResults);
  470. }
  471. public function dataGetEmailGroupsOnly() {
  472. return [
  473. // The user `User` can share with the current user
  474. [
  475. 'test',
  476. [
  477. [
  478. 'FN' => 'User',
  479. 'EMAIL' => ['test@example.com'],
  480. 'CLOUD' => ['test@localhost'],
  481. 'isLocalSystemBook' => true,
  482. 'UID' => 'User'
  483. ]
  484. ],
  485. ['users' => [['label' => 'User (test@example.com)','value' => ['shareType' => 0, 'shareWith' => 'test'],]], 'emails' => [], 'exact' => ['emails' => [], 'users' => []]],
  486. false,
  487. false,
  488. [
  489. "currentUser" => ["group1"],
  490. "User" => ["group1"]
  491. ]
  492. ],
  493. // The user `User` cannot share with the current user
  494. [
  495. 'test',
  496. [
  497. [
  498. 'FN' => 'User',
  499. 'EMAIL' => ['test@example.com'],
  500. 'CLOUD' => ['test@localhost'],
  501. 'isLocalSystemBook' => true,
  502. 'UID' => 'User'
  503. ]
  504. ],
  505. ['emails'=> [], 'exact' => ['emails' => []]],
  506. false,
  507. false,
  508. [
  509. "currentUser" => ["group1"],
  510. "User" => ["group2"]
  511. ]
  512. ],
  513. // The user `User` cannot share with the current user, but there is an exact match on the e-mail address -> share by e-mail
  514. [
  515. 'test@example.com',
  516. [
  517. [
  518. 'FN' => 'User',
  519. 'EMAIL' => ['test@example.com'],
  520. 'CLOUD' => ['test@localhost'],
  521. 'isLocalSystemBook' => true,
  522. 'UID' => 'User'
  523. ]
  524. ],
  525. ['emails' => [], 'exact' => ['emails' => [['label' => 'test@example.com', 'value' => ['shareType' => 4,'shareWith' => 'test@example.com']]]]],
  526. false,
  527. false,
  528. [
  529. "currentUser" => ["group1"],
  530. "User" => ["group2"]
  531. ]
  532. ]
  533. ];
  534. }
  535. }