User_LDAPTest.php 44 KB

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