Passed
Push — master ( b36584...4491ed )
by Roeland
09:59
created

User_LDAP::checkPassword()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 31
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 21
nc 5
nop 2
dl 0
loc 31
rs 9.2728
c 0
b 0
f 0
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Arthur Schiwon <[email protected]>
6
 * @author Bart Visscher <[email protected]>
7
 * @author Dominik Schmidt <[email protected]>
8
 * @author felixboehm <[email protected]>
9
 * @author Joas Schilling <[email protected]>
10
 * @author Jörn Friedrich Dreyer <[email protected]>
11
 * @author Lukas Reschke <[email protected]>
12
 * @author Morris Jobke <[email protected]>
13
 * @author Renaud Fortier <[email protected]>
14
 * @author Robin Appelman <[email protected]>
15
 * @author Robin McCorkell <[email protected]>
16
 * @author Roger Szabo <[email protected]>
17
 * @author root <[email protected]>
18
 * @author Thomas Müller <[email protected]>
19
 * @author Tom Needham <[email protected]>
20
 * @author Victor Dubiniuk <[email protected]>
21
 * @author Vinicius Cubas Brand <[email protected]>
22
 *
23
 * @license AGPL-3.0
24
 *
25
 * This code is free software: you can redistribute it and/or modify
26
 * it under the terms of the GNU Affero General Public License, version 3,
27
 * as published by the Free Software Foundation.
28
 *
29
 * This program is distributed in the hope that it will be useful,
30
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32
 * GNU Affero General Public License for more details.
33
 *
34
 * You should have received a copy of the GNU Affero General Public License, version 3,
35
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
36
 *
37
 */
