AbstractMappingTest.php 8.7 KB

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