RemotePluginTest.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2017 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-License-Identifier: AGPL-3.0-or-later
  5. */
  6. namespace Test\Collaboration\Collaborators;
  7. use OC\Collaboration\Collaborators\RemotePlugin;
  8. use OC\Collaboration\Collaborators\SearchResult;
  9. use OC\Federation\CloudIdManager;
  10. use OCP\Collaboration\Collaborators\SearchResultType;
  11. use OCP\Contacts\IManager;
  12. use OCP\EventDispatcher\IEventDispatcher;
  13. use OCP\Federation\ICloudIdManager;
  14. use OCP\ICacheFactory;
  15. use OCP\IConfig;
  16. use OCP\IURLGenerator;
  17. use OCP\IUser;
  18. use OCP\IUserManager;
  19. use OCP\IUserSession;
  20. use OCP\Share\IShare;
  21. use Test\TestCase;
  22. class RemotePluginTest extends TestCase {
  23. /** @var IUserManager|\PHPUnit\Framework\MockObject\MockObject */
  24. protected $userManager;
  25. /** @var IConfig|\PHPUnit\Framework\MockObject\MockObject */
  26. protected $config;
  27. /** @var IManager|\PHPUnit\Framework\MockObject\MockObject */
  28. protected $contactsManager;
  29. /** @var ICloudIdManager|\PHPUnit\Framework\MockObject\MockObject */
  30. protected $cloudIdManager;
  31. /** @var RemotePlugin */
  32. protected $plugin;
  33. /** @var SearchResult */
  34. protected $searchResult;
  35. protected function setUp(): void {
  36. parent::setUp();
  37. $this->userManager = $this->createMock(IUserManager::class);
  38. $this->config = $this->createMock(IConfig::class);
  39. $this->contactsManager = $this->createMock(IManager::class);
  40. $this->cloudIdManager = new CloudIdManager(
  41. $this->contactsManager,
  42. $this->createMock(IURLGenerator::class),
  43. $this->createMock(IUserManager::class),
  44. $this->createMock(ICacheFactory::class),
  45. $this->createMock(IEventDispatcher::class)
  46. );
  47. $this->searchResult = new SearchResult();
  48. }
  49. public function instantiatePlugin() {
  50. $user = $this->createMock(IUser::class);
  51. $user->expects($this->any())
  52. ->method('getUID')
  53. ->willReturn('admin');
  54. $userSession = $this->createMock(IUserSession::class);
  55. $userSession->expects($this->any())
  56. ->method('getUser')
  57. ->willReturn($user);
  58. $this->plugin = new RemotePlugin($this->contactsManager, $this->cloudIdManager, $this->config, $this->userManager, $userSession);
  59. }
  60. /**
  61. * @dataProvider dataGetRemote
  62. *
  63. * @param string $searchTerm
  64. * @param array $contacts
  65. * @param bool $shareeEnumeration
  66. * @param array $expected
  67. * @param bool $exactIdMatch
  68. * @param bool $reachedEnd
  69. */
  70. public function testSearch($searchTerm, array $contacts, $shareeEnumeration, array $expected, $exactIdMatch, $reachedEnd): void {
  71. $this->config->expects($this->any())
  72. ->method('getAppValue')
  73. ->willReturnCallback(
  74. function ($appName, $key, $default) use ($shareeEnumeration) {
  75. if ($appName === 'core' && $key === 'shareapi_allow_share_dialog_user_enumeration') {
  76. return $shareeEnumeration ? 'yes' : 'no';
  77. }
  78. return $default;
  79. }
  80. );
  81. $this->instantiatePlugin();
  82. $this->contactsManager->expects($this->any())
  83. ->method('search')
  84. ->willReturnCallback(function ($search, $searchAttributes) use ($searchTerm, $contacts) {
  85. if ($search === $searchTerm) {
  86. return $contacts;
  87. }
  88. return [];
  89. });
  90. $moreResults = $this->plugin->search($searchTerm, 2, 0, $this->searchResult);
  91. $result = $this->searchResult->asArray();
  92. $this->assertSame($exactIdMatch, $this->searchResult->hasExactIdMatch(new SearchResultType('remotes')));
  93. $this->assertEquals($expected, $result);
  94. $this->assertSame($reachedEnd, $moreResults);
  95. }
  96. /**
  97. * @dataProvider dataTestSplitUserRemote
  98. *
  99. * @param string $remote
  100. * @param string $expectedUser
  101. * @param string $expectedUrl
  102. */
  103. public function testSplitUserRemote($remote, $expectedUser, $expectedUrl): void {
  104. $this->instantiatePlugin();
  105. $this->contactsManager->expects($this->any())
  106. ->method('search')
  107. ->willReturn([]);
  108. [$remoteUser, $remoteUrl] = $this->plugin->splitUserRemote($remote);
  109. $this->assertSame($expectedUser, $remoteUser);
  110. $this->assertSame($expectedUrl, $remoteUrl);
  111. }
  112. /**
  113. * @dataProvider dataTestSplitUserRemoteError
  114. *
  115. * @param string $id
  116. */
  117. public function testSplitUserRemoteError($id): void {
  118. $this->expectException(\Exception::class);
  119. $this->instantiatePlugin();
  120. $this->plugin->splitUserRemote($id);
  121. }
  122. public function dataGetRemote() {
  123. return [
  124. ['test', [], true, ['remotes' => [], 'exact' => ['remotes' => []]], false, true],
  125. ['test', [], false, ['remotes' => [], 'exact' => ['remotes' => []]], false, true],
  126. [
  127. 'test@remote',
  128. [],
  129. true,
  130. ['remotes' => [], 'exact' => ['remotes' => [['label' => 'test (remote)', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'test@remote', 'server' => 'remote'], 'uuid' => 'test', 'name' => 'test']]]],
  131. false,
  132. true,
  133. ],
  134. [
  135. 'test@remote',
  136. [],
  137. false,
  138. ['remotes' => [], 'exact' => ['remotes' => [['label' => 'test (remote)', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'test@remote', 'server' => 'remote'], 'uuid' => 'test', 'name' => 'test']]]],
  139. false,
  140. true,
  141. ],
  142. [
  143. 'test',
  144. [
  145. [
  146. 'UID' => 'uid',
  147. 'FN' => 'User3 @ Localhost',
  148. ],
  149. [
  150. 'UID' => 'uid',
  151. 'FN' => 'User2 @ Localhost',
  152. 'CLOUD' => [
  153. ],
  154. ],
  155. [
  156. 'UID' => 'uid1',
  157. 'FN' => 'User @ Localhost',
  158. 'CLOUD' => [
  159. 'username@localhost',
  160. ],
  161. ],
  162. ],
  163. true,
  164. ['remotes' => [['name' => 'User @ Localhost', 'label' => 'User @ Localhost (username@localhost)', 'uuid' => 'uid1', 'type' => '', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']]], 'exact' => ['remotes' => []]],
  165. false,
  166. true,
  167. ],
  168. [
  169. 'test',
  170. [
  171. [
  172. 'UID' => 'uid',
  173. 'FN' => 'User3 @ Localhost',
  174. ],
  175. [
  176. 'UID' => 'uid',
  177. 'FN' => 'User2 @ Localhost',
  178. 'CLOUD' => [
  179. ],
  180. ],
  181. [
  182. 'UID' => 'uid',
  183. 'FN' => 'User @ Localhost',
  184. 'CLOUD' => [
  185. 'username@localhost',
  186. ],
  187. ],
  188. ],
  189. false,
  190. ['remotes' => [], 'exact' => ['remotes' => []]],
  191. false,
  192. true,
  193. ],
  194. [
  195. 'test@remote',
  196. [
  197. [
  198. 'UID' => 'uid',
  199. 'FN' => 'User3 @ Localhost',
  200. ],
  201. [
  202. 'UID' => 'uid',
  203. 'FN' => 'User2 @ Localhost',
  204. 'CLOUD' => [
  205. ],
  206. ],
  207. [
  208. 'UID' => 'uid',
  209. 'FN' => 'User @ Localhost',
  210. 'CLOUD' => [
  211. 'username@localhost',
  212. ],
  213. ],
  214. ],
  215. true,
  216. ['remotes' => [['name' => 'User @ Localhost', 'label' => 'User @ Localhost (username@localhost)', 'uuid' => 'uid', 'type' => '', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']]], 'exact' => ['remotes' => [['label' => 'test (remote)', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'test@remote', 'server' => 'remote'], 'uuid' => 'test', 'name' => 'test']]]],
  217. false,
  218. true,
  219. ],
  220. [
  221. 'test@remote',
  222. [
  223. [
  224. 'UID' => 'uid',
  225. 'FN' => 'User3 @ Localhost',
  226. ],
  227. [
  228. 'UID' => 'uid',
  229. 'FN' => 'User2 @ Localhost',
  230. 'CLOUD' => [
  231. ],
  232. ],
  233. [
  234. 'UID' => 'uid',
  235. 'FN' => 'User @ Localhost',
  236. 'CLOUD' => [
  237. 'username@localhost',
  238. ],
  239. ],
  240. ],
  241. false,
  242. ['remotes' => [], 'exact' => ['remotes' => [['label' => 'test (remote)', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'test@remote', 'server' => 'remote'], 'uuid' => 'test', 'name' => 'test']]]],
  243. false,
  244. true,
  245. ],
  246. [
  247. 'username@localhost',
  248. [
  249. [
  250. 'UID' => 'uid3',
  251. 'FN' => 'User3 @ Localhost',
  252. ],
  253. [
  254. 'UID' => '2',
  255. 'FN' => 'User2 @ Localhost',
  256. 'CLOUD' => [
  257. ],
  258. ],
  259. [
  260. 'UID' => 'uid1',
  261. 'FN' => 'User @ Localhost',
  262. 'CLOUD' => [
  263. 'username@localhost',
  264. ],
  265. ],
  266. ],
  267. true,
  268. ['remotes' => [], 'exact' => ['remotes' => [['name' => 'User @ Localhost', 'label' => 'User @ Localhost (username@localhost)', 'uuid' => 'uid1', 'type' => '', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']]]]],
  269. true,
  270. true,
  271. ],
  272. [
  273. 'username@localhost',
  274. [
  275. [
  276. 'UID' => 'uid3',
  277. 'FN' => 'User3 @ Localhost',
  278. ],
  279. [
  280. 'UID' => 'uid2',
  281. 'FN' => 'User2 @ Localhost',
  282. 'CLOUD' => [
  283. ],
  284. ],
  285. [
  286. 'UID' => 'uid1',
  287. 'FN' => 'User @ Localhost',
  288. 'CLOUD' => [
  289. 'username@localhost',
  290. ],
  291. ],
  292. ],
  293. false,
  294. ['remotes' => [], 'exact' => ['remotes' => [['name' => 'User @ Localhost', 'label' => 'User @ Localhost (username@localhost)', 'uuid' => 'uid1', 'type' => '', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'username@localhost', 'server' => 'localhost']]]]],
  295. true,
  296. true,
  297. ],
  298. // contact with space
  299. [
  300. 'user name@localhost',
  301. [
  302. [
  303. 'UID' => 'uid1',
  304. 'FN' => 'User3 @ Localhost',
  305. ],
  306. [
  307. 'UID' => 'uid2',
  308. 'FN' => 'User2 @ Localhost',
  309. 'CLOUD' => [
  310. ],
  311. ],
  312. [
  313. 'UID' => 'uid3',
  314. 'FN' => 'User Name @ Localhost',
  315. 'CLOUD' => [
  316. 'user name@localhost',
  317. ],
  318. ],
  319. ],
  320. false,
  321. ['remotes' => [], 'exact' => ['remotes' => [['name' => 'User Name @ Localhost', 'label' => 'User Name @ Localhost (user name@localhost)', 'uuid' => 'uid3', 'type' => '', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'user name@localhost', 'server' => 'localhost']]]]],
  322. true,
  323. true,
  324. ],
  325. // remote with space, no contact
  326. [
  327. 'user space@remote',
  328. [
  329. [
  330. 'UID' => 'uid3',
  331. 'FN' => 'User3 @ Localhost',
  332. ],
  333. [
  334. 'UID' => 'uid2',
  335. 'FN' => 'User2 @ Localhost',
  336. 'CLOUD' => [
  337. ],
  338. ],
  339. [
  340. 'UID' => 'uid1',
  341. 'FN' => 'User @ Localhost',
  342. 'CLOUD' => [
  343. 'username@localhost',
  344. ],
  345. ],
  346. ],
  347. false,
  348. ['remotes' => [], 'exact' => ['remotes' => [['label' => 'user space (remote)', 'value' => ['shareType' => IShare::TYPE_REMOTE, 'shareWith' => 'user space@remote', 'server' => 'remote'], 'uuid' => 'user space', 'name' => 'user space']]]],
  349. false,
  350. true,
  351. ],
  352. ];
  353. }
  354. public function dataTestSplitUserRemote() {
  355. $userPrefix = ['user@name', 'username'];
  356. $protocols = ['', 'http://', 'https://'];
  357. $remotes = [
  358. 'localhost',
  359. 'local.host',
  360. 'dev.local.host',
  361. 'dev.local.host/path',
  362. 'dev.local.host/at@inpath',
  363. '127.0.0.1',
  364. '::1',
  365. '::192.0.2.128',
  366. '::192.0.2.128/at@inpath',
  367. ];
  368. $testCases = [];
  369. foreach ($userPrefix as $user) {
  370. foreach ($remotes as $remote) {
  371. foreach ($protocols as $protocol) {
  372. $baseUrl = $user . '@' . $protocol . $remote;
  373. if ($protocol === 'https://') {
  374. // https:// protocol is not expected in the final result
  375. $protocol = '';
  376. }
  377. $testCases[] = [$baseUrl, $user, $protocol . $remote];
  378. $testCases[] = [$baseUrl . '/', $user, $protocol . $remote];
  379. $testCases[] = [$baseUrl . '/index.php', $user, $protocol . $remote];
  380. $testCases[] = [$baseUrl . '/index.php/s/token', $user, $protocol . $remote];
  381. }
  382. }
  383. }
  384. return $testCases;
  385. }
  386. public function dataTestSplitUserRemoteError() {
  387. return [
  388. // Invalid path
  389. ['user@'],
  390. // Invalid user
  391. ['@server'],
  392. ['us/er@server'],
  393. ['us:er@server'],
  394. // Invalid splitting
  395. ['user'],
  396. [''],
  397. ['us/erserver'],
  398. ['us:erserver'],
  399. ];
  400. }
  401. }