AbstractMappingTest.php 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. <?php
  2. /**
  3. * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
  4. * SPDX-FileCopyrightText: 2016 ownCloud, Inc.
  5. * SPDX-License-Identifier: AGPL-3.0-only
  6. */
  7. namespace OCA\User_LDAP\Tests\Mapping;
  8. use OCA\User_LDAP\Mapping\AbstractMapping;
  9. use OCP\IDBConnection;
  10. abstract class AbstractMappingTest extends \Test\TestCase {
  11. abstract public function getMapper(\OCP\IDBConnection $dbMock);
  12. /**
  13. * kiss test on isColNameValid
  14. */
  15. public function testIsColNameValid(): void {
  16. $dbMock = $this->createMock(IDBConnection::class);
  17. $mapper = $this->getMapper($dbMock);
  18. $this->assertTrue($mapper->isColNameValid('ldap_dn'));
  19. $this->assertFalse($mapper->isColNameValid('foobar'));
  20. }
  21. /**
  22. * returns an array of test entries with dn, name and uuid as keys
  23. * @return array
  24. */
  25. protected function getTestData() {
  26. $data = [
  27. [
  28. 'dn' => 'uid=foobar,dc=example,dc=org',
  29. 'name' => 'Foobar',
  30. 'uuid' => '1111-AAAA-1234-CDEF',
  31. ],
  32. [
  33. 'dn' => 'uid=barfoo,dc=example,dc=org',
  34. 'name' => 'Barfoo',
  35. 'uuid' => '2222-BBBB-1234-CDEF',
  36. ],
  37. [
  38. 'dn' => 'uid=barabara,dc=example,dc=org',
  39. 'name' => 'BaraBara',
  40. 'uuid' => '3333-CCCC-1234-CDEF',
  41. ]
  42. ];
  43. return $data;
  44. }
  45. /**
  46. * calls map() on the given mapper and asserts result for true
  47. * @param \OCA\User_LDAP\Mapping\AbstractMapping $mapper
  48. * @param array $data
  49. */
  50. protected function mapEntries($mapper, $data) {
  51. foreach ($data as $entry) {
  52. $done = $mapper->map($entry['dn'], $entry['name'], $entry['uuid']);
  53. $this->assertTrue($done);
  54. }
  55. }
  56. /**
  57. * initializes environment for a test run and returns an array with
  58. * test objects. Preparing environment means that all mappings are cleared
  59. * first and then filled with test entries.
  60. * @return array 0 = \OCA\User_LDAP\Mapping\AbstractMapping, 1 = array of
  61. * users or groups
  62. */
  63. private function initTest() {
  64. $dbc = \OC::$server->getDatabaseConnection();
  65. $mapper = $this->getMapper($dbc);
  66. $data = $this->getTestData();
  67. // make sure DB is pristine, then fill it with test entries
  68. $mapper->clear();
  69. $this->mapEntries($mapper, $data);
  70. return [$mapper, $data];
  71. }
  72. /**
  73. * tests map() method with input that should result in not-mapping.
  74. * Hint: successful mapping is tested inherently with mapEntries().
  75. */
  76. public function testMap(): void {
  77. [$mapper, $data] = $this->initTest();
  78. // test that mapping will not happen when it shall not
  79. $tooLongDN = 'uid=joann,ou=Secret Small Specialized Department,ou=Some Tremendously Important Department,ou=Another Very Important Department,ou=Pretty Meaningful Derpartment,ou=Quite Broad And General Department,ou=The Topmost Department,dc=hugelysuccessfulcompany,dc=com';
  80. $paramKeys = ['', 'dn', 'name', 'uuid', $tooLongDN];
  81. foreach ($paramKeys as $key) {
  82. $failEntry = $data[0];
  83. if (!empty($key)) {
  84. $failEntry[$key] = 'do-not-get-mapped';
  85. }
  86. $isMapped = $mapper->map($failEntry['dn'], $failEntry['name'], $failEntry['uuid']);
  87. $this->assertFalse($isMapped);
  88. }
  89. }
  90. /**
  91. * tests unmap() for both successful and unsuccessful removing of
  92. * mapping entries
  93. */
  94. public function testUnmap(): void {
  95. [$mapper, $data] = $this->initTest();
  96. foreach ($data as $entry) {
  97. $fdnBefore = $mapper->getDNByName($entry['name']);
  98. $result = $mapper->unmap($entry['name']);
  99. $fdnAfter = $mapper->getDNByName($entry['name']);
  100. $this->assertTrue($result);
  101. $this->assertSame($fdnBefore, $entry['dn']);
  102. $this->assertFalse($fdnAfter);
  103. }
  104. $result = $mapper->unmap('notAnEntry');
  105. $this->assertFalse($result);
  106. }
  107. /**
  108. * tests getDNByName(), getNameByDN() and getNameByUUID() for successful
  109. * and unsuccessful requests.
  110. */
  111. public function testGetMethods(): void {
  112. [$mapper, $data] = $this->initTest();
  113. foreach ($data as $entry) {
  114. $fdn = $mapper->getDNByName($entry['name']);
  115. $this->assertSame($fdn, $entry['dn']);
  116. }
  117. $fdn = $mapper->getDNByName('nosuchname');
  118. $this->assertFalse($fdn);
  119. foreach ($data as $entry) {
  120. $name = $mapper->getNameByDN($entry['dn']);
  121. $this->assertSame($name, $entry['name']);
  122. }
  123. $name = $mapper->getNameByDN('nosuchdn');
  124. $this->assertFalse($name);
  125. foreach ($data as $entry) {
  126. $name = $mapper->getNameByUUID($entry['uuid']);
  127. $this->assertSame($name, $entry['name']);
  128. }
  129. $name = $mapper->getNameByUUID('nosuchuuid');
  130. $this->assertFalse($name);
  131. }
  132. /**
  133. * tests getNamesBySearch() for successful and unsuccessful requests.
  134. */
  135. public function testSearch(): void {
  136. [$mapper,] = $this->initTest();
  137. $names = $mapper->getNamesBySearch('oo', '%', '%');
  138. $this->assertTrue(is_array($names));
  139. $this->assertSame(2, count($names));
  140. $this->assertTrue(in_array('Foobar', $names));
  141. $this->assertTrue(in_array('Barfoo', $names));
  142. $names = $mapper->getNamesBySearch('nada');
  143. $this->assertTrue(is_array($names));
  144. $this->assertSame(0, count($names));
  145. }
  146. /**
  147. * tests setDNbyUUID() for successful and unsuccessful update.
  148. */
  149. public function testSetDNMethod(): void {
  150. [$mapper, $data] = $this->initTest();
  151. $newDN = 'uid=modified,dc=example,dc=org';
  152. $done = $mapper->setDNbyUUID($newDN, $data[0]['uuid']);
  153. $this->assertTrue($done);
  154. $fdn = $mapper->getDNByName($data[0]['name']);
  155. $this->assertSame($fdn, $newDN);
  156. $newDN = 'uid=notme,dc=example,dc=org';
  157. $done = $mapper->setDNbyUUID($newDN, 'iamnothere');
  158. $this->assertFalse($done);
  159. $name = $mapper->getNameByDN($newDN);
  160. $this->assertFalse($name);
  161. }
  162. /**
  163. * tests setUUIDbyDN() for successful and unsuccessful update.
  164. */
  165. public function testSetUUIDMethod(): void {
  166. /** @var AbstractMapping $mapper */
  167. [$mapper, $data] = $this->initTest();
  168. $newUUID = 'ABC737-DEF754';
  169. $done = $mapper->setUUIDbyDN($newUUID, 'uid=notme,dc=example,dc=org');
  170. $this->assertFalse($done);
  171. $name = $mapper->getNameByUUID($newUUID);
  172. $this->assertFalse($name);
  173. $done = $mapper->setUUIDbyDN($newUUID, $data[0]['dn']);
  174. $this->assertTrue($done);
  175. $uuid = $mapper->getUUIDByDN($data[0]['dn']);
  176. $this->assertSame($uuid, $newUUID);
  177. }
  178. /**
  179. * tests clear() for successful update.
  180. */
  181. public function testClear(): void {
  182. [$mapper, $data] = $this->initTest();
  183. $done = $mapper->clear();
  184. $this->assertTrue($done);
  185. foreach ($data as $entry) {
  186. $name = $mapper->getNameByUUID($entry['uuid']);
  187. $this->assertFalse($name);
  188. }
  189. }
  190. /**
  191. * tests clear() for successful update.
  192. */
  193. public function testClearCb(): void {
  194. [$mapper, $data] = $this->initTest();
  195. $callbackCalls = 0;
  196. $test = $this;
  197. $callback = function (string $id) use ($test, &$callbackCalls) {
  198. $test->assertTrue(trim($id) !== '');
  199. $callbackCalls++;
  200. };
  201. $done = $mapper->clearCb($callback, $callback);
  202. $this->assertTrue($done);
  203. $this->assertSame(count($data) * 2, $callbackCalls);
  204. foreach ($data as $entry) {
  205. $name = $mapper->getNameByUUID($entry['uuid']);
  206. $this->assertFalse($name);
  207. }
  208. }
  209. /**
  210. * tests getList() method
  211. */
  212. public function testList(): void {
  213. [$mapper, $data] = $this->initTest();
  214. // get all entries without specifying offset or limit
  215. $results = $mapper->getList();
  216. $this->assertSame(3, count($results));
  217. // get all-1 entries by specifying offset, and an high limit
  218. // specifying only offset without limit will not work by underlying lib
  219. $results = $mapper->getList(1, 999);
  220. $this->assertSame(count($data) - 1, count($results));
  221. // get first 2 entries by limit, but not offset
  222. $results = $mapper->getList(0, 2);
  223. $this->assertSame(2, count($results));
  224. // get 2nd entry by specifying both offset and limit
  225. $results = $mapper->getList(1, 1);
  226. $this->assertSame(1, count($results));
  227. }
  228. public function testGetListOfIdsByDn(): void {
  229. /** @var AbstractMapping $mapper */
  230. [$mapper,] = $this->initTest();
  231. $listOfDNs = [];
  232. for ($i = 0; $i < 66640; $i++) {
  233. // Postgres has a limit of 65535 values in a single IN list
  234. $name = 'as_' . $i;
  235. $dn = 'uid=' . $name . ',dc=example,dc=org';
  236. $listOfDNs[] = $dn;
  237. if ($i % 20 === 0) {
  238. $mapper->map($dn, $name, 'fake-uuid-' . $i);
  239. }
  240. }
  241. $result = $mapper->getListOfIdsByDn($listOfDNs);
  242. $this->assertSame(66640 / 20, count($result));
  243. }
  244. }