Completed
Push — stable13 ( cc09db...73c1fa )
by Morris
87:47 queued 55:22
created
apps/user_ldap/lib/User_LDAP.php 2 patches
Indentation   +574 added lines, -574 removed lines patch added patch discarded remove patch
@@ -51,582 +51,582 @@
 block discarded – undo
51 51
 use OCP\Util;
52 52
 
53 53
 class User_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserInterface, IUserLDAP {
54
-	/** @var \OCP\IConfig */
55
-	protected $ocConfig;
56
-
57
-	/** @var INotificationManager */
58
-	protected $notificationManager;
59
-
60
-	/** @var string */
61
-	protected $currentUserInDeletionProcess;
62
-
63
-	/** @var UserPluginManager */
64
-	protected $userPluginManager;
65
-
66
-	/**
67
-	 * @param Access $access
68
-	 * @param \OCP\IConfig $ocConfig
69
-	 * @param \OCP\Notification\IManager $notificationManager
70
-	 * @param IUserSession $userSession
71
-	 */
72
-	public function __construct(Access $access, IConfig $ocConfig, INotificationManager $notificationManager, IUserSession $userSession, UserPluginManager $userPluginManager) {
73
-		parent::__construct($access);
74
-		$this->ocConfig = $ocConfig;
75
-		$this->notificationManager = $notificationManager;
76
-		$this->userPluginManager = $userPluginManager;
77
-		$this->registerHooks($userSession);
78
-	}
79
-
80
-	protected function registerHooks(IUserSession $userSession) {
81
-		$userSession->listen('\OC\User', 'preDelete', [$this, 'preDeleteUser']);
82
-		$userSession->listen('\OC\User', 'postDelete', [$this, 'postDeleteUser']);
83
-	}
84
-
85
-	public function preDeleteUser(IUser $user) {
86
-		$this->currentUserInDeletionProcess = $user->getUID();
87
-	}
88
-
89
-	public function postDeleteUser() {
90
-		$this->currentUserInDeletionProcess = null;
91
-	}
92
-
93
-	/**
94
-	 * checks whether the user is allowed to change his avatar in Nextcloud
95
-	 *
96
-	 * @param string $uid the Nextcloud user name
97
-	 * @return boolean either the user can or cannot
98
-	 * @throws \Exception
99
-	 */
100
-	public function canChangeAvatar($uid) {
101
-		if ($this->userPluginManager->implementsActions(Backend::PROVIDE_AVATAR)) {
102
-			return $this->userPluginManager->canChangeAvatar($uid);
103
-		}
104
-
105
-		if(!$this->implementsActions(Backend::PROVIDE_AVATAR)) {
106
-			return true;
107
-		}
108
-
109
-		$user = $this->access->userManager->get($uid);
110
-		if(!$user instanceof User) {
111
-			return false;
112
-		}
113
-		$imageData = $user->getAvatarImage();
114
-		if($imageData === false) {
115
-			return true;
116
-		}
117
-		return !$user->updateAvatar(true);
118
-	}
119
-
120
-	/**
121
-	 * returns the username for the given login name, if available
122
-	 *
123
-	 * @param string $loginName
124
-	 * @return string|false
125
-	 */
126
-	public function loginName2UserName($loginName) {
127
-		$cacheKey = 'loginName2UserName-'.$loginName;
128
-		$username = $this->access->connection->getFromCache($cacheKey);
129
-		if(!is_null($username)) {
130
-			return $username;
131
-		}
132
-
133
-		try {
134
-			$ldapRecord = $this->getLDAPUserByLoginName($loginName);
135
-			$user = $this->access->userManager->get($ldapRecord['dn'][0]);
136
-			if($user instanceof OfflineUser) {
137
-				// this path is not really possible, however get() is documented
138
-				// to return User or OfflineUser so we are very defensive here.
139
-				$this->access->connection->writeToCache($cacheKey, false);
140
-				return false;
141
-			}
142
-			$username = $user->getUsername();
143
-			$this->access->connection->writeToCache($cacheKey, $username);
144
-			return $username;
145
-		} catch (NotOnLDAP $e) {
146
-			$this->access->connection->writeToCache($cacheKey, false);
147
-			return false;
148
-		}
149
-	}
54
+    /** @var \OCP\IConfig */
55
+    protected $ocConfig;
56
+
57
+    /** @var INotificationManager */
58
+    protected $notificationManager;
59
+
60
+    /** @var string */
61
+    protected $currentUserInDeletionProcess;
62
+
63
+    /** @var UserPluginManager */
64
+    protected $userPluginManager;
65
+
66
+    /**
67
+     * @param Access $access
68
+     * @param \OCP\IConfig $ocConfig
69
+     * @param \OCP\Notification\IManager $notificationManager
70
+     * @param IUserSession $userSession
71
+     */
72
+    public function __construct(Access $access, IConfig $ocConfig, INotificationManager $notificationManager, IUserSession $userSession, UserPluginManager $userPluginManager) {
73
+        parent::__construct($access);
74
+        $this->ocConfig = $ocConfig;
75
+        $this->notificationManager = $notificationManager;
76
+        $this->userPluginManager = $userPluginManager;
77
+        $this->registerHooks($userSession);
78
+    }
79
+
80
+    protected function registerHooks(IUserSession $userSession) {
81
+        $userSession->listen('\OC\User', 'preDelete', [$this, 'preDeleteUser']);
82
+        $userSession->listen('\OC\User', 'postDelete', [$this, 'postDeleteUser']);
83
+    }
84
+
85
+    public function preDeleteUser(IUser $user) {
86
+        $this->currentUserInDeletionProcess = $user->getUID();
87
+    }
88
+
89
+    public function postDeleteUser() {
90
+        $this->currentUserInDeletionProcess = null;
91
+    }
92
+
93
+    /**
94
+     * checks whether the user is allowed to change his avatar in Nextcloud
95
+     *
96
+     * @param string $uid the Nextcloud user name
97
+     * @return boolean either the user can or cannot
98
+     * @throws \Exception
99
+     */
100
+    public function canChangeAvatar($uid) {
101
+        if ($this->userPluginManager->implementsActions(Backend::PROVIDE_AVATAR)) {
102
+            return $this->userPluginManager->canChangeAvatar($uid);
103
+        }
104
+
105
+        if(!$this->implementsActions(Backend::PROVIDE_AVATAR)) {
106
+            return true;
107
+        }
108
+
109
+        $user = $this->access->userManager->get($uid);
110
+        if(!$user instanceof User) {
111
+            return false;
112
+        }
113
+        $imageData = $user->getAvatarImage();
114
+        if($imageData === false) {
115
+            return true;
116
+        }
117
+        return !$user->updateAvatar(true);
118
+    }
119
+
120
+    /**
121
+     * returns the username for the given login name, if available
122
+     *
123
+     * @param string $loginName
124
+     * @return string|false
125
+     */
126
+    public function loginName2UserName($loginName) {
127
+        $cacheKey = 'loginName2UserName-'.$loginName;
128
+        $username = $this->access->connection->getFromCache($cacheKey);
129
+        if(!is_null($username)) {
130
+            return $username;
131
+        }
132
+
133
+        try {
134
+            $ldapRecord = $this->getLDAPUserByLoginName($loginName);
135
+            $user = $this->access->userManager->get($ldapRecord['dn'][0]);
136
+            if($user instanceof OfflineUser) {
137
+                // this path is not really possible, however get() is documented
138
+                // to return User or OfflineUser so we are very defensive here.
139
+                $this->access->connection->writeToCache($cacheKey, false);
140
+                return false;
141
+            }
142
+            $username = $user->getUsername();
143
+            $this->access->connection->writeToCache($cacheKey, $username);
144
+            return $username;
145
+        } catch (NotOnLDAP $e) {
146
+            $this->access->connection->writeToCache($cacheKey, false);
147
+            return false;
148
+        }
149
+    }
150 150
 	
151
-	/**
152
-	 * returns the username for the given LDAP DN, if available
153
-	 *
154
-	 * @param string $dn
155
-	 * @return string|false with the username
156
-	 */
157
-	public function dn2UserName($dn) {
158
-		return $this->access->dn2username($dn);
159
-	}
160
-
161
-	/**
162
-	 * returns an LDAP record based on a given login name
163
-	 *
164
-	 * @param string $loginName
165
-	 * @return array
166
-	 * @throws NotOnLDAP
167
-	 */
168
-	public function getLDAPUserByLoginName($loginName) {
169
-		//find out dn of the user name
170
-		$attrs = $this->access->userManager->getAttributes();
171
-		$users = $this->access->fetchUsersByLoginName($loginName, $attrs);
172
-		if(count($users) < 1) {
173
-			throw new NotOnLDAP('No user available for the given login name on ' .
174
-				$this->access->connection->ldapHost . ':' . $this->access->connection->ldapPort);
175
-		}
176
-		return $users[0];
177
-	}
178
-
179
-	/**
180
-	 * Check if the password is correct without logging in the user
181
-	 *
182
-	 * @param string $uid The username
183
-	 * @param string $password The password
184
-	 * @return false|string
185
-	 */
186
-	public function checkPassword($uid, $password) {
187
-		try {
188
-			$ldapRecord = $this->getLDAPUserByLoginName($uid);
189
-		} catch(NotOnLDAP $e) {
190
-			if($this->ocConfig->getSystemValue('loglevel', Util::WARN) === Util::DEBUG) {
191
-				\OC::$server->getLogger()->logException($e, ['app' => 'user_ldap']);
192
-			}
193
-			return false;
194
-		}
195
-		$dn = $ldapRecord['dn'][0];
196
-		$user = $this->access->userManager->get($dn);
197
-
198
-		if(!$user instanceof User) {
199
-			Util::writeLog('user_ldap',
200
-				'LDAP Login: Could not get user object for DN ' . $dn .
201
-				'. Maybe the LDAP entry has no set display name attribute?',
202
-				Util::WARN);
203
-			return false;
204
-		}
205
-		if($user->getUsername() !== false) {
206
-			//are the credentials OK?
207
-			if(!$this->access->areCredentialsValid($dn, $password)) {
208
-				return false;
209
-			}
210
-
211
-			$this->access->cacheUserExists($user->getUsername());
212
-			$user->processAttributes($ldapRecord);
213
-			$user->markLogin();
214
-
215
-			return $user->getUsername();
216
-		}
217
-
218
-		return false;
219
-	}
220
-
221
-	/**
222
-	 * Set password
223
-	 * @param string $uid The username
224
-	 * @param string $password The new password
225
-	 * @return bool
226
-	 */
227
-	public function setPassword($uid, $password) {
228
-		if ($this->userPluginManager->implementsActions(Backend::SET_PASSWORD)) {
229
-			return $this->userPluginManager->setPassword($uid, $password);
230
-		}
231
-
232
-		$user = $this->access->userManager->get($uid);
233
-
234
-		if(!$user instanceof User) {
235
-			throw new \Exception('LDAP setPassword: Could not get user object for uid ' . $uid .
236
-				'. Maybe the LDAP entry has no set display name attribute?');
237
-		}
238
-		if($user->getUsername() !== false && $this->access->setPassword($user->getDN(), $password)) {
239
-			$ldapDefaultPPolicyDN = $this->access->connection->ldapDefaultPPolicyDN;
240
-			$turnOnPasswordChange = $this->access->connection->turnOnPasswordChange;
241
-			if (!empty($ldapDefaultPPolicyDN) && (intval($turnOnPasswordChange) === 1)) {
242
-				//remove last password expiry warning if any
243
-				$notification = $this->notificationManager->createNotification();
244
-				$notification->setApp('user_ldap')
245
-					->setUser($uid)
246
-					->setObject('pwd_exp_warn', $uid)
247
-				;
248
-				$this->notificationManager->markProcessed($notification);
249
-			}
250
-			return true;
251
-		}
252
-
253
-		return false;
254
-	}
255
-
256
-	/**
257
-	 * Get a list of all users
258
-	 *
259
-	 * @param string $search
260
-	 * @param integer $limit
261
-	 * @param integer $offset
262
-	 * @return string[] an array of all uids
263
-	 */
264
-	public function getUsers($search = '', $limit = 10, $offset = 0) {
265
-		$search = $this->access->escapeFilterPart($search, true);
266
-		$cachekey = 'getUsers-'.$search.'-'.$limit.'-'.$offset;
267
-
268
-		//check if users are cached, if so return
269
-		$ldap_users = $this->access->connection->getFromCache($cachekey);
270
-		if(!is_null($ldap_users)) {
271
-			return $ldap_users;
272
-		}
273
-
274
-		// if we'd pass -1 to LDAP search, we'd end up in a Protocol
275
-		// error. With a limit of 0, we get 0 results. So we pass null.
276
-		if($limit <= 0) {
277
-			$limit = null;
278
-		}
279
-		$filter = $this->access->combineFilterWithAnd(array(
280
-			$this->access->connection->ldapUserFilter,
281
-			$this->access->connection->ldapUserDisplayName . '=*',
282
-			$this->access->getFilterPartForUserSearch($search)
283
-		));
284
-
285
-		Util::writeLog('user_ldap',
286
-			'getUsers: Options: search '.$search.' limit '.$limit.' offset '.$offset.' Filter: '.$filter,
287
-			Util::DEBUG);
288
-		//do the search and translate results to Nextcloud names
289
-		$ldap_users = $this->access->fetchListOfUsers(
290
-			$filter,
291
-			$this->access->userManager->getAttributes(true),
292
-			$limit, $offset);
293
-		$ldap_users = $this->access->nextcloudUserNames($ldap_users);
294
-		Util::writeLog('user_ldap', 'getUsers: '.count($ldap_users). ' Users found', Util::DEBUG);
295
-
296
-		$this->access->connection->writeToCache($cachekey, $ldap_users);
297
-		return $ldap_users;
298
-	}
299
-
300
-	/**
301
-	 * checks whether a user is still available on LDAP
302
-	 *
303
-	 * @param string|\OCA\User_LDAP\User\User $user either the Nextcloud user
304
-	 * name or an instance of that user
305
-	 * @return bool
306
-	 * @throws \Exception
307
-	 * @throws \OC\ServerNotAvailableException
308
-	 */
309
-	public function userExistsOnLDAP($user) {
310
-		if(is_string($user)) {
311
-			$user = $this->access->userManager->get($user);
312
-		}
313
-		if(is_null($user)) {
314
-			return false;
315
-		}
316
-
317
-		$dn = $user->getDN();
318
-		//check if user really still exists by reading its entry
319
-		if(!is_array($this->access->readAttribute($dn, '', $this->access->connection->ldapUserFilter))) {
320
-			$lcr = $this->access->connection->getConnectionResource();
321
-			if(is_null($lcr)) {
322
-				throw new \Exception('No LDAP Connection to server ' . $this->access->connection->ldapHost);
323
-			}
324
-
325
-			try {
326
-				$uuid = $this->access->getUserMapper()->getUUIDByDN($dn);
327
-				if (!$uuid) {
328
-					return false;
329
-				}
330
-				$newDn = $this->access->getUserDnByUuid($uuid);
331
-				//check if renamed user is still valid by reapplying the ldap filter
332
-				if (!is_array($this->access->readAttribute($newDn, '', $this->access->connection->ldapUserFilter))) {
333
-					return false;
334
-				}
335
-				$this->access->getUserMapper()->setDNbyUUID($newDn, $uuid);
336
-				return true;
337
-			} catch (ServerNotAvailableException $e) {
338
-				throw $e;
339
-			} catch (\Exception $e) {
340
-				return false;
341
-			}
342
-		}
343
-
344
-		if($user instanceof OfflineUser) {
345
-			$user->unmark();
346
-		}
347
-
348
-		return true;
349
-	}
350
-
351
-	/**
352
-	 * check if a user exists
353
-	 * @param string $uid the username
354
-	 * @return boolean
355
-	 * @throws \Exception when connection could not be established
356
-	 */
357
-	public function userExists($uid) {
358
-		$userExists = $this->access->connection->getFromCache('userExists'.$uid);
359
-		if(!is_null($userExists)) {
360
-			return (bool)$userExists;
361
-		}
362
-		//getting dn, if false the user does not exist. If dn, he may be mapped only, requires more checking.
363
-		$user = $this->access->userManager->get($uid);
364
-
365
-		if(is_null($user)) {
366
-			Util::writeLog('user_ldap', 'No DN found for '.$uid.' on '.
367
-				$this->access->connection->ldapHost, Util::DEBUG);
368
-			$this->access->connection->writeToCache('userExists'.$uid, false);
369
-			return false;
370
-		} else if($user instanceof OfflineUser) {
371
-			//express check for users marked as deleted. Returning true is
372
-			//necessary for cleanup
373
-			return true;
374
-		}
375
-
376
-		$result = $this->userExistsOnLDAP($user);
377
-		$this->access->connection->writeToCache('userExists'.$uid, $result);
378
-		if($result === true) {
379
-			$user->update();
380
-		}
381
-		return $result;
382
-	}
383
-
384
-	/**
385
-	* returns whether a user was deleted in LDAP
386
-	*
387
-	* @param string $uid The username of the user to delete
388
-	* @return bool
389
-	*/
390
-	public function deleteUser($uid) {
391
-		if ($this->userPluginManager->canDeleteUser()) {
392
-			return $this->userPluginManager->deleteUser($uid);
393
-		}
394
-
395
-		$marked = $this->ocConfig->getUserValue($uid, 'user_ldap', 'isDeleted', 0);
396
-		if(intval($marked) === 0) {
397
-			\OC::$server->getLogger()->notice(
398
-				'User '.$uid . ' is not marked as deleted, not cleaning up.',
399
-				array('app' => 'user_ldap'));
400
-			return false;
401
-		}
402
-		\OC::$server->getLogger()->info('Cleaning up after user ' . $uid,
403
-			array('app' => 'user_ldap'));
404
-
405
-		$this->access->getUserMapper()->unmap($uid);
406
-		$this->access->userManager->invalidate($uid);
407
-		return true;
408
-	}
409
-
410
-	/**
411
-	 * get the user's home directory
412
-	 *
413
-	 * @param string $uid the username
414
-	 * @return bool|string
415
-	 * @throws NoUserException
416
-	 * @throws \Exception
417
-	 */
418
-	public function getHome($uid) {
419
-		// user Exists check required as it is not done in user proxy!
420
-		if(!$this->userExists($uid)) {
421
-			return false;
422
-		}
423
-
424
-		if ($this->userPluginManager->implementsActions(Backend::GET_HOME)) {
425
-			return $this->userPluginManager->getHome($uid);
426
-		}
427
-
428
-		$cacheKey = 'getHome'.$uid;
429
-		$path = $this->access->connection->getFromCache($cacheKey);
430
-		if(!is_null($path)) {
431
-			return $path;
432
-		}
433
-
434
-		// early return path if it is a deleted user
435
-		$user = $this->access->userManager->get($uid);
436
-		if($user instanceof OfflineUser) {
437
-			if($this->currentUserInDeletionProcess !== null
438
-				&& $this->currentUserInDeletionProcess === $user->getOCName()
439
-			) {
440
-				return $user->getHomePath();
441
-			} else {
442
-				throw new NoUserException($uid . ' is not a valid user anymore');
443
-			}
444
-		} else if ($user === null) {
445
-			throw new NoUserException($uid . ' is not a valid user anymore');
446
-		}
447
-
448
-		$path = $user->getHomePath();
449
-		$this->access->cacheUserHome($uid, $path);
450
-
451
-		return $path;
452
-	}
453
-
454
-	/**
455
-	 * get display name of the user
456
-	 * @param string $uid user ID of the user
457
-	 * @return string|false display name
458
-	 */
459
-	public function getDisplayName($uid) {
460
-		if ($this->userPluginManager->implementsActions(Backend::GET_DISPLAYNAME)) {
461
-			return $this->userPluginManager->getDisplayName($uid);
462
-		}
463
-
464
-		if(!$this->userExists($uid)) {
465
-			return false;
466
-		}
467
-
468
-		$cacheKey = 'getDisplayName'.$uid;
469
-		if(!is_null($displayName = $this->access->connection->getFromCache($cacheKey))) {
470
-			return $displayName;
471
-		}
472
-
473
-		//Check whether the display name is configured to have a 2nd feature
474
-		$additionalAttribute = $this->access->connection->ldapUserDisplayName2;
475
-		$displayName2 = '';
476
-		if ($additionalAttribute !== '') {
477
-			$displayName2 = $this->access->readAttribute(
478
-				$this->access->username2dn($uid),
479
-				$additionalAttribute);
480
-		}
481
-
482
-		$displayName = $this->access->readAttribute(
483
-			$this->access->username2dn($uid),
484
-			$this->access->connection->ldapUserDisplayName);
485
-
486
-		if($displayName && (count($displayName) > 0)) {
487
-			$displayName = $displayName[0];
488
-
489
-			if (is_array($displayName2)){
490
-				$displayName2 = count($displayName2) > 0 ? $displayName2[0] : '';
491
-			}
492
-
493
-			$user = $this->access->userManager->get($uid);
494
-			if ($user instanceof User) {
495
-				$displayName = $user->composeAndStoreDisplayName($displayName, $displayName2);
496
-				$this->access->connection->writeToCache($cacheKey, $displayName);
497
-			}
498
-			if ($user instanceof OfflineUser) {
499
-				/** @var OfflineUser $user*/
500
-				$displayName = $user->getDisplayName();
501
-			}
502
-			return $displayName;
503
-		}
504
-
505
-		return null;
506
-	}
507
-
508
-	/**
509
-	 * set display name of the user
510
-	 * @param string $uid user ID of the user
511
-	 * @param string $displayName new display name of the user
512
-	 * @return string|false display name
513
-	 */
514
-	public function setDisplayName($uid, $displayName) {
515
-		if ($this->userPluginManager->implementsActions(Backend::SET_DISPLAYNAME)) {
516
-			return $this->userPluginManager->setDisplayName($uid, $displayName);
517
-		}
518
-		return false;
519
-	}
520
-
521
-	/**
522
-	 * Get a list of all display names
523
-	 *
524
-	 * @param string $search
525
-	 * @param string|null $limit
526
-	 * @param string|null $offset
527
-	 * @return array an array of all displayNames (value) and the corresponding uids (key)
528
-	 */
529
-	public function getDisplayNames($search = '', $limit = null, $offset = null) {
530
-		$cacheKey = 'getDisplayNames-'.$search.'-'.$limit.'-'.$offset;
531
-		if(!is_null($displayNames = $this->access->connection->getFromCache($cacheKey))) {
532
-			return $displayNames;
533
-		}
534
-
535
-		$displayNames = array();
536
-		$users = $this->getUsers($search, $limit, $offset);
537
-		foreach ($users as $user) {
538
-			$displayNames[$user] = $this->getDisplayName($user);
539
-		}
540
-		$this->access->connection->writeToCache($cacheKey, $displayNames);
541
-		return $displayNames;
542
-	}
543
-
544
-	/**
545
-	* Check if backend implements actions
546
-	* @param int $actions bitwise-or'ed actions
547
-	* @return boolean
548
-	*
549
-	* Returns the supported actions as int to be
550
-	* compared with \OC\User\Backend::CREATE_USER etc.
551
-	*/
552
-	public function implementsActions($actions) {
553
-		return (bool)((Backend::CHECK_PASSWORD
554
-			| Backend::GET_HOME
555
-			| Backend::GET_DISPLAYNAME
556
-			| (($this->access->connection->ldapUserAvatarRule !== 'none') ? Backend::PROVIDE_AVATAR : 0)
557
-			| Backend::COUNT_USERS
558
-			| ((intval($this->access->connection->turnOnPasswordChange) === 1)?(Backend::SET_PASSWORD):0)
559
-			| $this->userPluginManager->getImplementedActions())
560
-			& $actions);
561
-	}
562
-
563
-	/**
564
-	 * @return bool
565
-	 */
566
-	public function hasUserListings() {
567
-		return true;
568
-	}
569
-
570
-	/**
571
-	 * counts the users in LDAP
572
-	 *
573
-	 * @return int|bool
574
-	 */
575
-	public function countUsers() {
576
-		if ($this->userPluginManager->implementsActions(Backend::COUNT_USERS)) {
577
-			return $this->userPluginManager->countUsers();
578
-		}
579
-
580
-		$filter = $this->access->getFilterForUserCount();
581
-		$cacheKey = 'countUsers-'.$filter;
582
-		if(!is_null($entries = $this->access->connection->getFromCache($cacheKey))) {
583
-			return $entries;
584
-		}
585
-		$entries = $this->access->countUsers($filter);
586
-		$this->access->connection->writeToCache($cacheKey, $entries);
587
-		return $entries;
588
-	}
589
-
590
-	/**
591
-	 * Backend name to be shown in user management
592
-	 * @return string the name of the backend to be shown
593
-	 */
594
-	public function getBackendName(){
595
-		return 'LDAP';
596
-	}
151
+    /**
152
+     * returns the username for the given LDAP DN, if available
153
+     *
154
+     * @param string $dn
155
+     * @return string|false with the username
156
+     */
157
+    public function dn2UserName($dn) {
158
+        return $this->access->dn2username($dn);
159
+    }
160
+
161
+    /**
162
+     * returns an LDAP record based on a given login name
163
+     *
164
+     * @param string $loginName
165
+     * @return array
166
+     * @throws NotOnLDAP
167
+     */
168
+    public function getLDAPUserByLoginName($loginName) {
169
+        //find out dn of the user name
170
+        $attrs = $this->access->userManager->getAttributes();
171
+        $users = $this->access->fetchUsersByLoginName($loginName, $attrs);
172
+        if(count($users) < 1) {
173
+            throw new NotOnLDAP('No user available for the given login name on ' .
174
+                $this->access->connection->ldapHost . ':' . $this->access->connection->ldapPort);
175
+        }
176
+        return $users[0];
177
+    }
178
+
179
+    /**
180
+     * Check if the password is correct without logging in the user
181
+     *
182
+     * @param string $uid The username
183
+     * @param string $password The password
184
+     * @return false|string
185
+     */
186
+    public function checkPassword($uid, $password) {
187
+        try {
188
+            $ldapRecord = $this->getLDAPUserByLoginName($uid);
189
+        } catch(NotOnLDAP $e) {
190
+            if($this->ocConfig->getSystemValue('loglevel', Util::WARN) === Util::DEBUG) {
191
+                \OC::$server->getLogger()->logException($e, ['app' => 'user_ldap']);
192
+            }
193
+            return false;
194
+        }
195
+        $dn = $ldapRecord['dn'][0];
196
+        $user = $this->access->userManager->get($dn);
197
+
198
+        if(!$user instanceof User) {
199
+            Util::writeLog('user_ldap',
200
+                'LDAP Login: Could not get user object for DN ' . $dn .
201
+                '. Maybe the LDAP entry has no set display name attribute?',
202
+                Util::WARN);
203
+            return false;
204
+        }
205
+        if($user->getUsername() !== false) {
206
+            //are the credentials OK?
207
+            if(!$this->access->areCredentialsValid($dn, $password)) {
208
+                return false;
209
+            }
210
+
211
+            $this->access->cacheUserExists($user->getUsername());
212
+            $user->processAttributes($ldapRecord);
213
+            $user->markLogin();
214
+
215
+            return $user->getUsername();
216
+        }
217
+
218
+        return false;
219
+    }
220
+
221
+    /**
222
+     * Set password
223
+     * @param string $uid The username
224
+     * @param string $password The new password
225
+     * @return bool
226
+     */
227
+    public function setPassword($uid, $password) {
228
+        if ($this->userPluginManager->implementsActions(Backend::SET_PASSWORD)) {
229
+            return $this->userPluginManager->setPassword($uid, $password);
230
+        }
231
+
232
+        $user = $this->access->userManager->get($uid);
233
+
234
+        if(!$user instanceof User) {
235
+            throw new \Exception('LDAP setPassword: Could not get user object for uid ' . $uid .
236
+                '. Maybe the LDAP entry has no set display name attribute?');
237
+        }
238
+        if($user->getUsername() !== false && $this->access->setPassword($user->getDN(), $password)) {
239
+            $ldapDefaultPPolicyDN = $this->access->connection->ldapDefaultPPolicyDN;
240
+            $turnOnPasswordChange = $this->access->connection->turnOnPasswordChange;
241
+            if (!empty($ldapDefaultPPolicyDN) && (intval($turnOnPasswordChange) === 1)) {
242
+                //remove last password expiry warning if any
243
+                $notification = $this->notificationManager->createNotification();
244
+                $notification->setApp('user_ldap')
245
+                    ->setUser($uid)
246
+                    ->setObject('pwd_exp_warn', $uid)
247
+                ;
248
+                $this->notificationManager->markProcessed($notification);
249
+            }
250
+            return true;
251
+        }
252
+
253
+        return false;
254
+    }
255
+
256
+    /**
257
+     * Get a list of all users
258
+     *
259
+     * @param string $search
260
+     * @param integer $limit
261
+     * @param integer $offset
262
+     * @return string[] an array of all uids
263
+     */
264
+    public function getUsers($search = '', $limit = 10, $offset = 0) {
265
+        $search = $this->access->escapeFilterPart($search, true);
266
+        $cachekey = 'getUsers-'.$search.'-'.$limit.'-'.$offset;
267
+
268
+        //check if users are cached, if so return
269
+        $ldap_users = $this->access->connection->getFromCache($cachekey);
270
+        if(!is_null($ldap_users)) {
271
+            return $ldap_users;
272
+        }
273
+
274
+        // if we'd pass -1 to LDAP search, we'd end up in a Protocol
275
+        // error. With a limit of 0, we get 0 results. So we pass null.
276
+        if($limit <= 0) {
277
+            $limit = null;
278
+        }
279
+        $filter = $this->access->combineFilterWithAnd(array(
280
+            $this->access->connection->ldapUserFilter,
281
+            $this->access->connection->ldapUserDisplayName . '=*',
282
+            $this->access->getFilterPartForUserSearch($search)
283
+        ));
284
+
285
+        Util::writeLog('user_ldap',
286
+            'getUsers: Options: search '.$search.' limit '.$limit.' offset '.$offset.' Filter: '.$filter,
287
+            Util::DEBUG);
288
+        //do the search and translate results to Nextcloud names
289
+        $ldap_users = $this->access->fetchListOfUsers(
290
+            $filter,
291
+            $this->access->userManager->getAttributes(true),
292
+            $limit, $offset);
293
+        $ldap_users = $this->access->nextcloudUserNames($ldap_users);
294
+        Util::writeLog('user_ldap', 'getUsers: '.count($ldap_users). ' Users found', Util::DEBUG);
295
+
296
+        $this->access->connection->writeToCache($cachekey, $ldap_users);
297
+        return $ldap_users;
298
+    }
299
+
300
+    /**
301
+     * checks whether a user is still available on LDAP
302
+     *
303
+     * @param string|\OCA\User_LDAP\User\User $user either the Nextcloud user
304
+     * name or an instance of that user
305
+     * @return bool
306
+     * @throws \Exception
307
+     * @throws \OC\ServerNotAvailableException
308
+     */
309
+    public function userExistsOnLDAP($user) {
310
+        if(is_string($user)) {
311
+            $user = $this->access->userManager->get($user);
312
+        }
313
+        if(is_null($user)) {
314
+            return false;
315
+        }
316
+
317
+        $dn = $user->getDN();
318
+        //check if user really still exists by reading its entry
319
+        if(!is_array($this->access->readAttribute($dn, '', $this->access->connection->ldapUserFilter))) {
320
+            $lcr = $this->access->connection->getConnectionResource();
321
+            if(is_null($lcr)) {
322
+                throw new \Exception('No LDAP Connection to server ' . $this->access->connection->ldapHost);
323
+            }
324
+
325
+            try {
326
+                $uuid = $this->access->getUserMapper()->getUUIDByDN($dn);
327
+                if (!$uuid) {
328
+                    return false;
329
+                }
330
+                $newDn = $this->access->getUserDnByUuid($uuid);
331
+                //check if renamed user is still valid by reapplying the ldap filter
332
+                if (!is_array($this->access->readAttribute($newDn, '', $this->access->connection->ldapUserFilter))) {
333
+                    return false;
334
+                }
335
+                $this->access->getUserMapper()->setDNbyUUID($newDn, $uuid);
336
+                return true;
337
+            } catch (ServerNotAvailableException $e) {
338
+                throw $e;
339
+            } catch (\Exception $e) {
340
+                return false;
341
+            }
342
+        }
343
+
344
+        if($user instanceof OfflineUser) {
345
+            $user->unmark();
346
+        }
347
+
348
+        return true;
349
+    }
350
+
351
+    /**
352
+     * check if a user exists
353
+     * @param string $uid the username
354
+     * @return boolean
355
+     * @throws \Exception when connection could not be established
356
+     */
357
+    public function userExists($uid) {
358
+        $userExists = $this->access->connection->getFromCache('userExists'.$uid);
359
+        if(!is_null($userExists)) {
360
+            return (bool)$userExists;
361
+        }
362
+        //getting dn, if false the user does not exist. If dn, he may be mapped only, requires more checking.
363
+        $user = $this->access->userManager->get($uid);
364
+
365
+        if(is_null($user)) {
366
+            Util::writeLog('user_ldap', 'No DN found for '.$uid.' on '.
367
+                $this->access->connection->ldapHost, Util::DEBUG);
368
+            $this->access->connection->writeToCache('userExists'.$uid, false);
369
+            return false;
370
+        } else if($user instanceof OfflineUser) {
371
+            //express check for users marked as deleted. Returning true is
372
+            //necessary for cleanup
373
+            return true;
374
+        }
375
+
376
+        $result = $this->userExistsOnLDAP($user);
377
+        $this->access->connection->writeToCache('userExists'.$uid, $result);
378
+        if($result === true) {
379
+            $user->update();
380
+        }
381
+        return $result;
382
+    }
383
+
384
+    /**
385
+     * returns whether a user was deleted in LDAP
386
+     *
387
+     * @param string $uid The username of the user to delete
388
+     * @return bool
389
+     */
390
+    public function deleteUser($uid) {
391
+        if ($this->userPluginManager->canDeleteUser()) {
392
+            return $this->userPluginManager->deleteUser($uid);
393
+        }
394
+
395
+        $marked = $this->ocConfig->getUserValue($uid, 'user_ldap', 'isDeleted', 0);
396
+        if(intval($marked) === 0) {
397
+            \OC::$server->getLogger()->notice(
398
+                'User '.$uid . ' is not marked as deleted, not cleaning up.',
399
+                array('app' => 'user_ldap'));
400
+            return false;
401
+        }
402
+        \OC::$server->getLogger()->info('Cleaning up after user ' . $uid,
403
+            array('app' => 'user_ldap'));
404
+
405
+        $this->access->getUserMapper()->unmap($uid);
406
+        $this->access->userManager->invalidate($uid);
407
+        return true;
408
+    }
409
+
410
+    /**
411
+     * get the user's home directory
412
+     *
413
+     * @param string $uid the username
414
+     * @return bool|string
415
+     * @throws NoUserException
416
+     * @throws \Exception
417
+     */
418
+    public function getHome($uid) {
419
+        // user Exists check required as it is not done in user proxy!
420
+        if(!$this->userExists($uid)) {
421
+            return false;
422
+        }
423
+
424
+        if ($this->userPluginManager->implementsActions(Backend::GET_HOME)) {
425
+            return $this->userPluginManager->getHome($uid);
426
+        }
427
+
428
+        $cacheKey = 'getHome'.$uid;
429
+        $path = $this->access->connection->getFromCache($cacheKey);
430
+        if(!is_null($path)) {
431
+            return $path;
432
+        }
433
+
434
+        // early return path if it is a deleted user
435
+        $user = $this->access->userManager->get($uid);
436
+        if($user instanceof OfflineUser) {
437
+            if($this->currentUserInDeletionProcess !== null
438
+                && $this->currentUserInDeletionProcess === $user->getOCName()
439
+            ) {
440
+                return $user->getHomePath();
441
+            } else {
442
+                throw new NoUserException($uid . ' is not a valid user anymore');
443
+            }
444
+        } else if ($user === null) {
445
+            throw new NoUserException($uid . ' is not a valid user anymore');
446
+        }
447
+
448
+        $path = $user->getHomePath();
449
+        $this->access->cacheUserHome($uid, $path);
450
+
451
+        return $path;
452
+    }
453
+
454
+    /**
455
+     * get display name of the user
456
+     * @param string $uid user ID of the user
457
+     * @return string|false display name
458
+     */
459
+    public function getDisplayName($uid) {
460
+        if ($this->userPluginManager->implementsActions(Backend::GET_DISPLAYNAME)) {
461
+            return $this->userPluginManager->getDisplayName($uid);
462
+        }
463
+
464
+        if(!$this->userExists($uid)) {
465
+            return false;
466
+        }
467
+
468
+        $cacheKey = 'getDisplayName'.$uid;
469
+        if(!is_null($displayName = $this->access->connection->getFromCache($cacheKey))) {
470
+            return $displayName;
471
+        }
472
+
473
+        //Check whether the display name is configured to have a 2nd feature
474
+        $additionalAttribute = $this->access->connection->ldapUserDisplayName2;
475
+        $displayName2 = '';
476
+        if ($additionalAttribute !== '') {
477
+            $displayName2 = $this->access->readAttribute(
478
+                $this->access->username2dn($uid),
479
+                $additionalAttribute);
480
+        }
481
+
482
+        $displayName = $this->access->readAttribute(
483
+            $this->access->username2dn($uid),
484
+            $this->access->connection->ldapUserDisplayName);
485
+
486
+        if($displayName && (count($displayName) > 0)) {
487
+            $displayName = $displayName[0];
488
+
489
+            if (is_array($displayName2)){
490
+                $displayName2 = count($displayName2) > 0 ? $displayName2[0] : '';
491
+            }
492
+
493
+            $user = $this->access->userManager->get($uid);
494
+            if ($user instanceof User) {
495
+                $displayName = $user->composeAndStoreDisplayName($displayName, $displayName2);
496
+                $this->access->connection->writeToCache($cacheKey, $displayName);
497
+            }
498
+            if ($user instanceof OfflineUser) {
499
+                /** @var OfflineUser $user*/
500
+                $displayName = $user->getDisplayName();
501
+            }
502
+            return $displayName;
503
+        }
504
+
505
+        return null;
506
+    }
507
+
508
+    /**
509
+     * set display name of the user
510
+     * @param string $uid user ID of the user
511
+     * @param string $displayName new display name of the user
512
+     * @return string|false display name
513
+     */
514
+    public function setDisplayName($uid, $displayName) {
515
+        if ($this->userPluginManager->implementsActions(Backend::SET_DISPLAYNAME)) {
516
+            return $this->userPluginManager->setDisplayName($uid, $displayName);
517
+        }
518
+        return false;
519
+    }
520
+
521
+    /**
522
+     * Get a list of all display names
523
+     *
524
+     * @param string $search
525
+     * @param string|null $limit
526
+     * @param string|null $offset
527
+     * @return array an array of all displayNames (value) and the corresponding uids (key)
528
+     */
529
+    public function getDisplayNames($search = '', $limit = null, $offset = null) {
530
+        $cacheKey = 'getDisplayNames-'.$search.'-'.$limit.'-'.$offset;
531
+        if(!is_null($displayNames = $this->access->connection->getFromCache($cacheKey))) {
532
+            return $displayNames;
533
+        }
534
+
535
+        $displayNames = array();
536
+        $users = $this->getUsers($search, $limit, $offset);
537
+        foreach ($users as $user) {
538
+            $displayNames[$user] = $this->getDisplayName($user);
539
+        }
540
+        $this->access->connection->writeToCache($cacheKey, $displayNames);
541
+        return $displayNames;
542
+    }
543
+
544
+    /**
545
+     * Check if backend implements actions
546
+     * @param int $actions bitwise-or'ed actions
547
+     * @return boolean
548
+     *
549
+     * Returns the supported actions as int to be
550
+     * compared with \OC\User\Backend::CREATE_USER etc.
551
+     */
552
+    public function implementsActions($actions) {
553
+        return (bool)((Backend::CHECK_PASSWORD
554
+            | Backend::GET_HOME
555
+            | Backend::GET_DISPLAYNAME
556
+            | (($this->access->connection->ldapUserAvatarRule !== 'none') ? Backend::PROVIDE_AVATAR : 0)
557
+            | Backend::COUNT_USERS
558
+            | ((intval($this->access->connection->turnOnPasswordChange) === 1)?(Backend::SET_PASSWORD):0)
559
+            | $this->userPluginManager->getImplementedActions())
560
+            & $actions);
561
+    }
562
+
563
+    /**
564
+     * @return bool
565
+     */
566
+    public function hasUserListings() {
567
+        return true;
568
+    }
569
+
570
+    /**
571
+     * counts the users in LDAP
572
+     *
573
+     * @return int|bool
574
+     */
575
+    public function countUsers() {
576
+        if ($this->userPluginManager->implementsActions(Backend::COUNT_USERS)) {
577
+            return $this->userPluginManager->countUsers();
578
+        }
579
+
580
+        $filter = $this->access->getFilterForUserCount();
581
+        $cacheKey = 'countUsers-'.$filter;
582
+        if(!is_null($entries = $this->access->connection->getFromCache($cacheKey))) {
583
+            return $entries;
584
+        }
585
+        $entries = $this->access->countUsers($filter);
586
+        $this->access->connection->writeToCache($cacheKey, $entries);
587
+        return $entries;
588
+    }
589
+
590
+    /**
591
+     * Backend name to be shown in user management
592
+     * @return string the name of the backend to be shown
593
+     */
594
+    public function getBackendName(){
595
+        return 'LDAP';
596
+    }
597 597
 	
598
-	/**
599
-	 * Return access for LDAP interaction.
600
-	 * @param string $uid
601
-	 * @return Access instance of Access for LDAP interaction
602
-	 */
603
-	public function getLDAPAccess($uid) {
604
-		return $this->access;
605
-	}
598
+    /**
599
+     * Return access for LDAP interaction.
600
+     * @param string $uid
601
+     * @return Access instance of Access for LDAP interaction
602
+     */
603
+    public function getLDAPAccess($uid) {
604
+        return $this->access;
605
+    }
606 606
 	
607
-	/**
608
-	 * Return LDAP connection resource from a cloned connection.
609
-	 * The cloned connection needs to be closed manually.
610
-	 * of the current access.
611
-	 * @param string $uid
612
-	 * @return resource of the LDAP connection
613
-	 */
614
-	public function getNewLDAPConnection($uid) {
615
-		$connection = clone $this->access->getConnection();
616
-		return $connection->getConnectionResource();
617
-	}
618
-
619
-	/**
620
-	 * create new user
621
-	 * @param string $username username of the new user
622
-	 * @param string $password password of the new user
623
-	 * @return bool was the user created?
624
-	 */
625
-	public function createUser($username, $password) {
626
-		if ($this->userPluginManager->implementsActions(Backend::CREATE_USER)) {
627
-			return $this->userPluginManager->createUser($username, $password);
628
-		}
629
-		return false;
630
-	}
607
+    /**
608
+     * Return LDAP connection resource from a cloned connection.
609
+     * The cloned connection needs to be closed manually.
610
+     * of the current access.
611
+     * @param string $uid
612
+     * @return resource of the LDAP connection
613
+     */
614
+    public function getNewLDAPConnection($uid) {
615
+        $connection = clone $this->access->getConnection();
616
+        return $connection->getConnectionResource();
617
+    }
618
+
619
+    /**
620
+     * create new user
621
+     * @param string $username username of the new user
622
+     * @param string $password password of the new user
623
+     * @return bool was the user created?
624
+     */
625
+    public function createUser($username, $password) {
626
+        if ($this->userPluginManager->implementsActions(Backend::CREATE_USER)) {
627
+            return $this->userPluginManager->createUser($username, $password);
628
+        }
629
+        return false;
630
+    }
631 631
 
632 632
 }
