User_LDAPTest.php 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467
  1. <?php
  2. /**
  3. * @copyright Copyright (c) 2016, ownCloud, Inc.
  4. *
  5. * @author Arthur Schiwon <blizzz@arthur-schiwon.de>
  6. * @author Christoph Wurst <christoph@winzerhof-wurst.at>
  7. * @author Joas Schilling <coding@schilljs.com>
  8. * @author Jörn Friedrich Dreyer <jfd@butonic.de>
  9. * @author Lukas Reschke <lukas@statuscode.ch>
  10. * @author Morris Jobke <hey@morrisjobke.de>
  11. * @author Robin McCorkell <robin@mccorkell.me.uk>
  12. * @author Roeland Jago Douma <roeland@famdouma.nl>
  13. * @author Roger Szabo <roger.szabo@web.de>
  14. * @author Thomas Müller <thomas.mueller@tmit.eu>
  15. * @author Vinicius Cubas Brand <vinicius@eita.org.br>
  16. *
  17. * @license AGPL-3.0
  18. *
  19. * This code is free software: you can redistribute it and/or modify
  20. * it under the terms of the GNU Affero General Public License, version 3,
  21. * as published by the Free Software Foundation.
  22. *
  23. * This program is distributed in the hope that it will be useful,
  24. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  25. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  26. * GNU Affero General Public License for more details.
  27. *
  28. * You should have received a copy of the GNU Affero General Public License, version 3,
  29. * along with this program. If not, see <http://www.gnu.org/licenses/>
  30. *
  31. */
  32. namespace OCA\User_LDAP\Tests;
  33. use OC\User\Backend;
  34. use OC\User\Session;
  35. use OCA\User_LDAP\Access;
  36. use OCA\User_LDAP\Connection;
  37. use OCA\User_LDAP\Mapping\AbstractMapping;
  38. use OCA\User_LDAP\Mapping\UserMapping;
  39. use OCA\User_LDAP\User\DeletedUsersIndex;
  40. use OCA\User_LDAP\User\Manager;
  41. use OCA\User_LDAP\User\OfflineUser;
  42. use OCA\User_LDAP\User\User;
  43. use OCA\User_LDAP\User_LDAP;
  44. use OCA\User_LDAP\User_LDAP as UserLDAP;
  45. use OCA\User_LDAP\UserPluginManager;
  46. use OCP\HintException;
  47. use OCP\IConfig;
  48. use OCP\IUser;
  49. use OCP\Notification\IManager as INotificationManager;
  50. use PHPUnit\Framework\MockObject\MockObject;
  51. use Psr\Log\LoggerInterface;
  52. use Test\TestCase;
  53. /**
  54. * Class Test_User_Ldap_Direct
  55. *
  56. * @group DB
  57. *
  58. * @package OCA\User_LDAP\Tests
  59. */
  60. class User_LDAPTest extends TestCase {
  61. /** @var User_LDAP */
  62. protected $backend;
  63. /** @var Access|MockObject */
  64. protected $access;
  65. /** @var OfflineUser|MockObject */
  66. protected $offlineUser;
  67. /** @var IConfig|MockObject */
  68. protected $config;
  69. /** @var INotificationManager|MockObject */
  70. protected $notificationManager;
  71. /** @var Session|MockObject */
  72. protected $session;
  73. /** @var UserPluginManager|MockObject */
  74. protected $pluginManager;
  75. /** @var Connection|MockObject */
  76. protected $connection;
  77. /** @var Manager|MockObject */
  78. protected $userManager;
  79. /** @var LoggerInterface|MockObject */
  80. protected $logger;
  81. /** @var DeletedUsersIndex|MockObject */
  82. protected $deletedUsersIndex;
  83. protected function setUp(): void {
  84. parent::setUp();
  85. \OC_User::clearBackends();
  86. \OC::$server->getGroupManager()->clearBackends();
  87. $this->connection = $this->createMock(Connection::class);
  88. $this->userManager = $this->createMock(Manager::class);
  89. $this->access = $this->createMock(Access::class);
  90. $this->access->connection = $this->connection;
  91. $this->access->userManager = $this->userManager;
  92. $this->config = $this->createMock(IConfig::class);
  93. $this->notificationManager = $this->createMock(INotificationManager::class);
  94. // Cannot use IUserSession because of private listen() methods
  95. $this->session = $this->createMock(Session::class);
  96. $this->pluginManager = $this->createMock(UserPluginManager::class);
  97. $this->logger = $this->createMock(LoggerInterface::class);
  98. $this->deletedUsersIndex = $this->createMock(DeletedUsersIndex::class);
  99. $this->backend = new User_LDAP(
  100. $this->access,
  101. $this->config,
  102. $this->notificationManager,
  103. $this->session,
  104. $this->pluginManager,
  105. $this->logger,
  106. $this->deletedUsersIndex,
  107. );
  108. }
  109. private function prepareMockForUserExists() {
  110. $this->access->expects($this->any())
  111. ->method('username2dn')
  112. ->willReturnCallback(function ($uid) {
  113. switch ($uid) {
  114. case 'gunslinger':
  115. return 'dnOfRoland,dc=test';
  116. break;
  117. case 'formerUser':
  118. return 'dnOfFormerUser,dc=test';
  119. break;
  120. case 'newyorker':
  121. return 'dnOfNewYorker,dc=test';
  122. break;
  123. case 'ladyofshadows':
  124. return 'dnOfLadyOfShadows,dc=test';
  125. break;
  126. default:
  127. return false;
  128. }
  129. });
  130. $this->access->method('fetchUsersByLoginName')
  131. ->willReturn([]);
  132. }
  133. /**
  134. * Prepares the Access mock for checkPassword tests
  135. * @param bool $noDisplayName
  136. * @return void
  137. */
  138. private function prepareAccessForCheckPassword($noDisplayName = false) {
  139. $this->connection->expects($this->any())
  140. ->method('__get')
  141. ->willReturnCallback(function ($name) {
  142. if ($name === 'ldapLoginFilter') {
  143. return '%uid';
  144. }
  145. return null;
  146. });
  147. $this->access->expects($this->any())
  148. ->method('fetchListOfUsers')
  149. ->willReturnCallback(function ($filter) {
  150. if ($filter === 'roland') {
  151. return [['dn' => ['dnOfRoland,dc=test']]];
  152. }
  153. return [];
  154. });
  155. $this->access->expects($this->any())
  156. ->method('fetchUsersByLoginName')
  157. ->willReturnCallback(function ($uid) {
  158. if ($uid === 'roland') {
  159. return [['dn' => ['dnOfRoland,dc=test']]];
  160. }
  161. return [];
  162. });
  163. $retVal = 'gunslinger';
  164. if ($noDisplayName === true) {
  165. $retVal = false;
  166. }
  167. $this->access->expects($this->any())
  168. ->method('dn2username')
  169. ->with($this->equalTo('dnOfRoland,dc=test'))
  170. ->willReturn($retVal);
  171. $this->access->expects($this->any())
  172. ->method('stringResemblesDN')
  173. ->with($this->equalTo('dnOfRoland,dc=test'))
  174. ->willReturn(true);
  175. $this->access->expects($this->any())
  176. ->method('areCredentialsValid')
  177. ->willReturnCallback(function ($dn, $pwd) {
  178. if ($pwd === 'dt19') {
  179. return true;
  180. }
  181. return false;
  182. });
  183. $this->userManager->expects($this->any())
  184. ->method('getAttributes')
  185. ->willReturn(['dn', 'uid', 'mail', 'displayname']);
  186. }
  187. public function testCheckPasswordUidReturn() {
  188. $user = $this->createMock(User::class);
  189. $user->expects($this->any())
  190. ->method('getUsername')
  191. ->willReturn('gunslinger');
  192. $this->prepareAccessForCheckPassword();
  193. $this->userManager->expects($this->any())
  194. ->method('get')
  195. ->willReturn($user);
  196. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  197. \OC_User::useBackend($backend);
  198. $result = $backend->checkPassword('roland', 'dt19');
  199. $this->assertEquals('gunslinger', $result);
  200. }
  201. public function testCheckPasswordWrongPassword() {
  202. $this->prepareAccessForCheckPassword();
  203. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  204. \OC_User::useBackend($backend);
  205. $result = $backend->checkPassword('roland', 'wrong');
  206. $this->assertFalse($result);
  207. }
  208. public function testCheckPasswordWrongUser() {
  209. $this->prepareAccessForCheckPassword();
  210. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  211. \OC_User::useBackend($backend);
  212. $result = $backend->checkPassword('mallory', 'evil');
  213. $this->assertFalse($result);
  214. }
  215. public function testCheckPasswordNoDisplayName() {
  216. $this->prepareAccessForCheckPassword(true);
  217. $this->prepareAccessForCheckPassword();
  218. $this->userManager->expects($this->atLeastOnce())
  219. ->method('get')
  220. ->willReturn(null);
  221. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  222. \OC_User::useBackend($backend);
  223. $result = $backend->checkPassword('roland', 'dt19');
  224. $this->assertFalse($result);
  225. }
  226. public function testCheckPasswordPublicAPI() {
  227. $user = $this->createMock(User::class);
  228. $user->expects($this->any())
  229. ->method('getUsername')
  230. ->willReturn('gunslinger');
  231. $this->prepareAccessForCheckPassword();
  232. $this->userManager->expects($this->any())
  233. ->method('get')
  234. ->willReturn($user);
  235. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  236. \OC_User::useBackend($backend);
  237. $user = \OC::$server->getUserManager()->checkPassword('roland', 'dt19');
  238. $result = false;
  239. if ($user !== false) {
  240. $result = $user->getUID();
  241. }
  242. $this->assertEquals('gunslinger', $result);
  243. }
  244. public function testCheckPasswordPublicAPIWrongPassword() {
  245. $this->prepareAccessForCheckPassword();
  246. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  247. \OC_User::useBackend($backend);
  248. $user = \OC::$server->getUserManager()->checkPassword('roland', 'wrong');
  249. $result = false;
  250. if ($user !== false) {
  251. $result = $user->getUID();
  252. }
  253. $this->assertFalse($result);
  254. }
  255. public function testCheckPasswordPublicAPIWrongUser() {
  256. $this->prepareAccessForCheckPassword();
  257. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  258. \OC_User::useBackend($backend);
  259. $user = \OC::$server->getUserManager()->checkPassword('mallory', 'evil');
  260. $result = false;
  261. if ($user !== false) {
  262. $result = $user->getUID();
  263. }
  264. $this->assertFalse($result);
  265. }
  266. public function testDeleteUserCancel() {
  267. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  268. $result = $backend->deleteUser('notme');
  269. $this->assertFalse($result);
  270. }
  271. public function testDeleteUserSuccess() {
  272. $uid = 'jeremy';
  273. $home = '/var/vhome/jdings/';
  274. $mapping = $this->createMock(UserMapping::class);
  275. $mapping->expects($this->once())
  276. ->method('unmap')
  277. ->willReturn(true);
  278. $this->access->expects($this->once())
  279. ->method('getUserMapper')
  280. ->willReturn($mapping);
  281. $this->connection->expects($this->any())
  282. ->method('getConnectionResource')
  283. ->willReturn('this is an ldap link');
  284. $this->deletedUsersIndex->expects($this->once())
  285. ->method('isUserMarked')
  286. ->with($uid)
  287. ->willReturn(true);
  288. $offlineUser = $this->createMock(OfflineUser::class);
  289. $offlineUser->expects($this->once())
  290. ->method('getHomePath')
  291. ->willReturn($home);
  292. $this->userManager->expects($this->atLeastOnce())
  293. ->method('get')
  294. ->willReturn($offlineUser);
  295. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  296. $result = $backend->deleteUser($uid);
  297. $this->assertTrue($result);
  298. /** @noinspection PhpUnhandledExceptionInspection */
  299. $this->assertSame($backend->getHome($uid), $home);
  300. }
  301. public function testDeleteUserWithPlugin() {
  302. $this->pluginManager->expects($this->once())
  303. ->method('canDeleteUser')
  304. ->willReturn(true);
  305. $this->pluginManager->expects($this->once())
  306. ->method('deleteUser')
  307. ->with('uid')
  308. ->willReturn(true);
  309. $this->deletedUsersIndex->expects($this->once())
  310. ->method('isUserMarked')
  311. ->with('uid')
  312. ->willReturn(true);
  313. $mapper = $this->createMock(UserMapping::class);
  314. $mapper->expects($this->once())
  315. ->method('unmap')
  316. ->with('uid');
  317. $this->access->expects($this->atLeastOnce())
  318. ->method('getUserMapper')
  319. ->willReturn($mapper);
  320. $this->userManager->expects($this->once())
  321. ->method('invalidate')
  322. ->with('uid');
  323. $this->assertEquals(true, $this->backend->deleteUser('uid'));
  324. }
  325. /**
  326. * Prepares the Access mock for getUsers tests
  327. */
  328. private function prepareAccessForGetUsers() {
  329. $this->access->expects($this->once())
  330. ->method('escapeFilterPart')
  331. ->willReturnCallback(function ($search) {
  332. return $search;
  333. });
  334. $this->access->expects($this->any())
  335. ->method('getFilterPartForUserSearch')
  336. ->willReturnCallback(function ($search) {
  337. return $search;
  338. });
  339. $this->access->expects($this->any())
  340. ->method('combineFilterWithAnd')
  341. ->willReturnCallback(function ($param) {
  342. return $param[2];
  343. });
  344. $this->access->expects($this->any())
  345. ->method('fetchListOfUsers')
  346. ->willReturnCallback(function ($search, $a, $l, $o) {
  347. $users = ['gunslinger', 'newyorker', 'ladyofshadows'];
  348. if (empty($search)) {
  349. $result = $users;
  350. } else {
  351. $result = [];
  352. foreach ($users as $user) {
  353. if (stripos($user, $search) !== false) {
  354. $result[] = $user;
  355. }
  356. }
  357. }
  358. if (!is_null($l) || !is_null($o)) {
  359. $result = array_slice($result, $o, $l);
  360. }
  361. return $result;
  362. });
  363. $this->access->expects($this->any())
  364. ->method('nextcloudUserNames')
  365. ->willReturnArgument(0);
  366. $this->access->method('fetchUsersByLoginName')
  367. ->willReturn([]);
  368. $this->access->userManager->expects($this->any())
  369. ->method('getAttributes')
  370. ->willReturn(['dn', 'uid', 'mail', 'displayname']);
  371. }
  372. public function testGetUsersNoParam() {
  373. $this->prepareAccessForGetUsers();
  374. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  375. $result = $backend->getUsers();
  376. $this->assertEquals(3, count($result));
  377. }
  378. public function testGetUsersLimitOffset() {
  379. $this->prepareAccessForGetUsers();
  380. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  381. $result = $backend->getUsers('', 1, 2);
  382. $this->assertEquals(1, count($result));
  383. }
  384. public function testGetUsersLimitOffset2() {
  385. $this->prepareAccessForGetUsers();
  386. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  387. $result = $backend->getUsers('', 2, 1);
  388. $this->assertEquals(2, count($result));
  389. }
  390. public function testGetUsersSearchWithResult() {
  391. $this->prepareAccessForGetUsers();
  392. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  393. $result = $backend->getUsers('yo');
  394. $this->assertEquals(2, count($result));
  395. }
  396. public function testGetUsersSearchEmptyResult() {
  397. $this->prepareAccessForGetUsers();
  398. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  399. $result = $backend->getUsers('nix');
  400. $this->assertEquals(0, count($result));
  401. }
  402. private function getUsers($search = '', $limit = null, $offset = null) {
  403. $users = \OC::$server->getUserManager()->search($search, $limit, $offset);
  404. $uids = array_map(function (IUser $user) {
  405. return $user->getUID();
  406. }, $users);
  407. return $uids;
  408. }
  409. public function testGetUsersViaAPINoParam() {
  410. $this->prepareAccessForGetUsers();
  411. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  412. \OC_User::useBackend($backend);
  413. $result = $this->getUsers();
  414. $this->assertEquals(3, count($result));
  415. }
  416. public function testGetUsersViaAPILimitOffset() {
  417. $this->prepareAccessForGetUsers();
  418. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  419. \OC_User::useBackend($backend);
  420. $result = $this->getUsers('', 1, 2);
  421. $this->assertEquals(1, count($result));
  422. }
  423. public function testGetUsersViaAPILimitOffset2() {
  424. $this->prepareAccessForGetUsers();
  425. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  426. \OC_User::useBackend($backend);
  427. $result = $this->getUsers('', 2, 1);
  428. $this->assertEquals(2, count($result));
  429. }
  430. public function testGetUsersViaAPISearchWithResult() {
  431. $this->prepareAccessForGetUsers();
  432. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  433. \OC_User::useBackend($backend);
  434. $result = $this->getUsers('yo');
  435. $this->assertEquals(2, count($result));
  436. }
  437. public function testGetUsersViaAPISearchEmptyResult() {
  438. $this->prepareAccessForGetUsers();
  439. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  440. \OC_User::useBackend($backend);
  441. $result = $this->getUsers('nix');
  442. $this->assertEquals(0, count($result));
  443. }
  444. public function testUserExists() {
  445. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  446. $this->prepareMockForUserExists();
  447. $user = $this->createMock(User::class);
  448. $this->userManager->expects($this->atLeastOnce())
  449. ->method('get')
  450. ->willReturn($user);
  451. $this->access->expects($this->any())
  452. ->method('getUserMapper')
  453. ->willReturn($this->createMock(UserMapping::class));
  454. //test for existing user
  455. /** @noinspection PhpUnhandledExceptionInspection */
  456. $result = $backend->userExists('gunslinger');
  457. $this->assertTrue($result);
  458. }
  459. public function testUserExistsForDeleted() {
  460. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  461. $this->prepareMockForUserExists();
  462. $mapper = $this->createMock(UserMapping::class);
  463. $mapper->expects($this->any())
  464. ->method('getUUIDByDN')
  465. ->with('dnOfFormerUser,dc=test')
  466. ->willReturn('45673458748');
  467. $this->access->expects($this->any())
  468. ->method('getUserMapper')
  469. ->willReturn($mapper);
  470. $user = $this->createMock(User::class);
  471. $this->userManager->expects($this->atLeastOnce())
  472. ->method('get')
  473. ->willReturn($user);
  474. //test for deleted user – always returns true as long as we have the user in DB
  475. $this->assertTrue($backend->userExists('formerUser'));
  476. }
  477. public function testUserExistsForNeverExisting() {
  478. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  479. $this->prepareMockForUserExists();
  480. $this->access->expects($this->any())
  481. ->method('readAttribute')
  482. ->willReturnCallback(function ($dn) {
  483. if ($dn === 'dnOfRoland,dc=test') {
  484. return [];
  485. }
  486. return false;
  487. });
  488. //test for never-existing user
  489. /** @noinspection PhpUnhandledExceptionInspection */
  490. $result = $backend->userExists('mallory');
  491. $this->assertFalse($result);
  492. }
  493. public function testUserExistsPublicAPI() {
  494. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  495. $this->prepareMockForUserExists();
  496. \OC_User::useBackend($backend);
  497. $user = $this->createMock(User::class);
  498. $user->expects($this->any())
  499. ->method('getDN')
  500. ->willReturn('dnOfRoland,dc=test');
  501. $this->access->expects($this->any())
  502. ->method('readAttribute')
  503. ->willReturnCallback(function ($dn) {
  504. if ($dn === 'dnOfRoland,dc=test') {
  505. return [];
  506. }
  507. return false;
  508. });
  509. $this->userManager->expects($this->atLeastOnce())
  510. ->method('get')
  511. ->willReturn($user);
  512. $this->access->expects($this->any())
  513. ->method('getUserMapper')
  514. ->willReturn($this->createMock(UserMapping::class));
  515. //test for existing user
  516. $result = \OC::$server->getUserManager()->userExists('gunslinger');
  517. $this->assertTrue($result);
  518. }
  519. public function testDeleteUserExisting() {
  520. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  521. //we do not support deleting existing users at all
  522. $result = $backend->deleteUser('gunslinger');
  523. $this->assertFalse($result);
  524. }
  525. public function testGetHomeAbsolutePath() {
  526. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  527. $this->prepareMockForUserExists();
  528. $this->connection->expects($this->any())
  529. ->method('__get')
  530. ->willReturnCallback(function ($name) {
  531. if ($name === 'homeFolderNamingRule') {
  532. return 'attr:testAttribute';
  533. }
  534. return null;
  535. });
  536. $this->access->expects($this->any())
  537. ->method('readAttribute')
  538. ->willReturnCallback(function ($dn, $attr) {
  539. switch ($dn) {
  540. case 'dnOfRoland,dc=test':
  541. if ($attr === 'testAttribute') {
  542. return ['/tmp/rolandshome/'];
  543. }
  544. return [];
  545. break;
  546. default:
  547. return false;
  548. }
  549. });
  550. $user = $this->createMock(User::class);
  551. $user->expects($this->any())
  552. ->method('getUsername')
  553. ->willReturn('gunslinger');
  554. $user->expects($this->any())
  555. ->method('getDN')
  556. ->willReturn('dnOfRoland,dc=test');
  557. $user->expects($this->any())
  558. ->method('getHomePath')
  559. ->willReturn('/tmp/rolandshome/');
  560. $this->userManager->expects($this->atLeastOnce())
  561. ->method('get')
  562. ->willReturn($user);
  563. //absolute path
  564. /** @noinspection PhpUnhandledExceptionInspection */
  565. $result = $backend->getHome('gunslinger');
  566. $this->assertEquals('/tmp/rolandshome/', $result);
  567. }
  568. public function testGetHomeRelative() {
  569. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  570. $this->prepareMockForUserExists();
  571. $dataDir = \OC::$server->getConfig()->getSystemValue(
  572. 'datadirectory', \OC::$SERVERROOT.'/data');
  573. $this->connection->expects($this->any())
  574. ->method('__get')
  575. ->willReturnCallback(function ($name) {
  576. if ($name === 'homeFolderNamingRule') {
  577. return 'attr:testAttribute';
  578. }
  579. return null;
  580. });
  581. $this->access->expects($this->any())
  582. ->method('readAttribute')
  583. ->willReturnCallback(function ($dn, $attr) {
  584. switch ($dn) {
  585. case 'dnOfLadyOfShadows,dc=test':
  586. if ($attr === 'testAttribute') {
  587. return ['susannah/'];
  588. }
  589. return [];
  590. break;
  591. default:
  592. return false;
  593. }
  594. });
  595. $user = $this->createMock(User::class);
  596. $user->expects($this->any())
  597. ->method('getUsername')
  598. ->willReturn('ladyofshadows');
  599. $user->expects($this->any())
  600. ->method('getDN')
  601. ->willReturn('dnOfLadyOfShadows,dc=test');
  602. $user->expects($this->any())
  603. ->method('getHomePath')
  604. ->willReturn($dataDir.'/susannah/');
  605. $this->userManager->expects($this->atLeastOnce())
  606. ->method('get')
  607. ->willReturn($user);
  608. /** @noinspection PhpUnhandledExceptionInspection */
  609. $result = $backend->getHome('ladyofshadows');
  610. $this->assertEquals($dataDir.'/susannah/', $result);
  611. }
  612. public function testGetHomeNoPath() {
  613. $this->expectException(\Exception::class);
  614. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  615. $this->prepareMockForUserExists();
  616. $this->connection->expects($this->any())
  617. ->method('__get')
  618. ->willReturnCallback(function ($name) {
  619. if ($name === 'homeFolderNamingRule') {
  620. return 'attr:testAttribute';
  621. }
  622. return null;
  623. });
  624. $this->access->expects($this->any())
  625. ->method('readAttribute')
  626. ->willReturnCallback(function ($dn, $attr) {
  627. switch ($dn) {
  628. default:
  629. return false;
  630. }
  631. });
  632. $this->access->connection->expects($this->any())
  633. ->method('getFromCache')
  634. ->willReturnCallback(function ($key) {
  635. if ($key === 'userExistsnewyorker') {
  636. return true;
  637. }
  638. return null;
  639. });
  640. $user = $this->createMock(User::class);
  641. $user->expects($this->any())
  642. ->method('getUsername')
  643. ->willReturn('newyorker');
  644. $user->expects($this->any())
  645. ->method('getHomePath')
  646. ->willThrowException(new \Exception());
  647. $this->userManager->expects($this->atLeastOnce())
  648. ->method('get')
  649. ->willReturn($user);
  650. //no path at all – triggers OC default behaviour
  651. $result = $backend->getHome('newyorker');
  652. $this->assertFalse($result);
  653. }
  654. public function testGetHomeDeletedUser() {
  655. $uid = 'newyorker';
  656. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  657. $this->prepareMockForUserExists();
  658. $this->connection->expects($this->any())
  659. ->method('__get')
  660. ->willReturnCallback(function ($name) {
  661. if ($name === 'homeFolderNamingRule') {
  662. return 'attr:testAttribute';
  663. }
  664. return null;
  665. });
  666. $this->access->expects($this->any())
  667. ->method('readAttribute')
  668. ->willReturn([]);
  669. $userMapper = $this->createMock(UserMapping::class);
  670. $this->access->expects($this->any())
  671. ->method('getUserMapper')
  672. ->willReturn($userMapper);
  673. $this->config->expects($this->any())
  674. ->method('getUserValue')
  675. ->willReturn(true);
  676. $offlineUser = $this->createMock(OfflineUser::class);
  677. $offlineUser->expects($this->atLeastOnce())
  678. ->method('getHomePath')
  679. ->willReturn('');
  680. $this->userManager->expects($this->atLeastOnce())
  681. ->method('get')
  682. ->willReturn($offlineUser);
  683. $result = $backend->getHome($uid);
  684. $this->assertFalse($result);
  685. }
  686. public function testGetHomeWithPlugin() {
  687. $this->pluginManager->expects($this->once())
  688. ->method('implementsActions')
  689. ->with(Backend::GET_HOME)
  690. ->willReturn(true);
  691. $this->pluginManager->expects($this->once())
  692. ->method('getHome')
  693. ->with('uid')
  694. ->willReturn('result');
  695. $this->connection->expects($this->any())
  696. ->method('getFromCache')
  697. ->willReturnCallback(function ($uid) {
  698. return true;
  699. });
  700. /** @noinspection PhpUnhandledExceptionInspection */
  701. $this->assertEquals($this->backend->getHome('uid'), 'result');
  702. }
  703. private function prepareAccessForGetDisplayName() {
  704. $this->connection->expects($this->any())
  705. ->method('__get')
  706. ->willReturnCallback(function ($name) {
  707. if ($name === 'ldapUserDisplayName') {
  708. return 'displayname';
  709. } elseif ($name === 'ldapUserDisplayName2') {
  710. return 'displayname2';
  711. }
  712. return null;
  713. });
  714. $this->access->expects($this->any())
  715. ->method('readAttribute')
  716. ->willReturnCallback(function ($dn, $attr) {
  717. switch ($dn) {
  718. case 'dnOfRoland,dc=test':
  719. if ($attr === 'displayname') {
  720. return ['Roland Deschain'];
  721. }
  722. return [];
  723. break;
  724. default:
  725. return false;
  726. }
  727. });
  728. $this->access->method('fetchUsersByLoginName')
  729. ->willReturn([]);
  730. }
  731. public function testGetDisplayName() {
  732. $this->prepareAccessForGetDisplayName();
  733. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  734. $this->prepareMockForUserExists();
  735. $this->connection->expects($this->any())
  736. ->method('getConnectionResource')
  737. ->willReturnCallback(function () {
  738. return true;
  739. });
  740. $user1 = $this->createMock(User::class);
  741. $user1->expects($this->once())
  742. ->method('composeAndStoreDisplayName')
  743. ->willReturn('Roland Deschain');
  744. $user1->expects($this->any())
  745. ->method('getDN')
  746. ->willReturn('dnOfRoland,dc=test');
  747. $user2 = $this->createMock(User::class);
  748. $user2->expects($this->never())
  749. ->method('composeAndStoreDisplayName');
  750. $user2->expects($this->any())
  751. ->method('getDN')
  752. ->willReturn('another DN');
  753. $mapper = $this->createMock(UserMapping::class);
  754. $mapper->expects($this->any())
  755. ->method('getUUIDByDN')
  756. ->willReturnCallback(function ($dn) {
  757. return $dn;
  758. });
  759. $this->userManager->expects($this->any())
  760. ->method('get')
  761. ->willReturnCallback(function ($uid) use ($user1, $user2) {
  762. if ($uid === 'gunslinger') {
  763. return $user1;
  764. } elseif ($uid === 'newyorker') {
  765. return $user2;
  766. }
  767. return null;
  768. });
  769. $this->access->expects($this->any())
  770. ->method('getUserMapper')
  771. ->willReturn($mapper);
  772. $this->access->expects($this->any())
  773. ->method('getUserDnByUuid')
  774. ->willReturnCallback(function ($uuid) {
  775. return $uuid . '1';
  776. });
  777. //with displayName
  778. $result = $backend->getDisplayName('gunslinger');
  779. $this->assertEquals('Roland Deschain', $result);
  780. //empty displayname retrieved
  781. $result = $backend->getDisplayName('newyorker');
  782. $this->assertEquals(null, $result);
  783. }
  784. public function testGetDisplayNamePublicAPI() {
  785. $this->access->expects($this->any())
  786. ->method('username2dn')
  787. ->willReturnCallback(function ($uid) {
  788. switch ($uid) {
  789. case 'gunslinger':
  790. return 'dnOfRoland,dc=test';
  791. break;
  792. case 'formerUser':
  793. return 'dnOfFormerUser,dc=test';
  794. break;
  795. case 'newyorker':
  796. return 'dnOfNewYorker,dc=test';
  797. break;
  798. case 'ladyofshadows':
  799. return 'dnOfLadyOfShadows,dc=test';
  800. break;
  801. default:
  802. return false;
  803. }
  804. });
  805. $this->prepareAccessForGetDisplayName();
  806. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  807. $this->prepareMockForUserExists();
  808. $this->connection->expects($this->any())
  809. ->method('getConnectionResource')
  810. ->willReturnCallback(function () {
  811. return true;
  812. });
  813. \OC_User::useBackend($backend);
  814. $user1 = $this->createMock(User::class);
  815. $user1->expects($this->once())
  816. ->method('composeAndStoreDisplayName')
  817. ->willReturn('Roland Deschain');
  818. $user1->expects($this->any())
  819. ->method('getDN')
  820. ->willReturn('dnOfRoland,dc=test');
  821. $user2 = $this->createMock(User::class);
  822. $user2->expects($this->never())
  823. ->method('composeAndStoreDisplayName');
  824. $user2->expects($this->any())
  825. ->method('getDN')
  826. ->willReturn('another DN');
  827. $mapper = $this->createMock(UserMapping::class);
  828. $mapper->expects($this->any())
  829. ->method('getUUIDByDN')
  830. ->willReturnCallback(function ($dn) {
  831. return $dn;
  832. });
  833. $this->userManager->expects($this->any())
  834. ->method('get')
  835. ->willReturnCallback(function ($uid) use ($user1, $user2) {
  836. if ($uid === 'gunslinger') {
  837. return $user1;
  838. } elseif ($uid === 'newyorker') {
  839. return $user2;
  840. }
  841. return null;
  842. });
  843. $this->access->expects($this->any())
  844. ->method('getUserMapper')
  845. ->willReturn($mapper);
  846. $this->access->expects($this->any())
  847. ->method('getUserDnByUuid')
  848. ->willReturnCallback(function ($uuid) {
  849. return $uuid . '1';
  850. });
  851. //with displayName
  852. $result = \OC::$server->getUserManager()->get('gunslinger')->getDisplayName();
  853. $this->assertEquals('Roland Deschain', $result);
  854. //empty displayname retrieved
  855. $result = \OC::$server->getUserManager()->get('newyorker') === null ? 'newyorker' : \OC::$server->getUserManager()->get('newyorker')->getDisplayName();
  856. $this->assertEquals('newyorker', $result);
  857. }
  858. public function testGetDisplayNameWithPlugin() {
  859. $this->pluginManager->expects($this->once())
  860. ->method('implementsActions')
  861. ->with(Backend::GET_DISPLAYNAME)
  862. ->willReturn(true);
  863. $this->pluginManager->expects($this->once())
  864. ->method('getDisplayName')
  865. ->with('uid')
  866. ->willReturn('result');
  867. $this->assertEquals($this->backend->getDisplayName('uid'), 'result');
  868. }
  869. //no test for getDisplayNames, because it just invokes getUsers and
  870. //getDisplayName
  871. public function testCountUsers() {
  872. $this->access->expects($this->once())
  873. ->method('countUsers')
  874. ->willReturn(5);
  875. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  876. $result = $backend->countUsers();
  877. $this->assertEquals(5, $result);
  878. }
  879. public function testCountUsersFailing() {
  880. $this->access->expects($this->once())
  881. ->method('countUsers')
  882. ->willReturn(false);
  883. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  884. $result = $backend->countUsers();
  885. $this->assertFalse($result);
  886. }
  887. public function testCountUsersWithPlugin() {
  888. $this->pluginManager->expects($this->once())
  889. ->method('implementsActions')
  890. ->with(Backend::COUNT_USERS)
  891. ->willReturn(true);
  892. $this->pluginManager->expects($this->once())
  893. ->method('countUsers')
  894. ->willReturn(42);
  895. $this->assertEquals($this->backend->countUsers(), 42);
  896. }
  897. public function testLoginName2UserNameSuccess() {
  898. $loginName = 'Alice';
  899. $username = 'alice';
  900. $dn = 'uid=alice,dc=what,dc=ever';
  901. $this->access->expects($this->once())
  902. ->method('fetchUsersByLoginName')
  903. ->with($this->equalTo($loginName))
  904. ->willReturn([['dn' => [$dn]]]);
  905. $this->access->expects($this->any())
  906. ->method('stringResemblesDN')
  907. ->with($this->equalTo($dn))
  908. ->willReturn(true);
  909. $this->access->expects($this->any())
  910. ->method('dn2username')
  911. ->with($this->equalTo($dn))
  912. ->willReturn($username);
  913. $this->connection->expects($this->exactly(2))
  914. ->method('getFromCache')
  915. ->with($this->equalTo('loginName2UserName-'.$loginName))
  916. ->willReturnOnConsecutiveCalls(null, $username);
  917. $this->connection->expects($this->once())
  918. ->method('writeToCache')
  919. ->with($this->equalTo('loginName2UserName-'.$loginName), $this->equalTo($username));
  920. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  921. $user = $this->createMock(User::class);
  922. $user->expects($this->any())
  923. ->method('getUsername')
  924. ->willReturn('alice');
  925. $this->userManager->expects($this->atLeastOnce())
  926. ->method('get')
  927. ->with($dn)
  928. ->willReturn($user);
  929. $this->userManager->expects($this->any())
  930. ->method('getAttributes')
  931. ->willReturn(['dn', 'uid', 'mail', 'displayname']);
  932. $name = $backend->loginName2UserName($loginName);
  933. $this->assertSame($username, $name);
  934. // and once again to verify that caching works
  935. $backend->loginName2UserName($loginName);
  936. }
  937. public function testLoginName2UserNameNoUsersOnLDAP() {
  938. $loginName = 'Loki';
  939. $this->access->expects($this->once())
  940. ->method('fetchUsersByLoginName')
  941. ->with($this->equalTo($loginName))
  942. ->willReturn([]);
  943. $this->access->expects($this->never())
  944. ->method('stringResemblesDN');
  945. $this->access->expects($this->never())
  946. ->method('dn2username');
  947. $this->connection->expects($this->exactly(2))
  948. ->method('getFromCache')
  949. ->with($this->equalTo('loginName2UserName-'.$loginName))
  950. ->willReturnOnConsecutiveCalls(null, false);
  951. $this->connection->expects($this->once())
  952. ->method('writeToCache')
  953. ->with($this->equalTo('loginName2UserName-'.$loginName), false);
  954. $this->userManager->expects($this->any())
  955. ->method('getAttributes')
  956. ->willReturn(['dn', 'uid', 'mail', 'displayname']);
  957. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  958. $name = $backend->loginName2UserName($loginName);
  959. $this->assertSame(false, $name);
  960. // and once again to verify that caching works
  961. $backend->loginName2UserName($loginName);
  962. }
  963. public function testLoginName2UserNameOfflineUser() {
  964. $loginName = 'Alice';
  965. $dn = 'uid=alice,dc=what,dc=ever';
  966. $offlineUser = $this->getMockBuilder(OfflineUser::class)
  967. ->disableOriginalConstructor()
  968. ->getMock();
  969. $this->access->expects($this->once())
  970. ->method('fetchUsersByLoginName')
  971. ->with($this->equalTo($loginName))
  972. ->willReturn([['dn' => [$dn]]]);
  973. $this->connection->expects($this->exactly(2))
  974. ->method('getFromCache')
  975. ->with($this->equalTo('loginName2UserName-'.$loginName))
  976. ->willReturnOnConsecutiveCalls(null, false);
  977. $this->connection->expects($this->once())
  978. ->method('writeToCache')
  979. ->with($this->equalTo('loginName2UserName-'.$loginName), $this->equalTo(false));
  980. $this->userManager->expects($this->any())
  981. ->method('get')
  982. ->with($dn)
  983. ->willReturn($offlineUser);
  984. $this->userManager->expects($this->any())
  985. ->method('getAttributes')
  986. ->willReturn(['dn', 'uid', 'mail', 'displayname']);
  987. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  988. $name = $backend->loginName2UserName($loginName);
  989. $this->assertSame(false, $name);
  990. // and once again to verify that caching works
  991. $backend->loginName2UserName($loginName);
  992. }
  993. /**
  994. * Prepares the Access mock for setPassword tests
  995. *
  996. * @param bool $enablePasswordChange
  997. */
  998. private function prepareAccessForSetPassword($enablePasswordChange = true) {
  999. $this->connection->expects($this->any())
  1000. ->method('__get')
  1001. ->willReturnCallback(function ($name) use (&$enablePasswordChange) {
  1002. if ($name === 'ldapLoginFilter') {
  1003. return '%uid';
  1004. }
  1005. if ($name === 'turnOnPasswordChange') {
  1006. return $enablePasswordChange?1:0;
  1007. }
  1008. return null;
  1009. });
  1010. $this->connection->expects($this->any())
  1011. ->method('getFromCache')
  1012. ->willReturnCallback(function ($uid) {
  1013. if ($uid === 'userExists'.'roland') {
  1014. return true;
  1015. }
  1016. return null;
  1017. });
  1018. $this->access->expects($this->any())
  1019. ->method('fetchListOfUsers')
  1020. ->willReturnCallback(function ($filter) {
  1021. if ($filter === 'roland') {
  1022. return [['dn' => ['dnOfRoland,dc=test']]];
  1023. }
  1024. return [];
  1025. });
  1026. $this->access->expects($this->any())
  1027. ->method('fetchUsersByLoginName')
  1028. ->willReturnCallback(function ($uid) {
  1029. if ($uid === 'roland') {
  1030. return [['dn' => ['dnOfRoland,dc=test']]];
  1031. }
  1032. return [];
  1033. });
  1034. $this->access->expects($this->any())
  1035. ->method('dn2username')
  1036. ->with($this->equalTo('dnOfRoland,dc=test'))
  1037. ->willReturn('roland');
  1038. $this->access->expects($this->any())
  1039. ->method('stringResemblesDN')
  1040. ->with($this->equalTo('dnOfRoland,dc=test'))
  1041. ->willReturn(true);
  1042. $this->access->expects($this->any())
  1043. ->method('setPassword')
  1044. ->willReturnCallback(function ($uid, $password) {
  1045. if (strlen($password) <= 5) {
  1046. throw new HintException('Password fails quality checking policy', '', 19);
  1047. }
  1048. return true;
  1049. });
  1050. }
  1051. public function testSetPasswordInvalid() {
  1052. $this->expectException(\OCP\HintException::class);
  1053. $this->expectExceptionMessage('Password fails quality checking policy');
  1054. $this->prepareAccessForSetPassword($this->access);
  1055. $this->userManager->expects($this->atLeastOnce())
  1056. ->method('get')
  1057. ->willReturn($this->createMock(User::class));
  1058. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  1059. \OC_User::useBackend($backend);
  1060. $this->assertTrue(\OC_User::setPassword('roland', 'dt'));
  1061. }
  1062. public function testSetPasswordValid() {
  1063. $this->prepareAccessForSetPassword($this->access);
  1064. $this->userManager->expects($this->any())
  1065. ->method('get')
  1066. ->willReturn($this->createMock(User::class));
  1067. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  1068. $this->userManager->expects($this->any())
  1069. ->method('get')
  1070. ->willReturn($this->createMock(User::class));
  1071. \OC_User::useBackend($backend);
  1072. $this->assertTrue(\OC_User::setPassword('roland', 'dt12234$'));
  1073. }
  1074. public function testSetPasswordValidDisabled() {
  1075. $this->userManager->expects($this->any())
  1076. ->method('get')
  1077. ->willReturn($this->createMock(User::class));
  1078. $this->prepareAccessForSetPassword(false);
  1079. $backend = new UserLDAP($this->access, $this->config, $this->notificationManager, $this->session, $this->pluginManager, $this->logger, $this->deletedUsersIndex);
  1080. \OC_User::useBackend($backend);
  1081. $this->assertFalse(\OC_User::setPassword('roland', 'dt12234$'));
  1082. }
  1083. public function testSetPasswordWithInvalidUser() {
  1084. $this->expectException(\Exception::class);
  1085. $this->expectExceptionMessage('LDAP setPassword: Could not get user object for uid NotExistingUser. Maybe the LDAP entry has no set display name attribute?');
  1086. $this->userManager
  1087. ->expects($this->once())
  1088. ->method('get')
  1089. ->with('NotExistingUser')
  1090. ->willReturn(null);
  1091. $this->backend->setPassword('NotExistingUser', 'Password');
  1092. }
  1093. public function testSetPasswordWithUsernameFalse() {
  1094. $user = $this->createMock(User::class);
  1095. $user
  1096. ->expects($this->once())
  1097. ->method('getUsername')
  1098. ->willReturn(false);
  1099. $this->userManager
  1100. ->expects($this->once())
  1101. ->method('get')
  1102. ->with('NotExistingUser')
  1103. ->willReturn($user);
  1104. /** @noinspection PhpUnhandledExceptionInspection */
  1105. $this->assertFalse($this->backend->setPassword('NotExistingUser', 'Password'));
  1106. }
  1107. public function testSetPasswordWithPlugin() {
  1108. $this->pluginManager->expects($this->once())
  1109. ->method('implementsActions')
  1110. ->with(Backend::SET_PASSWORD)
  1111. ->willReturn(true);
  1112. $this->pluginManager->expects($this->once())
  1113. ->method('setPassword')
  1114. ->with('uid', 'password')
  1115. ->willReturn('result');
  1116. /** @noinspection PhpUnhandledExceptionInspection */
  1117. $this->assertEquals($this->backend->setPassword('uid', 'password'), 'result');
  1118. }
  1119. public function avatarDataProvider() {
  1120. return [
  1121. [ 'validImageData', false ],
  1122. [ 'corruptImageData', true ],
  1123. [ false, true]
  1124. ];
  1125. }
  1126. /** @dataProvider avatarDataProvider */
  1127. public function testCanChangeAvatar($imageData, $expected) {
  1128. $isValidImage = str_starts_with((string)$imageData, 'valid');
  1129. $user = $this->createMock(User::class);
  1130. $user->expects($this->once())
  1131. ->method('getAvatarImage')
  1132. ->willReturn($imageData);
  1133. $user->expects($this->atMost(1))
  1134. ->method('updateAvatar')
  1135. ->willReturn($isValidImage);
  1136. $this->userManager->expects($this->atLeastOnce())
  1137. ->method('get')
  1138. ->willReturn($user);
  1139. /** @noinspection PhpUnhandledExceptionInspection */
  1140. $this->assertSame($expected, $this->backend->canChangeAvatar('uid'));
  1141. }
  1142. public function testCanChangeAvatarWithPlugin() {
  1143. $this->pluginManager->expects($this->once())
  1144. ->method('implementsActions')
  1145. ->with(Backend::PROVIDE_AVATAR)
  1146. ->willReturn(true);
  1147. $this->pluginManager->expects($this->once())
  1148. ->method('canChangeAvatar')
  1149. ->with('uid')
  1150. ->willReturn('result');
  1151. $this->assertEquals($this->backend->canChangeAvatar('uid'), 'result');
  1152. }
  1153. public function testSetDisplayNameWithPlugin() {
  1154. $newDisplayName = 'J. Baker';
  1155. $this->pluginManager->expects($this->once())
  1156. ->method('implementsActions')
  1157. ->with(Backend::SET_DISPLAYNAME)
  1158. ->willReturn(true);
  1159. $this->pluginManager->expects($this->once())
  1160. ->method('setDisplayName')
  1161. ->with('uid', $newDisplayName)
  1162. ->willReturn($newDisplayName);
  1163. $this->access->expects($this->once())
  1164. ->method('cacheUserDisplayName');
  1165. $this->assertEquals($newDisplayName, $this->backend->setDisplayName('uid', $newDisplayName));
  1166. }
  1167. public function testSetDisplayNameErrorWithPlugin() {
  1168. $this->expectException(\OCP\HintException::class);
  1169. $newDisplayName = 'J. Baker';
  1170. $this->pluginManager->expects($this->once())
  1171. ->method('implementsActions')
  1172. ->with(Backend::SET_DISPLAYNAME)
  1173. ->willReturn(true);
  1174. $this->pluginManager->expects($this->once())
  1175. ->method('setDisplayName')
  1176. ->with('uid', $newDisplayName)
  1177. ->willThrowException(new HintException('something happned'));
  1178. $this->access->expects($this->never())
  1179. ->method('cacheUserDisplayName');
  1180. $this->backend->setDisplayName('uid', $newDisplayName);
  1181. }
  1182. public function testSetDisplayNameFailing() {
  1183. $this->pluginManager->expects($this->once())
  1184. ->method('implementsActions')
  1185. ->with(Backend::SET_DISPLAYNAME)
  1186. ->willReturn(false);
  1187. $this->access->expects($this->never())
  1188. ->method('cacheUserDisplayName');
  1189. $this->assertFalse($this->backend->setDisplayName('uid', 'displayName'));
  1190. }
  1191. public function testCreateUserWithPlugin() {
  1192. $uid = 'alien6372';
  1193. $uuid = '123-2345-36756-123-2345234-4431';
  1194. $pwd = 'passwørd';
  1195. $this->pluginManager->expects($this->once())
  1196. ->method('implementsActions')
  1197. ->with(Backend::CREATE_USER)
  1198. ->willReturn(true);
  1199. $this->pluginManager->expects($this->once())
  1200. ->method('createUser')
  1201. ->with($uid, $pwd)
  1202. ->willReturn('result');
  1203. $this->access->expects($this->atLeastOnce())
  1204. ->method('getUUID')
  1205. ->willReturn($uuid);
  1206. $this->access->expects($this->once())
  1207. ->method('mapAndAnnounceIfApplicable')
  1208. ->with($this->isInstanceOf(AbstractMapping::class), $this->anything(), $uid, $uuid, true);
  1209. $this->access->expects($this->any())
  1210. ->method('getUserMapper')
  1211. ->willReturn($this->createMock(UserMapping::class));
  1212. $this->assertEquals($this->backend->createUser($uid, $pwd), true);
  1213. }
  1214. public function testCreateUserFailing() {
  1215. $this->pluginManager->expects($this->once())
  1216. ->method('implementsActions')
  1217. ->with(Backend::CREATE_USER)
  1218. ->willReturn(false);
  1219. $this->assertFalse($this->backend->createUser('uid', 'password'));
  1220. }
  1221. public function actionProvider() {
  1222. return [
  1223. [ 'ldapUserAvatarRule', 'default', Backend::PROVIDE_AVATAR, true] ,
  1224. [ 'ldapUserAvatarRule', 'data:selfiePhoto', Backend::PROVIDE_AVATAR, true],
  1225. [ 'ldapUserAvatarRule', 'none', Backend::PROVIDE_AVATAR, false],
  1226. [ 'turnOnPasswordChange', 0, Backend::SET_PASSWORD, false],
  1227. [ 'turnOnPasswordChange', 1, Backend::SET_PASSWORD, true],
  1228. ];
  1229. }
  1230. /**
  1231. * @dataProvider actionProvider
  1232. */
  1233. public function testImplementsAction($configurable, $value, $actionCode, $expected) {
  1234. $this->pluginManager->expects($this->once())
  1235. ->method('getImplementedActions')
  1236. ->willReturn(0);
  1237. $this->connection->expects($this->any())
  1238. ->method('__get')
  1239. ->willReturnMap([
  1240. [$configurable, $value],
  1241. ]);
  1242. $this->assertSame($expected, $this->backend->implementsActions($actionCode));
  1243. }
  1244. }