RemotePluginTest.php 12 KB

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