You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

AbstractMappingTest.php 8.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016, ownCloud, Inc.
  4. *
  5. * @author Aaron Wood <aaronjwood@gmail.com>
  6. * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
  7. * @author Christoph Wurst <christoph@winzerhof-wurst.at>
  8. * @author Joas Schilling <coding@schilljs.com>
  9. * @author Morris Jobke <hey@morrisjobke.de>
  10. * @author Roeland Jago Douma <roeland@famdouma.nl>
  11. * @author Stefan Weil <sw@weilnetz.de>
  12. *
  13. * @license AGPL-3.0
  14. *
  15. * This code is free software: you can redistribute it and/or modify
  16. * it under the terms of the GNU Affero General Public License, version 3,
  17. * as published by the Free Software Foundation.
  18. *
  19. * This program is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  22. * GNU Affero General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU Affero General Public License, version 3,
  25. * along with this program. If not, see <http://www.gnu.org/licenses/>
  26. *
  27. */
  28. namespace OCA\User_LDAP\Tests\Mapping;
  29. use OCA\User_LDAP\Mapping\AbstractMapping;
  30. use OCP\IDBConnection;
  31. abstract class AbstractMappingTest extends \Test\TestCase {
  32. abstract public function getMapper(\OCP\IDBConnection $dbMock);
  33. /**
  34. * kiss test on isColNameValid
  35. */
  36. public function testIsColNameValid() {
  37. $dbMock = $this->createMock(IDBConnection::class);
  38. $mapper = $this->getMapper($dbMock);
  39. $this->assertTrue($mapper->isColNameValid('ldap_dn'));
  40. $this->assertFalse($mapper->isColNameValid('foobar'));
  41. }
  42. /**
  43. * returns an array of test entries with dn, name and uuid as keys
  44. * @return array
  45. */
  46. protected function getTestData() {
  47. $data = [
  48. [
  49. 'dn' => 'uid=foobar,dc=example,dc=org',
  50. 'name' => 'Foobar',
  51. 'uuid' => '1111-AAAA-1234-CDEF',
  52. ],
  53. [
  54. 'dn' => 'uid=barfoo,dc=example,dc=org',
  55. 'name' => 'Barfoo',
  56. 'uuid' => '2222-BBBB-1234-CDEF',
  57. ],
  58. [
  59. 'dn' => 'uid=barabara,dc=example,dc=org',
  60. 'name' => 'BaraBara',
  61. 'uuid' => '3333-CCCC-1234-CDEF',
  62. ]
  63. ];
  64. return $data;
  65. }
  66. /**
  67. * calls map() on the given mapper and asserts result for true
  68. * @param \OCA\User_LDAP\Mapping\AbstractMapping $mapper
  69. * @param array $data
  70. */
  71. protected function mapEntries($mapper, $data) {
  72. foreach ($data as $entry) {
  73. $done = $mapper->map($entry['dn'], $entry['name'], $entry['uuid']);
  74. $this->assertTrue($done);
  75. }
  76. }
  77. /**
  78. * initalizes environment for a test run and returns an array with
  79. * test objects. Preparing environment means that all mappings are cleared
  80. * first and then filled with test entries.
  81. * @return array 0 = \OCA\User_LDAP\Mapping\AbstractMapping, 1 = array of
  82. * users or groups
  83. */
  84. private function initTest() {
  85. $dbc = \OC::$server->getDatabaseConnection();
  86. $mapper = $this->getMapper($dbc);
  87. $data = $this->getTestData();
  88. // make sure DB is pristine, then fill it with test entries
  89. $mapper->clear();
  90. $this->mapEntries($mapper, $data);
  91. return [$mapper, $data];
  92. }
  93. /**
  94. * tests map() method with input that should result in not-mapping.
  95. * Hint: successful mapping is tested inherently with mapEntries().
  96. */
  97. public function testMap() {
  98. [$mapper, $data] = $this->initTest();
  99. // test that mapping will not happen when it shall not
  100. $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';
  101. $paramKeys = ['', 'dn', 'name', 'uuid', $tooLongDN];
  102. foreach ($paramKeys as $key) {
  103. $failEntry = $data[0];
  104. if (!empty($key)) {
  105. $failEntry[$key] = 'do-not-get-mapped';
  106. }
  107. $isMapped = $mapper->map($failEntry['dn'], $failEntry['name'], $failEntry['uuid']);
  108. $this->assertFalse($isMapped);
  109. }
  110. }
  111. /**
  112. * tests unmap() for both successful and unsuccessful removing of
  113. * mapping entries
  114. */
  115. public function testUnmap() {
  116. [$mapper, $data] = $this->initTest();
  117. foreach ($data as $entry) {
  118. $result = $mapper->unmap($entry['name']);
  119. $this->assertTrue($result);
  120. }
  121. $result = $mapper->unmap('notAnEntry');
  122. $this->assertFalse($result);
  123. }
  124. /**
  125. * tests getDNByName(), getNameByDN() and getNameByUUID() for successful
  126. * and unsuccessful requests.
  127. */
  128. public function testGetMethods() {
  129. [$mapper, $data] = $this->initTest();
  130. foreach ($data as $entry) {
  131. $fdn = $mapper->getDNByName($entry['name']);
  132. $this->assertSame($fdn, $entry['dn']);
  133. }
  134. $fdn = $mapper->getDNByName('nosuchname');
  135. $this->assertFalse($fdn);
  136. foreach ($data as $entry) {
  137. $name = $mapper->getNameByDN($entry['dn']);
  138. $this->assertSame($name, $entry['name']);
  139. }
  140. $name = $mapper->getNameByDN('nosuchdn');
  141. $this->assertFalse($name);
  142. foreach ($data as $entry) {
  143. $name = $mapper->getNameByUUID($entry['uuid']);
  144. $this->assertSame($name, $entry['name']);
  145. }
  146. $name = $mapper->getNameByUUID('nosuchuuid');
  147. $this->assertFalse($name);
  148. }
  149. /**
  150. * tests getNamesBySearch() for successful and unsuccessful requests.
  151. */
  152. public function testSearch() {
  153. [$mapper,] = $this->initTest();
  154. $names = $mapper->getNamesBySearch('oo', '%', '%');
  155. $this->assertTrue(is_array($names));
  156. $this->assertSame(2, count($names));
  157. $this->assertTrue(in_array('Foobar', $names));
  158. $this->assertTrue(in_array('Barfoo', $names));
  159. $names = $mapper->getNamesBySearch('nada');
  160. $this->assertTrue(is_array($names));
  161. $this->assertSame(0, count($names));
  162. }
  163. /**
  164. * tests setDNbyUUID() for successful and unsuccessful update.
  165. */
  166. public function testSetDNMethod() {
  167. [$mapper, $data] = $this->initTest();
  168. $newDN = 'uid=modified,dc=example,dc=org';
  169. $done = $mapper->setDNbyUUID($newDN, $data[0]['uuid']);
  170. $this->assertTrue($done);
  171. $fdn = $mapper->getDNByName($data[0]['name']);
  172. $this->assertSame($fdn, $newDN);
  173. $newDN = 'uid=notme,dc=example,dc=org';
  174. $done = $mapper->setDNbyUUID($newDN, 'iamnothere');
  175. $this->assertFalse($done);
  176. $name = $mapper->getNameByDN($newDN);
  177. $this->assertFalse($name);
  178. }
  179. /**
  180. * tests setUUIDbyDN() for successful and unsuccessful update.
  181. */
  182. public function testSetUUIDMethod() {
  183. /** @var AbstractMapping $mapper */
  184. [$mapper, $data] = $this->initTest();
  185. $newUUID = 'ABC737-DEF754';
  186. $done = $mapper->setUUIDbyDN($newUUID, 'uid=notme,dc=example,dc=org');
  187. $this->assertFalse($done);
  188. $name = $mapper->getNameByUUID($newUUID);
  189. $this->assertFalse($name);
  190. $done = $mapper->setUUIDbyDN($newUUID, $data[0]['dn']);
  191. $this->assertTrue($done);
  192. $uuid = $mapper->getUUIDByDN($data[0]['dn']);
  193. $this->assertSame($uuid, $newUUID);
  194. }
  195. /**
  196. * tests clear() for successful update.
  197. */
  198. public function testClear() {
  199. [$mapper, $data] = $this->initTest();
  200. $done = $mapper->clear();
  201. $this->assertTrue($done);
  202. foreach ($data as $entry) {
  203. $name = $mapper->getNameByUUID($entry['uuid']);
  204. $this->assertFalse($name);
  205. }
  206. }
  207. /**
  208. * tests clear() for successful update.
  209. */
  210. public function testClearCb() {
  211. [$mapper, $data] = $this->initTest();
  212. $callbackCalls = 0;
  213. $test = $this;
  214. $callback = function (string $id) use ($test, &$callbackCalls) {
  215. $test->assertTrue(trim($id) !== '');
  216. $callbackCalls++;
  217. };
  218. $done = $mapper->clearCb($callback, $callback);
  219. $this->assertTrue($done);
  220. $this->assertSame(count($data) * 2, $callbackCalls);
  221. foreach ($data as $entry) {
  222. $name = $mapper->getNameByUUID($entry['uuid']);
  223. $this->assertFalse($name);
  224. }
  225. }
  226. /**
  227. * tests getList() method
  228. */
  229. public function testList() {
  230. [$mapper, $data] = $this->initTest();
  231. // get all entries without specifying offset or limit
  232. $results = $mapper->getList();
  233. $this->assertSame(3, count($results));
  234. // get all-1 entries by specifying offset, and an high limit
  235. // specifying only offset without limit will not work by underlying lib
  236. $results = $mapper->getList(1, 999);
  237. $this->assertSame(count($data) - 1, count($results));
  238. // get first 2 entries by limit, but not offset
  239. $results = $mapper->getList(null, 2);
  240. $this->assertSame(2, count($results));
  241. // get 2nd entry by specifying both offset and limit
  242. $results = $mapper->getList(1, 1);
  243. $this->assertSame(1, count($results));
  244. }
  245. public function testGetListOfIdsByDn() {
  246. /** @var AbstractMapping $mapper */
  247. [$mapper,] = $this->initTest();
  248. $listOfDNs = [];
  249. for ($i = 0; $i < 66640; $i++) {
  250. // Postgres has a limit of 65535 values in a single IN list
  251. $name = 'as_' . $i;
  252. $dn = 'uid=' . $name . ',dc=example,dc=org';
  253. $listOfDNs[] = $dn;
  254. if ($i % 20 === 0) {
  255. $mapper->map($dn, $name, 'fake-uuid-' . $i);
  256. }
  257. }
  258. $result = $mapper->getListOfIdsByDn($listOfDNs);
  259. $this->assertSame(66640 / 20, count($result));
  260. }
  261. }