Please login to merge, or discard this patch.
Spacing   +50 added lines, -50 removed lines patch added patch discarded remove patch
@@ -102,16 +102,16 @@  discard block
 block discarded – undo
102 102
 			return $this->userPluginManager->canChangeAvatar($uid);
103 103
 		}
104 104
 
105
-		if(!$this->implementsActions(Backend::PROVIDE_AVATAR)) {
105
+		if (!$this->implementsActions(Backend::PROVIDE_AVATAR)) {
106 106
 			return true;
107 107
 		}
108 108
 
109 109
 		$user = $this->access->userManager->get($uid);
110
-		if(!$user instanceof User) {
110
+		if (!$user instanceof User) {
111 111
 			return false;
112 112
 		}
113 113
 		$imageData = $user->getAvatarImage();
114
-		if($imageData === false) {
114
+		if ($imageData === false) {
115 115
 			return true;
116 116
 		}
117 117
 		return !$user->updateAvatar(true);
@@ -126,14 +126,14 @@  discard block
 block discarded – undo
126 126
 	public function loginName2UserName($loginName) {
127 127
 		$cacheKey = 'loginName2UserName-'.$loginName;
128 128
 		$username = $this->access->connection->getFromCache($cacheKey);
129
-		if(!is_null($username)) {
129
+		if (!is_null($username)) {
130 130
 			return $username;
131 131
 		}
132 132
 
133 133
 		try {
134 134
 			$ldapRecord = $this->getLDAPUserByLoginName($loginName);
135 135
 			$user = $this->access->userManager->get($ldapRecord['dn'][0]);
136
-			if($user instanceof OfflineUser) {
136
+			if ($user instanceof OfflineUser) {
137 137
 				// this path is not really possible, however get() is documented
138 138
 				// to return User or OfflineUser so we are very defensive here.
139 139
 				$this->access->connection->writeToCache($cacheKey, false);
@@ -169,9 +169,9 @@  discard block
 block discarded – undo
169 169
 		//find out dn of the user name
170 170
 		$attrs = $this->access->userManager->getAttributes();
171 171
 		$users = $this->access->fetchUsersByLoginName($loginName, $attrs);
172
-		if(count($users) < 1) {
173
-			throw new NotOnLDAP('No user available for the given login name on ' .
174
-				$this->access->connection->ldapHost . ':' . $this->access->connection->ldapPort);
172
+		if (count($users) < 1) {
173
+			throw new NotOnLDAP('No user available for the given login name on '.
174
+				$this->access->connection->ldapHost.':'.$this->access->connection->ldapPort);
175 175
 		}
176 176
 		return $users[0];
177 177
 	}
@@ -186,8 +186,8 @@  discard block
 block discarded – undo
186 186
 	public function checkPassword($uid, $password) {
187 187
 		try {
188 188
 			$ldapRecord = $this->getLDAPUserByLoginName($uid);
189
-		} catch(NotOnLDAP $e) {
190
-			if($this->ocConfig->getSystemValue('loglevel', Util::WARN) === Util::DEBUG) {
189
+		} catch (NotOnLDAP $e) {
190
+			if ($this->ocConfig->getSystemValue('loglevel', Util::WARN) === Util::DEBUG) {
191 191
 				\OC::$server->getLogger()->logException($e, ['app' => 'user_ldap']);
192 192
 			}
193 193
 			return false;
@@ -195,16 +195,16 @@  discard block
 block discarded – undo
195 195
 		$dn = $ldapRecord['dn'][0];
196 196
 		$user = $this->access->userManager->get($dn);
197 197
 
198
-		if(!$user instanceof User) {
198
+		if (!$user instanceof User) {
199 199
 			Util::writeLog('user_ldap',
200
-				'LDAP Login: Could not get user object for DN ' . $dn .
200
+				'LDAP Login: Could not get user object for DN '.$dn.
201 201
 				'. Maybe the LDAP entry has no set display name attribute?',
202 202
 				Util::WARN);
203 203
 			return false;
204 204
 		}
205
-		if($user->getUsername() !== false) {
205
+		if ($user->getUsername() !== false) {
206 206
 			//are the credentials OK?
207
-			if(!$this->access->areCredentialsValid($dn, $password)) {
207
+			if (!$this->access->areCredentialsValid($dn, $password)) {
208 208
 				return false;
209 209
 			}
210 210
 
@@ -231,11 +231,11 @@  discard block
 block discarded – undo
231 231
 
232 232
 		$user = $this->access->userManager->get($uid);
233 233
 
234
-		if(!$user instanceof User) {
235
-			throw new \Exception('LDAP setPassword: Could not get user object for uid ' . $uid .
234
+		if (!$user instanceof User) {
235
+			throw new \Exception('LDAP setPassword: Could not get user object for uid '.$uid.
236 236
 				'. Maybe the LDAP entry has no set display name attribute?');
237 237
 		}
238
-		if($user->getUsername() !== false && $this->access->setPassword($user->getDN(), $password)) {
238
+		if ($user->getUsername() !== false && $this->access->setPassword($user->getDN(), $password)) {
239 239
 			$ldapDefaultPPolicyDN = $this->access->connection->ldapDefaultPPolicyDN;
240 240
 			$turnOnPasswordChange = $this->access->connection->turnOnPasswordChange;
241 241
 			if (!empty($ldapDefaultPPolicyDN) && (intval($turnOnPasswordChange) === 1)) {
@@ -267,18 +267,18 @@  discard block
 block discarded – undo
267 267
 
268 268
 		//check if users are cached, if so return
269 269
 		$ldap_users = $this->access->connection->getFromCache($cachekey);
270
-		if(!is_null($ldap_users)) {
270
+		if (!is_null($ldap_users)) {
271 271
 			return $ldap_users;
272 272
 		}
273 273
 
274 274
 		// if we'd pass -1 to LDAP search, we'd end up in a Protocol
275 275
 		// error. With a limit of 0, we get 0 results. So we pass null.
276
-		if($limit <= 0) {
276
+		if ($limit <= 0) {
277 277
 			$limit = null;
278 278
 		}
279 279
 		$filter = $this->access->combineFilterWithAnd(array(
280 280
 			$this->access->connection->ldapUserFilter,
281
-			$this->access->connection->ldapUserDisplayName . '=*',
281
+			$this->access->connection->ldapUserDisplayName.'=*',
282 282
 			$this->access->getFilterPartForUserSearch($search)
283 283
 		));
284 284
 
@@ -291,7 +291,7 @@  discard block
 block discarded – undo
291 291
 			$this->access->userManager->getAttributes(true),
292 292
 			$limit, $offset);
293 293
 		$ldap_users = $this->access->nextcloudUserNames($ldap_users);
294
-		Util::writeLog('user_ldap', 'getUsers: '.count($ldap_users). ' Users found', Util::DEBUG);
294
+		Util::writeLog('user_ldap', 'getUsers: '.count($ldap_users).' Users found', Util::DEBUG);
295 295
 
296 296
 		$this->access->connection->writeToCache($cachekey, $ldap_users);
297 297
 		return $ldap_users;
@@ -307,19 +307,19 @@  discard block
 block discarded – undo
307 307
 	 * @throws \OC\ServerNotAvailableException
308 308
 	 */
309 309
 	public function userExistsOnLDAP($user) {
310
-		if(is_string($user)) {
310
+		if (is_string($user)) {
311 311
 			$user = $this->access->userManager->get($user);
312 312
 		}
313
-		if(is_null($user)) {
313
+		if (is_null($user)) {
314 314
 			return false;
315 315
 		}
316 316
 
317 317
 		$dn = $user->getDN();
318 318
 		//check if user really still exists by reading its entry
319
-		if(!is_array($this->access->readAttribute($dn, '', $this->access->connection->ldapUserFilter))) {
319
+		if (!is_array($this->access->readAttribute($dn, '', $this->access->connection->ldapUserFilter))) {
320 320
 			$lcr = $this->access->connection->getConnectionResource();
321
-			if(is_null($lcr)) {
322
-				throw new \Exception('No LDAP Connection to server ' . $this->access->connection->ldapHost);
321
+			if (is_null($lcr)) {
322
+				throw new \Exception('No LDAP Connection to server '.$this->access->connection->ldapHost);
323 323
 			}
324 324
 
325 325
 			try {
@@ -341,7 +341,7 @@  discard block
 block discarded – undo
341 341
 			}
342 342
 		}
343 343
 
344
-		if($user instanceof OfflineUser) {
344
+		if ($user instanceof OfflineUser) {
345 345
 			$user->unmark();
346 346
 		}
347 347
 
@@ -356,18 +356,18 @@  discard block
 block discarded – undo
356 356
 	 */
357 357
 	public function userExists($uid) {
358 358
 		$userExists = $this->access->connection->getFromCache('userExists'.$uid);
359
-		if(!is_null($userExists)) {
360
-			return (bool)$userExists;
359
+		if (!is_null($userExists)) {
360
+			return (bool) $userExists;
361 361
 		}
362 362
 		//getting dn, if false the user does not exist. If dn, he may be mapped only, requires more checking.
363 363
 		$user = $this->access->userManager->get($uid);
364 364
 
365
-		if(is_null($user)) {
365
+		if (is_null($user)) {
366 366
 			Util::writeLog('user_ldap', 'No DN found for '.$uid.' on '.
367 367
 				$this->access->connection->ldapHost, Util::DEBUG);
368 368
 			$this->access->connection->writeToCache('userExists'.$uid, false);
369 369
 			return false;
370
-		} else if($user instanceof OfflineUser) {
370
+		} else if ($user instanceof OfflineUser) {
371 371
 			//express check for users marked as deleted. Returning true is
372 372
 			//necessary for cleanup
373 373
 			return true;
@@ -375,7 +375,7 @@  discard block
 block discarded – undo
375 375
 
376 376
 		$result = $this->userExistsOnLDAP($user);
377 377
 		$this->access->connection->writeToCache('userExists'.$uid, $result);
378
-		if($result === true) {
378
+		if ($result === true) {
379 379
 			$user->update();
380 380
 		}
381 381
 		return $result;
@@ -393,13 +393,13 @@  discard block
 block discarded – undo
393 393
 		}
394 394
 
395 395
 		$marked = $this->ocConfig->getUserValue($uid, 'user_ldap', 'isDeleted', 0);
396
-		if(intval($marked) === 0) {
396
+		if (intval($marked) === 0) {
397 397
 			\OC::$server->getLogger()->notice(
398
-				'User '.$uid . ' is not marked as deleted, not cleaning up.',
398
+				'User '.$uid.' is not marked as deleted, not cleaning up.',
399 399
 				array('app' => 'user_ldap'));
400 400
 			return false;
401 401
 		}
402
-		\OC::$server->getLogger()->info('Cleaning up after user ' . $uid,
402
+		\OC::$server->getLogger()->info('Cleaning up after user '.$uid,
403 403
 			array('app' => 'user_ldap'));
404 404
 
405 405
 		$this->access->getUserMapper()->unmap($uid);
@@ -417,7 +417,7 @@  discard block
 block discarded – undo
417 417
 	 */
418 418
 	public function getHome($uid) {
419 419
 		// user Exists check required as it is not done in user proxy!
420
-		if(!$this->userExists($uid)) {
420
+		if (!$this->userExists($uid)) {
421 421
 			return false;
422 422
 		}
423 423
 
@@ -427,22 +427,22 @@  discard block
 block discarded – undo
427 427
 
428 428
 		$cacheKey = 'getHome'.$uid;
429 429
 		$path = $this->access->connection->getFromCache($cacheKey);
430
-		if(!is_null($path)) {
430
+		if (!is_null($path)) {
431 431
 			return $path;
432 432
 		}
433 433
 
434 434
 		// early return path if it is a deleted user
435 435
 		$user = $this->access->userManager->get($uid);
436
-		if($user instanceof OfflineUser) {
437
-			if($this->currentUserInDeletionProcess !== null
436
+		if ($user instanceof OfflineUser) {
437
+			if ($this->currentUserInDeletionProcess !== null
438 438
 				&& $this->currentUserInDeletionProcess === $user->getOCName()
439 439
 			) {
440 440
 				return $user->getHomePath();
441 441
 			} else {
442
-				throw new NoUserException($uid . ' is not a valid user anymore');
442
+				throw new NoUserException($uid.' is not a valid user anymore');
443 443
 			}
444 444
 		} else if ($user === null) {
445
-			throw new NoUserException($uid . ' is not a valid user anymore');
445
+			throw new NoUserException($uid.' is not a valid user anymore');
446 446
 		}
447 447
 
448 448
 		$path = $user->getHomePath();
@@ -461,12 +461,12 @@  discard block
 block discarded – undo
461 461
 			return $this->userPluginManager->getDisplayName($uid);
462 462
 		}
463 463
 
464
-		if(!$this->userExists($uid)) {
464
+		if (!$this->userExists($uid)) {
465 465
 			return false;
466 466
 		}
467 467
 
468 468
 		$cacheKey = 'getDisplayName'.$uid;
469
-		if(!is_null($displayName = $this->access->connection->getFromCache($cacheKey))) {
469
+		if (!is_null($displayName = $this->access->connection->getFromCache($cacheKey))) {
470 470
 			return $displayName;
471 471
 		}
472 472
 
@@ -483,10 +483,10 @@  discard block
 block discarded – undo
483 483
 			$this->access->username2dn($uid),
484 484
 			$this->access->connection->ldapUserDisplayName);
485 485
 
486
-		if($displayName && (count($displayName) > 0)) {
486
+		if ($displayName && (count($displayName) > 0)) {
487 487
 			$displayName = $displayName[0];
488 488
 
489
-			if (is_array($displayName2)){
489
+			if (is_array($displayName2)) {
490 490
 				$displayName2 = count($displayName2) > 0 ? $displayName2[0] : '';
491 491
 			}
492 492
 
@@ -528,7 +528,7 @@  discard block
 block discarded – undo
528 528
 	 */
529 529
 	public function getDisplayNames($search = '', $limit = null, $offset = null) {
530 530
 		$cacheKey = 'getDisplayNames-'.$search.'-'.$limit.'-'.$offset;
531
-		if(!is_null($displayNames = $this->access->connection->getFromCache($cacheKey))) {
531
+		if (!is_null($displayNames = $this->access->connection->getFromCache($cacheKey))) {
532 532
 			return $displayNames;
533 533
 		}
534 534
 
@@ -550,12 +550,12 @@  discard block
 block discarded – undo
550 550
 	* compared with \OC\User\Backend::CREATE_USER etc.
551 551
 	*/
552 552
 	public function implementsActions($actions) {
553
-		return (bool)((Backend::CHECK_PASSWORD
553
+		return (bool) ((Backend::CHECK_PASSWORD
554 554
 			| Backend::GET_HOME
555 555
 			| Backend::GET_DISPLAYNAME
556 556
 			| (($this->access->connection->ldapUserAvatarRule !== 'none') ? Backend::PROVIDE_AVATAR : 0)
557 557
 			| Backend::COUNT_USERS
558
-			| ((intval($this->access->connection->turnOnPasswordChange) === 1)?(Backend::SET_PASSWORD):0)
558
+			| ((intval($this->access->connection->turnOnPasswordChange) === 1) ? (Backend::SET_PASSWORD) : 0)
559 559
 			| $this->userPluginManager->getImplementedActions())
560 560
 			& $actions);
561 561
 	}
@@ -579,7 +579,7 @@  discard block
 block discarded – undo
579 579
 
580 580
 		$filter = $this->access->getFilterForUserCount();
581 581
 		$cacheKey = 'countUsers-'.$filter;
582
-		if(!is_null($entries = $this->access->connection->getFromCache($cacheKey))) {
582
+		if (!is_null($entries = $this->access->connection->getFromCache($cacheKey))) {
583 583
 			return $entries;
584 584
 		}
585 585
 		$entries = $this->access->countUsers($filter);
@@ -591,7 +591,7 @@  discard block
 block discarded – undo
591 591
 	 * Backend name to be shown in user management
592 592
 	 * @return string the name of the backend to be shown
593 593
 	 */
594
-	public function getBackendName(){
594
+	public function getBackendName() {
595 595
 		return 'LDAP';
596 596
 	}
597 597
 	
Please login to merge, or discard this patch.
apps/user_ldap/lib/User/User.php 2 patches
Indentation   +646 added lines, -646 removed lines patch added patch discarded remove patch
@@ -47,656 +47,656 @@
 block discarded – undo
47 47
  * represents an LDAP user, gets and holds user-specific information from LDAP
48 48
  */
49 49
 class User {
50
-	/**
51
-	 * @var IUserTools
52
-	 */
53
-	protected $access;
54
-	/**
55
-	 * @var Connection
56
-	 */
57
-	protected $connection;
58
-	/**
59
-	 * @var IConfig
60
-	 */
61
-	protected $config;
62
-	/**
63
-	 * @var FilesystemHelper
64
-	 */
65
-	protected $fs;
66
-	/**
67
-	 * @var Image
68
-	 */
69
-	protected $image;
70
-	/**
71
-	 * @var LogWrapper
72
-	 */
73
-	protected $log;
74
-	/**
75
-	 * @var IAvatarManager
76
-	 */
77
-	protected $avatarManager;
78
-	/**
79
-	 * @var IUserManager
80
-	 */
81
-	protected $userManager;
82
-	/**
83
-	 * @var INotificationManager
84
-	 */
85
-	protected $notificationManager;
86
-	/**
87
-	 * @var string
88
-	 */
89
-	protected $dn;
90
-	/**
91
-	 * @var string
92
-	 */
93
-	protected $uid;
94
-	/**
95
-	 * @var string[]
96
-	 */
97
-	protected $refreshedFeatures = array();
98
-	/**
99
-	 * @var string
100
-	 */
101
-	protected $avatarImage;
102
-
103
-	/**
104
-	 * DB config keys for user preferences
105
-	 */
106
-	const USER_PREFKEY_FIRSTLOGIN  = 'firstLoginAccomplished';
107
-	const USER_PREFKEY_LASTREFRESH = 'lastFeatureRefresh';
108
-
109
-	/**
110
-	 * @brief constructor, make sure the subclasses call this one!
111
-	 * @param string $username the internal username
112
-	 * @param string $dn the LDAP DN
113
-	 * @param IUserTools $access an instance that implements IUserTools for
114
-	 * LDAP interaction
115
-	 * @param IConfig $config
116
-	 * @param FilesystemHelper $fs
117
-	 * @param Image $image any empty instance
118
-	 * @param LogWrapper $log
119
-	 * @param IAvatarManager $avatarManager
120
-	 * @param IUserManager $userManager
121
-	 * @param INotificationManager $notificationManager
122
-	 */
123
-	public function __construct($username, $dn, IUserTools $access,
124
-		IConfig $config, FilesystemHelper $fs, Image $image,
125
-		LogWrapper $log, IAvatarManager $avatarManager, IUserManager $userManager,
126
-		INotificationManager $notificationManager) {
50
+    /**
51
+     * @var IUserTools
52
+     */
53
+    protected $access;
54
+    /**
55
+     * @var Connection
56
+     */
57
+    protected $connection;
58
+    /**
59
+     * @var IConfig
60
+     */
61
+    protected $config;
62
+    /**
63
+     * @var FilesystemHelper
64
+     */
65
+    protected $fs;
66
+    /**
67
+     * @var Image
68
+     */
69
+    protected $image;
70
+    /**
71
+     * @var LogWrapper
72
+     */
73
+    protected $log;
74
+    /**
75
+     * @var IAvatarManager
76
+     */
77
+    protected $avatarManager;
78
+    /**
79
+     * @var IUserManager
80
+     */
81
+    protected $userManager;
82
+    /**
83
+     * @var INotificationManager
84
+     */
85
+    protected $notificationManager;
86
+    /**
87
+     * @var string
88
+     */
89
+    protected $dn;
90
+    /**
91
+     * @var string
92
+     */
93
+    protected $uid;
94
+    /**
95
+     * @var string[]
96
+     */
97
+    protected $refreshedFeatures = array();
98
+    /**
99
+     * @var string
100
+     */
101
+    protected $avatarImage;
102
+
103
+    /**
104
+     * DB config keys for user preferences
105
+     */
106
+    const USER_PREFKEY_FIRSTLOGIN  = 'firstLoginAccomplished';
107
+    const USER_PREFKEY_LASTREFRESH = 'lastFeatureRefresh';
108
+
109
+    /**
110
+     * @brief constructor, make sure the subclasses call this one!
111
+     * @param string $username the internal username
112
+     * @param string $dn the LDAP DN
113
+     * @param IUserTools $access an instance that implements IUserTools for
114
+     * LDAP interaction
115
+     * @param IConfig $config
116
+     * @param FilesystemHelper $fs
117
+     * @param Image $image any empty instance
118
+     * @param LogWrapper $log
119
+     * @param IAvatarManager $avatarManager
120
+     * @param IUserManager $userManager
121
+     * @param INotificationManager $notificationManager
122
+     */
123
+    public function __construct($username, $dn, IUserTools $access,
124
+        IConfig $config, FilesystemHelper $fs, Image $image,
125
+        LogWrapper $log, IAvatarManager $avatarManager, IUserManager $userManager,
126
+        INotificationManager $notificationManager) {
127 127
 	
128
-		if ($username === null) {
129
-			$log->log("uid for '$dn' must not be null!", Util::ERROR);
130
-			throw new \InvalidArgumentException('uid must not be null!');
131
-		} else if ($username === '') {
132
-			$log->log("uid for '$dn' must not be an empty string", Util::ERROR);
133
-			throw new \InvalidArgumentException('uid must not be an empty string!');
134
-		}
135
-
136
-		$this->access              = $access;
137
-		$this->connection          = $access->getConnection();
138
-		$this->config              = $config;
139
-		$this->fs                  = $fs;
140
-		$this->dn                  = $dn;
141
-		$this->uid                 = $username;
142
-		$this->image               = $image;
143
-		$this->log                 = $log;
144
-		$this->avatarManager       = $avatarManager;
145
-		$this->userManager         = $userManager;
146
-		$this->notificationManager = $notificationManager;
147
-
148
-		Util::connectHook('OC_User', 'post_login', $this, 'handlePasswordExpiry');
149
-	}
150
-
151
-	/**
152
-	 * @brief updates properties like email, quota or avatar provided by LDAP
153
-	 * @return null
154
-	 */
155
-	public function update() {
156
-		if(is_null($this->dn)) {
157
-			return null;
158
-		}
159
-
160
-		$hasLoggedIn = $this->config->getUserValue($this->uid, 'user_ldap',
161
-				self::USER_PREFKEY_FIRSTLOGIN, 0);
162
-
163
-		if($this->needsRefresh()) {
164
-			$this->updateEmail();
165
-			$this->updateQuota();
166
-			if($hasLoggedIn !== 0) {
167
-				//we do not need to try it, when the user has not been logged in
168
-				//before, because the file system will not be ready.
169
-				$this->updateAvatar();
170
-				//in order to get an avatar as soon as possible, mark the user
171
-				//as refreshed only when updating the avatar did happen
172
-				$this->markRefreshTime();
173
-			}
174
-		}
175
-	}
176
-
177
-	/**
178
-	 * processes results from LDAP for attributes as returned by getAttributesToRead()
179
-	 * @param array $ldapEntry the user entry as retrieved from LDAP
180
-	 */
181
-	public function processAttributes($ldapEntry) {
182
-		$this->markRefreshTime();
183
-		//Quota
184
-		$attr = strtolower($this->connection->ldapQuotaAttribute);
185
-		if(isset($ldapEntry[$attr])) {
186
-			$this->updateQuota($ldapEntry[$attr][0]);
187
-		} else {
188
-			if ($this->connection->ldapQuotaDefault !== '') {
189
-				$this->updateQuota();
190
-			}
191
-		}
192
-		unset($attr);
193
-
194
-		//displayName
195
-		$displayName = $displayName2 = '';
196
-		$attr = strtolower($this->connection->ldapUserDisplayName);
197
-		if(isset($ldapEntry[$attr])) {
198
-			$displayName = strval($ldapEntry[$attr][0]);
199
-		}
200
-		$attr = strtolower($this->connection->ldapUserDisplayName2);
201
-		if(isset($ldapEntry[$attr])) {
202
-			$displayName2 = strval($ldapEntry[$attr][0]);
203
-		}
204
-		if ($displayName !== '') {
205
-			$this->composeAndStoreDisplayName($displayName);
206
-			$this->access->cacheUserDisplayName(
207
-				$this->getUsername(),
208
-				$displayName,
209
-				$displayName2
210
-			);
211
-		}
212
-		unset($attr);
213
-
214
-		//Email
215
-		//email must be stored after displayname, because it would cause a user
216
-		//change event that will trigger fetching the display name again
217
-		$attr = strtolower($this->connection->ldapEmailAttribute);
218
-		if(isset($ldapEntry[$attr])) {
219
-			$this->updateEmail($ldapEntry[$attr][0]);
220
-		}
221
-		unset($attr);
222
-
223
-		// LDAP Username, needed for s2s sharing
224
-		if(isset($ldapEntry['uid'])) {
225
-			$this->storeLDAPUserName($ldapEntry['uid'][0]);
226
-		} else if(isset($ldapEntry['samaccountname'])) {
227
-			$this->storeLDAPUserName($ldapEntry['samaccountname'][0]);
228
-		}
229
-
230
-		//homePath
231
-		if(strpos($this->connection->homeFolderNamingRule, 'attr:') === 0) {
232
-			$attr = strtolower(substr($this->connection->homeFolderNamingRule, strlen('attr:')));
233
-			if(isset($ldapEntry[$attr])) {
234
-				$this->access->cacheUserHome(
235
-					$this->getUsername(), $this->getHomePath($ldapEntry[$attr][0]));
236
-			}
237
-		}
238
-
239
-		//memberOf groups
240
-		$cacheKey = 'getMemberOf'.$this->getUsername();
241
-		$groups = false;
242
-		if(isset($ldapEntry['memberof'])) {
243
-			$groups = $ldapEntry['memberof'];
244
-		}
245
-		$this->connection->writeToCache($cacheKey, $groups);
246
-
247
-		//Avatar
248
-		/** @var Connection $connection */
249
-		$connection = $this->access->getConnection();
250
-		$attributes = $connection->resolveRule('avatar');
251
-		foreach ($attributes as $attribute)  {
252
-			if(isset($ldapEntry[$attribute])) {
253
-				$this->avatarImage = $ldapEntry[$attribute][0];
254
-				// the call to the method that saves the avatar in the file
255
-				// system must be postponed after the login. It is to ensure
256
-				// external mounts are mounted properly (e.g. with login
257
-				// credentials from the session).
258
-				Util::connectHook('OC_User', 'post_login', $this, 'updateAvatarPostLogin');
259
-				break;
260
-			}
261
-		}
262
-	}
263
-
264
-	/**
265
-	 * @brief returns the LDAP DN of the user
266
-	 * @return string
267
-	 */
268
-	public function getDN() {
269
-		return $this->dn;
270
-	}
271
-
272
-	/**
273
-	 * @brief returns the Nextcloud internal username of the user
274
-	 * @return string
275
-	 */
276
-	public function getUsername() {
277
-		return $this->uid;
278
-	}
279
-
280
-	/**
281
-	 * returns the home directory of the user if specified by LDAP settings
282
-	 * @param string $valueFromLDAP
283
-	 * @return bool|string
284
-	 * @throws \Exception
285
-	 */
286
-	public function getHomePath($valueFromLDAP = null) {
287
-		$path = strval($valueFromLDAP);
288
-		$attr = null;
289
-
290
-		if (is_null($valueFromLDAP)
291
-		   && strpos($this->access->connection->homeFolderNamingRule, 'attr:') === 0
292
-		   && $this->access->connection->homeFolderNamingRule !== 'attr:')
293
-		{
294
-			$attr = substr($this->access->connection->homeFolderNamingRule, strlen('attr:'));
295
-			$homedir = $this->access->readAttribute(
296
-				$this->access->username2dn($this->getUsername()), $attr);
297
-			if ($homedir && isset($homedir[0])) {
298
-				$path = $homedir[0];
299
-			}
300
-		}
301
-
302
-		if ($path !== '') {
303
-			//if attribute's value is an absolute path take this, otherwise append it to data dir
304
-			//check for / at the beginning or pattern c:\ resp. c:/
305
-			if(   '/' !== $path[0]
306
-			   && !(3 < strlen($path) && ctype_alpha($path[0])
307
-			       && $path[1] === ':' && ('\\' === $path[2] || '/' === $path[2]))
308
-			) {
309
-				$path = $this->config->getSystemValue('datadirectory',
310
-						\OC::$SERVERROOT.'/data' ) . '/' . $path;
311
-			}
312
-			//we need it to store it in the DB as well in case a user gets
313
-			//deleted so we can clean up afterwards
314
-			$this->config->setUserValue(
315
-				$this->getUsername(), 'user_ldap', 'homePath', $path
316
-			);
317
-			return $path;
318
-		}
319
-
320
-		if(    !is_null($attr)
321
-			&& $this->config->getAppValue('user_ldap', 'enforce_home_folder_naming_rule', true)
322
-		) {
323
-			// a naming rule attribute is defined, but it doesn't exist for that LDAP user
324
-			throw new \Exception('Home dir attribute can\'t be read from LDAP for uid: ' . $this->getUsername());
325
-		}
326
-
327
-		//false will apply default behaviour as defined and done by OC_User
328
-		$this->config->setUserValue($this->getUsername(), 'user_ldap', 'homePath', '');
329
-		return false;
330
-	}
331
-
332
-	public function getMemberOfGroups() {
333
-		$cacheKey = 'getMemberOf'.$this->getUsername();
334
-		$memberOfGroups = $this->connection->getFromCache($cacheKey);
335
-		if(!is_null($memberOfGroups)) {
336
-			return $memberOfGroups;
337
-		}
338
-		$groupDNs = $this->access->readAttribute($this->getDN(), 'memberOf');
339
-		$this->connection->writeToCache($cacheKey, $groupDNs);
340
-		return $groupDNs;
341
-	}
342
-
343
-	/**
344
-	 * @brief reads the image from LDAP that shall be used as Avatar
345
-	 * @return string data (provided by LDAP) | false
346
-	 */
347
-	public function getAvatarImage() {
348
-		if(!is_null($this->avatarImage)) {
349
-			return $this->avatarImage;
350
-		}
351
-
352
-		$this->avatarImage = false;
353
-		/** @var Connection $connection */
354
-		$connection = $this->access->getConnection();
355
-		$attributes = $connection->resolveRule('avatar');
356
-		foreach($attributes as $attribute) {
357
-			$result = $this->access->readAttribute($this->dn, $attribute);
358
-			if($result !== false && is_array($result) && isset($result[0])) {
359
-				$this->avatarImage = $result[0];
360
-				break;
361
-			}
362
-		}
363
-
364
-		return $this->avatarImage;
365
-	}
366
-
367
-	/**
368
-	 * @brief marks the user as having logged in at least once
369
-	 * @return null
370
-	 */
371
-	public function markLogin() {
372
-		$this->config->setUserValue(
373
-			$this->uid, 'user_ldap', self::USER_PREFKEY_FIRSTLOGIN, 1);
374
-	}
375
-
376
-	/**
377
-	 * @brief marks the time when user features like email have been updated
378
-	 * @return null
379
-	 */
380
-	public function markRefreshTime() {
381
-		$this->config->setUserValue(
382
-			$this->uid, 'user_ldap', self::USER_PREFKEY_LASTREFRESH, time());
383
-	}
384
-
385
-	/**
386
-	 * @brief checks whether user features needs to be updated again by
387
-	 * comparing the difference of time of the last refresh to now with the
388
-	 * desired interval
389
-	 * @return bool
390
-	 */
391
-	private function needsRefresh() {
392
-		$lastChecked = $this->config->getUserValue($this->uid, 'user_ldap',
393
-			self::USER_PREFKEY_LASTREFRESH, 0);
394
-
395
-		if((time() - intval($lastChecked)) < intval($this->config->getAppValue('user_ldap', 'updateAttributesInterval', 86400)) ) {
396
-			return false;
397
-		}
398
-		return  true;
399
-	}
400
-
401
-	/**
402
-	 * Stores a key-value pair in relation to this user
403
-	 *
404
-	 * @param string $key
405
-	 * @param string $value
406
-	 */
407
-	private function store($key, $value) {
408
-		$this->config->setUserValue($this->uid, 'user_ldap', $key, $value);
409
-	}
410
-
411
-	/**
412
-	 * Composes the display name and stores it in the database. The final
413
-	 * display name is returned.
414
-	 *
415
-	 * @param string $displayName
416
-	 * @param string $displayName2
417
-	 * @returns string the effective display name
418
-	 */
419
-	public function composeAndStoreDisplayName($displayName, $displayName2 = '') {
420
-		$displayName2 = strval($displayName2);
421
-		if($displayName2 !== '') {
422
-			$displayName .= ' (' . $displayName2 . ')';
423
-		}
424
-		$this->store('displayName', $displayName);
425
-		return $displayName;
426
-	}
427
-
428
-	/**
429
-	 * Stores the LDAP Username in the Database
430
-	 * @param string $userName
431
-	 */
432
-	public function storeLDAPUserName($userName) {
433
-		$this->store('uid', $userName);
434
-	}
435
-
436
-	/**
437
-	 * @brief checks whether an update method specified by feature was run
438
-	 * already. If not, it will marked like this, because it is expected that
439
-	 * the method will be run, when false is returned.
440
-	 * @param string $feature email | quota | avatar (can be extended)
441
-	 * @return bool
442
-	 */
443
-	private function wasRefreshed($feature) {
444
-		if(isset($this->refreshedFeatures[$feature])) {
445
-			return true;
446
-		}
447
-		$this->refreshedFeatures[$feature] = 1;
448
-		return false;
449
-	}
450
-
451
-	/**
452
-	 * fetches the email from LDAP and stores it as Nextcloud user value
453
-	 * @param string $valueFromLDAP if known, to save an LDAP read request
454
-	 * @return null
455
-	 */
456
-	public function updateEmail($valueFromLDAP = null) {
457
-		if($this->wasRefreshed('email')) {
458
-			return;
459
-		}
460
-		$email = strval($valueFromLDAP);
461
-		if(is_null($valueFromLDAP)) {
462
-			$emailAttribute = $this->connection->ldapEmailAttribute;
463
-			if ($emailAttribute !== '') {
464
-				$aEmail = $this->access->readAttribute($this->dn, $emailAttribute);
465
-				if(is_array($aEmail) && (count($aEmail) > 0)) {
466
-					$email = strval($aEmail[0]);
467
-				}
468
-			}
469
-		}
470
-		if ($email !== '') {
471
-			$user = $this->userManager->get($this->uid);
472
-			if (!is_null($user)) {
473
-				$currentEmail = strval($user->getEMailAddress());
474
-				if ($currentEmail !== $email) {
475
-					$user->setEMailAddress($email);
476
-				}
477
-			}
478
-		}
479
-	}
480
-
481
-	/**
482
-	 * Overall process goes as follow:
483
-	 * 1. fetch the quota from LDAP and check if it's parseable with the "verifyQuotaValue" function
484
-	 * 2. if the value can't be fetched, is empty or not parseable, use the default LDAP quota
485
-	 * 3. if the default LDAP quota can't be parsed, use the Nextcloud's default quota (use 'default')
486
-	 * 4. check if the target user exists and set the quota for the user.
487
-	 *
488
-	 * In order to improve performance and prevent an unwanted extra LDAP call, the $valueFromLDAP
489
-	 * parameter can be passed with the value of the attribute. This value will be considered as the
490
-	 * quota for the user coming from the LDAP server (step 1 of the process) It can be useful to
491
-	 * fetch all the user's attributes in one call and use the fetched values in this function.
492
-	 * The expected value for that parameter is a string describing the quota for the user. Valid
493
-	 * values are 'none' (unlimited), 'default' (the Nextcloud's default quota), '1234' (quota in
494
-	 * bytes), '1234 MB' (quota in MB - check the \OC_Helper::computerFileSize method for more info)
495
-	 *
496
-	 * fetches the quota from LDAP and stores it as Nextcloud user value
497
-	 * @param string $valueFromLDAP the quota attribute's value can be passed,
498
-	 * to save the readAttribute request
499
-	 * @return null
500
-	 */
501
-	public function updateQuota($valueFromLDAP = null) {
502
-		if($this->wasRefreshed('quota')) {
503
-			return;
504
-		}
505
-
506
-		$quotaAttribute = $this->connection->ldapQuotaAttribute;
507
-		$defaultQuota = $this->connection->ldapQuotaDefault;
508
-		if($quotaAttribute === '' && $defaultQuota === '') {
509
-			return;
510
-		}
511
-
512
-		$quota = false;
513
-		if(is_null($valueFromLDAP) && $quotaAttribute !== '') {
514
-			$aQuota = $this->access->readAttribute($this->dn, $quotaAttribute);
515
-			if($aQuota && (count($aQuota) > 0) && $this->verifyQuotaValue($aQuota[0])) {
516
-				$quota = $aQuota[0];
517
-			} else if(is_array($aQuota) && isset($aQuota[0])) {
518
-				$this->log->log('no suitable LDAP quota found for user ' . $this->uid . ': [' . $aQuota[0] . ']', Util::DEBUG);
519
-			}
520
-		} else if ($this->verifyQuotaValue($valueFromLDAP)) {
521
-			$quota = $valueFromLDAP;
522
-		} else {
523
-			$this->log->log('no suitable LDAP quota found for user ' . $this->uid . ': [' . $valueFromLDAP . ']', Util::DEBUG);
524
-		}
525
-
526
-		if ($quota === false && $this->verifyQuotaValue($defaultQuota)) {
527
-			// quota not found using the LDAP attribute (or not parseable). Try the default quota
528
-			$quota = $defaultQuota;
529
-		} else if($quota === false) {
530
-			$this->log->log('no suitable default quota found for user ' . $this->uid . ': [' . $defaultQuota . ']', Util::DEBUG);
531
-			return;
532
-		}
533
-
534
-		$targetUser = $this->userManager->get($this->uid);
535
-		if ($targetUser instanceof IUser) {
536
-			$targetUser->setQuota($quota);
537
-		} else {
538
-			$this->log->log('trying to set a quota for user ' . $this->uid . ' but the user is missing', Util::INFO);
539
-		}
540
-	}
541
-
542
-	private function verifyQuotaValue($quotaValue) {
543
-		return $quotaValue === 'none' || $quotaValue === 'default' || \OC_Helper::computerFileSize($quotaValue) !== false;
544
-	}
545
-
546
-	/**
547
-	 * called by a post_login hook to save the avatar picture
548
-	 *
549
-	 * @param array $params
550
-	 */
551
-	public function updateAvatarPostLogin($params) {
552
-		if(isset($params['uid']) && $params['uid'] === $this->getUsername()) {
553
-			$this->updateAvatar();
554
-		}
555
-	}
556
-
557
-	/**
558
-	 * @brief attempts to get an image from LDAP and sets it as Nextcloud avatar
559
-	 * @return bool
560
-	 */
561
-	public function updateAvatar($force = false) {
562
-		if(!$force && $this->wasRefreshed('avatar')) {
563
-			return false;
564
-		}
565
-		$avatarImage = $this->getAvatarImage();
566
-		if($avatarImage === false) {
567
-			//not set, nothing left to do;
568
-			return false;
569
-		}
570
-		if(!$this->image->loadFromBase64(base64_encode($avatarImage))) {
571
-			return false;
572
-		}
573
-		return $this->setOwnCloudAvatar();
574
-	}
575
-
576
-	/**
577
-	 * @brief sets an image as Nextcloud avatar
578
-	 * @return bool
579
-	 */
580
-	private function setOwnCloudAvatar() {
581
-		if(!$this->image->valid()) {
582
-			$this->log->log('avatar image data from LDAP invalid for '.$this->dn, Util::ERROR);
583
-			return false;
584
-		}
585
-		//make sure it is a square and not bigger than 128x128
586
-		$size = min(array($this->image->width(), $this->image->height(), 128));
587
-		if(!$this->image->centerCrop($size)) {
588
-			$this->log->log('croping image for avatar failed for '.$this->dn, Util::ERROR);
589
-			return false;
590
-		}
591
-
592
-		if(!$this->fs->isLoaded()) {
593
-			$this->fs->setup($this->uid);
594
-		}
595
-
596
-		try {
597
-			$avatar = $this->avatarManager->getAvatar($this->uid);
598
-			$avatar->set($this->image);
599
-			return true;
600
-		} catch (\Exception $e) {
601
-			\OC::$server->getLogger()->notice(
602
-				'Could not set avatar for ' . $this->dn	. ', because: ' . $e->getMessage(),
603
-				['app' => 'user_ldap']);
604
-		}
605
-		return false;
606
-	}
607
-
608
-	/**
609
-	 * called by a post_login hook to handle password expiry
610
-	 *
611
-	 * @param array $params
612
-	 */
613
-	public function handlePasswordExpiry($params) {
614
-		$ppolicyDN = $this->connection->ldapDefaultPPolicyDN;
615
-		if (empty($ppolicyDN) || (intval($this->connection->turnOnPasswordChange) !== 1)) {
616
-			return;//password expiry handling disabled
617
-		}
618
-		$uid = $params['uid'];
619
-		if(isset($uid) && $uid === $this->getUsername()) {
620
-			//retrieve relevant user attributes
621
-			$result = $this->access->search('objectclass=*', array($this->dn), ['pwdpolicysubentry', 'pwdgraceusetime', 'pwdreset', 'pwdchangedtime']);
128
+        if ($username === null) {
129
+            $log->log("uid for '$dn' must not be null!", Util::ERROR);
130
+            throw new \InvalidArgumentException('uid must not be null!');
131
+        } else if ($username === '') {
132
+            $log->log("uid for '$dn' must not be an empty string", Util::ERROR);
133
+            throw new \InvalidArgumentException('uid must not be an empty string!');
134
+        }
135
+
136
+        $this->access              = $access;
137
+        $this->connection          = $access->getConnection();
138
+        $this->config              = $config;
139
+        $this->fs                  = $fs;
140
+        $this->dn                  = $dn;
141
+        $this->uid                 = $username;
142
+        $this->image               = $image;
143
+        $this->log                 = $log;
144
+        $this->avatarManager       = $avatarManager;
145
+        $this->userManager         = $userManager;
146
+        $this->notificationManager = $notificationManager;
147
+
148
+        Util::connectHook('OC_User', 'post_login', $this, 'handlePasswordExpiry');
149
+    }
150
+
151
+    /**
152
+     * @brief updates properties like email, quota or avatar provided by LDAP
153
+     * @return null
154
+     */
155
+    public function update() {
156
+        if(is_null($this->dn)) {
157
+            return null;
158
+        }
159
+
160
+        $hasLoggedIn = $this->config->getUserValue($this->uid, 'user_ldap',
161
+                self::USER_PREFKEY_FIRSTLOGIN, 0);
162
+
163
+        if($this->needsRefresh()) {
164
+            $this->updateEmail();
165
+            $this->updateQuota();
166
+            if($hasLoggedIn !== 0) {
167
+                //we do not need to try it, when the user has not been logged in
168
+                //before, because the file system will not be ready.
169
+                $this->updateAvatar();
170
+                //in order to get an avatar as soon as possible, mark the user
171
+                //as refreshed only when updating the avatar did happen
172
+                $this->markRefreshTime();
173
+            }
174
+        }
175
+    }
176
+
177
+    /**
178
+     * processes results from LDAP for attributes as returned by getAttributesToRead()
179
+     * @param array $ldapEntry the user entry as retrieved from LDAP
180
+     */
181
+    public function processAttributes($ldapEntry) {
182
+        $this->markRefreshTime();
183
+        //Quota
184
+        $attr = strtolower($this->connection->ldapQuotaAttribute);
185
+        if(isset($ldapEntry[$attr])) {
186
+            $this->updateQuota($ldapEntry[$attr][0]);
187
+        } else {
188
+            if ($this->connection->ldapQuotaDefault !== '') {
189
+                $this->updateQuota();
190
+            }
191
+        }
192
+        unset($attr);
193
+
194
+        //displayName
195
+        $displayName = $displayName2 = '';
196
+        $attr = strtolower($this->connection->ldapUserDisplayName);
197
+        if(isset($ldapEntry[$attr])) {
198
+            $displayName = strval($ldapEntry[$attr][0]);
199
+        }
200
+        $attr = strtolower($this->connection->ldapUserDisplayName2);
201
+        if(isset($ldapEntry[$attr])) {
202
+            $displayName2 = strval($ldapEntry[$attr][0]);
203
+        }
204
+        if ($displayName !== '') {
205
+            $this->composeAndStoreDisplayName($displayName);
206
+            $this->access->cacheUserDisplayName(
207
+                $this->getUsername(),
208
+                $displayName,
209
+                $displayName2
210
+            );
211
+        }
212
+        unset($attr);
213
+
214
+        //Email
215
+        //email must be stored after displayname, because it would cause a user
216
+        //change event that will trigger fetching the display name again
217
+        $attr = strtolower($this->connection->ldapEmailAttribute);
218
+        if(isset($ldapEntry[$attr])) {
219
+            $this->updateEmail($ldapEntry[$attr][0]);
220
+        }
221
+        unset($attr);
222
+
223
+        // LDAP Username, needed for s2s sharing
224
+        if(isset($ldapEntry['uid'])) {
225
+            $this->storeLDAPUserName($ldapEntry['uid'][0]);
226
+        } else if(isset($ldapEntry['samaccountname'])) {
227
+            $this->storeLDAPUserName($ldapEntry['samaccountname'][0]);
228
+        }
229
+
230
+        //homePath
231
+        if(strpos($this->connection->homeFolderNamingRule, 'attr:') === 0) {
232
+            $attr = strtolower(substr($this->connection->homeFolderNamingRule, strlen('attr:')));
233
+            if(isset($ldapEntry[$attr])) {
234
+                $this->access->cacheUserHome(
235
+                    $this->getUsername(), $this->getHomePath($ldapEntry[$attr][0]));
236
+            }
237
+        }
238
+
239
+        //memberOf groups
240
+        $cacheKey = 'getMemberOf'.$this->getUsername();
241
+        $groups = false;
242
+        if(isset($ldapEntry['memberof'])) {
243
+            $groups = $ldapEntry['memberof'];
244
+        }
245
+        $this->connection->writeToCache($cacheKey, $groups);
246
+
247
+        //Avatar
248
+        /** @var Connection $connection */
249
+        $connection = $this->access->getConnection();
250
+        $attributes = $connection->resolveRule('avatar');
251
+        foreach ($attributes as $attribute)  {
252
+            if(isset($ldapEntry[$attribute])) {
253
+                $this->avatarImage = $ldapEntry[$attribute][0];
254
+                // the call to the method that saves the avatar in the file
255
+                // system must be postponed after the login. It is to ensure
256
+                // external mounts are mounted properly (e.g. with login
257
+                // credentials from the session).
258
+                Util::connectHook('OC_User', 'post_login', $this, 'updateAvatarPostLogin');
259
+                break;
260
+            }
261
+        }
262
+    }
263
+
264
+    /**
265
+     * @brief returns the LDAP DN of the user
266
+     * @return string
267
+     */
268
+    public function getDN() {
269
+        return $this->dn;
270
+    }
271
+
272
+    /**
273
+     * @brief returns the Nextcloud internal username of the user
274
+     * @return string
275
+     */
276
+    public function getUsername() {
277
+        return $this->uid;
278
+    }
279
+
280
+    /**
281
+     * returns the home directory of the user if specified by LDAP settings
282
+     * @param string $valueFromLDAP
283
+     * @return bool|string
284
+     * @throws \Exception
285
+     */
286
+    public function getHomePath($valueFromLDAP = null) {
287
+        $path = strval($valueFromLDAP);
288
+        $attr = null;
289
+
290
+        if (is_null($valueFromLDAP)
291
+           && strpos($this->access->connection->homeFolderNamingRule, 'attr:') === 0
292
+           && $this->access->connection->homeFolderNamingRule !== 'attr:')
293
+        {
294
+            $attr = substr($this->access->connection->homeFolderNamingRule, strlen('attr:'));
295
+            $homedir = $this->access->readAttribute(
296
+                $this->access->username2dn($this->getUsername()), $attr);
297
+            if ($homedir && isset($homedir[0])) {
298
+                $path = $homedir[0];
299
+            }
300
+        }
301
+
302
+        if ($path !== '') {
303
+            //if attribute's value is an absolute path take this, otherwise append it to data dir
304
+            //check for / at the beginning or pattern c:\ resp. c:/
305
+            if(   '/' !== $path[0]
306
+               && !(3 < strlen($path) && ctype_alpha($path[0])
307
+                   && $path[1] === ':' && ('\\' === $path[2] || '/' === $path[2]))
308
+            ) {
309
+                $path = $this->config->getSystemValue('datadirectory',
310
+                        \OC::$SERVERROOT.'/data' ) . '/' . $path;
311
+            }
312
+            //we need it to store it in the DB as well in case a user gets
313
+            //deleted so we can clean up afterwards
314
+            $this->config->setUserValue(
315
+                $this->getUsername(), 'user_ldap', 'homePath', $path
316
+            );
317
+            return $path;
318
+        }
319
+
320
+        if(    !is_null($attr)
321
+            && $this->config->getAppValue('user_ldap', 'enforce_home_folder_naming_rule', true)
322
+        ) {
323
+            // a naming rule attribute is defined, but it doesn't exist for that LDAP user
324
+            throw new \Exception('Home dir attribute can\'t be read from LDAP for uid: ' . $this->getUsername());
325
+        }
326
+
327
+        //false will apply default behaviour as defined and done by OC_User
328
+        $this->config->setUserValue($this->getUsername(), 'user_ldap', 'homePath', '');
329
+        return false;
330
+    }
331
+
332
+    public function getMemberOfGroups() {
333
+        $cacheKey = 'getMemberOf'.$this->getUsername();
334
+        $memberOfGroups = $this->connection->getFromCache($cacheKey);
335
+        if(!is_null($memberOfGroups)) {
336
+            return $memberOfGroups;
337
+        }
338
+        $groupDNs = $this->access->readAttribute($this->getDN(), 'memberOf');
339
+        $this->connection->writeToCache($cacheKey, $groupDNs);
340
+        return $groupDNs;
341
+    }
342
+
343
+    /**
344
+     * @brief reads the image from LDAP that shall be used as Avatar
345
+     * @return string data (provided by LDAP) | false
346
+     */
347
+    public function getAvatarImage() {
348
+        if(!is_null($this->avatarImage)) {
349
+            return $this->avatarImage;
350
+        }
351
+
352
+        $this->avatarImage = false;
353
+        /** @var Connection $connection */
354
+        $connection = $this->access->getConnection();
355
+        $attributes = $connection->resolveRule('avatar');
356
+        foreach($attributes as $attribute) {
357
+            $result = $this->access->readAttribute($this->dn, $attribute);
358
+            if($result !== false && is_array($result) && isset($result[0])) {
359
+                $this->avatarImage = $result[0];
360
+                break;
361
+            }
362
+        }
363
+
364
+        return $this->avatarImage;
365
+    }
366
+
367
+    /**
368
+     * @brief marks the user as having logged in at least once
369
+     * @return null
370
+     */
371
+    public function markLogin() {
372
+        $this->config->setUserValue(
373
+            $this->uid, 'user_ldap', self::USER_PREFKEY_FIRSTLOGIN, 1);
374
+    }
375
+
376
+    /**
377
+     * @brief marks the time when user features like email have been updated
378
+     * @return null
379
+     */
380
+    public function markRefreshTime() {
381
+        $this->config->setUserValue(
382
+            $this->uid, 'user_ldap', self::USER_PREFKEY_LASTREFRESH, time());
383
+    }
384
+
385
+    /**
386
+     * @brief checks whether user features needs to be updated again by
387
+     * comparing the difference of time of the last refresh to now with the
388
+     * desired interval
389
+     * @return bool
390
+     */
391
+    private function needsRefresh() {
392
+        $lastChecked = $this->config->getUserValue($this->uid, 'user_ldap',
393
+            self::USER_PREFKEY_LASTREFRESH, 0);
394
+
395
+        if((time() - intval($lastChecked)) < intval($this->config->getAppValue('user_ldap', 'updateAttributesInterval', 86400)) ) {
396
+            return false;
397
+        }
398
+        return  true;
399
+    }
400
+
401
+    /**
402
+     * Stores a key-value pair in relation to this user
403
+     *
404
+     * @param string $key
405
+     * @param string $value
406
+     */
407
+    private function store($key, $value) {
408
+        $this->config->setUserValue($this->uid, 'user_ldap', $key, $value);
409
+    }
410
+
411
+    /**
412
+     * Composes the display name and stores it in the database. The final
413
+     * display name is returned.
414
+     *
415
+     * @param string $displayName
416
+     * @param string $displayName2
417
+     * @returns string the effective display name
418
+     */
419
+    public function composeAndStoreDisplayName($displayName, $displayName2 = '') {
420
+        $displayName2 = strval($displayName2);
421
+        if($displayName2 !== '') {
422
+            $displayName .= ' (' . $displayName2 . ')';
423
+        }
424
+        $this->store('displayName', $displayName);
425
+        return $displayName;
426
+    }
427
+
428
+    /**
429
+     * Stores the LDAP Username in the Database
430
+     * @param string $userName
431
+     */
432
+    public function storeLDAPUserName($userName) {
433
+        $this->store('uid', $userName);
434
+    }
435
+
436
+    /**
437
+     * @brief checks whether an update method specified by feature was run
438
+     * already. If not, it will marked like this, because it is expected that
439
+     * the method will be run, when false is returned.
440
+     * @param string $feature email | quota | avatar (can be extended)
441
+     * @return bool
442
+     */
443
+    private function wasRefreshed($feature) {
444
+        if(isset($this->refreshedFeatures[$feature])) {
445
+            return true;
446
+        }
447
+        $this->refreshedFeatures[$feature] = 1;
448
+        return false;
449
+    }
450
+
451
+    /**
452
+     * fetches the email from LDAP and stores it as Nextcloud user value
453
+     * @param string $valueFromLDAP if known, to save an LDAP read request
454
+     * @return null
455
+     */
456
+    public function updateEmail($valueFromLDAP = null) {
457
+        if($this->wasRefreshed('email')) {
458
+            return;
459
+        }
460
+        $email = strval($valueFromLDAP);
461
+        if(is_null($valueFromLDAP)) {
462
+            $emailAttribute = $this->connection->ldapEmailAttribute;
463
+            if ($emailAttribute !== '') {
464
+                $aEmail = $this->access->readAttribute($this->dn, $emailAttribute);
465
+                if(is_array($aEmail) && (count($aEmail) > 0)) {
466
+                    $email = strval($aEmail[0]);
467
+                }
468
+            }
469
+        }
470
+        if ($email !== '') {
471
+            $user = $this->userManager->get($this->uid);
472
+            if (!is_null($user)) {
473
+                $currentEmail = strval($user->getEMailAddress());
474
+                if ($currentEmail !== $email) {
475
+                    $user->setEMailAddress($email);
476
+                }
477
+            }
478
+        }
479
+    }
480
+
481
+    /**
482
+     * Overall process goes as follow:
483
+     * 1. fetch the quota from LDAP and check if it's parseable with the "verifyQuotaValue" function
484
+     * 2. if the value can't be fetched, is empty or not parseable, use the default LDAP quota
485
+     * 3. if the default LDAP quota can't be parsed, use the Nextcloud's default quota (use 'default')
486
+     * 4. check if the target user exists and set the quota for the user.
487
+     *
488
+     * In order to improve performance and prevent an unwanted extra LDAP call, the $valueFromLDAP
489
+     * parameter can be passed with the value of the attribute. This value will be considered as the
490
+     * quota for the user coming from the LDAP server (step 1 of the process) It can be useful to
491
+     * fetch all the user's attributes in one call and use the fetched values in this function.
492
+     * The expected value for that parameter is a string describing the quota for the user. Valid
493
+     * values are 'none' (unlimited), 'default' (the Nextcloud's default quota), '1234' (quota in
494
+     * bytes), '1234 MB' (quota in MB - check the \OC_Helper::computerFileSize method for more info)
495
+     *
496
+     * fetches the quota from LDAP and stores it as Nextcloud user value
497
+     * @param string $valueFromLDAP the quota attribute's value can be passed,
498
+     * to save the readAttribute request
499
+     * @return null
500
+     */
501
+    public function updateQuota($valueFromLDAP = null) {
502
+        if($this->wasRefreshed('quota')) {
503
+            return;
504
+        }
505
+
506
+        $quotaAttribute = $this->connection->ldapQuotaAttribute;
507
+        $defaultQuota = $this->connection->ldapQuotaDefault;
508
+        if($quotaAttribute === '' && $defaultQuota === '') {
509
+            return;
510
+        }
511
+
512
+        $quota = false;
513
+        if(is_null($valueFromLDAP) && $quotaAttribute !== '') {
514
+            $aQuota = $this->access->readAttribute($this->dn, $quotaAttribute);
515
+            if($aQuota && (count($aQuota) > 0) && $this->verifyQuotaValue($aQuota[0])) {
516
+                $quota = $aQuota[0];
517
+            } else if(is_array($aQuota) && isset($aQuota[0])) {
518
+                $this->log->log('no suitable LDAP quota found for user ' . $this->uid . ': [' . $aQuota[0] . ']', Util::DEBUG);
519
+            }
520
+        } else if ($this->verifyQuotaValue($valueFromLDAP)) {
521
+            $quota = $valueFromLDAP;
522
+        } else {
523
+            $this->log->log('no suitable LDAP quota found for user ' . $this->uid . ': [' . $valueFromLDAP . ']', Util::DEBUG);
524
+        }
525
+
526
+        if ($quota === false && $this->verifyQuotaValue($defaultQuota)) {
527
+            // quota not found using the LDAP attribute (or not parseable). Try the default quota
528
+            $quota = $defaultQuota;
529
+        } else if($quota === false) {
530
+            $this->log->log('no suitable default quota found for user ' . $this->uid . ': [' . $defaultQuota . ']', Util::DEBUG);
531
+            return;
532
+        }
533
+
534
+        $targetUser = $this->userManager->get($this->uid);
535
+        if ($targetUser instanceof IUser) {
536
+            $targetUser->setQuota($quota);
537
+        } else {
538
+            $this->log->log('trying to set a quota for user ' . $this->uid . ' but the user is missing', Util::INFO);
539
+        }
540
+    }
541
+
542
+    private function verifyQuotaValue($quotaValue) {
543
+        return $quotaValue === 'none' || $quotaValue === 'default' || \OC_Helper::computerFileSize($quotaValue) !== false;
544
+    }
545
+
546
+    /**
547
+     * called by a post_login hook to save the avatar picture
548
+     *
549
+     * @param array $params
550
+     */
551
+    public function updateAvatarPostLogin($params) {
552
+        if(isset($params['uid']) && $params['uid'] === $this->getUsername()) {
553
+            $this->updateAvatar();
554
+        }
555
+    }
556
+
557
+    /**
558
+     * @brief attempts to get an image from LDAP and sets it as Nextcloud avatar
559
+     * @return bool
560
+     */
561
+    public function updateAvatar($force = false) {
562
+        if(!$force && $this->wasRefreshed('avatar')) {
563
+            return false;
564
+        }
565
+        $avatarImage = $this->getAvatarImage();
566
+        if($avatarImage === false) {
567
+            //not set, nothing left to do;
568
+            return false;
569
+        }
570
+        if(!$this->image->loadFromBase64(base64_encode($avatarImage))) {
571
+            return false;
572
+        }
573
+        return $this->setOwnCloudAvatar();
574
+    }
575
+
576
+    /**
577
+     * @brief sets an image as Nextcloud avatar
578
+     * @return bool
579
+     */
580
+    private function setOwnCloudAvatar() {
581
+        if(!$this->image->valid()) {
582
+            $this->log->log('avatar image data from LDAP invalid for '.$this->dn, Util::ERROR);
583
+            return false;
584
+        }
585
+        //make sure it is a square and not bigger than 128x128
586
+        $size = min(array($this->image->width(), $this->image->height(), 128));
587
+        if(!$this->image->centerCrop($size)) {
588
+            $this->log->log('croping image for avatar failed for '.$this->dn, Util::ERROR);
589
+            return false;
590
+        }
591
+
592
+        if(!$this->fs->isLoaded()) {
593
+            $this->fs->setup($this->uid);
594
+        }
595
+
596
+        try {
597
+            $avatar = $this->avatarManager->getAvatar($this->uid);
598
+            $avatar->set($this->image);
599
+            return true;
600
+        } catch (\Exception $e) {
601
+            \OC::$server->getLogger()->notice(
602
+                'Could not set avatar for ' . $this->dn	. ', because: ' . $e->getMessage(),
603
+                ['app' => 'user_ldap']);
604
+        }
605
+        return false;
606
+    }
607
+
608
+    /**
609
+     * called by a post_login hook to handle password expiry
610
+     *
611
+     * @param array $params
612
+     */
613
+    public function handlePasswordExpiry($params) {
614
+        $ppolicyDN = $this->connection->ldapDefaultPPolicyDN;
615
+        if (empty($ppolicyDN) || (intval($this->connection->turnOnPasswordChange) !== 1)) {
616
+            return;//password expiry handling disabled
617
+        }
618
+        $uid = $params['uid'];
619
+        if(isset($uid) && $uid === $this->getUsername()) {
620
+            //retrieve relevant user attributes
621
+            $result = $this->access->search('objectclass=*', array($this->dn), ['pwdpolicysubentry', 'pwdgraceusetime', 'pwdreset', 'pwdchangedtime']);
622 622
 			
623
-			if(array_key_exists('pwdpolicysubentry', $result[0])) {
624
-				$pwdPolicySubentry = $result[0]['pwdpolicysubentry'];
625
-				if($pwdPolicySubentry && (count($pwdPolicySubentry) > 0)){
626
-					$ppolicyDN = $pwdPolicySubentry[0];//custom ppolicy DN
627
-				}
628
-			}
623
+            if(array_key_exists('pwdpolicysubentry', $result[0])) {
624
+                $pwdPolicySubentry = $result[0]['pwdpolicysubentry'];
625
+                if($pwdPolicySubentry && (count($pwdPolicySubentry) > 0)){
626
+                    $ppolicyDN = $pwdPolicySubentry[0];//custom ppolicy DN
627
+                }
628
+            }
629 629
 			
630
-			$pwdGraceUseTime = array_key_exists('pwdgraceusetime', $result[0]) ? $result[0]['pwdgraceusetime'] : null;
631
-			$pwdReset = array_key_exists('pwdreset', $result[0]) ? $result[0]['pwdreset'] : null;
632
-			$pwdChangedTime = array_key_exists('pwdchangedtime', $result[0]) ? $result[0]['pwdchangedtime'] : null;
630
+            $pwdGraceUseTime = array_key_exists('pwdgraceusetime', $result[0]) ? $result[0]['pwdgraceusetime'] : null;
631
+            $pwdReset = array_key_exists('pwdreset', $result[0]) ? $result[0]['pwdreset'] : null;
632
+            $pwdChangedTime = array_key_exists('pwdchangedtime', $result[0]) ? $result[0]['pwdchangedtime'] : null;
633 633
 			
634
-			//retrieve relevant password policy attributes
635
-			$cacheKey = 'ppolicyAttributes' . $ppolicyDN;
636
-			$result = $this->connection->getFromCache($cacheKey);
637
-			if(is_null($result)) {
638
-				$result = $this->access->search('objectclass=*', array($ppolicyDN), ['pwdgraceauthnlimit', 'pwdmaxage', 'pwdexpirewarning']);
639
-				$this->connection->writeToCache($cacheKey, $result);
640
-			}
634
+            //retrieve relevant password policy attributes
635
+            $cacheKey = 'ppolicyAttributes' . $ppolicyDN;
636
+            $result = $this->connection->getFromCache($cacheKey);
637
+            if(is_null($result)) {
638
+                $result = $this->access->search('objectclass=*', array($ppolicyDN), ['pwdgraceauthnlimit', 'pwdmaxage', 'pwdexpirewarning']);
639
+                $this->connection->writeToCache($cacheKey, $result);
640
+            }
641 641
 			
642
-			$pwdGraceAuthNLimit = array_key_exists('pwdgraceauthnlimit', $result[0]) ? $result[0]['pwdgraceauthnlimit'] : null;
643
-			$pwdMaxAge = array_key_exists('pwdmaxage', $result[0]) ? $result[0]['pwdmaxage'] : null;
644
-			$pwdExpireWarning = array_key_exists('pwdexpirewarning', $result[0]) ? $result[0]['pwdexpirewarning'] : null;
642
+            $pwdGraceAuthNLimit = array_key_exists('pwdgraceauthnlimit', $result[0]) ? $result[0]['pwdgraceauthnlimit'] : null;
643
+            $pwdMaxAge = array_key_exists('pwdmaxage', $result[0]) ? $result[0]['pwdmaxage'] : null;
644
+            $pwdExpireWarning = array_key_exists('pwdexpirewarning', $result[0]) ? $result[0]['pwdexpirewarning'] : null;
645 645
 			
646
-			//handle grace login
647
-			$pwdGraceUseTimeCount = count($pwdGraceUseTime);
648
-			if($pwdGraceUseTime && $pwdGraceUseTimeCount > 0) { //was this a grace login?
649
-				if($pwdGraceAuthNLimit 
650
-					&& (count($pwdGraceAuthNLimit) > 0)
651
-					&&($pwdGraceUseTimeCount < intval($pwdGraceAuthNLimit[0]))) { //at least one more grace login available?
652
-					$this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true');
653
-					header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
654
-					'user_ldap.renewPassword.showRenewPasswordForm', array('user' => $uid)));
655
-				} else { //no more grace login available
656
-					header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
657
-					'user_ldap.renewPassword.showLoginFormInvalidPassword', array('user' => $uid)));
658
-				}
659
-				exit();
660
-			}
661
-			//handle pwdReset attribute
662
-			if($pwdReset && (count($pwdReset) > 0) && $pwdReset[0] === 'TRUE') { //user must change his password
663
-				$this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true');
664
-				header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
665
-				'user_ldap.renewPassword.showRenewPasswordForm', array('user' => $uid)));
666
-				exit();
667
-			}
668
-			//handle password expiry warning
669
-			if($pwdChangedTime && (count($pwdChangedTime) > 0)) {
670
-				if($pwdMaxAge && (count($pwdMaxAge) > 0)
671
-					&& $pwdExpireWarning && (count($pwdExpireWarning) > 0)) {
672
-					$pwdMaxAgeInt = intval($pwdMaxAge[0]);
673
-					$pwdExpireWarningInt = intval($pwdExpireWarning[0]);
674
-					if($pwdMaxAgeInt > 0 && $pwdExpireWarningInt > 0){
675
-						$pwdChangedTimeDt = \DateTime::createFromFormat('YmdHisZ', $pwdChangedTime[0]);
676
-						$pwdChangedTimeDt->add(new \DateInterval('PT'.$pwdMaxAgeInt.'S'));
677
-						$currentDateTime = new \DateTime();
678
-						$secondsToExpiry = $pwdChangedTimeDt->getTimestamp() - $currentDateTime->getTimestamp();
679
-						if($secondsToExpiry <= $pwdExpireWarningInt) {
680
-							//remove last password expiry warning if any
681
-							$notification = $this->notificationManager->createNotification();
682
-							$notification->setApp('user_ldap')
683
-								->setUser($uid)
684
-								->setObject('pwd_exp_warn', $uid)
685
-							;
686
-							$this->notificationManager->markProcessed($notification);
687
-							//create new password expiry warning
688
-							$notification = $this->notificationManager->createNotification();
689
-							$notification->setApp('user_ldap')
690
-								->setUser($uid)
691
-								->setDateTime($currentDateTime)
692
-								->setObject('pwd_exp_warn', $uid) 
693
-								->setSubject('pwd_exp_warn_days', [(int) ceil($secondsToExpiry / 60 / 60 / 24)])
694
-							;
695
-							$this->notificationManager->notify($notification);
696
-						}
697
-					}
698
-				}
699
-			}
700
-		}
701
-	}
646
+            //handle grace login
647
+            $pwdGraceUseTimeCount = count($pwdGraceUseTime);
648
+            if($pwdGraceUseTime && $pwdGraceUseTimeCount > 0) { //was this a grace login?
649
+                if($pwdGraceAuthNLimit 
650
+                    && (count($pwdGraceAuthNLimit) > 0)
651
+                    &&($pwdGraceUseTimeCount < intval($pwdGraceAuthNLimit[0]))) { //at least one more grace login available?
652
+                    $this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true');
653
+                    header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
654
+                    'user_ldap.renewPassword.showRenewPasswordForm', array('user' => $uid)));
655
+                } else { //no more grace login available
656
+                    header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
657
+                    'user_ldap.renewPassword.showLoginFormInvalidPassword', array('user' => $uid)));
658
+                }
659
+                exit();
660
+            }
661
+            //handle pwdReset attribute
662
+            if($pwdReset && (count($pwdReset) > 0) && $pwdReset[0] === 'TRUE') { //user must change his password
663
+                $this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true');
664
+                header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
665
+                'user_ldap.renewPassword.showRenewPasswordForm', array('user' => $uid)));
666
+                exit();
667
+            }
668
+            //handle password expiry warning
669
+            if($pwdChangedTime && (count($pwdChangedTime) > 0)) {
670
+                if($pwdMaxAge && (count($pwdMaxAge) > 0)
671
+                    && $pwdExpireWarning && (count($pwdExpireWarning) > 0)) {
672
+                    $pwdMaxAgeInt = intval($pwdMaxAge[0]);
673
+                    $pwdExpireWarningInt = intval($pwdExpireWarning[0]);
674
+                    if($pwdMaxAgeInt > 0 && $pwdExpireWarningInt > 0){
675
+                        $pwdChangedTimeDt = \DateTime::createFromFormat('YmdHisZ', $pwdChangedTime[0]);
676
+                        $pwdChangedTimeDt->add(new \DateInterval('PT'.$pwdMaxAgeInt.'S'));
677
+                        $currentDateTime = new \DateTime();
678
+                        $secondsToExpiry = $pwdChangedTimeDt->getTimestamp() - $currentDateTime->getTimestamp();
679
+                        if($secondsToExpiry <= $pwdExpireWarningInt) {
680
+                            //remove last password expiry warning if any
681
+                            $notification = $this->notificationManager->createNotification();
682
+                            $notification->setApp('user_ldap')
683
+                                ->setUser($uid)
684
+                                ->setObject('pwd_exp_warn', $uid)
685
+                            ;
686
+                            $this->notificationManager->markProcessed($notification);
687
+                            //create new password expiry warning
688
+                            $notification = $this->notificationManager->createNotification();
689
+                            $notification->setApp('user_ldap')
690
+                                ->setUser($uid)
691
+                                ->setDateTime($currentDateTime)
692
+                                ->setObject('pwd_exp_warn', $uid) 
693
+                                ->setSubject('pwd_exp_warn_days', [(int) ceil($secondsToExpiry / 60 / 60 / 24)])
694
+                            ;
695
+                            $this->notificationManager->notify($notification);
696
+                        }
697
+                    }
698
+                }
699
+            }
700
+        }
701
+    }
702 702
 }
Please login to merge, or discard this patch.
Spacing   +61 added lines, -61 removed lines patch added patch discarded remove patch
@@ -153,17 +153,17 @@  discard block
 block discarded – undo
153 153
 	 * @return null
154 154
 	 */
155 155
 	public function update() {
156
-		if(is_null($this->dn)) {
156
+		if (is_null($this->dn)) {
157 157
 			return null;
158 158
 		}
159 159
 
160 160
 		$hasLoggedIn = $this->config->getUserValue($this->uid, 'user_ldap',
161 161
 				self::USER_PREFKEY_FIRSTLOGIN, 0);
162 162
 
163
-		if($this->needsRefresh()) {
163
+		if ($this->needsRefresh()) {
164 164
 			$this->updateEmail();
165 165
 			$this->updateQuota();
166
-			if($hasLoggedIn !== 0) {
166
+			if ($hasLoggedIn !== 0) {
167 167
 				//we do not need to try it, when the user has not been logged in
168 168
 				//before, because the file system will not be ready.
169 169
 				$this->updateAvatar();
@@ -182,7 +182,7 @@  discard block
 block discarded – undo
182 182
 		$this->markRefreshTime();
183 183
 		//Quota
184 184
 		$attr = strtolower($this->connection->ldapQuotaAttribute);
185
-		if(isset($ldapEntry[$attr])) {
185
+		if (isset($ldapEntry[$attr])) {
186 186
 			$this->updateQuota($ldapEntry[$attr][0]);
187 187
 		} else {
188 188
 			if ($this->connection->ldapQuotaDefault !== '') {
@@ -194,11 +194,11 @@  discard block
 block discarded – undo
194 194
 		//displayName
195 195
 		$displayName = $displayName2 = '';
196 196
 		$attr = strtolower($this->connection->ldapUserDisplayName);
197
-		if(isset($ldapEntry[$attr])) {
197
+		if (isset($ldapEntry[$attr])) {
198 198
 			$displayName = strval($ldapEntry[$attr][0]);
199 199
 		}
200 200
 		$attr = strtolower($this->connection->ldapUserDisplayName2);
201
-		if(isset($ldapEntry[$attr])) {
201
+		if (isset($ldapEntry[$attr])) {
202 202
 			$displayName2 = strval($ldapEntry[$attr][0]);
203 203
 		}
204 204
 		if ($displayName !== '') {
@@ -215,22 +215,22 @@  discard block
 block discarded – undo
215 215
 		//email must be stored after displayname, because it would cause a user
216 216
 		//change event that will trigger fetching the display name again
217 217
 		$attr = strtolower($this->connection->ldapEmailAttribute);
218
-		if(isset($ldapEntry[$attr])) {
218
+		if (isset($ldapEntry[$attr])) {
219 219
 			$this->updateEmail($ldapEntry[$attr][0]);
220 220
 		}
221 221
 		unset($attr);
222 222
 
223 223
 		// LDAP Username, needed for s2s sharing
224
-		if(isset($ldapEntry['uid'])) {
224
+		if (isset($ldapEntry['uid'])) {
225 225
 			$this->storeLDAPUserName($ldapEntry['uid'][0]);
226
-		} else if(isset($ldapEntry['samaccountname'])) {
226
+		} else if (isset($ldapEntry['samaccountname'])) {
227 227
 			$this->storeLDAPUserName($ldapEntry['samaccountname'][0]);
228 228
 		}
229 229
 
230 230
 		//homePath
231
-		if(strpos($this->connection->homeFolderNamingRule, 'attr:') === 0) {
231
+		if (strpos($this->connection->homeFolderNamingRule, 'attr:') === 0) {
232 232
 			$attr = strtolower(substr($this->connection->homeFolderNamingRule, strlen('attr:')));
233
-			if(isset($ldapEntry[$attr])) {
233
+			if (isset($ldapEntry[$attr])) {
234 234
 				$this->access->cacheUserHome(
235 235
 					$this->getUsername(), $this->getHomePath($ldapEntry[$attr][0]));
236 236
 			}
@@ -239,7 +239,7 @@  discard block
 block discarded – undo
239 239
 		//memberOf groups
240 240
 		$cacheKey = 'getMemberOf'.$this->getUsername();
241 241
 		$groups = false;
242
-		if(isset($ldapEntry['memberof'])) {
242
+		if (isset($ldapEntry['memberof'])) {
243 243
 			$groups = $ldapEntry['memberof'];
244 244
 		}
245 245
 		$this->connection->writeToCache($cacheKey, $groups);
@@ -248,8 +248,8 @@  discard block
 block discarded – undo
248 248
 		/** @var Connection $connection */
249 249
 		$connection = $this->access->getConnection();
250 250
 		$attributes = $connection->resolveRule('avatar');
251
-		foreach ($attributes as $attribute)  {
252
-			if(isset($ldapEntry[$attribute])) {
251
+		foreach ($attributes as $attribute) {
252
+			if (isset($ldapEntry[$attribute])) {
253 253
 				$this->avatarImage = $ldapEntry[$attribute][0];
254 254
 				// the call to the method that saves the avatar in the file
255 255
 				// system must be postponed after the login. It is to ensure
@@ -302,12 +302,12 @@  discard block
 block discarded – undo
302 302
 		if ($path !== '') {
303 303
 			//if attribute's value is an absolute path take this, otherwise append it to data dir
304 304
 			//check for / at the beginning or pattern c:\ resp. c:/
305
-			if(   '/' !== $path[0]
305
+			if ('/' !== $path[0]
306 306
 			   && !(3 < strlen($path) && ctype_alpha($path[0])
307 307
 			       && $path[1] === ':' && ('\\' === $path[2] || '/' === $path[2]))
308 308
 			) {
309 309
 				$path = $this->config->getSystemValue('datadirectory',
310
-						\OC::$SERVERROOT.'/data' ) . '/' . $path;
310
+						\OC::$SERVERROOT.'/data').'/'.$path;
311 311
 			}
312 312
 			//we need it to store it in the DB as well in case a user gets
313 313
 			//deleted so we can clean up afterwards
@@ -317,11 +317,11 @@  discard block
 block discarded – undo
317 317
 			return $path;
318 318
 		}
319 319
 
320
-		if(    !is_null($attr)
320
+		if (!is_null($attr)
321 321
 			&& $this->config->getAppValue('user_ldap', 'enforce_home_folder_naming_rule', true)
322 322
 		) {
323 323
 			// a naming rule attribute is defined, but it doesn't exist for that LDAP user
324
-			throw new \Exception('Home dir attribute can\'t be read from LDAP for uid: ' . $this->getUsername());
324
+			throw new \Exception('Home dir attribute can\'t be read from LDAP for uid: '.$this->getUsername());
325 325
 		}
326 326
 
327 327
 		//false will apply default behaviour as defined and done by OC_User
@@ -332,7 +332,7 @@  discard block
 block discarded – undo
332 332
 	public function getMemberOfGroups() {
333 333
 		$cacheKey = 'getMemberOf'.$this->getUsername();
334 334
 		$memberOfGroups = $this->connection->getFromCache($cacheKey);
335
-		if(!is_null($memberOfGroups)) {
335
+		if (!is_null($memberOfGroups)) {
336 336
 			return $memberOfGroups;
337 337
 		}
338 338
 		$groupDNs = $this->access->readAttribute($this->getDN(), 'memberOf');
@@ -345,7 +345,7 @@  discard block
 block discarded – undo
345 345
 	 * @return string data (provided by LDAP) | false
346 346
 	 */
347 347
 	public function getAvatarImage() {
348
-		if(!is_null($this->avatarImage)) {
348
+		if (!is_null($this->avatarImage)) {
349 349
 			return $this->avatarImage;
350 350
 		}
351 351
 
@@ -353,9 +353,9 @@  discard block
 block discarded – undo
353 353
 		/** @var Connection $connection */
354 354
 		$connection = $this->access->getConnection();
355 355
 		$attributes = $connection->resolveRule('avatar');
356
-		foreach($attributes as $attribute) {
356
+		foreach ($attributes as $attribute) {
357 357
 			$result = $this->access->readAttribute($this->dn, $attribute);
358
-			if($result !== false && is_array($result) && isset($result[0])) {
358
+			if ($result !== false && is_array($result) && isset($result[0])) {
359 359
 				$this->avatarImage = $result[0];
360 360
 				break;
361 361
 			}
@@ -392,7 +392,7 @@  discard block
 block discarded – undo
392 392
 		$lastChecked = $this->config->getUserValue($this->uid, 'user_ldap',
393 393
 			self::USER_PREFKEY_LASTREFRESH, 0);
394 394
 
395
-		if((time() - intval($lastChecked)) < intval($this->config->getAppValue('user_ldap', 'updateAttributesInterval', 86400)) ) {
395
+		if ((time() - intval($lastChecked)) < intval($this->config->getAppValue('user_ldap', 'updateAttributesInterval', 86400))) {
396 396
 			return false;
397 397
 		}
398 398
 		return  true;
@@ -418,8 +418,8 @@  discard block
 block discarded – undo
418 418
 	 */
419 419
 	public function composeAndStoreDisplayName($displayName, $displayName2 = '') {
420 420
 		$displayName2 = strval($displayName2);
421
-		if($displayName2 !== '') {
422
-			$displayName .= ' (' . $displayName2 . ')';
421
+		if ($displayName2 !== '') {
422
+			$displayName .= ' ('.$displayName2.')';
423 423
 		}
424 424
 		$this->store('displayName', $displayName);
425 425
 		return $displayName;
@@ -441,7 +441,7 @@  discard block
 block discarded – undo
441 441
 	 * @return bool
442 442
 	 */
443 443
 	private function wasRefreshed($feature) {
444
-		if(isset($this->refreshedFeatures[$feature])) {
444
+		if (isset($this->refreshedFeatures[$feature])) {
445 445
 			return true;
446 446
 		}
447 447
 		$this->refreshedFeatures[$feature] = 1;
@@ -454,15 +454,15 @@  discard block
 block discarded – undo
454 454
 	 * @return null
455 455
 	 */
456 456
 	public function updateEmail($valueFromLDAP = null) {
457
-		if($this->wasRefreshed('email')) {
457
+		if ($this->wasRefreshed('email')) {
458 458
 			return;
459 459
 		}
460 460
 		$email = strval($valueFromLDAP);
461
-		if(is_null($valueFromLDAP)) {
461
+		if (is_null($valueFromLDAP)) {
462 462
 			$emailAttribute = $this->connection->ldapEmailAttribute;
463 463
 			if ($emailAttribute !== '') {
464 464
 				$aEmail = $this->access->readAttribute($this->dn, $emailAttribute);
465
-				if(is_array($aEmail) && (count($aEmail) > 0)) {
465
+				if (is_array($aEmail) && (count($aEmail) > 0)) {
466 466
 					$email = strval($aEmail[0]);
467 467
 				}
468 468
 			}
@@ -499,35 +499,35 @@  discard block
 block discarded – undo
499 499
 	 * @return null
500 500
 	 */
501 501
 	public function updateQuota($valueFromLDAP = null) {
502
-		if($this->wasRefreshed('quota')) {
502
+		if ($this->wasRefreshed('quota')) {
503 503
 			return;
504 504
 		}
505 505
 
506 506
 		$quotaAttribute = $this->connection->ldapQuotaAttribute;
507 507
 		$defaultQuota = $this->connection->ldapQuotaDefault;
508
-		if($quotaAttribute === '' && $defaultQuota === '') {
508
+		if ($quotaAttribute === '' && $defaultQuota === '') {
509 509
 			return;
510 510
 		}
511 511
 
512 512
 		$quota = false;
513
-		if(is_null($valueFromLDAP) && $quotaAttribute !== '') {
513
+		if (is_null($valueFromLDAP) && $quotaAttribute !== '') {
514 514
 			$aQuota = $this->access->readAttribute($this->dn, $quotaAttribute);
515
-			if($aQuota && (count($aQuota) > 0) && $this->verifyQuotaValue($aQuota[0])) {
515
+			if ($aQuota && (count($aQuota) > 0) && $this->verifyQuotaValue($aQuota[0])) {
516 516
 				$quota = $aQuota[0];
517
-			} else if(is_array($aQuota) && isset($aQuota[0])) {
518
-				$this->log->log('no suitable LDAP quota found for user ' . $this->uid . ': [' . $aQuota[0] . ']', Util::DEBUG);
517
+			} else if (is_array($aQuota) && isset($aQuota[0])) {
518
+				$this->log->log('no suitable LDAP quota found for user '.$this->uid.': ['.$aQuota[0].']', Util::DEBUG);
519 519
 			}
520 520
 		} else if ($this->verifyQuotaValue($valueFromLDAP)) {
521 521
 			$quota = $valueFromLDAP;
522 522
 		} else {
523
-			$this->log->log('no suitable LDAP quota found for user ' . $this->uid . ': [' . $valueFromLDAP . ']', Util::DEBUG);
523
+			$this->log->log('no suitable LDAP quota found for user '.$this->uid.': ['.$valueFromLDAP.']', Util::DEBUG);
524 524
 		}
525 525
 
526 526
 		if ($quota === false && $this->verifyQuotaValue($defaultQuota)) {
527 527
 			// quota not found using the LDAP attribute (or not parseable). Try the default quota
528 528
 			$quota = $defaultQuota;
529
-		} else if($quota === false) {
530
-			$this->log->log('no suitable default quota found for user ' . $this->uid . ': [' . $defaultQuota . ']', Util::DEBUG);
529
+		} else if ($quota === false) {
530
+			$this->log->log('no suitable default quota found for user '.$this->uid.': ['.$defaultQuota.']', Util::DEBUG);
531 531
 			return;
532 532
 		}
533 533
 
@@ -535,7 +535,7 @@  discard block
 block discarded – undo
535 535
 		if ($targetUser instanceof IUser) {
536 536
 			$targetUser->setQuota($quota);
537 537
 		} else {
538
-			$this->log->log('trying to set a quota for user ' . $this->uid . ' but the user is missing', Util::INFO);
538
+			$this->log->log('trying to set a quota for user '.$this->uid.' but the user is missing', Util::INFO);
539 539
 		}
540 540
 	}
541 541
 
@@ -549,7 +549,7 @@  discard block
 block discarded – undo
549 549
 	 * @param array $params
550 550
 	 */
551 551
 	public function updateAvatarPostLogin($params) {
552
-		if(isset($params['uid']) && $params['uid'] === $this->getUsername()) {
552
+		if (isset($params['uid']) && $params['uid'] === $this->getUsername()) {
553 553
 			$this->updateAvatar();
554 554
 		}
555 555
 	}
@@ -559,15 +559,15 @@  discard block
 block discarded – undo
559 559
 	 * @return bool
560 560
 	 */
561 561
 	public function updateAvatar($force = false) {
562
-		if(!$force && $this->wasRefreshed('avatar')) {
562
+		if (!$force && $this->wasRefreshed('avatar')) {
563 563
 			return false;
564 564
 		}
565 565
 		$avatarImage = $this->getAvatarImage();
566
-		if($avatarImage === false) {
566
+		if ($avatarImage === false) {
567 567
 			//not set, nothing left to do;
568 568
 			return false;
569 569
 		}
570
-		if(!$this->image->loadFromBase64(base64_encode($avatarImage))) {
570
+		if (!$this->image->loadFromBase64(base64_encode($avatarImage))) {
571 571
 			return false;
572 572
 		}
573 573
 		return $this->setOwnCloudAvatar();
@@ -578,18 +578,18 @@  discard block
 block discarded – undo
578 578
 	 * @return bool
579 579
 	 */
580 580
 	private function setOwnCloudAvatar() {
581
-		if(!$this->image->valid()) {
581
+		if (!$this->image->valid()) {
582 582
 			$this->log->log('avatar image data from LDAP invalid for '.$this->dn, Util::ERROR);
583 583
 			return false;
584 584
 		}
585 585
 		//make sure it is a square and not bigger than 128x128
586 586
 		$size = min(array($this->image->width(), $this->image->height(), 128));
587
-		if(!$this->image->centerCrop($size)) {
587
+		if (!$this->image->centerCrop($size)) {
588 588
 			$this->log->log('croping image for avatar failed for '.$this->dn, Util::ERROR);
589 589
 			return false;
590 590
 		}
591 591
 
592
-		if(!$this->fs->isLoaded()) {
592
+		if (!$this->fs->isLoaded()) {
593 593
 			$this->fs->setup($this->uid);
594 594
 		}
595 595
 
@@ -599,7 +599,7 @@  discard block
 block discarded – undo
599 599
 			return true;
600 600
 		} catch (\Exception $e) {
601 601
 			\OC::$server->getLogger()->notice(
602
-				'Could not set avatar for ' . $this->dn	. ', because: ' . $e->getMessage(),
602
+				'Could not set avatar for '.$this->dn.', because: '.$e->getMessage(),
603 603
 				['app' => 'user_ldap']);
604 604
 		}
605 605
 		return false;
@@ -613,17 +613,17 @@  discard block
 block discarded – undo
613 613
 	public function handlePasswordExpiry($params) {
614 614
 		$ppolicyDN = $this->connection->ldapDefaultPPolicyDN;
615 615
 		if (empty($ppolicyDN) || (intval($this->connection->turnOnPasswordChange) !== 1)) {
616
-			return;//password expiry handling disabled
616
+			return; //password expiry handling disabled
617 617
 		}
618 618
 		$uid = $params['uid'];
619
-		if(isset($uid) && $uid === $this->getUsername()) {
619
+		if (isset($uid) && $uid === $this->getUsername()) {
620 620
 			//retrieve relevant user attributes
621 621
 			$result = $this->access->search('objectclass=*', array($this->dn), ['pwdpolicysubentry', 'pwdgraceusetime', 'pwdreset', 'pwdchangedtime']);
622 622
 			
623
-			if(array_key_exists('pwdpolicysubentry', $result[0])) {
623
+			if (array_key_exists('pwdpolicysubentry', $result[0])) {
624 624
 				$pwdPolicySubentry = $result[0]['pwdpolicysubentry'];
625
-				if($pwdPolicySubentry && (count($pwdPolicySubentry) > 0)){
626
-					$ppolicyDN = $pwdPolicySubentry[0];//custom ppolicy DN
625
+				if ($pwdPolicySubentry && (count($pwdPolicySubentry) > 0)) {
626
+					$ppolicyDN = $pwdPolicySubentry[0]; //custom ppolicy DN
627 627
 				}
628 628
 			}
629 629
 			
@@ -632,9 +632,9 @@  discard block
 block discarded – undo
632 632
 			$pwdChangedTime = array_key_exists('pwdchangedtime', $result[0]) ? $result[0]['pwdchangedtime'] : null;
633 633
 			
634 634
 			//retrieve relevant password policy attributes
635
-			$cacheKey = 'ppolicyAttributes' . $ppolicyDN;
635
+			$cacheKey = 'ppolicyAttributes'.$ppolicyDN;
636 636
 			$result = $this->connection->getFromCache($cacheKey);
637
-			if(is_null($result)) {
637
+			if (is_null($result)) {
638 638
 				$result = $this->access->search('objectclass=*', array($ppolicyDN), ['pwdgraceauthnlimit', 'pwdmaxage', 'pwdexpirewarning']);
639 639
 				$this->connection->writeToCache($cacheKey, $result);
640 640
 			}
@@ -645,8 +645,8 @@  discard block
 block discarded – undo
645 645
 			
646 646
 			//handle grace login
647 647
 			$pwdGraceUseTimeCount = count($pwdGraceUseTime);
648
-			if($pwdGraceUseTime && $pwdGraceUseTimeCount > 0) { //was this a grace login?
649
-				if($pwdGraceAuthNLimit 
648
+			if ($pwdGraceUseTime && $pwdGraceUseTimeCount > 0) { //was this a grace login?
649
+				if ($pwdGraceAuthNLimit 
650 650
 					&& (count($pwdGraceAuthNLimit) > 0)
651 651
 					&&($pwdGraceUseTimeCount < intval($pwdGraceAuthNLimit[0]))) { //at least one more grace login available?
652 652
 					$this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true');
@@ -659,24 +659,24 @@  discard block
 block discarded – undo
659 659
 				exit();
660 660
 			}
661 661
 			//handle pwdReset attribute
662
-			if($pwdReset && (count($pwdReset) > 0) && $pwdReset[0] === 'TRUE') { //user must change his password
662
+			if ($pwdReset && (count($pwdReset) > 0) && $pwdReset[0] === 'TRUE') { //user must change his password
663 663
 				$this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true');
664 664
 				header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
665 665
 				'user_ldap.renewPassword.showRenewPasswordForm', array('user' => $uid)));
666 666
 				exit();
667 667
 			}
668 668
 			//handle password expiry warning
669
-			if($pwdChangedTime && (count($pwdChangedTime) > 0)) {
670
-				if($pwdMaxAge && (count($pwdMaxAge) > 0)
669
+			if ($pwdChangedTime && (count($pwdChangedTime) > 0)) {
670
+				if ($pwdMaxAge && (count($pwdMaxAge) > 0)
671 671
 					&& $pwdExpireWarning && (count($pwdExpireWarning) > 0)) {
672 672
 					$pwdMaxAgeInt = intval($pwdMaxAge[0]);
673 673
 					$pwdExpireWarningInt = intval($pwdExpireWarning[0]);
674
-					if($pwdMaxAgeInt > 0 && $pwdExpireWarningInt > 0){
674
+					if ($pwdMaxAgeInt > 0 && $pwdExpireWarningInt > 0) {
675 675
 						$pwdChangedTimeDt = \DateTime::createFromFormat('YmdHisZ', $pwdChangedTime[0]);
676 676
 						$pwdChangedTimeDt->add(new \DateInterval('PT'.$pwdMaxAgeInt.'S'));
677 677
 						$currentDateTime = new \DateTime();
678 678
 						$secondsToExpiry = $pwdChangedTimeDt->getTimestamp() - $currentDateTime->getTimestamp();
679
-						if($secondsToExpiry <= $pwdExpireWarningInt) {
679
+						if ($secondsToExpiry <= $pwdExpireWarningInt) {
680 680
 							//remove last password expiry warning if any
681 681
 							$notification = $this->notificationManager->createNotification();
682 682
 							$notification->setApp('user_ldap')
Please login to merge, or discard this patch.
apps/user_ldap/lib/User/Manager.php 2 patches
Indentation   +194 added lines, -194 removed lines patch added patch discarded remove patch
@@ -45,224 +45,224 @@
 block discarded – undo
45 45
  * cache
46 46
  */
47 47
 class Manager {
48
-	/** @var IUserTools */
49
-	protected $access;
48
+    /** @var IUserTools */
49
+    protected $access;
50 50
 
51
-	/** @var IConfig */
52
-	protected $ocConfig;
51
+    /** @var IConfig */
52
+    protected $ocConfig;
53 53
 
54
-	/** @var IDBConnection */
55
-	protected $db;
54
+    /** @var IDBConnection */
55
+    protected $db;
56 56
 
57
-	/** @var IUserManager */
58
-	protected $userManager;
57
+    /** @var IUserManager */
58
+    protected $userManager;
59 59
 
60
-	/** @var INotificationManager */
61
-	protected $notificationManager;
60
+    /** @var INotificationManager */
61
+    protected $notificationManager;
62 62
 
63
-	/** @var FilesystemHelper */
64
-	protected $ocFilesystem;
63
+    /** @var FilesystemHelper */
64
+    protected $ocFilesystem;
65 65
 
66
-	/** @var LogWrapper */
67
-	protected $ocLog;
66
+    /** @var LogWrapper */
67
+    protected $ocLog;
68 68
 
69
-	/** @var Image */
70
-	protected $image;
69
+    /** @var Image */
70
+    protected $image;
71 71
 
72
-	/** @param \OCP\IAvatarManager */
73
-	protected $avatarManager;
72
+    /** @param \OCP\IAvatarManager */
73
+    protected $avatarManager;
74 74
 
75
-	/**
76
-	 * @var CappedMemoryCache $usersByDN
77
-	 */
78
-	protected $usersByDN;
79
-	/**
80
-	 * @var CappedMemoryCache $usersByUid
81
-	 */
82
-	protected $usersByUid;
75
+    /**
76
+     * @var CappedMemoryCache $usersByDN
77
+     */
78
+    protected $usersByDN;
79
+    /**
80
+     * @var CappedMemoryCache $usersByUid
81
+     */
82
+    protected $usersByUid;
83 83
 
84
-	/**
85
-	 * @param IConfig $ocConfig
86
-	 * @param \OCA\User_LDAP\FilesystemHelper $ocFilesystem object that
87
-	 * gives access to necessary functions from the OC filesystem
88
-	 * @param  \OCA\User_LDAP\LogWrapper $ocLog
89
-	 * @param IAvatarManager $avatarManager
90
-	 * @param Image $image an empty image instance
91
-	 * @param IDBConnection $db
92
-	 * @throws \Exception when the methods mentioned above do not exist
93
-	 */
94
-	public function __construct(IConfig $ocConfig,
95
-								FilesystemHelper $ocFilesystem, LogWrapper $ocLog,
96
-								IAvatarManager $avatarManager, Image $image,
97
-								IDBConnection $db, IUserManager $userManager,
98
-								INotificationManager $notificationManager) {
84
+    /**
85
+     * @param IConfig $ocConfig
86
+     * @param \OCA\User_LDAP\FilesystemHelper $ocFilesystem object that
87
+     * gives access to necessary functions from the OC filesystem
88
+     * @param  \OCA\User_LDAP\LogWrapper $ocLog
89
+     * @param IAvatarManager $avatarManager
90
+     * @param Image $image an empty image instance
91
+     * @param IDBConnection $db
92
+     * @throws \Exception when the methods mentioned above do not exist
93
+     */
94
+    public function __construct(IConfig $ocConfig,
95
+                                FilesystemHelper $ocFilesystem, LogWrapper $ocLog,
96
+                                IAvatarManager $avatarManager, Image $image,
97
+                                IDBConnection $db, IUserManager $userManager,
98
+                                INotificationManager $notificationManager) {
99 99
 
100
-		$this->ocConfig            = $ocConfig;
101
-		$this->ocFilesystem        = $ocFilesystem;
102
-		$this->ocLog               = $ocLog;
103
-		$this->avatarManager       = $avatarManager;
104
-		$this->image               = $image;
105
-		$this->db                  = $db;
106
-		$this->userManager         = $userManager;
107
-		$this->notificationManager = $notificationManager;
108
-		$this->usersByDN           = new CappedMemoryCache();
109
-		$this->usersByUid          = new CappedMemoryCache();
110
-	}
100
+        $this->ocConfig            = $ocConfig;
101
+        $this->ocFilesystem        = $ocFilesystem;
102
+        $this->ocLog               = $ocLog;
103
+        $this->avatarManager       = $avatarManager;
104
+        $this->image               = $image;
105
+        $this->db                  = $db;
106
+        $this->userManager         = $userManager;
107
+        $this->notificationManager = $notificationManager;
108
+        $this->usersByDN           = new CappedMemoryCache();
109
+        $this->usersByUid          = new CappedMemoryCache();
110
+    }
111 111
 
112
-	/**
113
-	 * @brief binds manager to an instance of IUserTools (implemented by
114
-	 * Access). It needs to be assigned first before the manager can be used.
115
-	 * @param IUserTools
116
-	 */
117
-	public function setLdapAccess(IUserTools $access) {
118
-		$this->access = $access;
119
-	}
112
+    /**
113
+     * @brief binds manager to an instance of IUserTools (implemented by
114
+     * Access). It needs to be assigned first before the manager can be used.
115
+     * @param IUserTools
116
+     */
117
+    public function setLdapAccess(IUserTools $access) {
118
+        $this->access = $access;
119
+    }
120 120
 
121
-	/**
122
-	 * @brief creates an instance of User and caches (just runtime) it in the
123
-	 * property array
124
-	 * @param string $dn the DN of the user
125
-	 * @param string $uid the internal (owncloud) username
126
-	 * @return \OCA\User_LDAP\User\User
127
-	 */
128
-	private function createAndCache($dn, $uid) {
129
-		$this->checkAccess();
130
-		$user = new User($uid, $dn, $this->access, $this->ocConfig,
131
-			$this->ocFilesystem, clone $this->image, $this->ocLog,
132
-			$this->avatarManager, $this->userManager, 
133
-			$this->notificationManager);
134
-		$this->usersByDN[$dn]   = $user;
135
-		$this->usersByUid[$uid] = $user;
136
-		return $user;
137
-	}
121
+    /**
122
+     * @brief creates an instance of User and caches (just runtime) it in the
123
+     * property array
124
+     * @param string $dn the DN of the user
125
+     * @param string $uid the internal (owncloud) username
126
+     * @return \OCA\User_LDAP\User\User
127
+     */
128
+    private function createAndCache($dn, $uid) {
129
+        $this->checkAccess();
130
+        $user = new User($uid, $dn, $this->access, $this->ocConfig,
131
+            $this->ocFilesystem, clone $this->image, $this->ocLog,
132
+            $this->avatarManager, $this->userManager, 
133
+            $this->notificationManager);
134
+        $this->usersByDN[$dn]   = $user;
135
+        $this->usersByUid[$uid] = $user;
136
+        return $user;
137
+    }
138 138
 
139
-	/**
140
-	 * removes a user entry from the cache
141
-	 * @param $uid
142
-	 */
143
-	public function invalidate($uid) {
144
-		if(!isset($this->usersByUid[$uid])) {
145
-			return;
146
-		}
147
-		$dn = $this->usersByUid[$uid]->getDN();
148
-		unset($this->usersByUid[$uid]);
149
-		unset($this->usersByDN[$dn]);
150
-	}
139
+    /**
140
+     * removes a user entry from the cache
141
+     * @param $uid
142
+     */
143
+    public function invalidate($uid) {
144
+        if(!isset($this->usersByUid[$uid])) {
145
+            return;
146
+        }
147
+        $dn = $this->usersByUid[$uid]->getDN();
148
+        unset($this->usersByUid[$uid]);
149
+        unset($this->usersByDN[$dn]);
150
+    }
151 151
 
152
-	/**
153
-	 * @brief checks whether the Access instance has been set
154
-	 * @throws \Exception if Access has not been set
155
-	 * @return null
156
-	 */
157
-	private function checkAccess() {
158
-		if(is_null($this->access)) {
159
-			throw new \Exception('LDAP Access instance must be set first');
160
-		}
161
-	}
152
+    /**
153
+     * @brief checks whether the Access instance has been set
154
+     * @throws \Exception if Access has not been set
155
+     * @return null
156
+     */
157
+    private function checkAccess() {
158
+        if(is_null($this->access)) {
159
+            throw new \Exception('LDAP Access instance must be set first');
160
+        }
161
+    }
162 162
 
163
-	/**
164
-	 * returns a list of attributes that will be processed further, e.g. quota,
165
-	 * email, displayname, or others.
166
-	 *
167
-	 * @param bool $minimal - optional, set to true to skip attributes with big
168
-	 * payload
169
-	 * @return string[]
170
-	 */
171
-	public function getAttributes($minimal = false) {
172
-		$attributes = array_merge(Access::UUID_ATTRIBUTES, ['dn', 'uid', 'samaccountname', 'memberof']);
173
-		$possible = array(
174
-			$this->access->getConnection()->ldapExpertUUIDUserAttr,
175
-			$this->access->getConnection()->ldapQuotaAttribute,
176
-			$this->access->getConnection()->ldapEmailAttribute,
177
-			$this->access->getConnection()->ldapUserDisplayName,
178
-			$this->access->getConnection()->ldapUserDisplayName2,
179
-		);
180
-		foreach($possible as $attr) {
181
-			if(!is_null($attr)) {
182
-				$attributes[] = $attr;
183
-			}
184
-		}
163
+    /**
164
+     * returns a list of attributes that will be processed further, e.g. quota,
165
+     * email, displayname, or others.
166
+     *
167
+     * @param bool $minimal - optional, set to true to skip attributes with big
168
+     * payload
169
+     * @return string[]
170
+     */
171
+    public function getAttributes($minimal = false) {
172
+        $attributes = array_merge(Access::UUID_ATTRIBUTES, ['dn', 'uid', 'samaccountname', 'memberof']);
173
+        $possible = array(
174
+            $this->access->getConnection()->ldapExpertUUIDUserAttr,
175
+            $this->access->getConnection()->ldapQuotaAttribute,
176
+            $this->access->getConnection()->ldapEmailAttribute,
177
+            $this->access->getConnection()->ldapUserDisplayName,
178
+            $this->access->getConnection()->ldapUserDisplayName2,
179
+        );
180
+        foreach($possible as $attr) {
181
+            if(!is_null($attr)) {
182
+                $attributes[] = $attr;
183
+            }
184
+        }
185 185
 
186
-		$homeRule = $this->access->getConnection()->homeFolderNamingRule;
187
-		if(strpos($homeRule, 'attr:') === 0) {
188
-			$attributes[] = substr($homeRule, strlen('attr:'));
189
-		}
186
+        $homeRule = $this->access->getConnection()->homeFolderNamingRule;
187
+        if(strpos($homeRule, 'attr:') === 0) {
188
+            $attributes[] = substr($homeRule, strlen('attr:'));
189
+        }
190 190
 
191
-		if(!$minimal) {
192
-			// attributes that are not really important but may come with big
193
-			// payload.
194
-			$attributes = array_merge(
195
-				$attributes,
196
-				$this->access->getConnection()->resolveRule('avatar')
197
-			);
198
-		}
191
+        if(!$minimal) {
192
+            // attributes that are not really important but may come with big
193
+            // payload.
194
+            $attributes = array_merge(
195
+                $attributes,
196
+                $this->access->getConnection()->resolveRule('avatar')
197
+            );
198
+        }
199 199
 
200
-		return $attributes;
201
-	}
200
+        return $attributes;
201
+    }
202 202
 
203
-	/**
204
-	 * Checks whether the specified user is marked as deleted
205
-	 * @param string $id the Nextcloud user name
206
-	 * @return bool
207
-	 */
208
-	public function isDeletedUser($id) {
209
-		$isDeleted = $this->ocConfig->getUserValue(
210
-			$id, 'user_ldap', 'isDeleted', 0);
211
-		return intval($isDeleted) === 1;
212
-	}
203
+    /**
204
+     * Checks whether the specified user is marked as deleted
205
+     * @param string $id the Nextcloud user name
206
+     * @return bool
207
+     */
208
+    public function isDeletedUser($id) {
209
+        $isDeleted = $this->ocConfig->getUserValue(
210
+            $id, 'user_ldap', 'isDeleted', 0);
211
+        return intval($isDeleted) === 1;
212
+    }
213 213
 
214
-	/**
215
-	 * creates and returns an instance of OfflineUser for the specified user
216
-	 * @param string $id
217
-	 * @return \OCA\User_LDAP\User\OfflineUser
218
-	 */
219
-	public function getDeletedUser($id) {
220
-		return new OfflineUser(
221
-			$id,
222
-			$this->ocConfig,
223
-			$this->db,
224
-			$this->access->getUserMapper());
225
-	}
214
+    /**
215
+     * creates and returns an instance of OfflineUser for the specified user
216
+     * @param string $id
217
+     * @return \OCA\User_LDAP\User\OfflineUser
218
+     */
219
+    public function getDeletedUser($id) {
220
+        return new OfflineUser(
221
+            $id,
222
+            $this->ocConfig,
223
+            $this->db,
224
+            $this->access->getUserMapper());
225
+    }
226 226
 
227
-	/**
228
-	 * @brief returns a User object by it's Nextcloud username
229
-	 * @param string $id the DN or username of the user
230
-	 * @return \OCA\User_LDAP\User\User|\OCA\User_LDAP\User\OfflineUser|null
231
-	 */
232
-	protected function createInstancyByUserName($id) {
233
-		//most likely a uid. Check whether it is a deleted user
234
-		if($this->isDeletedUser($id)) {
235
-			return $this->getDeletedUser($id);
236
-		}
237
-		$dn = $this->access->username2dn($id);
238
-		if($dn !== false) {
239
-			return $this->createAndCache($dn, $id);
240
-		}
241
-		return null;
242
-	}
227
+    /**
228
+     * @brief returns a User object by it's Nextcloud username
229
+     * @param string $id the DN or username of the user
230
+     * @return \OCA\User_LDAP\User\User|\OCA\User_LDAP\User\OfflineUser|null
231
+     */
232
+    protected function createInstancyByUserName($id) {
233
+        //most likely a uid. Check whether it is a deleted user
234
+        if($this->isDeletedUser($id)) {
235
+            return $this->getDeletedUser($id);
236
+        }
237
+        $dn = $this->access->username2dn($id);
238
+        if($dn !== false) {
239
+            return $this->createAndCache($dn, $id);
240
+        }
241
+        return null;
242
+    }
243 243
 
244
-	/**
245
-	 * @brief returns a User object by it's DN or Nextcloud username
246
-	 * @param string $id the DN or username of the user
247
-	 * @return \OCA\User_LDAP\User\User|\OCA\User_LDAP\User\OfflineUser|null
248
-	 * @throws \Exception when connection could not be established
249
-	 */
250
-	public function get($id) {
251
-		$this->checkAccess();
252
-		if(isset($this->usersByDN[$id])) {
253
-			return $this->usersByDN[$id];
254
-		} else if(isset($this->usersByUid[$id])) {
255
-			return $this->usersByUid[$id];
256
-		}
244
+    /**
245
+     * @brief returns a User object by it's DN or Nextcloud username
246
+     * @param string $id the DN or username of the user
247
+     * @return \OCA\User_LDAP\User\User|\OCA\User_LDAP\User\OfflineUser|null
248
+     * @throws \Exception when connection could not be established
249
+     */
250
+    public function get($id) {
251
+        $this->checkAccess();
252
+        if(isset($this->usersByDN[$id])) {
253
+            return $this->usersByDN[$id];
254
+        } else if(isset($this->usersByUid[$id])) {
255
+            return $this->usersByUid[$id];
256
+        }
257 257
 
258
-		if($this->access->stringResemblesDN($id) ) {
259
-			$uid = $this->access->dn2username($id);
260
-			if($uid !== false) {
261
-				return $this->createAndCache($id, $uid);
262
-			}
263
-		}
258
+        if($this->access->stringResemblesDN($id) ) {
259
+            $uid = $this->access->dn2username($id);
260
+            if($uid !== false) {
261
+                return $this->createAndCache($id, $uid);
262
+            }
263
+        }
264 264
 
265
-		return $this->createInstancyByUserName($id);
266
-	}
265
+        return $this->createInstancyByUserName($id);
266
+    }
267 267
 
268 268
 }
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -141,7 +141,7 @@  discard block
 block discarded – undo
141 141
 	 * @param $uid
142 142
 	 */
143 143
 	public function invalidate($uid) {
144
-		if(!isset($this->usersByUid[$uid])) {
144
+		if (!isset($this->usersByUid[$uid])) {
145 145
 			return;
146 146
 		}
147 147
 		$dn = $this->usersByUid[$uid]->getDN();
@@ -155,7 +155,7 @@  discard block
 block discarded – undo
155 155
 	 * @return null
156 156
 	 */
157 157
 	private function checkAccess() {
158
-		if(is_null($this->access)) {
158
+		if (is_null($this->access)) {
159 159
 			throw new \Exception('LDAP Access instance must be set first');
160 160
 		}
161 161
 	}
@@ -177,18 +177,18 @@  discard block
 block discarded – undo
177 177
 			$this->access->getConnection()->ldapUserDisplayName,
178 178
 			$this->access->getConnection()->ldapUserDisplayName2,
179 179
 		);
180
-		foreach($possible as $attr) {
181
-			if(!is_null($attr)) {
180
+		foreach ($possible as $attr) {
181
+			if (!is_null($attr)) {
182 182
 				$attributes[] = $attr;
183 183
 			}
184 184
 		}
185 185
 
186 186
 		$homeRule = $this->access->getConnection()->homeFolderNamingRule;
187
-		if(strpos($homeRule, 'attr:') === 0) {
187
+		if (strpos($homeRule, 'attr:') === 0) {
188 188
 			$attributes[] = substr($homeRule, strlen('attr:'));
189 189
 		}
190 190
 
191
-		if(!$minimal) {
191
+		if (!$minimal) {
192 192
 			// attributes that are not really important but may come with big
193 193
 			// payload.
194 194
 			$attributes = array_merge(
@@ -231,11 +231,11 @@  discard block
 block discarded – undo
231 231
 	 */
232 232
 	protected function createInstancyByUserName($id) {
233 233
 		//most likely a uid. Check whether it is a deleted user
234
-		if($this->isDeletedUser($id)) {
234
+		if ($this->isDeletedUser($id)) {
235 235
 			return $this->getDeletedUser($id);
236 236
 		}
237 237
 		$dn = $this->access->username2dn($id);
238
-		if($dn !== false) {
238
+		if ($dn !== false) {
239 239
 			return $this->createAndCache($dn, $id);
240 240
 		}
241 241
 		return null;
@@ -249,15 +249,15 @@  discard block
 block discarded – undo
249 249
 	 */
250 250
 	public function get($id) {
251 251
 		$this->checkAccess();
252
-		if(isset($this->usersByDN[$id])) {
252
+		if (isset($this->usersByDN[$id])) {
253 253
 			return $this->usersByDN[$id];
254
-		} else if(isset($this->usersByUid[$id])) {
254
+		} else if (isset($this->usersByUid[$id])) {
255 255
 			return $this->usersByUid[$id];
256 256
 		}
257 257
 
258
-		if($this->access->stringResemblesDN($id) ) {
258
+		if ($this->access->stringResemblesDN($id)) {
259 259
 			$uid = $this->access->dn2username($id);
260
-			if($uid !== false) {
260
+			if ($uid !== false) {
261 261
 				return $this->createAndCache($id, $uid);
262 262
 			}
263 263
 		}
Please login to merge, or discard this patch.
apps/user_ldap/lib/Configuration.php 2 patches
Indentation   +508 added lines, -508 removed lines patch added patch discarded remove patch
@@ -38,541 +38,541 @@
 block discarded – undo
38 38
  * @property string ldapUserAvatarRule
39 39
  */
40 40
 class Configuration {
41
-	const AVATAR_PREFIX_DEFAULT = 'default';
42
-	const AVATAR_PREFIX_NONE = 'none';
43
-	const AVATAR_PREFIX_DATA_ATTRIBUTE = 'data:';
41
+    const AVATAR_PREFIX_DEFAULT = 'default';
42
+    const AVATAR_PREFIX_NONE = 'none';
43
+    const AVATAR_PREFIX_DATA_ATTRIBUTE = 'data:';
44 44
 
45
-	protected $configPrefix = null;
46
-	protected $configRead = false;
47
-	/**
48
-	 * @var string[] pre-filled with one reference key so that at least one entry is written on save request and
49
-	 *               the config ID is registered
50
-	 */
51
-	protected $unsavedChanges = ['ldapConfigurationActive' => 'ldapConfigurationActive'];
45
+    protected $configPrefix = null;
46
+    protected $configRead = false;
47
+    /**
48
+     * @var string[] pre-filled with one reference key so that at least one entry is written on save request and
49
+     *               the config ID is registered
50
+     */
51
+    protected $unsavedChanges = ['ldapConfigurationActive' => 'ldapConfigurationActive'];
52 52
 
53
-	//settings
54
-	protected $config = array(
55
-		'ldapHost' => null,
56
-		'ldapPort' => null,
57
-		'ldapBackupHost' => null,
58
-		'ldapBackupPort' => null,
59
-		'ldapBase' => null,
60
-		'ldapBaseUsers' => null,
61
-		'ldapBaseGroups' => null,
62
-		'ldapAgentName' => null,
63
-		'ldapAgentPassword' => null,
64
-		'ldapTLS' => null,
65
-		'turnOffCertCheck' => null,
66
-		'ldapIgnoreNamingRules' => null,
67
-		'ldapUserDisplayName' => null,
68
-		'ldapUserDisplayName2' => null,
69
-		'ldapUserAvatarRule' => null,
70
-		'ldapGidNumber' => null,
71
-		'ldapUserFilterObjectclass' => null,
72
-		'ldapUserFilterGroups' => null,
73
-		'ldapUserFilter' => null,
74
-		'ldapUserFilterMode' => null,
75
-		'ldapGroupFilter' => null,
76
-		'ldapGroupFilterMode' => null,
77
-		'ldapGroupFilterObjectclass' => null,
78
-		'ldapGroupFilterGroups' => null,
79
-		'ldapGroupDisplayName' => null,
80
-		'ldapGroupMemberAssocAttr' => null,
81
-		'ldapLoginFilter' => null,
82
-		'ldapLoginFilterMode' => null,
83
-		'ldapLoginFilterEmail' => null,
84
-		'ldapLoginFilterUsername' => null,
85
-		'ldapLoginFilterAttributes' => null,
86
-		'ldapQuotaAttribute' => null,
87
-		'ldapQuotaDefault' => null,
88
-		'ldapEmailAttribute' => null,
89
-		'ldapCacheTTL' => null,
90
-		'ldapUuidUserAttribute' => 'auto',
91
-		'ldapUuidGroupAttribute' => 'auto',
92
-		'ldapOverrideMainServer' => false,
93
-		'ldapConfigurationActive' => false,
94
-		'ldapAttributesForUserSearch' => null,
95
-		'ldapAttributesForGroupSearch' => null,
96
-		'ldapExperiencedAdmin' => false,
97
-		'homeFolderNamingRule' => null,
98
-		'hasPagedResultSupport' => false,
99
-		'hasMemberOfFilterSupport' => false,
100
-		'useMemberOfToDetectMembership' => true,
101
-		'ldapExpertUsernameAttr' => null,
102
-		'ldapExpertUUIDUserAttr' => null,
103
-		'ldapExpertUUIDGroupAttr' => null,
104
-		'lastJpegPhotoLookup' => null,
105
-		'ldapNestedGroups' => false,
106
-		'ldapPagingSize' => null,
107
-		'turnOnPasswordChange' => false,
108
-		'ldapDynamicGroupMemberURL' => null,
109
-		'ldapDefaultPPolicyDN' => null,
110
-	);
53
+    //settings
54
+    protected $config = array(
55
+        'ldapHost' => null,
56
+        'ldapPort' => null,
57
+        'ldapBackupHost' => null,
58
+        'ldapBackupPort' => null,
59
+        'ldapBase' => null,
60
+        'ldapBaseUsers' => null,
61
+        'ldapBaseGroups' => null,
62
+        'ldapAgentName' => null,
63
+        'ldapAgentPassword' => null,
64
+        'ldapTLS' => null,
65
+        'turnOffCertCheck' => null,
66
+        'ldapIgnoreNamingRules' => null,
67
+        'ldapUserDisplayName' => null,
68
+        'ldapUserDisplayName2' => null,
69
+        'ldapUserAvatarRule' => null,
70
+        'ldapGidNumber' => null,
71
+        'ldapUserFilterObjectclass' => null,
72
+        'ldapUserFilterGroups' => null,
73
+        'ldapUserFilter' => null,
74
+        'ldapUserFilterMode' => null,
75
+        'ldapGroupFilter' => null,
76
+        'ldapGroupFilterMode' => null,
77
+        'ldapGroupFilterObjectclass' => null,
78
+        'ldapGroupFilterGroups' => null,
79
+        'ldapGroupDisplayName' => null,
80
+        'ldapGroupMemberAssocAttr' => null,
81
+        'ldapLoginFilter' => null,
82
+        'ldapLoginFilterMode' => null,
83
+        'ldapLoginFilterEmail' => null,
84
+        'ldapLoginFilterUsername' => null,
85
+        'ldapLoginFilterAttributes' => null,
86
+        'ldapQuotaAttribute' => null,
87
+        'ldapQuotaDefault' => null,
88
+        'ldapEmailAttribute' => null,
89
+        'ldapCacheTTL' => null,
90
+        'ldapUuidUserAttribute' => 'auto',
91
+        'ldapUuidGroupAttribute' => 'auto',
92
+        'ldapOverrideMainServer' => false,
93
+        'ldapConfigurationActive' => false,
94
+        'ldapAttributesForUserSearch' => null,
95
+        'ldapAttributesForGroupSearch' => null,
96
+        'ldapExperiencedAdmin' => false,
97
+        'homeFolderNamingRule' => null,
98
+        'hasPagedResultSupport' => false,
99
+        'hasMemberOfFilterSupport' => false,
100
+        'useMemberOfToDetectMembership' => true,
101
+        'ldapExpertUsernameAttr' => null,
102
+        'ldapExpertUUIDUserAttr' => null,
103
+        'ldapExpertUUIDGroupAttr' => null,
104
+        'lastJpegPhotoLookup' => null,
105
+        'ldapNestedGroups' => false,
106
+        'ldapPagingSize' => null,
107
+        'turnOnPasswordChange' => false,
108
+        'ldapDynamicGroupMemberURL' => null,
109
+        'ldapDefaultPPolicyDN' => null,
110
+    );
111 111
 
112
-	/**
113
-	 * @param string $configPrefix
114
-	 * @param bool $autoRead
115
-	 */
116
-	public function __construct($configPrefix, $autoRead = true) {
117
-		$this->configPrefix = $configPrefix;
118
-		if($autoRead) {
119
-			$this->readConfiguration();
120
-		}
121
-	}
112
+    /**
113
+     * @param string $configPrefix
114
+     * @param bool $autoRead
115
+     */
116
+    public function __construct($configPrefix, $autoRead = true) {
117
+        $this->configPrefix = $configPrefix;
118
+        if($autoRead) {
119
+            $this->readConfiguration();
120
+        }
121
+    }
122 122
 
123
-	/**
124
-	 * @param string $name
125
-	 * @return mixed|null
126
-	 */
127
-	public function __get($name) {
128
-		if(isset($this->config[$name])) {
129
-			return $this->config[$name];
130
-		}
131
-		return null;
132
-	}
123
+    /**
124
+     * @param string $name
125
+     * @return mixed|null
126
+     */
127
+    public function __get($name) {
128
+        if(isset($this->config[$name])) {
129
+            return $this->config[$name];
130
+        }
131
+        return null;
132
+    }
133 133
 
134
-	/**
135
-	 * @param string $name
136
-	 * @param mixed $value
137
-	 */
138
-	public function __set($name, $value) {
139
-		$this->setConfiguration(array($name => $value));
140
-	}
134
+    /**
135
+     * @param string $name
136
+     * @param mixed $value
137
+     */
138
+    public function __set($name, $value) {
139
+        $this->setConfiguration(array($name => $value));
140
+    }
141 141
 
142
-	/**
143
-	 * @return array
144
-	 */
145
-	public function getConfiguration() {
146
-		return $this->config;
147
-	}
142
+    /**
143
+     * @return array
144
+     */
145
+    public function getConfiguration() {
146
+        return $this->config;
147
+    }
148 148
 
149
-	/**
150
-	 * set LDAP configuration with values delivered by an array, not read
151
-	 * from configuration. It does not save the configuration! To do so, you
152
-	 * must call saveConfiguration afterwards.
153
-	 * @param array $config array that holds the config parameters in an associated
154
-	 * array
155
-	 * @param array &$applied optional; array where the set fields will be given to
156
-	 * @return false|null
157
-	 */
158
-	public function setConfiguration($config, &$applied = null) {
159
-		if(!is_array($config)) {
160
-			return false;
161
-		}
149
+    /**
150
+     * set LDAP configuration with values delivered by an array, not read
151
+     * from configuration. It does not save the configuration! To do so, you
152
+     * must call saveConfiguration afterwards.
153
+     * @param array $config array that holds the config parameters in an associated
154
+     * array
155
+     * @param array &$applied optional; array where the set fields will be given to
156
+     * @return false|null
157
+     */
158
+    public function setConfiguration($config, &$applied = null) {
159
+        if(!is_array($config)) {
160
+            return false;
161
+        }
162 162
 
163
-		$cta = $this->getConfigTranslationArray();
164
-		foreach($config as $inputKey => $val) {
165
-			if(strpos($inputKey, '_') !== false && array_key_exists($inputKey, $cta)) {
166
-				$key = $cta[$inputKey];
167
-			} elseif(array_key_exists($inputKey, $this->config)) {
168
-				$key = $inputKey;
169
-			} else {
170
-				continue;
171
-			}
163
+        $cta = $this->getConfigTranslationArray();
164
+        foreach($config as $inputKey => $val) {
165
+            if(strpos($inputKey, '_') !== false && array_key_exists($inputKey, $cta)) {
166
+                $key = $cta[$inputKey];
167
+            } elseif(array_key_exists($inputKey, $this->config)) {
168
+                $key = $inputKey;
169
+            } else {
170
+                continue;
171
+            }
172 172
 
173
-			$setMethod = 'setValue';
174
-			switch($key) {
175
-				case 'ldapAgentPassword':
176
-					$setMethod = 'setRawValue';
177
-					break;
178
-				case 'homeFolderNamingRule':
179
-					$trimmedVal = trim($val);
180
-					if ($trimmedVal !== '' && strpos($val, 'attr:') === false) {
181
-						$val = 'attr:'.$trimmedVal;
182
-					}
183
-					break;
184
-				case 'ldapBase':
185
-				case 'ldapBaseUsers':
186
-				case 'ldapBaseGroups':
187
-				case 'ldapAttributesForUserSearch':
188
-				case 'ldapAttributesForGroupSearch':
189
-				case 'ldapUserFilterObjectclass':
190
-				case 'ldapUserFilterGroups':
191
-				case 'ldapGroupFilterObjectclass':
192
-				case 'ldapGroupFilterGroups':
193
-				case 'ldapLoginFilterAttributes':
194
-					$setMethod = 'setMultiLine';
195
-					break;
196
-			}
197
-			$this->$setMethod($key, $val);
198
-			if(is_array($applied)) {
199
-				$applied[] = $inputKey;
200
-				// storing key as index avoids duplication, and as value for simplicity
201
-			}
202
-			$this->unsavedChanges[$key] = $key;
203
-		}
204
-		return null;
205
-	}
173
+            $setMethod = 'setValue';
174
+            switch($key) {
175
+                case 'ldapAgentPassword':
176
+                    $setMethod = 'setRawValue';
177
+                    break;
178
+                case 'homeFolderNamingRule':
179
+                    $trimmedVal = trim($val);
180
+                    if ($trimmedVal !== '' && strpos($val, 'attr:') === false) {
181
+                        $val = 'attr:'.$trimmedVal;
182
+                    }
183
+                    break;
184
+                case 'ldapBase':
185
+                case 'ldapBaseUsers':
186
+                case 'ldapBaseGroups':
187
+                case 'ldapAttributesForUserSearch':
188
+                case 'ldapAttributesForGroupSearch':
189
+                case 'ldapUserFilterObjectclass':
190
+                case 'ldapUserFilterGroups':
191
+                case 'ldapGroupFilterObjectclass':
192
+                case 'ldapGroupFilterGroups':
193
+                case 'ldapLoginFilterAttributes':
194
+                    $setMethod = 'setMultiLine';
195
+                    break;
196
+            }
197
+            $this->$setMethod($key, $val);
198
+            if(is_array($applied)) {
199
+                $applied[] = $inputKey;
200
+                // storing key as index avoids duplication, and as value for simplicity
201
+            }
202
+            $this->unsavedChanges[$key] = $key;
203
+        }
204
+        return null;
205
+    }
206 206
 
207
-	public function readConfiguration() {
208
-		if(!$this->configRead && !is_null($this->configPrefix)) {
209
-			$cta = array_flip($this->getConfigTranslationArray());
210
-			foreach($this->config as $key => $val) {
211
-				if(!isset($cta[$key])) {
212
-					//some are determined
213
-					continue;
214
-				}
215
-				$dbKey = $cta[$key];
216
-				switch($key) {
217
-					case 'ldapBase':
218
-					case 'ldapBaseUsers':
219
-					case 'ldapBaseGroups':
220
-					case 'ldapAttributesForUserSearch':
221
-					case 'ldapAttributesForGroupSearch':
222
-					case 'ldapUserFilterObjectclass':
223
-					case 'ldapUserFilterGroups':
224
-					case 'ldapGroupFilterObjectclass':
225
-					case 'ldapGroupFilterGroups':
226
-					case 'ldapLoginFilterAttributes':
227
-						$readMethod = 'getMultiLine';
228
-						break;
229
-					case 'ldapIgnoreNamingRules':
230
-						$readMethod = 'getSystemValue';
231
-						$dbKey = $key;
232
-						break;
233
-					case 'ldapAgentPassword':
234
-						$readMethod = 'getPwd';
235
-						break;
236
-					case 'ldapUserDisplayName2':
237
-					case 'ldapGroupDisplayName':
238
-						$readMethod = 'getLcValue';
239
-						break;
240
-					case 'ldapUserDisplayName':
241
-					default:
242
-						// user display name does not lower case because
243
-						// we rely on an upper case N as indicator whether to
244
-						// auto-detect it or not. FIXME
245
-						$readMethod = 'getValue';
246
-						break;
247
-				}
248
-				$this->config[$key] = $this->$readMethod($dbKey);
249
-			}
250
-			$this->configRead = true;
251
-		}
252
-	}
207
+    public function readConfiguration() {
208
+        if(!$this->configRead && !is_null($this->configPrefix)) {
209
+            $cta = array_flip($this->getConfigTranslationArray());
210
+            foreach($this->config as $key => $val) {
211
+                if(!isset($cta[$key])) {
212
+                    //some are determined
213
+                    continue;
214
+                }
215
+                $dbKey = $cta[$key];
216
+                switch($key) {
217
+                    case 'ldapBase':
218
+                    case 'ldapBaseUsers':
219
+                    case 'ldapBaseGroups':
220
+                    case 'ldapAttributesForUserSearch':
221
+                    case 'ldapAttributesForGroupSearch':
222
+                    case 'ldapUserFilterObjectclass':
223
+                    case 'ldapUserFilterGroups':
224
+                    case 'ldapGroupFilterObjectclass':
225
+                    case 'ldapGroupFilterGroups':
226
+                    case 'ldapLoginFilterAttributes':
227
+                        $readMethod = 'getMultiLine';
228
+                        break;
229
+                    case 'ldapIgnoreNamingRules':
230
+                        $readMethod = 'getSystemValue';
231
+                        $dbKey = $key;
232
+                        break;
233
+                    case 'ldapAgentPassword':
234
+                        $readMethod = 'getPwd';
235
+                        break;
236
+                    case 'ldapUserDisplayName2':
237
+                    case 'ldapGroupDisplayName':
238
+                        $readMethod = 'getLcValue';
239
+                        break;
240
+                    case 'ldapUserDisplayName':
241
+                    default:
242
+                        // user display name does not lower case because
243
+                        // we rely on an upper case N as indicator whether to
244
+                        // auto-detect it or not. FIXME
245
+                        $readMethod = 'getValue';
246
+                        break;
247
+                }
248
+                $this->config[$key] = $this->$readMethod($dbKey);
249
+            }
250
+            $this->configRead = true;
251
+        }
252
+    }
253 253
 
254
-	/**
255
-	 * saves the current config changes in the database
256
-	 */
257
-	public function saveConfiguration() {
258
-		$cta = array_flip($this->getConfigTranslationArray());
259
-		foreach($this->unsavedChanges as $key) {
260
-			$value = $this->config[$key];
261
-			switch ($key) {
262
-				case 'ldapAgentPassword':
263
-					$value = base64_encode($value);
264
-					break;
265
-				case 'ldapBase':
266
-				case 'ldapBaseUsers':
267
-				case 'ldapBaseGroups':
268
-				case 'ldapAttributesForUserSearch':
269
-				case 'ldapAttributesForGroupSearch':
270
-				case 'ldapUserFilterObjectclass':
271
-				case 'ldapUserFilterGroups':
272
-				case 'ldapGroupFilterObjectclass':
273
-				case 'ldapGroupFilterGroups':
274
-				case 'ldapLoginFilterAttributes':
275
-					if(is_array($value)) {
276
-						$value = implode("\n", $value);
277
-					}
278
-					break;
279
-				//following options are not stored but detected, skip them
280
-				case 'ldapIgnoreNamingRules':
281
-				case 'hasPagedResultSupport':
282
-				case 'ldapUuidUserAttribute':
283
-				case 'ldapUuidGroupAttribute':
284
-					continue 2;
285
-			}
286
-			if(is_null($value)) {
287
-				$value = '';
288
-			}
289
-			$this->saveValue($cta[$key], $value);
290
-		}
291
-		$this->saveValue('_lastChange', time());
292
-		$this->unsavedChanges = [];
293
-	}
254
+    /**
255
+     * saves the current config changes in the database
256
+     */
257
+    public function saveConfiguration() {
258
+        $cta = array_flip($this->getConfigTranslationArray());
259
+        foreach($this->unsavedChanges as $key) {
260
+            $value = $this->config[$key];
261
+            switch ($key) {
262
+                case 'ldapAgentPassword':
263
+                    $value = base64_encode($value);
264
+                    break;
265
+                case 'ldapBase':
266
+                case 'ldapBaseUsers':
267
+                case 'ldapBaseGroups':
268
+                case 'ldapAttributesForUserSearch':
269
+                case 'ldapAttributesForGroupSearch':
270
+                case 'ldapUserFilterObjectclass':
271
+                case 'ldapUserFilterGroups':
272
+                case 'ldapGroupFilterObjectclass':
273
+                case 'ldapGroupFilterGroups':
274
+                case 'ldapLoginFilterAttributes':
275
+                    if(is_array($value)) {
276
+                        $value = implode("\n", $value);
277
+                    }
278
+                    break;
279
+                //following options are not stored but detected, skip them
280
+                case 'ldapIgnoreNamingRules':
281
+                case 'hasPagedResultSupport':
282
+                case 'ldapUuidUserAttribute':
283
+                case 'ldapUuidGroupAttribute':
284
+                    continue 2;
285
+            }
286
+            if(is_null($value)) {
287
+                $value = '';
288
+            }
289
+            $this->saveValue($cta[$key], $value);
290
+        }
291
+        $this->saveValue('_lastChange', time());
292
+        $this->unsavedChanges = [];
293
+    }
294 294
 
295
-	/**
296
-	 * @param string $varName
297
-	 * @return array|string
298
-	 */
299
-	protected function getMultiLine($varName) {
300
-		$value = $this->getValue($varName);
301
-		if(empty($value)) {
302
-			$value = '';
303
-		} else {
304
-			$value = preg_split('/\r\n|\r|\n/', $value);
305
-		}
295
+    /**
296
+     * @param string $varName
297
+     * @return array|string
298
+     */
299
+    protected function getMultiLine($varName) {
300
+        $value = $this->getValue($varName);
301
+        if(empty($value)) {
302
+            $value = '';
303
+        } else {
304
+            $value = preg_split('/\r\n|\r|\n/', $value);
305
+        }
306 306
 
307
-		return $value;
308
-	}
307
+        return $value;
308
+    }
309 309
 
310
-	/**
311
-	 * Sets multi-line values as arrays
312
-	 * 
313
-	 * @param string $varName name of config-key
314
-	 * @param array|string $value to set
315
-	 */
316
-	protected function setMultiLine($varName, $value) {
317
-		if(empty($value)) {
318
-			$value = '';
319
-		} else if (!is_array($value)) {
320
-			$value = preg_split('/\r\n|\r|\n|;/', $value);
321
-			if($value === false) {
322
-				$value = '';
323
-			}
324
-		}
310
+    /**
311
+     * Sets multi-line values as arrays
312
+     * 
313
+     * @param string $varName name of config-key
314
+     * @param array|string $value to set
315
+     */
316
+    protected function setMultiLine($varName, $value) {
317
+        if(empty($value)) {
318
+            $value = '';
319
+        } else if (!is_array($value)) {
320
+            $value = preg_split('/\r\n|\r|\n|;/', $value);
321
+            if($value === false) {
322
+                $value = '';
323
+            }
324
+        }
325 325
 
326
-		if(!is_array($value)) {
327
-			$finalValue = trim($value);
328
-		} else {
329
-			$finalValue = [];
330
-			foreach($value as $key => $val) {
331
-				if(is_string($val)) {
332
-					$val = trim($val);
333
-					if ($val !== '') {
334
-						//accidental line breaks are not wanted and can cause
335
-						// odd behaviour. Thus, away with them.
336
-						$finalValue[] = $val;
337
-					}
338
-				} else {
339
-					$finalValue[] = $val;
340
-				}
341
-			}
342
-		}
326
+        if(!is_array($value)) {
327
+            $finalValue = trim($value);
328
+        } else {
329
+            $finalValue = [];
330
+            foreach($value as $key => $val) {
331
+                if(is_string($val)) {
332
+                    $val = trim($val);
333
+                    if ($val !== '') {
334
+                        //accidental line breaks are not wanted and can cause
335
+                        // odd behaviour. Thus, away with them.
336
+                        $finalValue[] = $val;
337
+                    }
338
+                } else {
339
+                    $finalValue[] = $val;
340
+                }
341
+            }
342
+        }
343 343
 
344
-		$this->setRawValue($varName, $finalValue);
345
-	}
344
+        $this->setRawValue($varName, $finalValue);
345
+    }
346 346
 
347
-	/**
348
-	 * @param string $varName
349
-	 * @return string
350
-	 */
351
-	protected function getPwd($varName) {
352
-		return base64_decode($this->getValue($varName));
353
-	}
347
+    /**
348
+     * @param string $varName
349
+     * @return string
350
+     */
351
+    protected function getPwd($varName) {
352
+        return base64_decode($this->getValue($varName));
353
+    }
354 354
 
355
-	/**
356
-	 * @param string $varName
357
-	 * @return string
358
-	 */
359
-	protected function getLcValue($varName) {
360
-		return mb_strtolower($this->getValue($varName), 'UTF-8');
361
-	}
355
+    /**
356
+     * @param string $varName
357
+     * @return string
358
+     */
359
+    protected function getLcValue($varName) {
360
+        return mb_strtolower($this->getValue($varName), 'UTF-8');
361
+    }
362 362
 
363
-	/**
364
-	 * @param string $varName
365
-	 * @return string
366
-	 */
367
-	protected function getSystemValue($varName) {
368
-		//FIXME: if another system value is added, softcode the default value
369
-		return \OC::$server->getConfig()->getSystemValue($varName, false);
370
-	}
363
+    /**
364
+     * @param string $varName
365
+     * @return string
366
+     */
367
+    protected function getSystemValue($varName) {
368
+        //FIXME: if another system value is added, softcode the default value
369
+        return \OC::$server->getConfig()->getSystemValue($varName, false);
370
+    }
371 371
 
372
-	/**
373
-	 * @param string $varName
374
-	 * @return string
375
-	 */
376
-	protected function getValue($varName) {
377
-		static $defaults;
378
-		if(is_null($defaults)) {
379
-			$defaults = $this->getDefaults();
380
-		}
381
-		return \OCP\Config::getAppValue('user_ldap',
382
-										$this->configPrefix.$varName,
383
-										$defaults[$varName]);
384
-	}
372
+    /**
373
+     * @param string $varName
374
+     * @return string
375
+     */
376
+    protected function getValue($varName) {
377
+        static $defaults;
378
+        if(is_null($defaults)) {
379
+            $defaults = $this->getDefaults();
380
+        }
381
+        return \OCP\Config::getAppValue('user_ldap',
382
+                                        $this->configPrefix.$varName,
383
+                                        $defaults[$varName]);
384
+    }
385 385
 
386
-	/**
387
-	 * Sets a scalar value.
388
-	 * 
389
-	 * @param string $varName name of config key
390
-	 * @param mixed $value to set
391
-	 */
392
-	protected function setValue($varName, $value) {
393
-		if(is_string($value)) {
394
-			$value = trim($value);
395
-		}
396
-		$this->config[$varName] = $value;
397
-	}
386
+    /**
387
+     * Sets a scalar value.
388
+     * 
389
+     * @param string $varName name of config key
390
+     * @param mixed $value to set
391
+     */
392
+    protected function setValue($varName, $value) {
393
+        if(is_string($value)) {
394
+            $value = trim($value);
395
+        }
396
+        $this->config[$varName] = $value;
397
+    }
398 398
 
399
-	/**
400
-	 * Sets a scalar value without trimming.
401
-	 *
402
-	 * @param string $varName name of config key
403
-	 * @param mixed $value to set
404
-	 */
405
-	protected function setRawValue($varName, $value) {
406
-		$this->config[$varName] = $value;
407
-	}
399
+    /**
400
+     * Sets a scalar value without trimming.
401
+     *
402
+     * @param string $varName name of config key
403
+     * @param mixed $value to set
404
+     */
405
+    protected function setRawValue($varName, $value) {
406
+        $this->config[$varName] = $value;
407
+    }
408 408
 
409
-	/**
410
-	 * @param string $varName
411
-	 * @param string $value
412
-	 * @return bool
413
-	 */
414
-	protected function saveValue($varName, $value) {
415
-		\OC::$server->getConfig()->setAppValue(
416
-			'user_ldap',
417
-			$this->configPrefix.$varName,
418
-			$value
419
-		);
420
-		return true;
421
-	}
409
+    /**
410
+     * @param string $varName
411
+     * @param string $value
412
+     * @return bool
413
+     */
414
+    protected function saveValue($varName, $value) {
415
+        \OC::$server->getConfig()->setAppValue(
416
+            'user_ldap',
417
+            $this->configPrefix.$varName,
418
+            $value
419
+        );
420
+        return true;
421
+    }
422 422
 
423
-	/**
424
-	 * @return array an associative array with the default values. Keys are correspond
425
-	 * to config-value entries in the database table
426
-	 */
427
-	public function getDefaults() {
428
-		return array(
429
-			'ldap_host'                         => '',
430
-			'ldap_port'                         => '',
431
-			'ldap_backup_host'                  => '',
432
-			'ldap_backup_port'                  => '',
433
-			'ldap_override_main_server'         => '',
434
-			'ldap_dn'                           => '',
435
-			'ldap_agent_password'               => '',
436
-			'ldap_base'                         => '',
437
-			'ldap_base_users'                   => '',
438
-			'ldap_base_groups'                  => '',
439
-			'ldap_userlist_filter'              => '',
440
-			'ldap_user_filter_mode'             => 0,
441
-			'ldap_userfilter_objectclass'       => '',
442
-			'ldap_userfilter_groups'            => '',
443
-			'ldap_login_filter'                 => '',
444
-			'ldap_login_filter_mode'            => 0,
445
-			'ldap_loginfilter_email'            => 0,
446
-			'ldap_loginfilter_username'         => 1,
447
-			'ldap_loginfilter_attributes'       => '',
448
-			'ldap_group_filter'                 => '',
449
-			'ldap_group_filter_mode'            => 0,
450
-			'ldap_groupfilter_objectclass'      => '',
451
-			'ldap_groupfilter_groups'           => '',
452
-			'ldap_gid_number'                   => 'gidNumber',
453
-			'ldap_display_name'                 => 'displayName',
454
-			'ldap_user_display_name_2'			=> '',
455
-			'ldap_group_display_name'           => 'cn',
456
-			'ldap_tls'                          => 0,
457
-			'ldap_quota_def'                    => '',
458
-			'ldap_quota_attr'                   => '',
459
-			'ldap_email_attr'                   => '',
460
-			'ldap_group_member_assoc_attribute' => 'uniqueMember',
461
-			'ldap_cache_ttl'                    => 600,
462
-			'ldap_uuid_user_attribute'          => 'auto',
463
-			'ldap_uuid_group_attribute'         => 'auto',
464
-			'home_folder_naming_rule'           => '',
465
-			'ldap_turn_off_cert_check'          => 0,
466
-			'ldap_configuration_active'         => 0,
467
-			'ldap_attributes_for_user_search'   => '',
468
-			'ldap_attributes_for_group_search'  => '',
469
-			'ldap_expert_username_attr'         => '',
470
-			'ldap_expert_uuid_user_attr'        => '',
471
-			'ldap_expert_uuid_group_attr'       => '',
472
-			'has_memberof_filter_support'       => 0,
473
-			'use_memberof_to_detect_membership' => 1,
474
-			'last_jpegPhoto_lookup'             => 0,
475
-			'ldap_nested_groups'                => 0,
476
-			'ldap_paging_size'                  => 500,
477
-			'ldap_turn_on_pwd_change'           => 0,
478
-			'ldap_experienced_admin'            => 0,
479
-			'ldap_dynamic_group_member_url'     => '',
480
-			'ldap_default_ppolicy_dn'           => '',
481
-			'ldap_user_avatar_rule'             => 'default',
482
-		);
483
-	}
423
+    /**
424
+     * @return array an associative array with the default values. Keys are correspond
425
+     * to config-value entries in the database table
426
+     */
427
+    public function getDefaults() {
428
+        return array(
429
+            'ldap_host'                         => '',
430
+            'ldap_port'                         => '',
431
+            'ldap_backup_host'                  => '',
432
+            'ldap_backup_port'                  => '',
433
+            'ldap_override_main_server'         => '',
434
+            'ldap_dn'                           => '',
435
+            'ldap_agent_password'               => '',
436
+            'ldap_base'                         => '',
437
+            'ldap_base_users'                   => '',
438
+            'ldap_base_groups'                  => '',
439
+            'ldap_userlist_filter'              => '',
440
+            'ldap_user_filter_mode'             => 0,
441
+            'ldap_userfilter_objectclass'       => '',
442
+            'ldap_userfilter_groups'            => '',
443
+            'ldap_login_filter'                 => '',
444
+            'ldap_login_filter_mode'            => 0,
445
+            'ldap_loginfilter_email'            => 0,
446
+            'ldap_loginfilter_username'         => 1,
447
+            'ldap_loginfilter_attributes'       => '',
448
+            'ldap_group_filter'                 => '',
449
+            'ldap_group_filter_mode'            => 0,
450
+            'ldap_groupfilter_objectclass'      => '',
451
+            'ldap_groupfilter_groups'           => '',
452
+            'ldap_gid_number'                   => 'gidNumber',
453
+            'ldap_display_name'                 => 'displayName',
454
+            'ldap_user_display_name_2'			=> '',
455
+            'ldap_group_display_name'           => 'cn',
456
+            'ldap_tls'                          => 0,
457
+            'ldap_quota_def'                    => '',
458
+            'ldap_quota_attr'                   => '',
459
+            'ldap_email_attr'                   => '',
460
+            'ldap_group_member_assoc_attribute' => 'uniqueMember',
461
+            'ldap_cache_ttl'                    => 600,
462
+            'ldap_uuid_user_attribute'          => 'auto',
463
+            'ldap_uuid_group_attribute'         => 'auto',
464
+            'home_folder_naming_rule'           => '',
465
+            'ldap_turn_off_cert_check'          => 0,
466
+            'ldap_configuration_active'         => 0,
467
+            'ldap_attributes_for_user_search'   => '',
468
+            'ldap_attributes_for_group_search'  => '',
469
+            'ldap_expert_username_attr'         => '',
470
+            'ldap_expert_uuid_user_attr'        => '',
471
+            'ldap_expert_uuid_group_attr'       => '',
472
+            'has_memberof_filter_support'       => 0,
473
+            'use_memberof_to_detect_membership' => 1,
474
+            'last_jpegPhoto_lookup'             => 0,
475
+            'ldap_nested_groups'                => 0,
476
+            'ldap_paging_size'                  => 500,
477
+            'ldap_turn_on_pwd_change'           => 0,
478
+            'ldap_experienced_admin'            => 0,
479
+            'ldap_dynamic_group_member_url'     => '',
480
+            'ldap_default_ppolicy_dn'           => '',
481
+            'ldap_user_avatar_rule'             => 'default',
482
+        );
483
+    }
484 484
 
485
-	/**
486
-	 * @return array that maps internal variable names to database fields
487
-	 */
488
-	public function getConfigTranslationArray() {
489
-		//TODO: merge them into one representation
490
-		static $array = array(
491
-			'ldap_host'                         => 'ldapHost',
492
-			'ldap_port'                         => 'ldapPort',
493
-			'ldap_backup_host'                  => 'ldapBackupHost',
494
-			'ldap_backup_port'                  => 'ldapBackupPort',
495
-			'ldap_override_main_server'         => 'ldapOverrideMainServer',
496
-			'ldap_dn'                           => 'ldapAgentName',
497
-			'ldap_agent_password'               => 'ldapAgentPassword',
498
-			'ldap_base'                         => 'ldapBase',
499
-			'ldap_base_users'                   => 'ldapBaseUsers',
500
-			'ldap_base_groups'                  => 'ldapBaseGroups',
501
-			'ldap_userfilter_objectclass'       => 'ldapUserFilterObjectclass',
502
-			'ldap_userfilter_groups'            => 'ldapUserFilterGroups',
503
-			'ldap_userlist_filter'              => 'ldapUserFilter',
504
-			'ldap_user_filter_mode'             => 'ldapUserFilterMode',
505
-			'ldap_user_avatar_rule'             => 'ldapUserAvatarRule',
506
-			'ldap_login_filter'                 => 'ldapLoginFilter',
507
-			'ldap_login_filter_mode'            => 'ldapLoginFilterMode',
508
-			'ldap_loginfilter_email'            => 'ldapLoginFilterEmail',
509
-			'ldap_loginfilter_username'         => 'ldapLoginFilterUsername',
510
-			'ldap_loginfilter_attributes'       => 'ldapLoginFilterAttributes',
511
-			'ldap_group_filter'                 => 'ldapGroupFilter',
512
-			'ldap_group_filter_mode'            => 'ldapGroupFilterMode',
513
-			'ldap_groupfilter_objectclass'      => 'ldapGroupFilterObjectclass',
514
-			'ldap_groupfilter_groups'           => 'ldapGroupFilterGroups',
515
-			'ldap_gid_number'                   => 'ldapGidNumber',
516
-			'ldap_display_name'                 => 'ldapUserDisplayName',
517
-			'ldap_user_display_name_2'			=> 'ldapUserDisplayName2',
518
-			'ldap_group_display_name'           => 'ldapGroupDisplayName',
519
-			'ldap_tls'                          => 'ldapTLS',
520
-			'ldap_quota_def'                    => 'ldapQuotaDefault',
521
-			'ldap_quota_attr'                   => 'ldapQuotaAttribute',
522
-			'ldap_email_attr'                   => 'ldapEmailAttribute',
523
-			'ldap_group_member_assoc_attribute' => 'ldapGroupMemberAssocAttr',
524
-			'ldap_cache_ttl'                    => 'ldapCacheTTL',
525
-			'home_folder_naming_rule'           => 'homeFolderNamingRule',
526
-			'ldap_turn_off_cert_check'          => 'turnOffCertCheck',
527
-			'ldap_configuration_active'         => 'ldapConfigurationActive',
528
-			'ldap_attributes_for_user_search'   => 'ldapAttributesForUserSearch',
529
-			'ldap_attributes_for_group_search'  => 'ldapAttributesForGroupSearch',
530
-			'ldap_expert_username_attr'         => 'ldapExpertUsernameAttr',
531
-			'ldap_expert_uuid_user_attr'        => 'ldapExpertUUIDUserAttr',
532
-			'ldap_expert_uuid_group_attr'       => 'ldapExpertUUIDGroupAttr',
533
-			'has_memberof_filter_support'       => 'hasMemberOfFilterSupport',
534
-			'use_memberof_to_detect_membership' => 'useMemberOfToDetectMembership',
535
-			'last_jpegPhoto_lookup'             => 'lastJpegPhotoLookup',
536
-			'ldap_nested_groups'                => 'ldapNestedGroups',
537
-			'ldap_paging_size'                  => 'ldapPagingSize',
538
-			'ldap_turn_on_pwd_change'           => 'turnOnPasswordChange',
539
-			'ldap_experienced_admin'            => 'ldapExperiencedAdmin',
540
-			'ldap_dynamic_group_member_url'     => 'ldapDynamicGroupMemberURL',
541
-			'ldap_default_ppolicy_dn'           => 'ldapDefaultPPolicyDN',
542
-		);
543
-		return $array;
544
-	}
485
+    /**
486
+     * @return array that maps internal variable names to database fields
487
+     */
488
+    public function getConfigTranslationArray() {
489
+        //TODO: merge them into one representation
490
+        static $array = array(
491
+            'ldap_host'                         => 'ldapHost',
492
+            'ldap_port'                         => 'ldapPort',
493
+            'ldap_backup_host'                  => 'ldapBackupHost',
494
+            'ldap_backup_port'                  => 'ldapBackupPort',
495
+            'ldap_override_main_server'         => 'ldapOverrideMainServer',
496
+            'ldap_dn'                           => 'ldapAgentName',
497
+            'ldap_agent_password'               => 'ldapAgentPassword',
498
+            'ldap_base'                         => 'ldapBase',
499
+            'ldap_base_users'                   => 'ldapBaseUsers',
500
+            'ldap_base_groups'                  => 'ldapBaseGroups',
501
+            'ldap_userfilter_objectclass'       => 'ldapUserFilterObjectclass',
502
+            'ldap_userfilter_groups'            => 'ldapUserFilterGroups',
503
+            'ldap_userlist_filter'              => 'ldapUserFilter',
504
+            'ldap_user_filter_mode'             => 'ldapUserFilterMode',
505
+            'ldap_user_avatar_rule'             => 'ldapUserAvatarRule',
506
+            'ldap_login_filter'                 => 'ldapLoginFilter',
507
+            'ldap_login_filter_mode'            => 'ldapLoginFilterMode',
508
+            'ldap_loginfilter_email'            => 'ldapLoginFilterEmail',
509
+            'ldap_loginfilter_username'         => 'ldapLoginFilterUsername',
510
+            'ldap_loginfilter_attributes'       => 'ldapLoginFilterAttributes',
511
+            'ldap_group_filter'                 => 'ldapGroupFilter',
512
+            'ldap_group_filter_mode'            => 'ldapGroupFilterMode',
513
+            'ldap_groupfilter_objectclass'      => 'ldapGroupFilterObjectclass',
514
+            'ldap_groupfilter_groups'           => 'ldapGroupFilterGroups',
515
+            'ldap_gid_number'                   => 'ldapGidNumber',
516
+            'ldap_display_name'                 => 'ldapUserDisplayName',
517
+            'ldap_user_display_name_2'			=> 'ldapUserDisplayName2',
518
+            'ldap_group_display_name'           => 'ldapGroupDisplayName',
519
+            'ldap_tls'                          => 'ldapTLS',
520
+            'ldap_quota_def'                    => 'ldapQuotaDefault',
521
+            'ldap_quota_attr'                   => 'ldapQuotaAttribute',
522
+            'ldap_email_attr'                   => 'ldapEmailAttribute',
523
+            'ldap_group_member_assoc_attribute' => 'ldapGroupMemberAssocAttr',
524
+            'ldap_cache_ttl'                    => 'ldapCacheTTL',
525
+            'home_folder_naming_rule'           => 'homeFolderNamingRule',
526
+            'ldap_turn_off_cert_check'          => 'turnOffCertCheck',
527
+            'ldap_configuration_active'         => 'ldapConfigurationActive',
528
+            'ldap_attributes_for_user_search'   => 'ldapAttributesForUserSearch',
529
+            'ldap_attributes_for_group_search'  => 'ldapAttributesForGroupSearch',
530
+            'ldap_expert_username_attr'         => 'ldapExpertUsernameAttr',
531
+            'ldap_expert_uuid_user_attr'        => 'ldapExpertUUIDUserAttr',
532
+            'ldap_expert_uuid_group_attr'       => 'ldapExpertUUIDGroupAttr',
533
+            'has_memberof_filter_support'       => 'hasMemberOfFilterSupport',
534
+            'use_memberof_to_detect_membership' => 'useMemberOfToDetectMembership',
535
+            'last_jpegPhoto_lookup'             => 'lastJpegPhotoLookup',
536
+            'ldap_nested_groups'                => 'ldapNestedGroups',
537
+            'ldap_paging_size'                  => 'ldapPagingSize',
538
+            'ldap_turn_on_pwd_change'           => 'turnOnPasswordChange',
539
+            'ldap_experienced_admin'            => 'ldapExperiencedAdmin',
540
+            'ldap_dynamic_group_member_url'     => 'ldapDynamicGroupMemberURL',
541
+            'ldap_default_ppolicy_dn'           => 'ldapDefaultPPolicyDN',
542
+        );
543
+        return $array;
544
+    }
545 545
 
546
-	/**
547
-	 * @param string $rule
548
-	 * @return array
549
-	 * @throws \RuntimeException
550
-	 */
551
-	public function resolveRule($rule) {
552
-		if($rule === 'avatar') {
553
-			return $this->getAvatarAttributes();
554
-		}
555
-		throw new \RuntimeException('Invalid rule');
556
-	}
546
+    /**
547
+     * @param string $rule
548
+     * @return array
549
+     * @throws \RuntimeException
550
+     */
551
+    public function resolveRule($rule) {
552
+        if($rule === 'avatar') {
553
+            return $this->getAvatarAttributes();
554
+        }
555
+        throw new \RuntimeException('Invalid rule');
556
+    }
557 557
 
558
-	public function getAvatarAttributes() {
559
-		$value = $this->ldapUserAvatarRule ?: self::AVATAR_PREFIX_DEFAULT;
560
-		$defaultAttributes = ['jpegphoto', 'thumbnailphoto'];
558
+    public function getAvatarAttributes() {
559
+        $value = $this->ldapUserAvatarRule ?: self::AVATAR_PREFIX_DEFAULT;
560
+        $defaultAttributes = ['jpegphoto', 'thumbnailphoto'];
561 561
 
562
-		if($value === self::AVATAR_PREFIX_NONE) {
563
-			return [];
564
-		}
565
-		if(strpos($value, self::AVATAR_PREFIX_DATA_ATTRIBUTE) === 0) {
566
-			$attribute = trim(substr($value, strlen(self::AVATAR_PREFIX_DATA_ATTRIBUTE)));
567
-			if($attribute === '') {
568
-				return $defaultAttributes;
569
-			}
570
-			return [strtolower($attribute)];
571
-		}
572
-		if($value !== self::AVATAR_PREFIX_DEFAULT) {
573
-			\OC::$server->getLogger()->warning('Invalid config value to ldapUserAvatarRule; falling back to default.');
574
-		}
575
-		return $defaultAttributes;
576
-	}
562
+        if($value === self::AVATAR_PREFIX_NONE) {
563
+            return [];
564
+        }
565
+        if(strpos($value, self::AVATAR_PREFIX_DATA_ATTRIBUTE) === 0) {
566
+            $attribute = trim(substr($value, strlen(self::AVATAR_PREFIX_DATA_ATTRIBUTE)));
567
+            if($attribute === '') {
568
+                return $defaultAttributes;
569
+            }
570
+            return [strtolower($attribute)];
571
+        }
572
+        if($value !== self::AVATAR_PREFIX_DEFAULT) {
573
+            \OC::$server->getLogger()->warning('Invalid config value to ldapUserAvatarRule; falling back to default.');
574
+        }
575
+        return $defaultAttributes;
576
+    }
577 577
 
578 578
 }
Please login to merge, or discard this patch.
Spacing   +28 added lines, -28 removed lines patch added patch discarded remove patch
@@ -115,7 +115,7 @@  discard block
 block discarded – undo
115 115
 	 */
116 116
 	public function __construct($configPrefix, $autoRead = true) {
117 117
 		$this->configPrefix = $configPrefix;
118
-		if($autoRead) {
118
+		if ($autoRead) {
119 119
 			$this->readConfiguration();
120 120
 		}
121 121
 	}
@@ -125,7 +125,7 @@  discard block
 block discarded – undo
125 125
 	 * @return mixed|null
126 126
 	 */
127 127
 	public function __get($name) {
128
-		if(isset($this->config[$name])) {
128
+		if (isset($this->config[$name])) {
129 129
 			return $this->config[$name];
130 130
 		}
131 131
 		return null;
@@ -156,22 +156,22 @@  discard block
 block discarded – undo
156 156
 	 * @return false|null
157 157
 	 */
158 158
 	public function setConfiguration($config, &$applied = null) {
159
-		if(!is_array($config)) {
159
+		if (!is_array($config)) {
160 160
 			return false;
161 161
 		}
162 162
 
163 163
 		$cta = $this->getConfigTranslationArray();
164
-		foreach($config as $inputKey => $val) {
165
-			if(strpos($inputKey, '_') !== false && array_key_exists($inputKey, $cta)) {
164
+		foreach ($config as $inputKey => $val) {
165
+			if (strpos($inputKey, '_') !== false && array_key_exists($inputKey, $cta)) {
166 166
 				$key = $cta[$inputKey];
167
-			} elseif(array_key_exists($inputKey, $this->config)) {
167
+			} elseif (array_key_exists($inputKey, $this->config)) {
168 168
 				$key = $inputKey;
169 169
 			} else {
170 170
 				continue;
171 171
 			}
172 172
 
173 173
 			$setMethod = 'setValue';
174
-			switch($key) {
174
+			switch ($key) {
175 175
 				case 'ldapAgentPassword':
176 176
 					$setMethod = 'setRawValue';
177 177
 					break;
@@ -195,7 +195,7 @@  discard block
 block discarded – undo
195 195
 					break;
196 196
 			}
197 197
 			$this->$setMethod($key, $val);
198
-			if(is_array($applied)) {
198
+			if (is_array($applied)) {
199 199
 				$applied[] = $inputKey;
200 200
 				// storing key as index avoids duplication, and as value for simplicity
201 201
 			}
@@ -205,15 +205,15 @@  discard block
 block discarded – undo
205 205
 	}
206 206
 
207 207
 	public function readConfiguration() {
208
-		if(!$this->configRead && !is_null($this->configPrefix)) {
208
+		if (!$this->configRead && !is_null($this->configPrefix)) {
209 209
 			$cta = array_flip($this->getConfigTranslationArray());
210
-			foreach($this->config as $key => $val) {
211
-				if(!isset($cta[$key])) {
210
+			foreach ($this->config as $key => $val) {
211
+				if (!isset($cta[$key])) {
212 212
 					//some are determined
213 213
 					continue;
214 214
 				}
215 215
 				$dbKey = $cta[$key];
216
-				switch($key) {
216
+				switch ($key) {
217 217
 					case 'ldapBase':
218 218
 					case 'ldapBaseUsers':
219 219
 					case 'ldapBaseGroups':
@@ -256,7 +256,7 @@  discard block
 block discarded – undo
256 256
 	 */
257 257
 	public function saveConfiguration() {
258 258
 		$cta = array_flip($this->getConfigTranslationArray());
259
-		foreach($this->unsavedChanges as $key) {
259
+		foreach ($this->unsavedChanges as $key) {
260 260
 			$value = $this->config[$key];
261 261
 			switch ($key) {
262 262
 				case 'ldapAgentPassword':
@@ -272,7 +272,7 @@  discard block
 block discarded – undo
272 272
 				case 'ldapGroupFilterObjectclass':
273 273
 				case 'ldapGroupFilterGroups':
274 274
 				case 'ldapLoginFilterAttributes':
275
-					if(is_array($value)) {
275
+					if (is_array($value)) {
276 276
 						$value = implode("\n", $value);
277 277
 					}
278 278
 					break;
@@ -283,7 +283,7 @@  discard block
 block discarded – undo
283 283
 				case 'ldapUuidGroupAttribute':
284 284
 					continue 2;
285 285
 			}
286
-			if(is_null($value)) {
286
+			if (is_null($value)) {
287 287
 				$value = '';
288 288
 			}
289 289
 			$this->saveValue($cta[$key], $value);
@@ -298,7 +298,7 @@  discard block
 block discarded – undo
298 298
 	 */
299 299
 	protected function getMultiLine($varName) {
300 300
 		$value = $this->getValue($varName);
301
-		if(empty($value)) {
301
+		if (empty($value)) {
302 302
 			$value = '';
303 303
 		} else {
304 304
 			$value = preg_split('/\r\n|\r|\n/', $value);
@@ -314,21 +314,21 @@  discard block
 block discarded – undo
314 314
 	 * @param array|string $value to set
315 315
 	 */
316 316
 	protected function setMultiLine($varName, $value) {
317
-		if(empty($value)) {
317
+		if (empty($value)) {
318 318
 			$value = '';
319 319
 		} else if (!is_array($value)) {
320 320
 			$value = preg_split('/\r\n|\r|\n|;/', $value);
321
-			if($value === false) {
321
+			if ($value === false) {
322 322
 				$value = '';
323 323
 			}
324 324
 		}
325 325
 
326
-		if(!is_array($value)) {
326
+		if (!is_array($value)) {
327 327
 			$finalValue = trim($value);
328 328
 		} else {
329 329
 			$finalValue = [];
330
-			foreach($value as $key => $val) {
331
-				if(is_string($val)) {
330
+			foreach ($value as $key => $val) {
331
+				if (is_string($val)) {
332 332
 					$val = trim($val);
333 333
 					if ($val !== '') {
334 334
 						//accidental line breaks are not wanted and can cause
@@ -375,7 +375,7 @@  discard block
 block discarded – undo
375 375
 	 */
376 376
 	protected function getValue($varName) {
377 377
 		static $defaults;
378
-		if(is_null($defaults)) {
378
+		if (is_null($defaults)) {
379 379
 			$defaults = $this->getDefaults();
380 380
 		}
381 381
 		return \OCP\Config::getAppValue('user_ldap',
@@ -390,7 +390,7 @@  discard block
 block discarded – undo
390 390
 	 * @param mixed $value to set
391 391
 	 */
392 392
 	protected function setValue($varName, $value) {
393
-		if(is_string($value)) {
393
+		if (is_string($value)) {
394 394
 			$value = trim($value);
395 395
 		}
396 396
 		$this->config[$varName] = $value;
@@ -549,7 +549,7 @@  discard block
 block discarded – undo
549 549
 	 * @throws \RuntimeException
550 550
 	 */
551 551
 	public function resolveRule($rule) {
552
-		if($rule === 'avatar') {
552
+		if ($rule === 'avatar') {
553 553
 			return $this->getAvatarAttributes();
554 554
 		}
555 555
 		throw new \RuntimeException('Invalid rule');
@@ -559,17 +559,17 @@  discard block
 block discarded – undo
559 559
 		$value = $this->ldapUserAvatarRule ?: self::AVATAR_PREFIX_DEFAULT;
560 560
 		$defaultAttributes = ['jpegphoto', 'thumbnailphoto'];
561 561
 
562
-		if($value === self::AVATAR_PREFIX_NONE) {
562
+		if ($value === self::AVATAR_PREFIX_NONE) {
563 563
 			return [];
564 564
 		}
565
-		if(strpos($value, self::AVATAR_PREFIX_DATA_ATTRIBUTE) === 0) {
565
+		if (strpos($value, self::AVATAR_PREFIX_DATA_ATTRIBUTE) === 0) {
566 566
 			$attribute = trim(substr($value, strlen(self::AVATAR_PREFIX_DATA_ATTRIBUTE)));
567
-			if($attribute === '') {
567
+			if ($attribute === '') {
568 568
 				return $defaultAttributes;
569 569
 			}
570 570
 			return [strtolower($attribute)];
571 571
 		}
572
-		if($value !== self::AVATAR_PREFIX_DEFAULT) {
572
+		if ($value !== self::AVATAR_PREFIX_DEFAULT) {
573 573
 			\OC::$server->getLogger()->warning('Invalid config value to ldapUserAvatarRule; falling back to default.');
574 574
 		}
575 575
 		return $defaultAttributes;
Please login to merge, or discard this patch.
apps/user_ldap/lib/Connection.php 1 patch
Indentation   +612 added lines, -612 removed lines patch added patch discarded remove patch
@@ -62,617 +62,617 @@
 block discarded – undo
62 62
  * @property string ldapEmailAttribute
63 63
  */
64 64
 class Connection extends LDAPUtility {
65
-	private $ldapConnectionRes = null;
66
-	private $configPrefix;
67
-	private $configID;
68
-	private $configured = false;
69
-	private $hasPagedResultSupport = true;
70
-	//whether connection should be kept on __destruct
71
-	private $dontDestruct = false;
72
-
73
-	/**
74
-	 * @var bool runtime flag that indicates whether supported primary groups are available
75
-	 */
76
-	public $hasPrimaryGroups = true;
77
-
78
-	/**
79
-	 * @var bool runtime flag that indicates whether supported POSIX gidNumber are available
80
-	 */
81
-	public $hasGidNumber = true;
82
-
83
-	//cache handler
84
-	protected $cache;
85
-
86
-	/** @var Configuration settings handler **/
87
-	protected $configuration;
88
-
89
-	protected $doNotValidate = false;
90
-
91
-	protected $ignoreValidation = false;
92
-
93
-	protected $bindResult = [];
94
-
95
-	/**
96
-	 * Constructor
97
-	 * @param ILDAPWrapper $ldap
98
-	 * @param string $configPrefix a string with the prefix for the configkey column (appconfig table)
99
-	 * @param string|null $configID a string with the value for the appid column (appconfig table) or null for on-the-fly connections
100
-	 */
101
-	public function __construct(ILDAPWrapper $ldap, $configPrefix = '', $configID = 'user_ldap') {
102
-		parent::__construct($ldap);
103
-		$this->configPrefix = $configPrefix;
104
-		$this->configID = $configID;
105
-		$this->configuration = new Configuration($configPrefix,
106
-												 !is_null($configID));
107
-		$memcache = \OC::$server->getMemCacheFactory();
108
-		if($memcache->isAvailable()) {
109
-			$this->cache = $memcache->createDistributed();
110
-		}
111
-		$helper = new Helper(\OC::$server->getConfig());
112
-		$this->doNotValidate = !in_array($this->configPrefix,
113
-			$helper->getServerConfigurationPrefixes());
114
-		$this->hasPagedResultSupport =
115
-			intval($this->configuration->ldapPagingSize) !== 0
116
-			|| $this->ldap->hasPagedResultSupport();
117
-	}
118
-
119
-	public function __destruct() {
120
-		if(!$this->dontDestruct && $this->ldap->isResource($this->ldapConnectionRes)) {
121
-			@$this->ldap->unbind($this->ldapConnectionRes);
122
-		}
123
-		$this->bindResult = [];
124
-	}
125
-
126
-	/**
127
-	 * defines behaviour when the instance is cloned
128
-	 */
129
-	public function __clone() {
130
-		$this->configuration = new Configuration($this->configPrefix,
131
-												 !is_null($this->configID));
132
-		if(count($this->bindResult) !== 0 && $this->bindResult['result'] === true) {
133
-			$this->bindResult = [];
134
-		}
135
-		$this->ldapConnectionRes = null;
136
-		$this->dontDestruct = true;
137
-	}
138
-
139
-	/**
140
-	 * @param string $name
141
-	 * @return bool|mixed
142
-	 */
143
-	public function __get($name) {
144
-		if(!$this->configured) {
145
-			$this->readConfiguration();
146
-		}
147
-
148
-		if($name === 'hasPagedResultSupport') {
149
-			return $this->hasPagedResultSupport;
150
-		}
151
-
152
-		return $this->configuration->$name;
153
-	}
154
-
155
-	/**
156
-	 * @param string $name
157
-	 * @param mixed $value
158
-	 */
159
-	public function __set($name, $value) {
160
-		$this->doNotValidate = false;
161
-		$before = $this->configuration->$name;
162
-		$this->configuration->$name = $value;
163
-		$after = $this->configuration->$name;
164
-		if($before !== $after) {
165
-			if ($this->configID !== '' && $this->configID !== null) {
166
-				$this->configuration->saveConfiguration();
167
-			}
168
-			$this->validateConfiguration();
169
-		}
170
-	}
171
-
172
-	/**
173
-	 * @param string $rule
174
-	 * @return array
175
-	 * @throws \RuntimeException
176
-	 */
177
-	public function resolveRule($rule) {
178
-		return $this->configuration->resolveRule($rule);
179
-	}
180
-
181
-	/**
182
-	 * sets whether the result of the configuration validation shall
183
-	 * be ignored when establishing the connection. Used by the Wizard
184
-	 * in early configuration state.
185
-	 * @param bool $state
186
-	 */
187
-	public function setIgnoreValidation($state) {
188
-		$this->ignoreValidation = (bool)$state;
189
-	}
190
-
191
-	/**
192
-	 * initializes the LDAP backend
193
-	 * @param bool $force read the config settings no matter what
194
-	 */
195
-	public function init($force = false) {
196
-		$this->readConfiguration($force);
197
-		$this->establishConnection();
198
-	}
199
-
200
-	/**
201
-	 * Returns the LDAP handler
202
-	 */
203
-	public function getConnectionResource() {
204
-		if(!$this->ldapConnectionRes) {
205
-			$this->init();
206
-		} else if(!$this->ldap->isResource($this->ldapConnectionRes)) {
207
-			$this->ldapConnectionRes = null;
208
-			$this->establishConnection();
209
-		}
210
-		if(is_null($this->ldapConnectionRes)) {
211
-			\OCP\Util::writeLog('user_ldap', 'No LDAP Connection to server ' . $this->configuration->ldapHost, \OCP\Util::ERROR);
212
-			throw new ServerNotAvailableException('Connection to LDAP server could not be established');
213
-		}
214
-		return $this->ldapConnectionRes;
215
-	}
216
-
217
-	/**
218
-	 * resets the connection resource
219
-	 */
220
-	public function resetConnectionResource() {
221
-		if(!is_null($this->ldapConnectionRes)) {
222
-			@$this->ldap->unbind($this->ldapConnectionRes);
223
-			$this->ldapConnectionRes = null;
224
-			$this->bindResult = [];
225
-		}
226
-	}
227
-
228
-	/**
229
-	 * @param string|null $key
230
-	 * @return string
231
-	 */
232
-	private function getCacheKey($key) {
233
-		$prefix = 'LDAP-'.$this->configID.'-'.$this->configPrefix.'-';
234
-		if(is_null($key)) {
235
-			return $prefix;
236
-		}
237
-		return $prefix.hash('sha256', $key);
238
-	}
239
-
240
-	/**
241
-	 * @param string $key
242
-	 * @return mixed|null
243
-	 */
244
-	public function getFromCache($key) {
245
-		if(!$this->configured) {
246
-			$this->readConfiguration();
247
-		}
248
-		if(is_null($this->cache) || !$this->configuration->ldapCacheTTL) {
249
-			return null;
250
-		}
251
-		$key = $this->getCacheKey($key);
252
-
253
-		return json_decode(base64_decode($this->cache->get($key)), true);
254
-	}
255
-
256
-	/**
257
-	 * @param string $key
258
-	 * @param mixed $value
259
-	 *
260
-	 * @return string
261
-	 */
262
-	public function writeToCache($key, $value) {
263
-		if(!$this->configured) {
264
-			$this->readConfiguration();
265
-		}
266
-		if(is_null($this->cache)
267
-			|| !$this->configuration->ldapCacheTTL
268
-			|| !$this->configuration->ldapConfigurationActive) {
269
-			return null;
270
-		}
271
-		$key   = $this->getCacheKey($key);
272
-		$value = base64_encode(json_encode($value));
273
-		$this->cache->set($key, $value, $this->configuration->ldapCacheTTL);
274
-	}
275
-
276
-	public function clearCache() {
277
-		if(!is_null($this->cache)) {
278
-			$this->cache->clear($this->getCacheKey(null));
279
-		}
280
-	}
281
-
282
-	/**
283
-	 * Caches the general LDAP configuration.
284
-	 * @param bool $force optional. true, if the re-read should be forced. defaults
285
-	 * to false.
286
-	 * @return null
287
-	 */
288
-	private function readConfiguration($force = false) {
289
-		if((!$this->configured || $force) && !is_null($this->configID)) {
290
-			$this->configuration->readConfiguration();
291
-			$this->configured = $this->validateConfiguration();
292
-		}
293
-	}
294
-
295
-	/**
296
-	 * set LDAP configuration with values delivered by an array, not read from configuration
297
-	 * @param array $config array that holds the config parameters in an associated array
298
-	 * @param array &$setParameters optional; array where the set fields will be given to
299
-	 * @return boolean true if config validates, false otherwise. Check with $setParameters for detailed success on single parameters
300
-	 */
301
-	public function setConfiguration($config, &$setParameters = null) {
302
-		if(is_null($setParameters)) {
303
-			$setParameters = array();
304
-		}
305
-		$this->doNotValidate = false;
306
-		$this->configuration->setConfiguration($config, $setParameters);
307
-		if(count($setParameters) > 0) {
308
-			$this->configured = $this->validateConfiguration();
309
-		}
310
-
311
-
312
-		return $this->configured;
313
-	}
314
-
315
-	/**
316
-	 * saves the current Configuration in the database and empties the
317
-	 * cache
318
-	 * @return null
319
-	 */
320
-	public function saveConfiguration() {
321
-		$this->configuration->saveConfiguration();
322
-		$this->clearCache();
323
-	}
324
-
325
-	/**
326
-	 * get the current LDAP configuration
327
-	 * @return array
328
-	 */
329
-	public function getConfiguration() {
330
-		$this->readConfiguration();
331
-		$config = $this->configuration->getConfiguration();
332
-		$cta = $this->configuration->getConfigTranslationArray();
333
-		$result = array();
334
-		foreach($cta as $dbkey => $configkey) {
335
-			switch($configkey) {
336
-				case 'homeFolderNamingRule':
337
-					if(strpos($config[$configkey], 'attr:') === 0) {
338
-						$result[$dbkey] = substr($config[$configkey], 5);
339
-					} else {
340
-						$result[$dbkey] = '';
341
-					}
342
-					break;
343
-				case 'ldapBase':
344
-				case 'ldapBaseUsers':
345
-				case 'ldapBaseGroups':
346
-				case 'ldapAttributesForUserSearch':
347
-				case 'ldapAttributesForGroupSearch':
348
-					if(is_array($config[$configkey])) {
349
-						$result[$dbkey] = implode("\n", $config[$configkey]);
350
-						break;
351
-					} //else follows default
352
-				default:
353
-					$result[$dbkey] = $config[$configkey];
354
-			}
355
-		}
356
-		return $result;
357
-	}
358
-
359
-	private function doSoftValidation() {
360
-		//if User or Group Base are not set, take over Base DN setting
361
-		foreach(array('ldapBaseUsers', 'ldapBaseGroups') as $keyBase) {
362
-			$val = $this->configuration->$keyBase;
363
-			if(empty($val)) {
364
-				$this->configuration->$keyBase = $this->configuration->ldapBase;
365
-			}
366
-		}
367
-
368
-		foreach(array('ldapExpertUUIDUserAttr'  => 'ldapUuidUserAttribute',
369
-					  'ldapExpertUUIDGroupAttr' => 'ldapUuidGroupAttribute')
370
-				as $expertSetting => $effectiveSetting) {
371
-			$uuidOverride = $this->configuration->$expertSetting;
372
-			if(!empty($uuidOverride)) {
373
-				$this->configuration->$effectiveSetting = $uuidOverride;
374
-			} else {
375
-				$uuidAttributes = Access::UUID_ATTRIBUTES;
376
-				array_unshift($uuidAttributes, 'auto');
377
-				if(!in_array($this->configuration->$effectiveSetting,
378
-							$uuidAttributes)
379
-					&& (!is_null($this->configID))) {
380
-					$this->configuration->$effectiveSetting = 'auto';
381
-					$this->configuration->saveConfiguration();
382
-					\OCP\Util::writeLog('user_ldap',
383
-										'Illegal value for the '.
384
-										$effectiveSetting.', '.'reset to '.
385
-										'autodetect.', \OCP\Util::INFO);
386
-				}
387
-
388
-			}
389
-		}
390
-
391
-		$backupPort = intval($this->configuration->ldapBackupPort);
392
-		if ($backupPort <= 0) {
393
-			$this->configuration->backupPort = $this->configuration->ldapPort;
394
-		}
395
-
396
-		//make sure empty search attributes are saved as simple, empty array
397
-		$saKeys = array('ldapAttributesForUserSearch',
398
-						'ldapAttributesForGroupSearch');
399
-		foreach($saKeys as $key) {
400
-			$val = $this->configuration->$key;
401
-			if(is_array($val) && count($val) === 1 && empty($val[0])) {
402
-				$this->configuration->$key = array();
403
-			}
404
-		}
405
-
406
-		if((stripos($this->configuration->ldapHost, 'ldaps://') === 0)
407
-			&& $this->configuration->ldapTLS) {
408
-			$this->configuration->ldapTLS = false;
409
-			\OCP\Util::writeLog('user_ldap',
410
-								'LDAPS (already using secure connection) and '.
411
-								'TLS do not work together. Switched off TLS.',
412
-								\OCP\Util::INFO);
413
-		}
414
-	}
415
-
416
-	/**
417
-	 * @return bool
418
-	 */
419
-	private function doCriticalValidation() {
420
-		$configurationOK = true;
421
-		$errorStr = 'Configuration Error (prefix '.
422
-					strval($this->configPrefix).'): ';
423
-
424
-		//options that shall not be empty
425
-		$options = array('ldapHost', 'ldapPort', 'ldapUserDisplayName',
426
-						 'ldapGroupDisplayName', 'ldapLoginFilter');
427
-		foreach($options as $key) {
428
-			$val = $this->configuration->$key;
429
-			if(empty($val)) {
430
-				switch($key) {
431
-					case 'ldapHost':
432
-						$subj = 'LDAP Host';
433
-						break;
434
-					case 'ldapPort':
435
-						$subj = 'LDAP Port';
436
-						break;
437
-					case 'ldapUserDisplayName':
438
-						$subj = 'LDAP User Display Name';
439
-						break;
440
-					case 'ldapGroupDisplayName':
441
-						$subj = 'LDAP Group Display Name';
442
-						break;
443
-					case 'ldapLoginFilter':
444
-						$subj = 'LDAP Login Filter';
445
-						break;
446
-					default:
447
-						$subj = $key;
448
-						break;
449
-				}
450
-				$configurationOK = false;
451
-				\OCP\Util::writeLog('user_ldap',
452
-									$errorStr.'No '.$subj.' given!',
453
-									\OCP\Util::WARN);
454
-			}
455
-		}
456
-
457
-		//combinations
458
-		$agent = $this->configuration->ldapAgentName;
459
-		$pwd = $this->configuration->ldapAgentPassword;
460
-		if (
461
-			($agent === ''  && $pwd !== '')
462
-			|| ($agent !== '' && $pwd === '')
463
-		) {
464
-			\OCP\Util::writeLog('user_ldap',
465
-								$errorStr.'either no password is given for the '.
466
-								'user agent or a password is given, but not an '.
467
-								'LDAP agent.',
468
-				\OCP\Util::WARN);
469
-			$configurationOK = false;
470
-		}
471
-
472
-		$base = $this->configuration->ldapBase;
473
-		$baseUsers = $this->configuration->ldapBaseUsers;
474
-		$baseGroups = $this->configuration->ldapBaseGroups;
475
-
476
-		if(empty($base) && empty($baseUsers) && empty($baseGroups)) {
477
-			\OCP\Util::writeLog('user_ldap',
478
-								$errorStr.'Not a single Base DN given.',
479
-								\OCP\Util::WARN);
480
-			$configurationOK = false;
481
-		}
482
-
483
-		if(mb_strpos($this->configuration->ldapLoginFilter, '%uid', 0, 'UTF-8')
484
-		   === false) {
485
-			\OCP\Util::writeLog('user_ldap',
486
-								$errorStr.'login filter does not contain %uid '.
487
-								'place holder.',
488
-								\OCP\Util::WARN);
489
-			$configurationOK = false;
490
-		}
491
-
492
-		return $configurationOK;
493
-	}
494
-
495
-	/**
496
-	 * Validates the user specified configuration
497
-	 * @return bool true if configuration seems OK, false otherwise
498
-	 */
499
-	private function validateConfiguration() {
500
-
501
-		if($this->doNotValidate) {
502
-			//don't do a validation if it is a new configuration with pure
503
-			//default values. Will be allowed on changes via __set or
504
-			//setConfiguration
505
-			return false;
506
-		}
507
-
508
-		// first step: "soft" checks: settings that are not really
509
-		// necessary, but advisable. If left empty, give an info message
510
-		$this->doSoftValidation();
511
-
512
-		//second step: critical checks. If left empty or filled wrong, mark as
513
-		//not configured and give a warning.
514
-		return $this->doCriticalValidation();
515
-	}
516
-
517
-
518
-	/**
519
-	 * Connects and Binds to LDAP
520
-	 *
521
-	 * @throws ServerNotAvailableException
522
-	 */
523
-	private function establishConnection() {
524
-		if(!$this->configuration->ldapConfigurationActive) {
525
-			return null;
526
-		}
527
-		static $phpLDAPinstalled = true;
528
-		if(!$phpLDAPinstalled) {
529
-			return false;
530
-		}
531
-		if(!$this->ignoreValidation && !$this->configured) {
532
-			\OCP\Util::writeLog('user_ldap',
533
-								'Configuration is invalid, cannot connect',
534
-								\OCP\Util::WARN);
535
-			return false;
536
-		}
537
-		if(!$this->ldapConnectionRes) {
538
-			if(!$this->ldap->areLDAPFunctionsAvailable()) {
539
-				$phpLDAPinstalled = false;
540
-				\OCP\Util::writeLog('user_ldap',
541
-									'function ldap_connect is not available. Make '.
542
-									'sure that the PHP ldap module is installed.',
543
-									\OCP\Util::ERROR);
544
-
545
-				return false;
546
-			}
547
-			if($this->configuration->turnOffCertCheck) {
548
-				if(putenv('LDAPTLS_REQCERT=never')) {
549
-					\OCP\Util::writeLog('user_ldap',
550
-						'Turned off SSL certificate validation successfully.',
551
-						\OCP\Util::DEBUG);
552
-				} else {
553
-					\OCP\Util::writeLog('user_ldap',
554
-										'Could not turn off SSL certificate validation.',
555
-										\OCP\Util::WARN);
556
-				}
557
-			}
558
-
559
-			$isOverrideMainServer = ($this->configuration->ldapOverrideMainServer
560
-				|| $this->getFromCache('overrideMainServer'));
561
-			$isBackupHost = (trim($this->configuration->ldapBackupHost) !== "");
562
-			$bindStatus = false;
563
-			try {
564
-				if (!$isOverrideMainServer) {
565
-					$this->doConnect($this->configuration->ldapHost,
566
-						$this->configuration->ldapPort);
567
-				}
568
-				return $this->bind();
569
-			} catch (ServerNotAvailableException $e) {
570
-				if(!$isBackupHost) {
571
-					throw $e;
572
-				}
573
-			}
574
-
575
-			//if LDAP server is not reachable, try the Backup (Replica!) Server
576
-			if($isBackupHost || $isOverrideMainServer) {
577
-				$this->doConnect($this->configuration->ldapBackupHost,
578
-								 $this->configuration->ldapBackupPort);
579
-				$this->bindResult = [];
580
-				$bindStatus = $this->bind();
581
-				$error = $this->ldap->isResource($this->ldapConnectionRes) ?
582
-					$this->ldap->errno($this->ldapConnectionRes) : -1;
583
-				if($bindStatus && $error === 0 && !$this->getFromCache('overrideMainServer')) {
584
-					//when bind to backup server succeeded and failed to main server,
585
-					//skip contacting him until next cache refresh
586
-					$this->writeToCache('overrideMainServer', true);
587
-				}
588
-			}
589
-
590
-			return $bindStatus;
591
-		}
592
-		return null;
593
-	}
594
-
595
-	/**
596
-	 * @param string $host
597
-	 * @param string $port
598
-	 * @return bool
599
-	 * @throws \OC\ServerNotAvailableException
600
-	 */
601
-	private function doConnect($host, $port) {
602
-		if ($host === '') {
603
-			return false;
604
-		}
605
-
606
-		$this->ldapConnectionRes = $this->ldap->connect($host, $port);
607
-
608
-		if(!$this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) {
609
-			throw new ServerNotAvailableException('Could not set required LDAP Protocol version.');
610
-		}
611
-
612
-		if(!$this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_REFERRALS, 0)) {
613
-			throw new ServerNotAvailableException('Could not disable LDAP referrals.');
614
-		}
615
-
616
-		if($this->configuration->ldapTLS) {
617
-			if(!$this->ldap->startTls($this->ldapConnectionRes)) {
618
-				throw new ServerNotAvailableException('Start TLS failed, when connecting to LDAP host ' . $host . '.');
619
-			}
620
-		}
621
-
622
-		return true;
623
-	}
624
-
625
-	/**
626
-	 * Binds to LDAP
627
-	 */
628
-	public function bind() {
629
-		if(!$this->configuration->ldapConfigurationActive) {
630
-			return false;
631
-		}
632
-		$cr = $this->ldapConnectionRes;
633
-		if(!$this->ldap->isResource($cr)) {
634
-			$cr = $this->getConnectionResource();
635
-		}
636
-
637
-		if(
638
-			count($this->bindResult) !== 0
639
-			&& $this->bindResult['dn'] === $this->configuration->ldapAgentName
640
-			&& \OC::$server->getHasher()->verify(
641
-				$this->configPrefix . $this->configuration->ldapAgentPassword,
642
-				$this->bindResult['hash']
643
-			)
644
-		) {
645
-			// don't attempt to bind again with the same data as before
646
-			// bind might have been invoked via getConnectionResource(),
647
-			// but we need results specifically for e.g. user login
648
-			return $this->bindResult['result'];
649
-		}
650
-
651
-		$ldapLogin = @$this->ldap->bind($cr,
652
-										$this->configuration->ldapAgentName,
653
-										$this->configuration->ldapAgentPassword);
654
-
655
-		$this->bindResult = [
656
-			'dn' => $this->configuration->ldapAgentName,
657
-			'hash' => \OC::$server->getHasher()->hash($this->configPrefix . $this->configuration->ldapAgentPassword),
658
-			'result' => $ldapLogin,
659
-		];
660
-
661
-		if(!$ldapLogin) {
662
-			$errno = $this->ldap->errno($cr);
663
-
664
-			\OCP\Util::writeLog('user_ldap',
665
-				'Bind failed: ' . $errno . ': ' . $this->ldap->error($cr),
666
-				\OCP\Util::WARN);
667
-
668
-			// Set to failure mode, if LDAP error code is not LDAP_SUCCESS or LDAP_INVALID_CREDENTIALS
669
-			if($errno !== 0x00 && $errno !== 0x31) {
670
-				$this->ldapConnectionRes = null;
671
-			}
672
-
673
-			return false;
674
-		}
675
-		return true;
676
-	}
65
+    private $ldapConnectionRes = null;
66
+    private $configPrefix;
67
+    private $configID;
68
+    private $configured = false;
69
+    private $hasPagedResultSupport = true;
70
+    //whether connection should be kept on __destruct
71
+    private $dontDestruct = false;
72
+
73
+    /**
74
+     * @var bool runtime flag that indicates whether supported primary groups are available
75
+     */
76
+    public $hasPrimaryGroups = true;
77
+
78
+    /**
79
+     * @var bool runtime flag that indicates whether supported POSIX gidNumber are available
80
+     */
81
+    public $hasGidNumber = true;
82
+
83
+    //cache handler
84
+    protected $cache;
85
+
86
+    /** @var Configuration settings handler **/
87
+    protected $configuration;
88
+
89
+    protected $doNotValidate = false;
90
+
91
+    protected $ignoreValidation = false;
92
+
93
+    protected $bindResult = [];
94
+
95
+    /**
96
+     * Constructor
97
+     * @param ILDAPWrapper $ldap
98
+     * @param string $configPrefix a string with the prefix for the configkey column (appconfig table)
99
+     * @param string|null $configID a string with the value for the appid column (appconfig table) or null for on-the-fly connections
100
+     */
101
+    public function __construct(ILDAPWrapper $ldap, $configPrefix = '', $configID = 'user_ldap') {
102
+        parent::__construct($ldap);
103
+        $this->configPrefix = $configPrefix;
104
+        $this->configID = $configID;
105
+        $this->configuration = new Configuration($configPrefix,
106
+                                                    !is_null($configID));
107
+        $memcache = \OC::$server->getMemCacheFactory();
108
+        if($memcache->isAvailable()) {
109
+            $this->cache = $memcache->createDistributed();
110
+        }
111
+        $helper = new Helper(\OC::$server->getConfig());
112
+        $this->doNotValidate = !in_array($this->configPrefix,
113
+            $helper->getServerConfigurationPrefixes());
114
+        $this->hasPagedResultSupport =
115
+            intval($this->configuration->ldapPagingSize) !== 0
116
+            || $this->ldap->hasPagedResultSupport();
117
+    }
118
+
119
+    public function __destruct() {
120
+        if(!$this->dontDestruct && $this->ldap->isResource($this->ldapConnectionRes)) {
121
+            @$this->ldap->unbind($this->ldapConnectionRes);
122
+        }
123
+        $this->bindResult = [];
124
+    }
125
+
126
+    /**
127
+     * defines behaviour when the instance is cloned
128
+     */
129
+    public function __clone() {
130
+        $this->configuration = new Configuration($this->configPrefix,
131
+                                                    !is_null($this->configID));
132
+        if(count($this->bindResult) !== 0 && $this->bindResult['result'] === true) {
133
+            $this->bindResult = [];
134
+        }
135
+        $this->ldapConnectionRes = null;
136
+        $this->dontDestruct = true;
137
+    }
138
+
139
+    /**
140
+     * @param string $name
141
+     * @return bool|mixed
142
+     */
143
+    public function __get($name) {
144
+        if(!$this->configured) {
145
+            $this->readConfiguration();
146
+        }
147
+
148
+        if($name === 'hasPagedResultSupport') {
149
+            return $this->hasPagedResultSupport;
150
+        }
151
+
152
+        return $this->configuration->$name;
153
+    }
154
+
155
+    /**
156
+     * @param string $name
157
+     * @param mixed $value
158
+     */
159
+    public function __set($name, $value) {
160
+        $this->doNotValidate = false;
161
+        $before = $this->configuration->$name;
162
+        $this->configuration->$name = $value;
163
+        $after = $this->configuration->$name;
164
+        if($before !== $after) {
165
+            if ($this->configID !== '' && $this->configID !== null) {
166
+                $this->configuration->saveConfiguration();
167
+            }
168
+            $this->validateConfiguration();
169
+        }
170
+    }
171
+
172
+    /**
173
+     * @param string $rule
174
+     * @return array
175
+     * @throws \RuntimeException
176
+     */
177
+    public function resolveRule($rule) {
178
+        return $this->configuration->resolveRule($rule);
179
+    }
180
+
181
+    /**
182
+     * sets whether the result of the configuration validation shall
183
+     * be ignored when establishing the connection. Used by the Wizard
184
+     * in early configuration state.
185
+     * @param bool $state
186
+     */
187
+    public function setIgnoreValidation($state) {
188
+        $this->ignoreValidation = (bool)$state;
189
+    }
190
+
191
+    /**
192
+     * initializes the LDAP backend
193
+     * @param bool $force read the config settings no matter what
194
+     */
195
+    public function init($force = false) {
196
+        $this->readConfiguration($force);
197
+        $this->establishConnection();
198
+    }
199
+
200
+    /**
201
+     * Returns the LDAP handler
202
+     */
203
+    public function getConnectionResource() {
204
+        if(!$this->ldapConnectionRes) {
205
+            $this->init();
206
+        } else if(!$this->ldap->isResource($this->ldapConnectionRes)) {
207
+            $this->ldapConnectionRes = null;
208
+            $this->establishConnection();
209
+        }
210
+        if(is_null($this->ldapConnectionRes)) {
211
+            \OCP\Util::writeLog('user_ldap', 'No LDAP Connection to server ' . $this->configuration->ldapHost, \OCP\Util::ERROR);
212
+            throw new ServerNotAvailableException('Connection to LDAP server could not be established');
213
+        }
214
+        return $this->ldapConnectionRes;
215
+    }
216
+
217
+    /**
218
+     * resets the connection resource
219
+     */
220
+    public function resetConnectionResource() {
221
+        if(!is_null($this->ldapConnectionRes)) {
222
+            @$this->ldap->unbind($this->ldapConnectionRes);
223
+            $this->ldapConnectionRes = null;
224
+            $this->bindResult = [];
225
+        }
226
+    }
227
+
228
+    /**
229
+     * @param string|null $key
230
+     * @return string
231
+     */
232
+    private function getCacheKey($key) {
233
+        $prefix = 'LDAP-'.$this->configID.'-'.$this->configPrefix.'-';
234
+        if(is_null($key)) {
235
+            return $prefix;
236
+        }
237
+        return $prefix.hash('sha256', $key);
238
+    }
239
+
240
+    /**
241
+     * @param string $key
242
+     * @return mixed|null
243
+     */
244
+    public function getFromCache($key) {
245
+        if(!$this->configured) {
246
+            $this->readConfiguration();
247
+        }
248
+        if(is_null($this->cache) || !$this->configuration->ldapCacheTTL) {
249
+            return null;
250
+        }
251
+        $key = $this->getCacheKey($key);
252
+
253
+        return json_decode(base64_decode($this->cache->get($key)), true);
254
+    }
255
+
256
+    /**
257
+     * @param string $key
258
+     * @param mixed $value
259
+     *
260
+     * @return string
261
+     */
262
+    public function writeToCache($key, $value) {
263
+        if(!$this->configured) {
264
+            $this->readConfiguration();
265
+        }
266
+        if(is_null($this->cache)
267
+            || !$this->configuration->ldapCacheTTL
268
+            || !$this->configuration->ldapConfigurationActive) {
269
+            return null;
270
+        }
271
+        $key   = $this->getCacheKey($key);
272
+        $value = base64_encode(json_encode($value));
273
+        $this->cache->set($key, $value, $this->configuration->ldapCacheTTL);
274
+    }
275
+
276
+    public function clearCache() {
277
+        if(!is_null($this->cache)) {
278
+            $this->cache->clear($this->getCacheKey(null));
279
+        }
280
+    }
281
+
282
+    /**
283
+     * Caches the general LDAP configuration.
284
+     * @param bool $force optional. true, if the re-read should be forced. defaults
285
+     * to false.
286
+     * @return null
287
+     */
288
+    private function readConfiguration($force = false) {
289
+        if((!$this->configured || $force) && !is_null($this->configID)) {
290
+            $this->configuration->readConfiguration();
291
+            $this->configured = $this->validateConfiguration();
292
+        }
293
+    }
294
+
295
+    /**
296
+     * set LDAP configuration with values delivered by an array, not read from configuration
297
+     * @param array $config array that holds the config parameters in an associated array
298
+     * @param array &$setParameters optional; array where the set fields will be given to
299
+     * @return boolean true if config validates, false otherwise. Check with $setParameters for detailed success on single parameters
300
+     */
301
+    public function setConfiguration($config, &$setParameters = null) {
302
+        if(is_null($setParameters)) {
303
+            $setParameters = array();
304
+        }
305
+        $this->doNotValidate = false;
306
+        $this->configuration->setConfiguration($config, $setParameters);
307
+        if(count($setParameters) > 0) {
308
+            $this->configured = $this->validateConfiguration();
309
+        }
310
+
311
+
312
+        return $this->configured;
313
+    }
314
+
315
+    /**
316
+     * saves the current Configuration in the database and empties the
317
+     * cache
318
+     * @return null
319
+     */
320
+    public function saveConfiguration() {
321
+        $this->configuration->saveConfiguration();
322
+        $this->clearCache();
323
+    }
324
+
325
+    /**
326
+     * get the current LDAP configuration
327
+     * @return array
328
+     */
329
+    public function getConfiguration() {
330
+        $this->readConfiguration();
331
+        $config = $this->configuration->getConfiguration();
332
+        $cta = $this->configuration->getConfigTranslationArray();
333
+        $result = array();
334
+        foreach($cta as $dbkey => $configkey) {
335
+            switch($configkey) {
336
+                case 'homeFolderNamingRule':
337
+                    if(strpos($config[$configkey], 'attr:') === 0) {
338
+                        $result[$dbkey] = substr($config[$configkey], 5);
339
+                    } else {
340
+                        $result[$dbkey] = '';
341
+                    }
342
+                    break;
343
+                case 'ldapBase':
344
+                case 'ldapBaseUsers':
345
+                case 'ldapBaseGroups':
346
+                case 'ldapAttributesForUserSearch':
347
+                case 'ldapAttributesForGroupSearch':
348
+                    if(is_array($config[$configkey])) {
349
+                        $result[$dbkey] = implode("\n", $config[$configkey]);
350
+                        break;
351
+                    } //else follows default
352
+                default:
353
+                    $result[$dbkey] = $config[$configkey];
354
+            }
355
+        }
356
+        return $result;
357
+    }
358
+
359
+    private function doSoftValidation() {
360
+        //if User or Group Base are not set, take over Base DN setting
361
+        foreach(array('ldapBaseUsers', 'ldapBaseGroups') as $keyBase) {
362
+            $val = $this->configuration->$keyBase;
363
+            if(empty($val)) {
364
+                $this->configuration->$keyBase = $this->configuration->ldapBase;
365
+            }
366
+        }
367
+
368
+        foreach(array('ldapExpertUUIDUserAttr'  => 'ldapUuidUserAttribute',
369
+                        'ldapExpertUUIDGroupAttr' => 'ldapUuidGroupAttribute')
370
+                as $expertSetting => $effectiveSetting) {
371
+            $uuidOverride = $this->configuration->$expertSetting;
372
+            if(!empty($uuidOverride)) {
373
+                $this->configuration->$effectiveSetting = $uuidOverride;
374
+            } else {
375
+                $uuidAttributes = Access::UUID_ATTRIBUTES;
376
+                array_unshift($uuidAttributes, 'auto');
377
+                if(!in_array($this->configuration->$effectiveSetting,
378
+                            $uuidAttributes)
379
+                    && (!is_null($this->configID))) {
380
+                    $this->configuration->$effectiveSetting = 'auto';
381
+                    $this->configuration->saveConfiguration();
382
+                    \OCP\Util::writeLog('user_ldap',
383
+                                        'Illegal value for the '.
384
+                                        $effectiveSetting.', '.'reset to '.
385
+                                        'autodetect.', \OCP\Util::INFO);
386
+                }
387
+
388
+            }
389
+        }
390
+
391
+        $backupPort = intval($this->configuration->ldapBackupPort);
392
+        if ($backupPort <= 0) {
393
+            $this->configuration->backupPort = $this->configuration->ldapPort;
394
+        }
395
+
396
+        //make sure empty search attributes are saved as simple, empty array
397
+        $saKeys = array('ldapAttributesForUserSearch',
398
+                        'ldapAttributesForGroupSearch');
399
+        foreach($saKeys as $key) {
400
+            $val = $this->configuration->$key;
401
+            if(is_array($val) && count($val) === 1 && empty($val[0])) {
402
+                $this->configuration->$key = array();
403
+            }
404
+        }
405
+
406
+        if((stripos($this->configuration->ldapHost, 'ldaps://') === 0)
407
+            && $this->configuration->ldapTLS) {
408
+            $this->configuration->ldapTLS = false;
409
+            \OCP\Util::writeLog('user_ldap',
410
+                                'LDAPS (already using secure connection) and '.
411
+                                'TLS do not work together. Switched off TLS.',
412
+                                \OCP\Util::INFO);
413
+        }
414
+    }
415
+
416
+    /**
417
+     * @return bool
418
+     */
419
+    private function doCriticalValidation() {
420
+        $configurationOK = true;
421
+        $errorStr = 'Configuration Error (prefix '.
422
+                    strval($this->configPrefix).'): ';
423
+
424
+        //options that shall not be empty
425
+        $options = array('ldapHost', 'ldapPort', 'ldapUserDisplayName',
426
+                            'ldapGroupDisplayName', 'ldapLoginFilter');
427
+        foreach($options as $key) {
428
+            $val = $this->configuration->$key;
429
+            if(empty($val)) {
430
+                switch($key) {
431
+                    case 'ldapHost':
432
+                        $subj = 'LDAP Host';
433
+                        break;
434
+                    case 'ldapPort':
435
+                        $subj = 'LDAP Port';
436
+                        break;
437
+                    case 'ldapUserDisplayName':
438
+                        $subj = 'LDAP User Display Name';
439
+                        break;
440
+                    case 'ldapGroupDisplayName':
441
+                        $subj = 'LDAP Group Display Name';
442
+                        break;
443
+                    case 'ldapLoginFilter':
444
+                        $subj = 'LDAP Login Filter';
445
+                        break;
446
+                    default:
447
+                        $subj = $key;
448
+                        break;
449
+                }
450
+                $configurationOK = false;
451
+                \OCP\Util::writeLog('user_ldap',
452
+                                    $errorStr.'No '.$subj.' given!',
453
+                                    \OCP\Util::WARN);
454
+            }
455
+        }
456
+
457
+        //combinations
458
+        $agent = $this->configuration->ldapAgentName;
459
+        $pwd = $this->configuration->ldapAgentPassword;
460
+        if (
461
+            ($agent === ''  && $pwd !== '')
462
+            || ($agent !== '' && $pwd === '')
463
+        ) {
464
+            \OCP\Util::writeLog('user_ldap',
465
+                                $errorStr.'either no password is given for the '.
466
+                                'user agent or a password is given, but not an '.
467
+                                'LDAP agent.',
468
+                \OCP\Util::WARN);
469
+            $configurationOK = false;
470
+        }
471
+
472
+        $base = $this->configuration->ldapBase;
473
+        $baseUsers = $this->configuration->ldapBaseUsers;
474
+        $baseGroups = $this->configuration->ldapBaseGroups;
475
+
476
+        if(empty($base) && empty($baseUsers) && empty($baseGroups)) {
477
+            \OCP\Util::writeLog('user_ldap',
478
+                                $errorStr.'Not a single Base DN given.',
479
+                                \OCP\Util::WARN);
480
+            $configurationOK = false;
481
+        }
482
+
483
+        if(mb_strpos($this->configuration->ldapLoginFilter, '%uid', 0, 'UTF-8')
484
+            === false) {
485
+            \OCP\Util::writeLog('user_ldap',
486
+                                $errorStr.'login filter does not contain %uid '.
487
+                                'place holder.',
488
+                                \OCP\Util::WARN);
489
+            $configurationOK = false;
490
+        }
491
+
492
+        return $configurationOK;
493
+    }
494
+
495
+    /**
496
+     * Validates the user specified configuration
497
+     * @return bool true if configuration seems OK, false otherwise
498
+     */
499
+    private function validateConfiguration() {
500
+
501
+        if($this->doNotValidate) {
502
+            //don't do a validation if it is a new configuration with pure
503
+            //default values. Will be allowed on changes via __set or
504
+            //setConfiguration
505
+            return false;
506
+        }
507
+
508
+        // first step: "soft" checks: settings that are not really
509
+        // necessary, but advisable. If left empty, give an info message
510
+        $this->doSoftValidation();
511
+
512
+        //second step: critical checks. If left empty or filled wrong, mark as
513
+        //not configured and give a warning.
514
+        return $this->doCriticalValidation();
515
+    }
516
+
517
+
518
+    /**
519
+     * Connects and Binds to LDAP
520
+     *
521
+     * @throws ServerNotAvailableException
522
+     */
523
+    private function establishConnection() {
524
+        if(!$this->configuration->ldapConfigurationActive) {
525
+            return null;
526
+        }
527
+        static $phpLDAPinstalled = true;
528
+        if(!$phpLDAPinstalled) {
529
+            return false;
530
+        }
531
+        if(!$this->ignoreValidation && !$this->configured) {
532
+            \OCP\Util::writeLog('user_ldap',
533
+                                'Configuration is invalid, cannot connect',
534
+                                \OCP\Util::WARN);
535
+            return false;
536
+        }
537
+        if(!$this->ldapConnectionRes) {
538
+            if(!$this->ldap->areLDAPFunctionsAvailable()) {
539
+                $phpLDAPinstalled = false;
540
+                \OCP\Util::writeLog('user_ldap',
541
+                                    'function ldap_connect is not available. Make '.
542
+                                    'sure that the PHP ldap module is installed.',
543
+                                    \OCP\Util::ERROR);
544
+
545
+                return false;
546
+            }
547
+            if($this->configuration->turnOffCertCheck) {
548
+                if(putenv('LDAPTLS_REQCERT=never')) {
549
+                    \OCP\Util::writeLog('user_ldap',
550
+                        'Turned off SSL certificate validation successfully.',
551
+                        \OCP\Util::DEBUG);
552
+                } else {
553
+                    \OCP\Util::writeLog('user_ldap',
554
+                                        'Could not turn off SSL certificate validation.',
555
+                                        \OCP\Util::WARN);
556
+                }
557
+            }
558
+
559
+            $isOverrideMainServer = ($this->configuration->ldapOverrideMainServer
560
+                || $this->getFromCache('overrideMainServer'));
561
+            $isBackupHost = (trim($this->configuration->ldapBackupHost) !== "");
562
+            $bindStatus = false;
563
+            try {
564
+                if (!$isOverrideMainServer) {
565
+                    $this->doConnect($this->configuration->ldapHost,
566
+                        $this->configuration->ldapPort);
567
+                }
568
+                return $this->bind();
569
+            } catch (ServerNotAvailableException $e) {
570
+                if(!$isBackupHost) {
571
+                    throw $e;
572
+                }
573
+            }
574
+
575
+            //if LDAP server is not reachable, try the Backup (Replica!) Server
576
+            if($isBackupHost || $isOverrideMainServer) {
577
+                $this->doConnect($this->configuration->ldapBackupHost,
578
+                                    $this->configuration->ldapBackupPort);
579
+                $this->bindResult = [];
580
+                $bindStatus = $this->bind();
581
+                $error = $this->ldap->isResource($this->ldapConnectionRes) ?
582
+                    $this->ldap->errno($this->ldapConnectionRes) : -1;
583
+                if($bindStatus && $error === 0 && !$this->getFromCache('overrideMainServer')) {
584
+                    //when bind to backup server succeeded and failed to main server,
585
+                    //skip contacting him until next cache refresh
586
+                    $this->writeToCache('overrideMainServer', true);
587
+                }
588
+            }
589
+
590
+            return $bindStatus;
591
+        }
592
+        return null;
593
+    }
594
+
595
+    /**
596
+     * @param string $host
597
+     * @param string $port
598
+     * @return bool
599
+     * @throws \OC\ServerNotAvailableException
600
+     */
601
+    private function doConnect($host, $port) {
602
+        if ($host === '') {
603
+            return false;
604
+        }
605
+
606
+        $this->ldapConnectionRes = $this->ldap->connect($host, $port);
607
+
608
+        if(!$this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) {
609
+            throw new ServerNotAvailableException('Could not set required LDAP Protocol version.');
610
+        }
611
+
612
+        if(!$this->ldap->setOption($this->ldapConnectionRes, LDAP_OPT_REFERRALS, 0)) {
613
+            throw new ServerNotAvailableException('Could not disable LDAP referrals.');
614
+        }
615
+
616
+        if($this->configuration->ldapTLS) {
617
+            if(!$this->ldap->startTls($this->ldapConnectionRes)) {
618
+                throw new ServerNotAvailableException('Start TLS failed, when connecting to LDAP host ' . $host . '.');
619
+            }
620
+        }
621
+
622
+        return true;
623
+    }
624
+
625
+    /**
626
+     * Binds to LDAP
627
+     */
628
+    public function bind() {
629
+        if(!$this->configuration->ldapConfigurationActive) {
630
+            return false;
631
+        }
632
+        $cr = $this->ldapConnectionRes;
633
+        if(!$this->ldap->isResource($cr)) {
634
+            $cr = $this->getConnectionResource();
635
+        }
636
+
637
+        if(
638
+            count($this->bindResult) !== 0
639
+            && $this->bindResult['dn'] === $this->configuration->ldapAgentName
640
+            && \OC::$server->getHasher()->verify(
641
+                $this->configPrefix . $this->configuration->ldapAgentPassword,
642
+                $this->bindResult['hash']
643
+            )
644
+        ) {
645
+            // don't attempt to bind again with the same data as before
646
+            // bind might have been invoked via getConnectionResource(),
647
+            // but we need results specifically for e.g. user login
648
+            return $this->bindResult['result'];
649
+        }
650
+
651
+        $ldapLogin = @$this->ldap->bind($cr,
652
+                                        $this->configuration->ldapAgentName,
653
+                                        $this->configuration->ldapAgentPassword);
654
+
655
+        $this->bindResult = [
656
+            'dn' => $this->configuration->ldapAgentName,
657
+            'hash' => \OC::$server->getHasher()->hash($this->configPrefix . $this->configuration->ldapAgentPassword),
658
+            'result' => $ldapLogin,
659
+        ];
660
+
661
+        if(!$ldapLogin) {
662
+            $errno = $this->ldap->errno($cr);
663
+
664
+            \OCP\Util::writeLog('user_ldap',
665
+                'Bind failed: ' . $errno . ': ' . $this->ldap->error($cr),
666
+                \OCP\Util::WARN);
667
+
668
+            // Set to failure mode, if LDAP error code is not LDAP_SUCCESS or LDAP_INVALID_CREDENTIALS
669
+            if($errno !== 0x00 && $errno !== 0x31) {
670
+                $this->ldapConnectionRes = null;
671
+            }
672
+
673
+            return false;
674
+        }
675
+        return true;
676
+    }
677 677
 
678 678
 }
Please login to merge, or discard this patch.