38
39
namespace OCA\User_LDAP;
40
41
use OC\ServerNotAvailableException;
42
use OC\User\Backend;
43
use OC\User\NoUserException;
44
use OCA\User_LDAP\Exceptions\NotOnLDAP;
45
use OCA\User_LDAP\User\OfflineUser;
46
use OCA\User_LDAP\User\User;
47
use OCP\IConfig;
48
use OCP\ILogger;
49
use OCP\IUser;
50
use OCP\IUserSession;
51
use OCP\Notification\IManager as INotificationManager;
52
use OCP\Util;
53
54
class User_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserInterface, IUserLDAP {
55
	/** @var \OCP\IConfig */
56
	protected $ocConfig;
57
58
	/** @var INotificationManager */
59
	protected $notificationManager;
60
61
	/** @var string */
62
	protected $currentUserInDeletionProcess;
63
64
	/** @var UserPluginManager */
65
	protected $userPluginManager;
66
67
	/**
68
	 * @param Access $access
69
	 * @param \OCP\IConfig $ocConfig
70
	 * @param \OCP\Notification\IManager $notificationManager
71
	 * @param IUserSession $userSession
72
	 */
73
	public function __construct(Access $access, IConfig $ocConfig, INotificationManager $notificationManager, IUserSession $userSession, UserPluginManager $userPluginManager) {
74
		parent::__construct($access);
75
		$this->ocConfig = $ocConfig;
76
		$this->notificationManager = $notificationManager;
77
		$this->userPluginManager = $userPluginManager;
78
		$this->registerHooks($userSession);
79
	}
80
81
	protected function registerHooks(IUserSession $userSession) {
82
		$userSession->listen('\OC\User', 'preDelete', [$this, 'preDeleteUser']);
0 ignored issues
show
Bug introduced by
The method listen() does not exist on OCP\IUserSession. It seems like you code against a sub-type of OCP\IUserSession such as OC\User\Session. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

82
		$userSession->/** @scrutinizer ignore-call */ 
83
                listen('\OC\User', 'preDelete', [$this, 'preDeleteUser']);
Loading history...
83
		$userSession->listen('\OC\User', 'postDelete', [$this, 'postDeleteUser']);
84
	}
85
86
	public function preDeleteUser(IUser $user) {
87
		$this->currentUserInDeletionProcess = $user->getUID();
88
	}
89
90
	public function postDeleteUser() {
91
		$this->currentUserInDeletionProcess = null;
92
	}
93
94
	/**
95
	 * checks whether the user is allowed to change his avatar in Nextcloud
96
	 *
97
	 * @param string $uid the Nextcloud user name
98
	 * @return boolean either the user can or cannot
99
	 * @throws \Exception
100
	 */
101
	public function canChangeAvatar($uid) {
102
		if ($this->userPluginManager->implementsActions(Backend::PROVIDE_AVATAR)) {
103
			return $this->userPluginManager->canChangeAvatar($uid);
104
		}
105
106
		if(!$this->implementsActions(Backend::PROVIDE_AVATAR)) {
107
			return true;
108
		}
109
110
		$user = $this->access->userManager->get($uid);
111
		if(!$user instanceof User) {
112
			return false;
113
		}
114
		$imageData = $user->getAvatarImage();
115
		if($imageData === false) {
0 ignored issues
show
introduced by
The condition $imageData === false is always false.
Loading history...
116
			return true;
117
		}
118
		return !$user->updateAvatar(true);
119
	}
120
121
	/**
122
	 * Return the username for the given login name, if available
123
	 *
124
	 * @param string $loginName
125
	 * @return string|false
126
	 * @throws \Exception
127
	 */
128
	public function loginName2UserName($loginName) {
129
		$cacheKey = 'loginName2UserName-' . $loginName;
130
		$username = $this->access->connection->getFromCache($cacheKey);
131
132
		if ($username !== null) {
133
			return $username;
134
		}
135
136
		try {
137
			$ldapRecord = $this->getLDAPUserByLoginName($loginName);
138
			$user = $this->access->userManager->get($ldapRecord['dn'][0]);
139
			if ($user === null || $user instanceof OfflineUser) {
140
				// this path is not really possible, however get() is documented
141
				// to return User, OfflineUser or null so we are very defensive here.
142
				$this->access->connection->writeToCache($cacheKey, false);
143
				return false;
144
			}
145
			$username = $user->getUsername();
146
			$this->access->connection->writeToCache($cacheKey, $username);
147
			return $username;
148
		} catch (NotOnLDAP $e) {
149
			$this->access->connection->writeToCache($cacheKey, false);
150
			return false;
151
		}
152
	}
153
	
154
	/**
155
	 * returns the username for the given LDAP DN, if available
156
	 *
157
	 * @param string $dn
158
	 * @return string|false with the username
159
	 */
160
	public function dn2UserName($dn) {
161
		return $this->access->dn2username($dn);
162
	}
163
164
	/**
165
	 * returns an LDAP record based on a given login name
166
	 *
167
	 * @param string $loginName
168
	 * @return array
169
	 * @throws NotOnLDAP
170
	 */
171
	public function getLDAPUserByLoginName($loginName) {
172
		//find out dn of the user name
173
		$attrs = $this->access->userManager->getAttributes();
174
		$users = $this->access->fetchUsersByLoginName($loginName, $attrs);
175
		if(count($users) < 1) {
176
			throw new NotOnLDAP('No user available for the given login name on ' .
177
				$this->access->connection->ldapHost . ':' . $this->access->connection->ldapPort);
178
		}
179
		return $users[0];
180
	}
181
182
	/**
183
	 * Check if the password is correct without logging in the user
184
	 *
185
	 * @param string $uid The username
186
	 * @param string $password The password
187
	 * @return false|string
188
	 */
189
	public function checkPassword($uid, $password) {
190
		try {
191
			$ldapRecord = $this->getLDAPUserByLoginName($uid);
192
		} catch(NotOnLDAP $e) {
193
			\OC::$server->getLogger()->logException($e, ['app' => 'user_ldap', 'level' => ILogger::DEBUG]);
194
			return false;
195
		}
196
		$dn = $ldapRecord['dn'][0];
197
		$user = $this->access->userManager->get($dn);
198
199
		if(!$user instanceof User) {
200
			Util::writeLog('user_ldap',
0 ignored issues
show
Deprecated Code introduced by
The function OCP\Util::writeLog() has been deprecated: 13.0.0 use log of \OCP\ILogger ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

200
			/** @scrutinizer ignore-deprecated */ Util::writeLog('user_ldap',

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
201
				'LDAP Login: Could not get user object for DN ' . $dn .
202
				'. Maybe the LDAP entry has no set display name attribute?',
203
				ILogger::WARN);
204
			return false;
205
		}
206
		if($user->getUsername() !== false) {
0 ignored issues
show
introduced by
The condition $user->getUsername() !== false is always true.
Loading history...
207
			//are the credentials OK?
208
			if(!$this->access->areCredentialsValid($dn, $password)) {
209
				return false;
210
			}
211
212
			$this->access->cacheUserExists($user->getUsername());
213
			$user->processAttributes($ldapRecord);
214
			$user->markLogin();
215
216
			return $user->getUsername();
217
		}
218
219
		return false;
220
	}
221
222
	/**
223
	 * Set password
224
	 * @param string $uid The username
225
	 * @param string $password The new password
226
	 * @return bool
227
	 */
228
	public function setPassword($uid, $password) {
229
		if ($this->userPluginManager->implementsActions(Backend::SET_PASSWORD)) {
230
			return $this->userPluginManager->setPassword($uid, $password);
231
		}
232
233
		$user = $this->access->userManager->get($uid);
234
235
		if(!$user instanceof User) {
236
			throw new \Exception('LDAP setPassword: Could not get user object for uid ' . $uid .
237
				'. Maybe the LDAP entry has no set display name attribute?');
238
		}
239
		if($user->getUsername() !== false && $this->access->setPassword($user->getDN(), $password)) {
240
			$ldapDefaultPPolicyDN = $this->access->connection->ldapDefaultPPolicyDN;
0 ignored issues
show
Bug Best Practice introduced by
The property ldapDefaultPPolicyDN does not exist on OCA\User_LDAP\Connection. Since you implemented __get, consider adding a @property annotation.
Loading history...
241
			$turnOnPasswordChange = $this->access->connection->turnOnPasswordChange;
242
			if (!empty($ldapDefaultPPolicyDN) && ((int)$turnOnPasswordChange === 1)) {
243
				//remove last password expiry warning if any
244
				$notification = $this->notificationManager->createNotification();
245
				$notification->setApp('user_ldap')
246
					->setUser($uid)
247
					->setObject('pwd_exp_warn', $uid)
248
				;
249
				$this->notificationManager->markProcessed($notification);
250
			}
251
			return true;
252
		}
253
254
		return false;
255
	}
256
257
	/**
258
	 * Get a list of all users
259
	 *
260
	 * @param string $search
261
	 * @param integer $limit
262
	 * @param integer $offset
263
	 * @return string[] an array of all uids
264
	 */
265
	public function getUsers($search = '', $limit = 10, $offset = 0) {
266
		$search = $this->access->escapeFilterPart($search, true);
267
		$cachekey = 'getUsers-'.$search.'-'.$limit.'-'.$offset;
268
269
		//check if users are cached, if so return
270
		$ldap_users = $this->access->connection->getFromCache($cachekey);
271
		if(!is_null($ldap_users)) {
272
			return $ldap_users;
273
		}
274
275
		// if we'd pass -1 to LDAP search, we'd end up in a Protocol
276
		// error. With a limit of 0, we get 0 results. So we pass null.
277
		if($limit <= 0) {
278
			$limit = null;
279
		}
280
		$filter = $this->access->combineFilterWithAnd(array(
281
			$this->access->connection->ldapUserFilter,
282
			$this->access->connection->ldapUserDisplayName . '=*',
283
			$this->access->getFilterPartForUserSearch($search)
284
		));
285
286
		Util::writeLog('user_ldap',
0 ignored issues
show
Deprecated Code introduced by
The function OCP\Util::writeLog() has been deprecated: 13.0.0 use log of \OCP\ILogger ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

286
		/** @scrutinizer ignore-deprecated */ Util::writeLog('user_ldap',

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
287
			'getUsers: Options: search '.$search.' limit '.$limit.' offset '.$offset.' Filter: '.$filter,
288
			ILogger::DEBUG);
289
		//do the search and translate results to Nextcloud names
290
		$ldap_users = $this->access->fetchListOfUsers(
291
			$filter,
292
			$this->access->userManager->getAttributes(true),
293
			$limit, $offset);
294
		$ldap_users = $this->access->nextcloudUserNames($ldap_users);
295
		Util::writeLog('user_ldap', 'getUsers: '.count($ldap_users). ' Users found', ILogger::DEBUG);
0 ignored issues
show
Deprecated Code introduced by
The function OCP\Util::writeLog() has been deprecated: 13.0.0 use log of \OCP\ILogger ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

295
		/** @scrutinizer ignore-deprecated */ Util::writeLog('user_ldap', 'getUsers: '.count($ldap_users). ' Users found', ILogger::DEBUG);

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
296
297
		$this->access->connection->writeToCache($cachekey, $ldap_users);
298
		return $ldap_users;
299
	}
300
301
	/**
302
	 * checks whether a user is still available on LDAP
303
	 *
304
	 * @param string|\OCA\User_LDAP\User\User $user either the Nextcloud user
305
	 * name or an instance of that user
306
	 * @return bool
307
	 * @throws \Exception
308
	 * @throws \OC\ServerNotAvailableException
309
	 */
310
	public function userExistsOnLDAP($user) {
311
		if(is_string($user)) {
312
			$user = $this->access->userManager->get($user);
313
		}
314
		if(is_null($user)) {
315
			return false;
316
		}
317
318
		$dn = $user->getDN();
319
		//check if user really still exists by reading its entry
320
		if(!is_array($this->access->readAttribute($dn, '', $this->access->connection->ldapUserFilter))) {
321
			try {
322
				$uuid = $this->access->getUserMapper()->getUUIDByDN($dn);
323
				if (!$uuid) {
324
					return false;
325
				}
326
				$newDn = $this->access->getUserDnByUuid($uuid);
327
				//check if renamed user is still valid by reapplying the ldap filter
328
				if ($newDn === $dn || !is_array($this->access->readAttribute($newDn, '', $this->access->connection->ldapUserFilter))) {
329
					return false;
330
				}
331
				$this->access->getUserMapper()->setDNbyUUID($newDn, $uuid);
332
				return true;
333
			} catch (ServerNotAvailableException $e) {
334
				throw $e;
335
			} catch (\Exception $e) {
336
				return false;
337
			}
338
		}
339
340
		if($user instanceof OfflineUser) {
341
			$user->unmark();
342
		}
343
344
		return true;
345
	}
346
347
	/**
348
	 * check if a user exists
349
	 * @param string $uid the username
350
	 * @return boolean
351
	 * @throws \Exception when connection could not be established
352
	 */
353
	public function userExists($uid) {
354
		$userExists = $this->access->connection->getFromCache('userExists'.$uid);
355
		if(!is_null($userExists)) {
356
			return (bool)$userExists;
357
		}
358
		//getting dn, if false the user does not exist. If dn, he may be mapped only, requires more checking.
359
		$user = $this->access->userManager->get($uid);
360
361
		if(is_null($user)) {
362
			Util::writeLog('user_ldap', 'No DN found for '.$uid.' on '.
0 ignored issues
show
Deprecated Code introduced by
The function OCP\Util::writeLog() has been deprecated: 13.0.0 use log of \OCP\ILogger ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

362
			/** @scrutinizer ignore-deprecated */ Util::writeLog('user_ldap', 'No DN found for '.$uid.' on '.

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
363
				$this->access->connection->ldapHost, ILogger::DEBUG);
364
			$this->access->connection->writeToCache('userExists'.$uid, false);
365
			return false;
366
		} else if($user instanceof OfflineUser) {
367
			//express check for users marked as deleted. Returning true is
368
			//necessary for cleanup
369
			return true;
370
		}
371
372
		$result = $this->userExistsOnLDAP($user);
373
		$this->access->connection->writeToCache('userExists'.$uid, $result);
374
		return $result;
375
	}
376
377
	/**
378
	* returns whether a user was deleted in LDAP
379
	*
380
	* @param string $uid The username of the user to delete
381
	* @return bool
382
	*/
383
	public function deleteUser($uid) {
384
		if ($this->userPluginManager->canDeleteUser()) {
385
			return $this->userPluginManager->deleteUser($uid);
386
		}
387
388
		$marked = $this->ocConfig->getUserValue($uid, 'user_ldap', 'isDeleted', 0);
389
		if((int)$marked === 0) {
390
			\OC::$server->getLogger()->notice(
391
				'User '.$uid . ' is not marked as deleted, not cleaning up.',
392
				array('app' => 'user_ldap'));
393
			return false;
394
		}
395
		\OC::$server->getLogger()->info('Cleaning up after user ' . $uid,
396
			array('app' => 'user_ldap'));
397
398
		$this->access->getUserMapper()->unmap($uid); // we don't emit unassign signals here, since it is implicit to delete signals fired from core
399
		$this->access->userManager->invalidate($uid);
400
		return true;
401
	}
402
403
	/**
404
	 * get the user's home directory
405
	 *
406
	 * @param string $uid the username
407
	 * @return bool|string
408
	 * @throws NoUserException
409
	 * @throws \Exception
410
	 */
411
	public function getHome($uid) {
412
		// user Exists check required as it is not done in user proxy!
413
		if(!$this->userExists($uid)) {
414
			return false;
415
		}
416
417
		if ($this->userPluginManager->implementsActions(Backend::GET_HOME)) {
418
			return $this->userPluginManager->getHome($uid);
419
		}
420
421
		$cacheKey = 'getHome'.$uid;
422
		$path = $this->access->connection->getFromCache($cacheKey);
423
		if(!is_null($path)) {
424
			return $path;
425
		}
426
427
		// early return path if it is a deleted user
428
		$user = $this->access->userManager->get($uid);
429
		if($user instanceof OfflineUser) {
430
			if($this->currentUserInDeletionProcess !== null
431
				&& $this->currentUserInDeletionProcess === $user->getOCName()
432
			) {
433
				return $user->getHomePath();
434
			} else {
435
				throw new NoUserException($uid . ' is not a valid user anymore');
436
			}
437
		} else if ($user === null) {
438
			throw new NoUserException($uid . ' is not a valid user anymore');
439
		}
440
441
		$path = $user->getHomePath();
442
		$this->access->cacheUserHome($uid, $path);
443
444
		return $path;
445
	}
446
447
	/**
448
	 * get display name of the user
449
	 * @param string $uid user ID of the user
450
	 * @return string|false display name
451
	 */
452
	public function getDisplayName($uid) {
453
		if ($this->userPluginManager->implementsActions(Backend::GET_DISPLAYNAME)) {
454
			return $this->userPluginManager->getDisplayName($uid);
455
		}
456
457
		if(!$this->userExists($uid)) {
458
			return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the return type mandated by OCP\UserInterface::getDisplayName() of string.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
459
		}
460
461
		$cacheKey = 'getDisplayName'.$uid;
462
		if(!is_null($displayName = $this->access->connection->getFromCache($cacheKey))) {
463
			return $displayName;
464
		}
465
466
		//Check whether the display name is configured to have a 2nd feature
467
		$additionalAttribute = $this->access->connection->ldapUserDisplayName2;
468
		$displayName2 = '';
469
		if ($additionalAttribute !== '') {
470
			$displayName2 = $this->access->readAttribute(
471
				$this->access->username2dn($uid),
472
				$additionalAttribute);
473
		}
474
475
		$displayName = $this->access->readAttribute(
476
			$this->access->username2dn($uid),
477
			$this->access->connection->ldapUserDisplayName);
478
479
		if($displayName && (count($displayName) > 0)) {
480
			$displayName = $displayName[0];
481
482
			if (is_array($displayName2)){
483
				$displayName2 = count($displayName2) > 0 ? $displayName2[0] : '';
484
			}
485
486
			$user = $this->access->userManager->get($uid);
487
			if ($user instanceof User) {
488
				$displayName = $user->composeAndStoreDisplayName($displayName, $displayName2);
489
				$this->access->connection->writeToCache($cacheKey, $displayName);
490
			}
491
			if ($user instanceof OfflineUser) {
492
				/** @var OfflineUser $user*/
493
				$displayName = $user->getDisplayName();
494
			}
495
			return $displayName;
496
		}
497
498
		return null;
499
	}
500
501
	/**
502
	 * set display name of the user
503
	 * @param string $uid user ID of the user
504
	 * @param string $displayName new display name of the user
505
	 * @return string|false display name
506
	 */
507
	public function setDisplayName($uid, $displayName) {
508
		if ($this->userPluginManager->implementsActions(Backend::SET_DISPLAYNAME)) {
509
			return $this->userPluginManager->setDisplayName($uid, $displayName);
510
		}
511
		return false;
512
	}
513
514
	/**
515
	 * Get a list of all display names
516
	 *
517
	 * @param string $search
518
	 * @param string|null $limit
519
	 * @param string|null $offset
520
	 * @return array an array of all displayNames (value) and the corresponding uids (key)
521
	 */
522
	public function getDisplayNames($search = '', $limit = null, $offset = null) {
523
		$cacheKey = 'getDisplayNames-'.$search.'-'.$limit.'-'.$offset;
524
		if(!is_null($displayNames = $this->access->connection->getFromCache($cacheKey))) {
525
			return $displayNames;
526
		}
527
528
		$displayNames = array();
529
		$users = $this->getUsers($search, $limit, $offset);
530
		foreach ($users as $user) {
531
			$displayNames[$user] = $this->getDisplayName($user);
532
		}
533
		$this->access->connection->writeToCache($cacheKey, $displayNames);
534
		return $displayNames;
535
	}
536
537
	/**
538
	* Check if backend implements actions
539
	* @param int $actions bitwise-or'ed actions
540
	* @return boolean
541
	*
542
	* Returns the supported actions as int to be
543
	* compared with \OC\User\Backend::CREATE_USER etc.
544
	*/
545
	public function implementsActions($actions) {
546
		return (bool)((Backend::CHECK_PASSWORD
547
			| Backend::GET_HOME
548
			| Backend::GET_DISPLAYNAME
549
			| (($this->access->connection->ldapUserAvatarRule !== 'none') ? Backend::PROVIDE_AVATAR : 0)
550
			| Backend::COUNT_USERS
551
			| (((int)$this->access->connection->turnOnPasswordChange === 1)? Backend::SET_PASSWORD :0)
552
			| $this->userPluginManager->getImplementedActions())
553
			& $actions);
554
	}
555
556
	/**
557
	 * @return bool
558
	 */
559
	public function hasUserListings() {
560
		return true;
561
	}
562
563
	/**
564
	 * counts the users in LDAP
565
	 *
566
	 * @return int|bool
567
	 */
568
	public function countUsers() {
569
		if ($this->userPluginManager->implementsActions(Backend::COUNT_USERS)) {
570
			return $this->userPluginManager->countUsers();
571
		}
572
573
		$filter = $this->access->getFilterForUserCount();
574
		$cacheKey = 'countUsers-'.$filter;
575
		if(!is_null($entries = $this->access->connection->getFromCache($cacheKey))) {
576
			return $entries;
577
		}
578
		$entries = $this->access->countUsers($filter);
579
		$this->access->connection->writeToCache($cacheKey, $entries);
580
		return $entries;
581
	}
582
583
	/**
584
	 * Backend name to be shown in user management
585
	 * @return string the name of the backend to be shown
586
	 */
587
	public function getBackendName(){
588
		return 'LDAP';
589
	}
590
	
591
	/**
592
	 * Return access for LDAP interaction.
593
	 * @param string $uid
594
	 * @return Access instance of Access for LDAP interaction
595
	 */
596
	public function getLDAPAccess($uid) {
597
		return $this->access;
598
	}
599
	
600
	/**
601
	 * Return LDAP connection resource from a cloned connection.
602
	 * The cloned connection needs to be closed manually.
603
	 * of the current access.
604
	 * @param string $uid
605
	 * @return resource of the LDAP connection
606
	 */
607
	public function getNewLDAPConnection($uid) {
608
		$connection = clone $this->access->getConnection();
609
		return $connection->getConnectionResource();
610
	}
611
612
	/**
613
	 * create new user
614
	 * @param string $username username of the new user
615
	 * @param string $password password of the new user
616
	 * @throws \UnexpectedValueException
617
	 * @return bool
618
	 */
619
	public function createUser($username, $password) {
620
		if ($this->userPluginManager->implementsActions(Backend::CREATE_USER)) {
621
			if ($dn = $this->userPluginManager->createUser($username, $password)) {
622
				if (is_string($dn)) {
0 ignored issues
show
introduced by
The condition is_string($dn) is always true.
Loading history...
623
					//updates user mapping
624
					$this->access->dn2ocname($dn, $username, true);
625
				} else {
626
					throw new \UnexpectedValueException("LDAP Plugin: Method createUser changed to return the user DN instead of boolean.");
627
				}
628
			}
629
			return (bool) $dn;
630
		}
631
		return false;
632
	}
633
634
}
635