Completed
Push — master ( 4051a2...42912a )
by Blizzz
22:43
created
apps/user_ldap/lib/User_LDAP.php 2 patches
Indentation   +570 added lines, -570 removed lines patch added patch discarded remove patch
@@ -52,578 +52,578 @@
 block discarded – undo
52 52
 use OCP\Util;
53 53
 
54 54
 class User_LDAP extends BackendUtility implements \OCP\IUserBackend, \OCP\UserInterface, IUserLDAP {
55
-	/** @var \OCP\IConfig */
56
-	protected $ocConfig;
57
-
58
-	/** @var INotificationManager */
59
-	protected $notificationManager;
60
-
61
-	/** @var string */
62
-	protected $currentUserInDeletionProcess;
63
-
64
-	/** @var UserPluginManager */
65
-	protected $userPluginManager;
66
-
67
-	/**
68
-	 * @param Access $access
69
-	 * @param \OCP\IConfig $ocConfig
70
-	 * @param \OCP\Notification\IManager $notificationManager
71
-	 * @param IUserSession $userSession
72
-	 */
73
-	public function __construct(Access $access, IConfig $ocConfig, INotificationManager $notificationManager, IUserSession $userSession, UserPluginManager $userPluginManager) {
74
-		parent::__construct($access);
75
-		$this->ocConfig = $ocConfig;
76
-		$this->notificationManager = $notificationManager;
77
-		$this->userPluginManager = $userPluginManager;
78
-		$this->registerHooks($userSession);
79
-	}
80
-
81
-	protected function registerHooks(IUserSession $userSession) {
82
-		$userSession->listen('\OC\User', 'preDelete', [$this, 'preDeleteUser']);
83
-		$userSession->listen('\OC\User', 'postDelete', [$this, 'postDeleteUser']);
84
-	}
85
-
86
-	public function preDeleteUser(IUser $user) {
87
-		$this->currentUserInDeletionProcess = $user->getUID();
88
-	}
89
-
90
-	public function postDeleteUser() {
91
-		$this->currentUserInDeletionProcess = null;
92
-	}
93
-
94
-	/**
95
-	 * checks whether the user is allowed to change his avatar in Nextcloud
96
-	 *
97
-	 * @param string $uid the Nextcloud user name
98
-	 * @return boolean either the user can or cannot
99
-	 * @throws \Exception
100
-	 */
101
-	public function canChangeAvatar($uid) {
102
-		if ($this->userPluginManager->implementsActions(Backend::PROVIDE_AVATAR)) {
103
-			return $this->userPluginManager->canChangeAvatar($uid);
104
-		}
105
-
106
-		$user = $this->access->userManager->get($uid);
107
-		if(!$user instanceof User) {
108
-			return false;
109
-		}
110
-		$imageData = $user->getAvatarImage();
111
-		if($imageData === false) {
112
-			return true;
113
-		}
114
-		return !$user->updateAvatar(true);
115
-	}
116
-
117
-	/**
118
-	 * returns the username for the given login name, if available
119
-	 *
120
-	 * @param string $loginName
121
-	 * @return string|false
122
-	 */
123
-	public function loginName2UserName($loginName) {
124
-		$cacheKey = 'loginName2UserName-'.$loginName;
125
-		$username = $this->access->connection->getFromCache($cacheKey);
126
-		if(!is_null($username)) {
127
-			return $username;
128
-		}
129
-
130
-		try {
131
-			$ldapRecord = $this->getLDAPUserByLoginName($loginName);
132
-			$user = $this->access->userManager->get($ldapRecord['dn'][0]);
133
-			if($user instanceof OfflineUser) {
134
-				// this path is not really possible, however get() is documented
135
-				// to return User or OfflineUser so we are very defensive here.
136
-				$this->access->connection->writeToCache($cacheKey, false);
137
-				return false;
138
-			}
139
-			$username = $user->getUsername();
140
-			$this->access->connection->writeToCache($cacheKey, $username);
141
-			return $username;
142
-		} catch (NotOnLDAP $e) {
143
-			$this->access->connection->writeToCache($cacheKey, false);
144
-			return false;
145
-		}
146
-	}
55
+    /** @var \OCP\IConfig */
56
+    protected $ocConfig;
57
+
58
+    /** @var INotificationManager */
59
+    protected $notificationManager;
60
+
61
+    /** @var string */
62
+    protected $currentUserInDeletionProcess;
63
+
64
+    /** @var UserPluginManager */
65
+    protected $userPluginManager;
66
+
67
+    /**
68
+     * @param Access $access
69
+     * @param \OCP\IConfig $ocConfig
70
+     * @param \OCP\Notification\IManager $notificationManager
71
+     * @param IUserSession $userSession
72
+     */
73
+    public function __construct(Access $access, IConfig $ocConfig, INotificationManager $notificationManager, IUserSession $userSession, UserPluginManager $userPluginManager) {
74
+        parent::__construct($access);
75
+        $this->ocConfig = $ocConfig;
76
+        $this->notificationManager = $notificationManager;
77
+        $this->userPluginManager = $userPluginManager;
78
+        $this->registerHooks($userSession);
79
+    }
80
+
81
+    protected function registerHooks(IUserSession $userSession) {
82
+        $userSession->listen('\OC\User', 'preDelete', [$this, 'preDeleteUser']);
83
+        $userSession->listen('\OC\User', 'postDelete', [$this, 'postDeleteUser']);
84
+    }
85
+
86
+    public function preDeleteUser(IUser $user) {
87
+        $this->currentUserInDeletionProcess = $user->getUID();
88
+    }
89
+
90
+    public function postDeleteUser() {
91
+        $this->currentUserInDeletionProcess = null;
92
+    }
93
+
94
+    /**
95
+     * checks whether the user is allowed to change his avatar in Nextcloud
96
+     *
97
+     * @param string $uid the Nextcloud user name
98
+     * @return boolean either the user can or cannot
99
+     * @throws \Exception
100
+     */
101
+    public function canChangeAvatar($uid) {
102
+        if ($this->userPluginManager->implementsActions(Backend::PROVIDE_AVATAR)) {
103
+            return $this->userPluginManager->canChangeAvatar($uid);
104
+        }
105
+
106
+        $user = $this->access->userManager->get($uid);
107
+        if(!$user instanceof User) {
108
+            return false;
109
+        }
110
+        $imageData = $user->getAvatarImage();
111
+        if($imageData === false) {
112
+            return true;
113
+        }
114
+        return !$user->updateAvatar(true);
115
+    }
116
+
117
+    /**
118
+     * returns the username for the given login name, if available
119
+     *
120
+     * @param string $loginName
121
+     * @return string|false
122
+     */
123
+    public function loginName2UserName($loginName) {
124
+        $cacheKey = 'loginName2UserName-'.$loginName;
125
+        $username = $this->access->connection->getFromCache($cacheKey);
126
+        if(!is_null($username)) {
127
+            return $username;
128
+        }
129
+
130
+        try {
131
+            $ldapRecord = $this->getLDAPUserByLoginName($loginName);
132
+            $user = $this->access->userManager->get($ldapRecord['dn'][0]);
133
+            if($user instanceof OfflineUser) {
134
+                // this path is not really possible, however get() is documented
135
+                // to return User or OfflineUser so we are very defensive here.
136
+                $this->access->connection->writeToCache($cacheKey, false);
137
+                return false;
138
+            }
139
+            $username = $user->getUsername();
140
+            $this->access->connection->writeToCache($cacheKey, $username);
141
+            return $username;
142
+        } catch (NotOnLDAP $e) {
143
+            $this->access->connection->writeToCache($cacheKey, false);
144
+            return false;
145
+        }
146
+    }
147 147
 	
148
-	/**
149
-	 * returns the username for the given LDAP DN, if available
150
-	 *
151
-	 * @param string $dn
152
-	 * @return string|false with the username
153
-	 */
154
-	public function dn2UserName($dn) {
155
-		return $this->access->dn2username($dn);
156
-	}
157
-
158
-	/**
159
-	 * returns an LDAP record based on a given login name
160
-	 *
161
-	 * @param string $loginName
162
-	 * @return array
163
-	 * @throws NotOnLDAP
164
-	 */
165
-	public function getLDAPUserByLoginName($loginName) {
166
-		//find out dn of the user name
167
-		$attrs = $this->access->userManager->getAttributes();
168
-		$users = $this->access->fetchUsersByLoginName($loginName, $attrs);
169
-		if(count($users) < 1) {
170
-			throw new NotOnLDAP('No user available for the given login name on ' .
171
-				$this->access->connection->ldapHost . ':' . $this->access->connection->ldapPort);
172
-		}
173
-		return $users[0];
174
-	}
175
-
176
-	/**
177
-	 * Check if the password is correct without logging in the user
178
-	 *
179
-	 * @param string $uid The username
180
-	 * @param string $password The password
181
-	 * @return false|string
182
-	 */
183
-	public function checkPassword($uid, $password) {
184
-		try {
185
-			$ldapRecord = $this->getLDAPUserByLoginName($uid);
186
-		} catch(NotOnLDAP $e) {
187
-			if($this->ocConfig->getSystemValue('loglevel', ILogger::WARN) === ILogger::DEBUG) {
188
-				\OC::$server->getLogger()->logException($e, ['app' => 'user_ldap']);
189
-			}
190
-			return false;
191
-		}
192
-		$dn = $ldapRecord['dn'][0];
193
-		$user = $this->access->userManager->get($dn);
194
-
195
-		if(!$user instanceof User) {
196
-			Util::writeLog('user_ldap',
197
-				'LDAP Login: Could not get user object for DN ' . $dn .
198
-				'. Maybe the LDAP entry has no set display name attribute?',
199
-				ILogger::WARN);
200
-			return false;
201
-		}
202
-		if($user->getUsername() !== false) {
203
-			//are the credentials OK?
204
-			if(!$this->access->areCredentialsValid($dn, $password)) {
205
-				return false;
206
-			}
207
-
208
-			$this->access->cacheUserExists($user->getUsername());
209
-			$user->processAttributes($ldapRecord);
210
-			$user->markLogin();
211
-
212
-			return $user->getUsername();
213
-		}
214
-
215
-		return false;
216
-	}
217
-
218
-	/**
219
-	 * Set password
220
-	 * @param string $uid The username
221
-	 * @param string $password The new password
222
-	 * @return bool
223
-	 */
224
-	public function setPassword($uid, $password) {
225
-		if ($this->userPluginManager->implementsActions(Backend::SET_PASSWORD)) {
226
-			return $this->userPluginManager->setPassword($uid, $password);
227
-		}
228
-
229
-		$user = $this->access->userManager->get($uid);
230
-
231
-		if(!$user instanceof User) {
232
-			throw new \Exception('LDAP setPassword: Could not get user object for uid ' . $uid .
233
-				'. Maybe the LDAP entry has no set display name attribute?');
234
-		}
235
-		if($user->getUsername() !== false && $this->access->setPassword($user->getDN(), $password)) {
236
-			$ldapDefaultPPolicyDN = $this->access->connection->ldapDefaultPPolicyDN;
237
-			$turnOnPasswordChange = $this->access->connection->turnOnPasswordChange;
238
-			if (!empty($ldapDefaultPPolicyDN) && ((int)$turnOnPasswordChange === 1)) {
239
-				//remove last password expiry warning if any
240
-				$notification = $this->notificationManager->createNotification();
241
-				$notification->setApp('user_ldap')
242
-					->setUser($uid)
243
-					->setObject('pwd_exp_warn', $uid)
244
-				;
245
-				$this->notificationManager->markProcessed($notification);
246
-			}
247
-			return true;
248
-		}
249
-
250
-		return false;
251
-	}
252
-
253
-	/**
254
-	 * Get a list of all users
255
-	 *
256
-	 * @param string $search
257
-	 * @param integer $limit
258
-	 * @param integer $offset
259
-	 * @return string[] an array of all uids
260
-	 */
261
-	public function getUsers($search = '', $limit = 10, $offset = 0) {
262
-		$search = $this->access->escapeFilterPart($search, true);
263
-		$cachekey = 'getUsers-'.$search.'-'.$limit.'-'.$offset;
264
-
265
-		//check if users are cached, if so return
266
-		$ldap_users = $this->access->connection->getFromCache($cachekey);
267
-		if(!is_null($ldap_users)) {
268
-			return $ldap_users;
269
-		}
270
-
271
-		// if we'd pass -1 to LDAP search, we'd end up in a Protocol
272
-		// error. With a limit of 0, we get 0 results. So we pass null.
273
-		if($limit <= 0) {
274
-			$limit = null;
275
-		}
276
-		$filter = $this->access->combineFilterWithAnd(array(
277
-			$this->access->connection->ldapUserFilter,
278
-			$this->access->connection->ldapUserDisplayName . '=*',
279
-			$this->access->getFilterPartForUserSearch($search)
280
-		));
281
-
282
-		Util::writeLog('user_ldap',
283
-			'getUsers: Options: search '.$search.' limit '.$limit.' offset '.$offset.' Filter: '.$filter,
284
-			ILogger::DEBUG);
285
-		//do the search and translate results to Nextcloud names
286
-		$ldap_users = $this->access->fetchListOfUsers(
287
-			$filter,
288
-			$this->access->userManager->getAttributes(true),
289
-			$limit, $offset);
290
-		$ldap_users = $this->access->nextcloudUserNames($ldap_users);
291
-		Util::writeLog('user_ldap', 'getUsers: '.count($ldap_users). ' Users found', ILogger::DEBUG);
292
-
293
-		$this->access->connection->writeToCache($cachekey, $ldap_users);
294
-		return $ldap_users;
295
-	}
296
-
297
-	/**
298
-	 * checks whether a user is still available on LDAP
299
-	 *
300
-	 * @param string|\OCA\User_LDAP\User\User $user either the Nextcloud user
301
-	 * name or an instance of that user
302
-	 * @return bool
303
-	 * @throws \Exception
304
-	 * @throws \OC\ServerNotAvailableException
305
-	 */
306
-	public function userExistsOnLDAP($user) {
307
-		if(is_string($user)) {
308
-			$user = $this->access->userManager->get($user);
309
-		}
310
-		if(is_null($user)) {
311
-			return false;
312
-		}
313
-
314
-		$dn = $user->getDN();
315
-		//check if user really still exists by reading its entry
316
-		if(!is_array($this->access->readAttribute($dn, '', $this->access->connection->ldapUserFilter))) {
317
-			$lcr = $this->access->connection->getConnectionResource();
318
-			if(is_null($lcr)) {
319
-				throw new \Exception('No LDAP Connection to server ' . $this->access->connection->ldapHost);
320
-			}
321
-
322
-			try {
323
-				$uuid = $this->access->getUserMapper()->getUUIDByDN($dn);
324
-				if (!$uuid) {
325
-					return false;
326
-				}
327
-				$newDn = $this->access->getUserDnByUuid($uuid);
328
-				//check if renamed user is still valid by reapplying the ldap filter
329
-				if (!is_array($this->access->readAttribute($newDn, '', $this->access->connection->ldapUserFilter))) {
330
-					return false;
331
-				}
332
-				$this->access->getUserMapper()->setDNbyUUID($newDn, $uuid);
333
-				return true;
334
-			} catch (ServerNotAvailableException $e) {
335
-				throw $e;
336
-			} catch (\Exception $e) {
337
-				return false;
338
-			}
339
-		}
340
-
341
-		if($user instanceof OfflineUser) {
342
-			$user->unmark();
343
-		}
344
-
345
-		return true;
346
-	}
347
-
348
-	/**
349
-	 * check if a user exists
350
-	 * @param string $uid the username
351
-	 * @return boolean
352
-	 * @throws \Exception when connection could not be established
353
-	 */
354
-	public function userExists($uid) {
355
-		$userExists = $this->access->connection->getFromCache('userExists'.$uid);
356
-		if(!is_null($userExists)) {
357
-			return (bool)$userExists;
358
-		}
359
-		//getting dn, if false the user does not exist. If dn, he may be mapped only, requires more checking.
360
-		$user = $this->access->userManager->get($uid);
361
-
362
-		if(is_null($user)) {
363
-			Util::writeLog('user_ldap', 'No DN found for '.$uid.' on '.
364
-				$this->access->connection->ldapHost, ILogger::DEBUG);
365
-			$this->access->connection->writeToCache('userExists'.$uid, false);
366
-			return false;
367
-		} else if($user instanceof OfflineUser) {
368
-			//express check for users marked as deleted. Returning true is
369
-			//necessary for cleanup
370
-			return true;
371
-		}
372
-
373
-		$result = $this->userExistsOnLDAP($user);
374
-		$this->access->connection->writeToCache('userExists'.$uid, $result);
375
-		if($result === true) {
376
-			$user->update();
377
-		}
378
-		return $result;
379
-	}
380
-
381
-	/**
382
-	* returns whether a user was deleted in LDAP
383
-	*
384
-	* @param string $uid The username of the user to delete
385
-	* @return bool
386
-	*/
387
-	public function deleteUser($uid) {
388
-		if ($this->userPluginManager->canDeleteUser()) {
389
-			return $this->userPluginManager->deleteUser($uid);
390
-		}
391
-
392
-		$marked = $this->ocConfig->getUserValue($uid, 'user_ldap', 'isDeleted', 0);
393
-		if((int)$marked === 0) {
394
-			\OC::$server->getLogger()->notice(
395
-				'User '.$uid . ' is not marked as deleted, not cleaning up.',
396
-				array('app' => 'user_ldap'));
397
-			return false;
398
-		}
399
-		\OC::$server->getLogger()->info('Cleaning up after user ' . $uid,
400
-			array('app' => 'user_ldap'));
401
-
402
-		$this->access->getUserMapper()->unmap($uid); // we don't emit unassign signals here, since it is implicit to delete signals fired from core
403
-		$this->access->userManager->invalidate($uid);
404
-		return true;
405
-	}
406
-
407
-	/**
408
-	 * get the user's home directory
409
-	 *
410
-	 * @param string $uid the username
411
-	 * @return bool|string
412
-	 * @throws NoUserException
413
-	 * @throws \Exception
414
-	 */
415
-	public function getHome($uid) {
416
-		// user Exists check required as it is not done in user proxy!
417
-		if(!$this->userExists($uid)) {
418
-			return false;
419
-		}
420
-
421
-		if ($this->userPluginManager->implementsActions(Backend::GET_HOME)) {
422
-			return $this->userPluginManager->getHome($uid);
423
-		}
424
-
425
-		$cacheKey = 'getHome'.$uid;
426
-		$path = $this->access->connection->getFromCache($cacheKey);
427
-		if(!is_null($path)) {
428
-			return $path;
429
-		}
430
-
431
-		// early return path if it is a deleted user
432
-		$user = $this->access->userManager->get($uid);
433
-		if($user instanceof OfflineUser) {
434
-			if($this->currentUserInDeletionProcess !== null
435
-				&& $this->currentUserInDeletionProcess === $user->getOCName()
436
-			) {
437
-				return $user->getHomePath();
438
-			} else {
439
-				throw new NoUserException($uid . ' is not a valid user anymore');
440
-			}
441
-		} else if ($user === null) {
442
-			throw new NoUserException($uid . ' is not a valid user anymore');
443
-		}
444
-
445
-		$path = $user->getHomePath();
446
-		$this->access->cacheUserHome($uid, $path);
447
-
448
-		return $path;
449
-	}
450
-
451
-	/**
452
-	 * get display name of the user
453
-	 * @param string $uid user ID of the user
454
-	 * @return string|false display name
455
-	 */
456
-	public function getDisplayName($uid) {
457
-		if ($this->userPluginManager->implementsActions(Backend::GET_DISPLAYNAME)) {
458
-			return $this->userPluginManager->getDisplayName($uid);
459
-		}
460
-
461
-		if(!$this->userExists($uid)) {
462
-			return false;
463
-		}
464
-
465
-		$cacheKey = 'getDisplayName'.$uid;
466
-		if(!is_null($displayName = $this->access->connection->getFromCache($cacheKey))) {
467
-			return $displayName;
468
-		}
469
-
470
-		//Check whether the display name is configured to have a 2nd feature
471
-		$additionalAttribute = $this->access->connection->ldapUserDisplayName2;
472
-		$displayName2 = '';
473
-		if ($additionalAttribute !== '') {
474
-			$displayName2 = $this->access->readAttribute(
475
-				$this->access->username2dn($uid),
476
-				$additionalAttribute);
477
-		}
478
-
479
-		$displayName = $this->access->readAttribute(
480
-			$this->access->username2dn($uid),
481
-			$this->access->connection->ldapUserDisplayName);
482
-
483
-		if($displayName && (count($displayName) > 0)) {
484
-			$displayName = $displayName[0];
485
-
486
-			if (is_array($displayName2)){
487
-				$displayName2 = count($displayName2) > 0 ? $displayName2[0] : '';
488
-			}
489
-
490
-			$user = $this->access->userManager->get($uid);
491
-			if ($user instanceof User) {
492
-				$displayName = $user->composeAndStoreDisplayName($displayName, $displayName2);
493
-				$this->access->connection->writeToCache($cacheKey, $displayName);
494
-			}
495
-			if ($user instanceof OfflineUser) {
496
-				/** @var OfflineUser $user*/
497
-				$displayName = $user->getDisplayName();
498
-			}
499
-			return $displayName;
500
-		}
501
-
502
-		return null;
503
-	}
504
-
505
-	/**
506
-	 * set display name of the user
507
-	 * @param string $uid user ID of the user
508
-	 * @param string $displayName new display name of the user
509
-	 * @return string|false display name
510
-	 */
511
-	public function setDisplayName($uid, $displayName) {
512
-		if ($this->userPluginManager->implementsActions(Backend::SET_DISPLAYNAME)) {
513
-			return $this->userPluginManager->setDisplayName($uid, $displayName);
514
-		}
515
-		return false;
516
-	}
517
-
518
-	/**
519
-	 * Get a list of all display names
520
-	 *
521
-	 * @param string $search
522
-	 * @param string|null $limit
523
-	 * @param string|null $offset
524
-	 * @return array an array of all displayNames (value) and the corresponding uids (key)
525
-	 */
526
-	public function getDisplayNames($search = '', $limit = null, $offset = null) {
527
-		$cacheKey = 'getDisplayNames-'.$search.'-'.$limit.'-'.$offset;
528
-		if(!is_null($displayNames = $this->access->connection->getFromCache($cacheKey))) {
529
-			return $displayNames;
530
-		}
531
-
532
-		$displayNames = array();
533
-		$users = $this->getUsers($search, $limit, $offset);
534
-		foreach ($users as $user) {
535
-			$displayNames[$user] = $this->getDisplayName($user);
536
-		}
537
-		$this->access->connection->writeToCache($cacheKey, $displayNames);
538
-		return $displayNames;
539
-	}
540
-
541
-	/**
542
-	* Check if backend implements actions
543
-	* @param int $actions bitwise-or'ed actions
544
-	* @return boolean
545
-	*
546
-	* Returns the supported actions as int to be
547
-	* compared with \OC\User\Backend::CREATE_USER etc.
548
-	*/
549
-	public function implementsActions($actions) {
550
-		return (bool)((Backend::CHECK_PASSWORD
551
-			| Backend::GET_HOME
552
-			| Backend::GET_DISPLAYNAME
553
-			| Backend::PROVIDE_AVATAR
554
-			| Backend::COUNT_USERS
555
-			| (((int)$this->access->connection->turnOnPasswordChange === 1)? Backend::SET_PASSWORD :0)
556
-			| $this->userPluginManager->getImplementedActions())
557
-			& $actions);
558
-	}
559
-
560
-	/**
561
-	 * @return bool
562
-	 */
563
-	public function hasUserListings() {
564
-		return true;
565
-	}
566
-
567
-	/**
568
-	 * counts the users in LDAP
569
-	 *
570
-	 * @return int|bool
571
-	 */
572
-	public function countUsers() {
573
-		if ($this->userPluginManager->implementsActions(Backend::COUNT_USERS)) {
574
-			return $this->userPluginManager->countUsers();
575
-		}
576
-
577
-		$filter = $this->access->getFilterForUserCount();
578
-		$cacheKey = 'countUsers-'.$filter;
579
-		if(!is_null($entries = $this->access->connection->getFromCache($cacheKey))) {
580
-			return $entries;
581
-		}
582
-		$entries = $this->access->countUsers($filter);
583
-		$this->access->connection->writeToCache($cacheKey, $entries);
584
-		return $entries;
585
-	}
586
-
587
-	/**
588
-	 * Backend name to be shown in user management
589
-	 * @return string the name of the backend to be shown
590
-	 */
591
-	public function getBackendName(){
592
-		return 'LDAP';
593
-	}
148
+    /**
149
+     * returns the username for the given LDAP DN, if available
150
+     *
151
+     * @param string $dn
152
+     * @return string|false with the username
153
+     */
154
+    public function dn2UserName($dn) {
155
+        return $this->access->dn2username($dn);
156
+    }
157
+
158
+    /**
159
+     * returns an LDAP record based on a given login name
160
+     *
161
+     * @param string $loginName
162
+     * @return array
163
+     * @throws NotOnLDAP
164
+     */
165
+    public function getLDAPUserByLoginName($loginName) {
166
+        //find out dn of the user name
167
+        $attrs = $this->access->userManager->getAttributes();
168
+        $users = $this->access->fetchUsersByLoginName($loginName, $attrs);
169
+        if(count($users) < 1) {
170
+            throw new NotOnLDAP('No user available for the given login name on ' .
171
+                $this->access->connection->ldapHost . ':' . $this->access->connection->ldapPort);
172
+        }
173
+        return $users[0];
174
+    }
175
+
176
+    /**
177
+     * Check if the password is correct without logging in the user
178
+     *
179
+     * @param string $uid The username
180
+     * @param string $password The password
181
+     * @return false|string
182
+     */
183
+    public function checkPassword($uid, $password) {
184
+        try {
185
+            $ldapRecord = $this->getLDAPUserByLoginName($uid);
186
+        } catch(NotOnLDAP $e) {
187
+            if($this->ocConfig->getSystemValue('loglevel', ILogger::WARN) === ILogger::DEBUG) {
188
+                \OC::$server->getLogger()->logException($e, ['app' => 'user_ldap']);
189
+            }
190
+            return false;
191
+        }
192
+        $dn = $ldapRecord['dn'][0];
193
+        $user = $this->access->userManager->get($dn);
194
+
195
+        if(!$user instanceof User) {
196
+            Util::writeLog('user_ldap',
197
+                'LDAP Login: Could not get user object for DN ' . $dn .
198
+                '. Maybe the LDAP entry has no set display name attribute?',
199
+                ILogger::WARN);
200
+            return false;
201
+        }
202
+        if($user->getUsername() !== false) {
203
+            //are the credentials OK?
204
+            if(!$this->access->areCredentialsValid($dn, $password)) {
205
+                return false;
206
+            }
207
+
208
+            $this->access->cacheUserExists($user->getUsername());
209
+            $user->processAttributes($ldapRecord);
210
+            $user->markLogin();
211
+
212
+            return $user->getUsername();
213
+        }
214
+
215
+        return false;
216
+    }
217
+
218
+    /**
219
+     * Set password
220
+     * @param string $uid The username
221
+     * @param string $password The new password
222
+     * @return bool
223
+     */
224
+    public function setPassword($uid, $password) {
225
+        if ($this->userPluginManager->implementsActions(Backend::SET_PASSWORD)) {
226
+            return $this->userPluginManager->setPassword($uid, $password);
227
+        }
228
+
229
+        $user = $this->access->userManager->get($uid);
230
+
231
+        if(!$user instanceof User) {
232
+            throw new \Exception('LDAP setPassword: Could not get user object for uid ' . $uid .
233
+                '. Maybe the LDAP entry has no set display name attribute?');
234
+        }
235
+        if($user->getUsername() !== false && $this->access->setPassword($user->getDN(), $password)) {
236
+            $ldapDefaultPPolicyDN = $this->access->connection->ldapDefaultPPolicyDN;
237
+            $turnOnPasswordChange = $this->access->connection->turnOnPasswordChange;
238
+            if (!empty($ldapDefaultPPolicyDN) && ((int)$turnOnPasswordChange === 1)) {
239
+                //remove last password expiry warning if any
240
+                $notification = $this->notificationManager->createNotification();
241
+                $notification->setApp('user_ldap')
242
+                    ->setUser($uid)
243
+                    ->setObject('pwd_exp_warn', $uid)
244
+                ;
245
+                $this->notificationManager->markProcessed($notification);
246
+            }
247
+            return true;
248
+        }
249
+
250
+        return false;
251
+    }
252
+
253
+    /**
254
+     * Get a list of all users
255
+     *
256
+     * @param string $search
257
+     * @param integer $limit
258
+     * @param integer $offset
259
+     * @return string[] an array of all uids
260
+     */
261
+    public function getUsers($search = '', $limit = 10, $offset = 0) {
262
+        $search = $this->access->escapeFilterPart($search, true);
263
+        $cachekey = 'getUsers-'.$search.'-'.$limit.'-'.$offset;
264
+
265
+        //check if users are cached, if so return
266
+        $ldap_users = $this->access->connection->getFromCache($cachekey);
267
+        if(!is_null($ldap_users)) {
268
+            return $ldap_users;
269
+        }
270
+
271
+        // if we'd pass -1 to LDAP search, we'd end up in a Protocol
272
+        // error. With a limit of 0, we get 0 results. So we pass null.
273
+        if($limit <= 0) {
274
+            $limit = null;
275
+        }
276
+        $filter = $this->access->combineFilterWithAnd(array(
277
+            $this->access->connection->ldapUserFilter,
278
+            $this->access->connection->ldapUserDisplayName . '=*',
279
+            $this->access->getFilterPartForUserSearch($search)
280
+        ));
281
+
282
+        Util::writeLog('user_ldap',
283
+            'getUsers: Options: search '.$search.' limit '.$limit.' offset '.$offset.' Filter: '.$filter,
284
+            ILogger::DEBUG);
285
+        //do the search and translate results to Nextcloud names
286
+        $ldap_users = $this->access->fetchListOfUsers(
287
+            $filter,
288
+            $this->access->userManager->getAttributes(true),
289
+            $limit, $offset);
290
+        $ldap_users = $this->access->nextcloudUserNames($ldap_users);
291
+        Util::writeLog('user_ldap', 'getUsers: '.count($ldap_users). ' Users found', ILogger::DEBUG);
292
+
293
+        $this->access->connection->writeToCache($cachekey, $ldap_users);
294
+        return $ldap_users;
295
+    }
296
+
297
+    /**
298
+     * checks whether a user is still available on LDAP
299
+     *
300
+     * @param string|\OCA\User_LDAP\User\User $user either the Nextcloud user
301
+     * name or an instance of that user
302
+     * @return bool
303
+     * @throws \Exception
304
+     * @throws \OC\ServerNotAvailableException
305
+     */
306
+    public function userExistsOnLDAP($user) {
307
+        if(is_string($user)) {
308
+            $user = $this->access->userManager->get($user);
309
+        }
310
+        if(is_null($user)) {
311
+            return false;
312
+        }
313
+
314
+        $dn = $user->getDN();
315
+        //check if user really still exists by reading its entry
316
+        if(!is_array($this->access->readAttribute($dn, '', $this->access->connection->ldapUserFilter))) {
317
+            $lcr = $this->access->connection->getConnectionResource();
318
+            if(is_null($lcr)) {
319
+                throw new \Exception('No LDAP Connection to server ' . $this->access->connection->ldapHost);
320
+            }
321
+
322
+            try {
323
+                $uuid = $this->access->getUserMapper()->getUUIDByDN($dn);
324
+                if (!$uuid) {
325
+                    return false;
326
+                }
327
+                $newDn = $this->access->getUserDnByUuid($uuid);
328
+                //check if renamed user is still valid by reapplying the ldap filter
329
+                if (!is_array($this->access->readAttribute($newDn, '', $this->access->connection->ldapUserFilter))) {
330
+                    return false;
331
+                }
332
+                $this->access->getUserMapper()->setDNbyUUID($newDn, $uuid);
333
+                return true;
334
+            } catch (ServerNotAvailableException $e) {
335
+                throw $e;
336
+            } catch (\Exception $e) {
337
+                return false;
338
+            }
339
+        }
340
+
341
+        if($user instanceof OfflineUser) {
342
+            $user->unmark();
343
+        }
344
+
345
+        return true;
346
+    }
347
+
348
+    /**
349
+     * check if a user exists
350
+     * @param string $uid the username
351
+     * @return boolean
352
+     * @throws \Exception when connection could not be established
353
+     */
354
+    public function userExists($uid) {
355
+        $userExists = $this->access->connection->getFromCache('userExists'.$uid);
356
+        if(!is_null($userExists)) {
357
+            return (bool)$userExists;
358
+        }
359
+        //getting dn, if false the user does not exist. If dn, he may be mapped only, requires more checking.
360
+        $user = $this->access->userManager->get($uid);
361
+
362
+        if(is_null($user)) {
363
+            Util::writeLog('user_ldap', 'No DN found for '.$uid.' on '.
364
+                $this->access->connection->ldapHost, ILogger::DEBUG);
365
+            $this->access->connection->writeToCache('userExists'.$uid, false);
366
+            return false;
367
+        } else if($user instanceof OfflineUser) {
368
+            //express check for users marked as deleted. Returning true is
369
+            //necessary for cleanup
370
+            return true;
371
+        }
372
+
373
+        $result = $this->userExistsOnLDAP($user);
374
+        $this->access->connection->writeToCache('userExists'.$uid, $result);
375
+        if($result === true) {
376
+            $user->update();
377
+        }
378
+        return $result;
379
+    }
380
+
381
+    /**
382
+     * returns whether a user was deleted in LDAP
383
+     *
384
+     * @param string $uid The username of the user to delete
385
+     * @return bool
386
+     */
387
+    public function deleteUser($uid) {
388
+        if ($this->userPluginManager->canDeleteUser()) {
389
+            return $this->userPluginManager->deleteUser($uid);
390
+        }
391
+
392
+        $marked = $this->ocConfig->getUserValue($uid, 'user_ldap', 'isDeleted', 0);
393
+        if((int)$marked === 0) {
394
+            \OC::$server->getLogger()->notice(
395
+                'User '.$uid . ' is not marked as deleted, not cleaning up.',
396
+                array('app' => 'user_ldap'));
397
+            return false;
398
+        }
399
+        \OC::$server->getLogger()->info('Cleaning up after user ' . $uid,
400
+            array('app' => 'user_ldap'));
401
+
402
+        $this->access->getUserMapper()->unmap($uid); // we don't emit unassign signals here, since it is implicit to delete signals fired from core
403
+        $this->access->userManager->invalidate($uid);
404
+        return true;
405
+    }
406
+
407
+    /**
408
+     * get the user's home directory
409
+     *
410
+     * @param string $uid the username
411
+     * @return bool|string
412
+     * @throws NoUserException
413
+     * @throws \Exception
414
+     */
415
+    public function getHome($uid) {
416
+        // user Exists check required as it is not done in user proxy!
417
+        if(!$this->userExists($uid)) {
418
+            return false;
419
+        }
420
+
421
+        if ($this->userPluginManager->implementsActions(Backend::GET_HOME)) {
422
+            return $this->userPluginManager->getHome($uid);
423
+        }
424
+
425
+        $cacheKey = 'getHome'.$uid;
426
+        $path = $this->access->connection->getFromCache($cacheKey);
427
+        if(!is_null($path)) {
428
+            return $path;
429
+        }
430
+
431
+        // early return path if it is a deleted user
432
+        $user = $this->access->userManager->get($uid);
433
+        if($user instanceof OfflineUser) {
434
+            if($this->currentUserInDeletionProcess !== null
435
+                && $this->currentUserInDeletionProcess === $user->getOCName()
436
+            ) {
437
+                return $user->getHomePath();
438
+            } else {
439
+                throw new NoUserException($uid . ' is not a valid user anymore');
440
+            }
441
+        } else if ($user === null) {
442
+            throw new NoUserException($uid . ' is not a valid user anymore');
443
+        }
444
+
445
+        $path = $user->getHomePath();
446
+        $this->access->cacheUserHome($uid, $path);
447
+
448
+        return $path;
449
+    }
450
+
451
+    /**
452
+     * get display name of the user
453
+     * @param string $uid user ID of the user
454
+     * @return string|false display name
455
+     */
456
+    public function getDisplayName($uid) {
457
+        if ($this->userPluginManager->implementsActions(Backend::GET_DISPLAYNAME)) {
458
+            return $this->userPluginManager->getDisplayName($uid);
459
+        }
460
+
461
+        if(!$this->userExists($uid)) {
462
+            return false;
463
+        }
464
+
465
+        $cacheKey = 'getDisplayName'.$uid;
466
+        if(!is_null($displayName = $this->access->connection->getFromCache($cacheKey))) {
467
+            return $displayName;
468
+        }
469
+
470
+        //Check whether the display name is configured to have a 2nd feature
471
+        $additionalAttribute = $this->access->connection->ldapUserDisplayName2;
472
+        $displayName2 = '';
473
+        if ($additionalAttribute !== '') {
474
+            $displayName2 = $this->access->readAttribute(
475
+                $this->access->username2dn($uid),
476
+                $additionalAttribute);
477
+        }
478
+
479
+        $displayName = $this->access->readAttribute(
480
+            $this->access->username2dn($uid),
481
+            $this->access->connection->ldapUserDisplayName);
482
+
483
+        if($displayName && (count($displayName) > 0)) {
484
+            $displayName = $displayName[0];
485
+
486
+            if (is_array($displayName2)){
487
+                $displayName2 = count($displayName2) > 0 ? $displayName2[0] : '';
488
+            }
489
+
490
+            $user = $this->access->userManager->get($uid);
491
+            if ($user instanceof User) {
492
+                $displayName = $user->composeAndStoreDisplayName($displayName, $displayName2);
493
+                $this->access->connection->writeToCache($cacheKey, $displayName);
494
+            }
495
+            if ($user instanceof OfflineUser) {
496
+                /** @var OfflineUser $user*/
497
+                $displayName = $user->getDisplayName();
498
+            }
499
+            return $displayName;
500
+        }
501
+
502
+        return null;
503
+    }
504
+
505
+    /**
506
+     * set display name of the user
507
+     * @param string $uid user ID of the user
508
+     * @param string $displayName new display name of the user
509
+     * @return string|false display name
510
+     */
511
+    public function setDisplayName($uid, $displayName) {
512
+        if ($this->userPluginManager->implementsActions(Backend::SET_DISPLAYNAME)) {
513
+            return $this->userPluginManager->setDisplayName($uid, $displayName);
514
+        }
515
+        return false;
516
+    }
517
+
518
+    /**
519
+     * Get a list of all display names
520
+     *
521
+     * @param string $search
522
+     * @param string|null $limit
523
+     * @param string|null $offset
524
+     * @return array an array of all displayNames (value) and the corresponding uids (key)
525
+     */
526
+    public function getDisplayNames($search = '', $limit = null, $offset = null) {
527
+        $cacheKey = 'getDisplayNames-'.$search.'-'.$limit.'-'.$offset;
528
+        if(!is_null($displayNames = $this->access->connection->getFromCache($cacheKey))) {
529
+            return $displayNames;
530
+        }
531
+
532
+        $displayNames = array();
533
+        $users = $this->getUsers($search, $limit, $offset);
534
+        foreach ($users as $user) {
535
+            $displayNames[$user] = $this->getDisplayName($user);
536
+        }
537
+        $this->access->connection->writeToCache($cacheKey, $displayNames);
538
+        return $displayNames;
539
+    }
540
+
541
+    /**
542
+     * Check if backend implements actions
543
+     * @param int $actions bitwise-or'ed actions
544
+     * @return boolean
545
+     *
546
+     * Returns the supported actions as int to be
547
+     * compared with \OC\User\Backend::CREATE_USER etc.
548
+     */
549
+    public function implementsActions($actions) {
550
+        return (bool)((Backend::CHECK_PASSWORD
551
+            | Backend::GET_HOME
552
+            | Backend::GET_DISPLAYNAME
553
+            | Backend::PROVIDE_AVATAR
554
+            | Backend::COUNT_USERS
555
+            | (((int)$this->access->connection->turnOnPasswordChange === 1)? Backend::SET_PASSWORD :0)
556
+            | $this->userPluginManager->getImplementedActions())
557
+            & $actions);
558
+    }
559
+
560
+    /**
561
+     * @return bool
562
+     */
563
+    public function hasUserListings() {
564
+        return true;
565
+    }
566
+
567
+    /**
568
+     * counts the users in LDAP
569
+     *
570
+     * @return int|bool
571
+     */
572
+    public function countUsers() {
573
+        if ($this->userPluginManager->implementsActions(Backend::COUNT_USERS)) {
574
+            return $this->userPluginManager->countUsers();
575
+        }
576
+
577
+        $filter = $this->access->getFilterForUserCount();
578
+        $cacheKey = 'countUsers-'.$filter;
579
+        if(!is_null($entries = $this->access->connection->getFromCache($cacheKey))) {
580
+            return $entries;
581
+        }
582
+        $entries = $this->access->countUsers($filter);
583
+        $this->access->connection->writeToCache($cacheKey, $entries);
584
+        return $entries;
585
+    }
586
+
587
+    /**
588
+     * Backend name to be shown in user management
589
+     * @return string the name of the backend to be shown
590
+     */
591
+    public function getBackendName(){
592
+        return 'LDAP';
593
+    }
594 594
 	
595
-	/**
596
-	 * Return access for LDAP interaction.
597
-	 * @param string $uid
598
-	 * @return Access instance of Access for LDAP interaction
599
-	 */
600
-	public function getLDAPAccess($uid) {
601
-		return $this->access;
602
-	}
595
+    /**
596
+     * Return access for LDAP interaction.
597
+     * @param string $uid
598
+     * @return Access instance of Access for LDAP interaction
599
+     */
600
+    public function getLDAPAccess($uid) {
601
+        return $this->access;
602
+    }
603 603
 	
604
-	/**
605
-	 * Return LDAP connection resource from a cloned connection.
606
-	 * The cloned connection needs to be closed manually.
607
-	 * of the current access.
608
-	 * @param string $uid
609
-	 * @return resource of the LDAP connection
610
-	 */
611
-	public function getNewLDAPConnection($uid) {
612
-		$connection = clone $this->access->getConnection();
613
-		return $connection->getConnectionResource();
614
-	}
615
-
616
-	/**
617
-	 * create new user
618
-	 * @param string $username username of the new user
619
-	 * @param string $password password of the new user
620
-	 * @return bool was the user created?
621
-	 */
622
-	public function createUser($username, $password) {
623
-		if ($this->userPluginManager->implementsActions(Backend::CREATE_USER)) {
624
-			return $this->userPluginManager->createUser($username, $password);
625
-		}
626
-		return false;
627
-	}
604
+    /**
605
+     * Return LDAP connection resource from a cloned connection.
606
+     * The cloned connection needs to be closed manually.
607
+     * of the current access.
608
+     * @param string $uid
609
+     * @return resource of the LDAP connection
610
+     */
611
+    public function getNewLDAPConnection($uid) {
612
+        $connection = clone $this->access->getConnection();
613
+        return $connection->getConnectionResource();
614
+    }
615
+
616
+    /**
617
+     * create new user
618
+     * @param string $username username of the new user
619
+     * @param string $password password of the new user
620
+     * @return bool was the user created?
621
+     */
622
+    public function createUser($username, $password) {
623
+        if ($this->userPluginManager->implementsActions(Backend::CREATE_USER)) {
624
+            return $this->userPluginManager->createUser($username, $password);
625
+        }
626
+        return false;
627
+    }
628 628
 
629 629
 }
Please login to merge, or discard this patch.
Spacing   +50 added lines, -50 removed lines patch added patch discarded remove patch
@@ -104,11 +104,11 @@  discard block
 block discarded – undo
104 104
 		}
105 105
 
106 106
 		$user = $this->access->userManager->get($uid);
107
-		if(!$user instanceof User) {
107
+		if (!$user instanceof User) {
108 108
 			return false;
109 109
 		}
110 110
 		$imageData = $user->getAvatarImage();
111
-		if($imageData === false) {
111
+		if ($imageData === false) {
112 112
 			return true;
113 113
 		}
114 114
 		return !$user->updateAvatar(true);
@@ -123,14 +123,14 @@  discard block
 block discarded – undo
123 123
 	public function loginName2UserName($loginName) {
124 124
 		$cacheKey = 'loginName2UserName-'.$loginName;
125 125
 		$username = $this->access->connection->getFromCache($cacheKey);
126
-		if(!is_null($username)) {
126
+		if (!is_null($username)) {
127 127
 			return $username;
128 128
 		}
129 129
 
130 130
 		try {
131 131
 			$ldapRecord = $this->getLDAPUserByLoginName($loginName);
132 132
 			$user = $this->access->userManager->get($ldapRecord['dn'][0]);
133
-			if($user instanceof OfflineUser) {
133
+			if ($user instanceof OfflineUser) {
134 134
 				// this path is not really possible, however get() is documented
135 135
 				// to return User or OfflineUser so we are very defensive here.
136 136
 				$this->access->connection->writeToCache($cacheKey, false);
@@ -166,9 +166,9 @@  discard block
 block discarded – undo
166 166
 		//find out dn of the user name
167 167
 		$attrs = $this->access->userManager->getAttributes();
168 168
 		$users = $this->access->fetchUsersByLoginName($loginName, $attrs);
169
-		if(count($users) < 1) {
170
-			throw new NotOnLDAP('No user available for the given login name on ' .
171
-				$this->access->connection->ldapHost . ':' . $this->access->connection->ldapPort);
169
+		if (count($users) < 1) {
170
+			throw new NotOnLDAP('No user available for the given login name on '.
171
+				$this->access->connection->ldapHost.':'.$this->access->connection->ldapPort);
172 172
 		}
173 173
 		return $users[0];
174 174
 	}
@@ -183,8 +183,8 @@  discard block
 block discarded – undo
183 183
 	public function checkPassword($uid, $password) {
184 184
 		try {
185 185
 			$ldapRecord = $this->getLDAPUserByLoginName($uid);
186
-		} catch(NotOnLDAP $e) {
187
-			if($this->ocConfig->getSystemValue('loglevel', ILogger::WARN) === ILogger::DEBUG) {
186
+		} catch (NotOnLDAP $e) {
187
+			if ($this->ocConfig->getSystemValue('loglevel', ILogger::WARN) === ILogger::DEBUG) {
188 188
 				\OC::$server->getLogger()->logException($e, ['app' => 'user_ldap']);
189 189
 			}
190 190
 			return false;
@@ -192,16 +192,16 @@  discard block
 block discarded – undo
192 192
 		$dn = $ldapRecord['dn'][0];
193 193
 		$user = $this->access->userManager->get($dn);
194 194
 
195
-		if(!$user instanceof User) {
195
+		if (!$user instanceof User) {
196 196
 			Util::writeLog('user_ldap',
197
-				'LDAP Login: Could not get user object for DN ' . $dn .
197
+				'LDAP Login: Could not get user object for DN '.$dn.
198 198
 				'. Maybe the LDAP entry has no set display name attribute?',
199 199
 				ILogger::WARN);
200 200
 			return false;
201 201
 		}
202
-		if($user->getUsername() !== false) {
202
+		if ($user->getUsername() !== false) {
203 203
 			//are the credentials OK?
204
-			if(!$this->access->areCredentialsValid($dn, $password)) {
204
+			if (!$this->access->areCredentialsValid($dn, $password)) {
205 205
 				return false;
206 206
 			}
207 207
 
@@ -228,14 +228,14 @@  discard block
 block discarded – undo
228 228
 
229 229
 		$user = $this->access->userManager->get($uid);
230 230
 
231
-		if(!$user instanceof User) {
232
-			throw new \Exception('LDAP setPassword: Could not get user object for uid ' . $uid .
231
+		if (!$user instanceof User) {
232
+			throw new \Exception('LDAP setPassword: Could not get user object for uid '.$uid.
233 233
 				'. Maybe the LDAP entry has no set display name attribute?');
234 234
 		}
235
-		if($user->getUsername() !== false && $this->access->setPassword($user->getDN(), $password)) {
235
+		if ($user->getUsername() !== false && $this->access->setPassword($user->getDN(), $password)) {
236 236
 			$ldapDefaultPPolicyDN = $this->access->connection->ldapDefaultPPolicyDN;
237 237
 			$turnOnPasswordChange = $this->access->connection->turnOnPasswordChange;
238
-			if (!empty($ldapDefaultPPolicyDN) && ((int)$turnOnPasswordChange === 1)) {
238
+			if (!empty($ldapDefaultPPolicyDN) && ((int) $turnOnPasswordChange === 1)) {
239 239
 				//remove last password expiry warning if any
240 240
 				$notification = $this->notificationManager->createNotification();
241 241
 				$notification->setApp('user_ldap')
@@ -264,18 +264,18 @@  discard block
 block discarded – undo
264 264
 
265 265
 		//check if users are cached, if so return
266 266
 		$ldap_users = $this->access->connection->getFromCache($cachekey);
267
-		if(!is_null($ldap_users)) {
267
+		if (!is_null($ldap_users)) {
268 268
 			return $ldap_users;
269 269
 		}
270 270
 
271 271
 		// if we'd pass -1 to LDAP search, we'd end up in a Protocol
272 272
 		// error. With a limit of 0, we get 0 results. So we pass null.
273
-		if($limit <= 0) {
273
+		if ($limit <= 0) {
274 274
 			$limit = null;
275 275
 		}
276 276
 		$filter = $this->access->combineFilterWithAnd(array(
277 277
 			$this->access->connection->ldapUserFilter,
278
-			$this->access->connection->ldapUserDisplayName . '=*',
278
+			$this->access->connection->ldapUserDisplayName.'=*',
279 279
 			$this->access->getFilterPartForUserSearch($search)
280 280
 		));
281 281
 
@@ -288,7 +288,7 @@  discard block
 block discarded – undo
288 288
 			$this->access->userManager->getAttributes(true),
289 289
 			$limit, $offset);
290 290
 		$ldap_users = $this->access->nextcloudUserNames($ldap_users);
291
-		Util::writeLog('user_ldap', 'getUsers: '.count($ldap_users). ' Users found', ILogger::DEBUG);
291
+		Util::writeLog('user_ldap', 'getUsers: '.count($ldap_users).' Users found', ILogger::DEBUG);
292 292
 
293 293
 		$this->access->connection->writeToCache($cachekey, $ldap_users);
294 294
 		return $ldap_users;
@@ -304,19 +304,19 @@  discard block
 block discarded – undo
304 304
 	 * @throws \OC\ServerNotAvailableException
305 305
 	 */
306 306
 	public function userExistsOnLDAP($user) {
307
-		if(is_string($user)) {
307
+		if (is_string($user)) {
308 308
 			$user = $this->access->userManager->get($user);
309 309
 		}
310
-		if(is_null($user)) {
310
+		if (is_null($user)) {
311 311
 			return false;
312 312
 		}
313 313
 
314 314
 		$dn = $user->getDN();
315 315
 		//check if user really still exists by reading its entry
316
-		if(!is_array($this->access->readAttribute($dn, '', $this->access->connection->ldapUserFilter))) {
316
+		if (!is_array($this->access->readAttribute($dn, '', $this->access->connection->ldapUserFilter))) {
317 317
 			$lcr = $this->access->connection->getConnectionResource();
318
-			if(is_null($lcr)) {
319
-				throw new \Exception('No LDAP Connection to server ' . $this->access->connection->ldapHost);
318
+			if (is_null($lcr)) {
319
+				throw new \Exception('No LDAP Connection to server '.$this->access->connection->ldapHost);
320 320
 			}
321 321
 
322 322
 			try {
@@ -338,7 +338,7 @@  discard block
 block discarded – undo
338 338
 			}
339 339
 		}
340 340
 
341
-		if($user instanceof OfflineUser) {
341
+		if ($user instanceof OfflineUser) {
342 342
 			$user->unmark();
343 343
 		}
344 344
 
@@ -353,18 +353,18 @@  discard block
 block discarded – undo
353 353
 	 */
354 354
 	public function userExists($uid) {
355 355
 		$userExists = $this->access->connection->getFromCache('userExists'.$uid);
356
-		if(!is_null($userExists)) {
357
-			return (bool)$userExists;
356
+		if (!is_null($userExists)) {
357
+			return (bool) $userExists;
358 358
 		}
359 359
 		//getting dn, if false the user does not exist. If dn, he may be mapped only, requires more checking.
360 360
 		$user = $this->access->userManager->get($uid);
361 361
 
362
-		if(is_null($user)) {
362
+		if (is_null($user)) {
363 363
 			Util::writeLog('user_ldap', 'No DN found for '.$uid.' on '.
364 364
 				$this->access->connection->ldapHost, ILogger::DEBUG);
365 365
 			$this->access->connection->writeToCache('userExists'.$uid, false);
366 366
 			return false;
367
-		} else if($user instanceof OfflineUser) {
367
+		} else if ($user instanceof OfflineUser) {
368 368
 			//express check for users marked as deleted. Returning true is
369 369
 			//necessary for cleanup
370 370
 			return true;
@@ -372,7 +372,7 @@  discard block
 block discarded – undo
372 372
 
373 373
 		$result = $this->userExistsOnLDAP($user);
374 374
 		$this->access->connection->writeToCache('userExists'.$uid, $result);
375
-		if($result === true) {
375
+		if ($result === true) {
376 376
 			$user->update();
377 377
 		}
378 378
 		return $result;
@@ -390,13 +390,13 @@  discard block
 block discarded – undo
390 390
 		}
391 391
 
392 392
 		$marked = $this->ocConfig->getUserValue($uid, 'user_ldap', 'isDeleted', 0);
393
-		if((int)$marked === 0) {
393
+		if ((int) $marked === 0) {
394 394
 			\OC::$server->getLogger()->notice(
395
-				'User '.$uid . ' is not marked as deleted, not cleaning up.',
395
+				'User '.$uid.' is not marked as deleted, not cleaning up.',
396 396
 				array('app' => 'user_ldap'));
397 397
 			return false;
398 398
 		}
399
-		\OC::$server->getLogger()->info('Cleaning up after user ' . $uid,
399
+		\OC::$server->getLogger()->info('Cleaning up after user '.$uid,
400 400
 			array('app' => 'user_ldap'));
401 401
 
402 402
 		$this->access->getUserMapper()->unmap($uid); // we don't emit unassign signals here, since it is implicit to delete signals fired from core
@@ -414,7 +414,7 @@  discard block
 block discarded – undo
414 414
 	 */
415 415
 	public function getHome($uid) {
416 416
 		// user Exists check required as it is not done in user proxy!
417
-		if(!$this->userExists($uid)) {
417
+		if (!$this->userExists($uid)) {
418 418
 			return false;
419 419
 		}
420 420
 
@@ -424,22 +424,22 @@  discard block
 block discarded – undo
424 424
 
425 425
 		$cacheKey = 'getHome'.$uid;
426 426
 		$path = $this->access->connection->getFromCache($cacheKey);
427
-		if(!is_null($path)) {
427
+		if (!is_null($path)) {
428 428
 			return $path;
429 429
 		}
430 430
 
431 431
 		// early return path if it is a deleted user
432 432
 		$user = $this->access->userManager->get($uid);
433
-		if($user instanceof OfflineUser) {
434
-			if($this->currentUserInDeletionProcess !== null
433
+		if ($user instanceof OfflineUser) {
434
+			if ($this->currentUserInDeletionProcess !== null
435 435
 				&& $this->currentUserInDeletionProcess === $user->getOCName()
436 436
 			) {
437 437
 				return $user->getHomePath();
438 438
 			} else {
439
-				throw new NoUserException($uid . ' is not a valid user anymore');
439
+				throw new NoUserException($uid.' is not a valid user anymore');
440 440
 			}
441 441
 		} else if ($user === null) {
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
 
445 445
 		$path = $user->getHomePath();
@@ -458,12 +458,12 @@  discard block
 block discarded – undo
458 458
 			return $this->userPluginManager->getDisplayName($uid);
459 459
 		}
460 460
 
461
-		if(!$this->userExists($uid)) {
461
+		if (!$this->userExists($uid)) {
462 462
 			return false;
463 463
 		}
464 464
 
465 465
 		$cacheKey = 'getDisplayName'.$uid;
466
-		if(!is_null($displayName = $this->access->connection->getFromCache($cacheKey))) {
466
+		if (!is_null($displayName = $this->access->connection->getFromCache($cacheKey))) {
467 467
 			return $displayName;
468 468
 		}
469 469
 
@@ -480,10 +480,10 @@  discard block
 block discarded – undo
480 480
 			$this->access->username2dn($uid),
481 481
 			$this->access->connection->ldapUserDisplayName);
482 482
 
483
-		if($displayName && (count($displayName) > 0)) {
483
+		if ($displayName && (count($displayName) > 0)) {
484 484
 			$displayName = $displayName[0];
485 485
 
486
-			if (is_array($displayName2)){
486
+			if (is_array($displayName2)) {
487 487
 				$displayName2 = count($displayName2) > 0 ? $displayName2[0] : '';
488 488
 			}
489 489
 
@@ -525,7 +525,7 @@  discard block
 block discarded – undo
525 525
 	 */
526 526
 	public function getDisplayNames($search = '', $limit = null, $offset = null) {
527 527
 		$cacheKey = 'getDisplayNames-'.$search.'-'.$limit.'-'.$offset;
528
-		if(!is_null($displayNames = $this->access->connection->getFromCache($cacheKey))) {
528
+		if (!is_null($displayNames = $this->access->connection->getFromCache($cacheKey))) {
529 529
 			return $displayNames;
530 530
 		}
531 531
 
@@ -547,12 +547,12 @@  discard block
 block discarded – undo
547 547
 	* compared with \OC\User\Backend::CREATE_USER etc.
548 548
 	*/
549 549
 	public function implementsActions($actions) {
550
-		return (bool)((Backend::CHECK_PASSWORD
550
+		return (bool) ((Backend::CHECK_PASSWORD
551 551
 			| Backend::GET_HOME
552 552
 			| Backend::GET_DISPLAYNAME
553 553
 			| Backend::PROVIDE_AVATAR
554 554
 			| Backend::COUNT_USERS
555
-			| (((int)$this->access->connection->turnOnPasswordChange === 1)? Backend::SET_PASSWORD :0)
555
+			| (((int) $this->access->connection->turnOnPasswordChange === 1) ? Backend::SET_PASSWORD : 0)
556 556
 			| $this->userPluginManager->getImplementedActions())
557 557
 			& $actions);
558 558
 	}
@@ -576,7 +576,7 @@  discard block
 block discarded – undo
576 576
 
577 577
 		$filter = $this->access->getFilterForUserCount();
578 578
 		$cacheKey = 'countUsers-'.$filter;
579
-		if(!is_null($entries = $this->access->connection->getFromCache($cacheKey))) {
579
+		if (!is_null($entries = $this->access->connection->getFromCache($cacheKey))) {
580 580
 			return $entries;
581 581
 		}
582 582
 		$entries = $this->access->countUsers($filter);
@@ -588,7 +588,7 @@  discard block
 block discarded – undo
588 588
 	 * Backend name to be shown in user management
589 589
 	 * @return string the name of the backend to be shown
590 590
 	 */
591
-	public function getBackendName(){
591
+	public function getBackendName() {
592 592
 		return 'LDAP';
593 593
 	}
594 594
 	
Please login to merge, or discard this patch.
apps/user_ldap/lib/User/User.php 2 patches
Indentation   +644 added lines, -644 removed lines patch added patch discarded remove patch
@@ -47,654 +47,654 @@
 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!", ILogger::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", ILogger::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
-		\OCP\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 = (string)$ldapEntry[$attr][0];
199
-		}
200
-		$attr = strtolower($this->connection->ldapUserDisplayName2);
201
-		if(isset($ldapEntry[$attr])) {
202
-			$displayName2 = (string)$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
-		$attrs = array('jpegphoto', 'thumbnailphoto');
249
-		foreach ($attrs as $attr)  {
250
-			if(isset($ldapEntry[$attr])) {
251
-				$this->avatarImage = $ldapEntry[$attr][0];
252
-				// the call to the method that saves the avatar in the file
253
-				// system must be postponed after the login. It is to ensure
254
-				// external mounts are mounted properly (e.g. with login
255
-				// credentials from the session).
256
-				\OCP\Util::connectHook('OC_User', 'post_login', $this, 'updateAvatarPostLogin');
257
-				break;
258
-			}
259
-		}
260
-	}
261
-
262
-	/**
263
-	 * @brief returns the LDAP DN of the user
264
-	 * @return string
265
-	 */
266
-	public function getDN() {
267
-		return $this->dn;
268
-	}
269
-
270
-	/**
271
-	 * @brief returns the Nextcloud internal username of the user
272
-	 * @return string
273
-	 */
274
-	public function getUsername() {
275
-		return $this->uid;
276
-	}
277
-
278
-	/**
279
-	 * returns the home directory of the user if specified by LDAP settings
280
-	 * @param string $valueFromLDAP
281
-	 * @return bool|string
282
-	 * @throws \Exception
283
-	 */
284
-	public function getHomePath($valueFromLDAP = null) {
285
-		$path = (string)$valueFromLDAP;
286
-		$attr = null;
287
-
288
-		if (is_null($valueFromLDAP)
289
-		   && strpos($this->access->connection->homeFolderNamingRule, 'attr:') === 0
290
-		   && $this->access->connection->homeFolderNamingRule !== 'attr:')
291
-		{
292
-			$attr = substr($this->access->connection->homeFolderNamingRule, strlen('attr:'));
293
-			$homedir = $this->access->readAttribute(
294
-				$this->access->username2dn($this->getUsername()), $attr);
295
-			if ($homedir && isset($homedir[0])) {
296
-				$path = $homedir[0];
297
-			}
298
-		}
299
-
300
-		if ($path !== '') {
301
-			//if attribute's value is an absolute path take this, otherwise append it to data dir
302
-			//check for / at the beginning or pattern c:\ resp. c:/
303
-			if(   '/' !== $path[0]
304
-			   && !(3 < strlen($path) && ctype_alpha($path[0])
305
-			       && $path[1] === ':' && ('\\' === $path[2] || '/' === $path[2]))
306
-			) {
307
-				$path = $this->config->getSystemValue('datadirectory',
308
-						\OC::$SERVERROOT.'/data' ) . '/' . $path;
309
-			}
310
-			//we need it to store it in the DB as well in case a user gets
311
-			//deleted so we can clean up afterwards
312
-			$this->config->setUserValue(
313
-				$this->getUsername(), 'user_ldap', 'homePath', $path
314
-			);
315
-			return $path;
316
-		}
317
-
318
-		if(    !is_null($attr)
319
-			&& $this->config->getAppValue('user_ldap', 'enforce_home_folder_naming_rule', true)
320
-		) {
321
-			// a naming rule attribute is defined, but it doesn't exist for that LDAP user
322
-			throw new \Exception('Home dir attribute can\'t be read from LDAP for uid: ' . $this->getUsername());
323
-		}
324
-
325
-		//false will apply default behaviour as defined and done by OC_User
326
-		$this->config->setUserValue($this->getUsername(), 'user_ldap', 'homePath', '');
327
-		return false;
328
-	}
329
-
330
-	public function getMemberOfGroups() {
331
-		$cacheKey = 'getMemberOf'.$this->getUsername();
332
-		$memberOfGroups = $this->connection->getFromCache($cacheKey);
333
-		if(!is_null($memberOfGroups)) {
334
-			return $memberOfGroups;
335
-		}
336
-		$groupDNs = $this->access->readAttribute($this->getDN(), 'memberOf');
337
-		$this->connection->writeToCache($cacheKey, $groupDNs);
338
-		return $groupDNs;
339
-	}
340
-
341
-	/**
342
-	 * @brief reads the image from LDAP that shall be used as Avatar
343
-	 * @return string data (provided by LDAP) | false
344
-	 */
345
-	public function getAvatarImage() {
346
-		if(!is_null($this->avatarImage)) {
347
-			return $this->avatarImage;
348
-		}
349
-
350
-		$this->avatarImage = false;
351
-		$attributes = array('jpegPhoto', 'thumbnailPhoto');
352
-		foreach($attributes as $attribute) {
353
-			$result = $this->access->readAttribute($this->dn, $attribute);
354
-			if($result !== false && is_array($result) && isset($result[0])) {
355
-				$this->avatarImage = $result[0];
356
-				break;
357
-			}
358
-		}
359
-
360
-		return $this->avatarImage;
361
-	}
362
-
363
-	/**
364
-	 * @brief marks the user as having logged in at least once
365
-	 * @return null
366
-	 */
367
-	public function markLogin() {
368
-		$this->config->setUserValue(
369
-			$this->uid, 'user_ldap', self::USER_PREFKEY_FIRSTLOGIN, 1);
370
-	}
371
-
372
-	/**
373
-	 * @brief marks the time when user features like email have been updated
374
-	 * @return null
375
-	 */
376
-	public function markRefreshTime() {
377
-		$this->config->setUserValue(
378
-			$this->uid, 'user_ldap', self::USER_PREFKEY_LASTREFRESH, time());
379
-	}
380
-
381
-	/**
382
-	 * @brief checks whether user features needs to be updated again by
383
-	 * comparing the difference of time of the last refresh to now with the
384
-	 * desired interval
385
-	 * @return bool
386
-	 */
387
-	private function needsRefresh() {
388
-		$lastChecked = $this->config->getUserValue($this->uid, 'user_ldap',
389
-			self::USER_PREFKEY_LASTREFRESH, 0);
390
-
391
-		if((time() - (int)$lastChecked) < (int)$this->config->getAppValue('user_ldap', 'updateAttributesInterval', 86400)) {
392
-			return false;
393
-		}
394
-		return  true;
395
-	}
396
-
397
-	/**
398
-	 * Stores a key-value pair in relation to this user
399
-	 *
400
-	 * @param string $key
401
-	 * @param string $value
402
-	 */
403
-	private function store($key, $value) {
404
-		$this->config->setUserValue($this->uid, 'user_ldap', $key, $value);
405
-	}
406
-
407
-	/**
408
-	 * Composes the display name and stores it in the database. The final
409
-	 * display name is returned.
410
-	 *
411
-	 * @param string $displayName
412
-	 * @param string $displayName2
413
-	 * @returns string the effective display name
414
-	 */
415
-	public function composeAndStoreDisplayName($displayName, $displayName2 = '') {
416
-		$displayName2 = (string)$displayName2;
417
-		if($displayName2 !== '') {
418
-			$displayName .= ' (' . $displayName2 . ')';
419
-		}
420
-		$this->store('displayName', $displayName);
421
-		return $displayName;
422
-	}
423
-
424
-	/**
425
-	 * Stores the LDAP Username in the Database
426
-	 * @param string $userName
427
-	 */
428
-	public function storeLDAPUserName($userName) {
429
-		$this->store('uid', $userName);
430
-	}
431
-
432
-	/**
433
-	 * @brief checks whether an update method specified by feature was run
434
-	 * already. If not, it will marked like this, because it is expected that
435
-	 * the method will be run, when false is returned.
436
-	 * @param string $feature email | quota | avatar (can be extended)
437
-	 * @return bool
438
-	 */
439
-	private function wasRefreshed($feature) {
440
-		if(isset($this->refreshedFeatures[$feature])) {
441
-			return true;
442
-		}
443
-		$this->refreshedFeatures[$feature] = 1;
444
-		return false;
445
-	}
446
-
447
-	/**
448
-	 * fetches the email from LDAP and stores it as Nextcloud user value
449
-	 * @param string $valueFromLDAP if known, to save an LDAP read request
450
-	 * @return null
451
-	 */
452
-	public function updateEmail($valueFromLDAP = null) {
453
-		if($this->wasRefreshed('email')) {
454
-			return;
455
-		}
456
-		$email = (string)$valueFromLDAP;
457
-		if(is_null($valueFromLDAP)) {
458
-			$emailAttribute = $this->connection->ldapEmailAttribute;
459
-			if ($emailAttribute !== '') {
460
-				$aEmail = $this->access->readAttribute($this->dn, $emailAttribute);
461
-				if(is_array($aEmail) && (count($aEmail) > 0)) {
462
-					$email = (string)$aEmail[0];
463
-				}
464
-			}
465
-		}
466
-		if ($email !== '') {
467
-			$user = $this->userManager->get($this->uid);
468
-			if (!is_null($user)) {
469
-				$currentEmail = (string)$user->getEMailAddress();
470
-				if ($currentEmail !== $email) {
471
-					$user->setEMailAddress($email);
472
-				}
473
-			}
474
-		}
475
-	}
476
-
477
-	/**
478
-	 * Overall process goes as follow:
479
-	 * 1. fetch the quota from LDAP and check if it's parseable with the "verifyQuotaValue" function
480
-	 * 2. if the value can't be fetched, is empty or not parseable, use the default LDAP quota
481
-	 * 3. if the default LDAP quota can't be parsed, use the Nextcloud's default quota (use 'default')
482
-	 * 4. check if the target user exists and set the quota for the user.
483
-	 *
484
-	 * In order to improve performance and prevent an unwanted extra LDAP call, the $valueFromLDAP
485
-	 * parameter can be passed with the value of the attribute. This value will be considered as the
486
-	 * quota for the user coming from the LDAP server (step 1 of the process) It can be useful to
487
-	 * fetch all the user's attributes in one call and use the fetched values in this function.
488
-	 * The expected value for that parameter is a string describing the quota for the user. Valid
489
-	 * values are 'none' (unlimited), 'default' (the Nextcloud's default quota), '1234' (quota in
490
-	 * bytes), '1234 MB' (quota in MB - check the \OC_Helper::computerFileSize method for more info)
491
-	 *
492
-	 * fetches the quota from LDAP and stores it as Nextcloud user value
493
-	 * @param string $valueFromLDAP the quota attribute's value can be passed,
494
-	 * to save the readAttribute request
495
-	 * @return null
496
-	 */
497
-	public function updateQuota($valueFromLDAP = null) {
498
-		if($this->wasRefreshed('quota')) {
499
-			return;
500
-		}
501
-
502
-		$quotaAttribute = $this->connection->ldapQuotaAttribute;
503
-		$defaultQuota = $this->connection->ldapQuotaDefault;
504
-		if($quotaAttribute === '' && $defaultQuota === '') {
505
-			return;
506
-		}
507
-
508
-		$quota = false;
509
-		if(is_null($valueFromLDAP) && $quotaAttribute !== '') {
510
-			$aQuota = $this->access->readAttribute($this->dn, $quotaAttribute);
511
-			if($aQuota && (count($aQuota) > 0) && $this->verifyQuotaValue($aQuota[0])) {
512
-				$quota = $aQuota[0];
513
-			} else if(is_array($aQuota) && isset($aQuota[0])) {
514
-				$this->log->log('no suitable LDAP quota found for user ' . $this->uid . ': [' . $aQuota[0] . ']', ILogger::DEBUG);
515
-			}
516
-		} else if ($this->verifyQuotaValue($valueFromLDAP)) {
517
-			$quota = $valueFromLDAP;
518
-		} else {
519
-			$this->log->log('no suitable LDAP quota found for user ' . $this->uid . ': [' . $valueFromLDAP . ']', ILogger::DEBUG);
520
-		}
521
-
522
-		if ($quota === false && $this->verifyQuotaValue($defaultQuota)) {
523
-			// quota not found using the LDAP attribute (or not parseable). Try the default quota
524
-			$quota = $defaultQuota;
525
-		} else if($quota === false) {
526
-			$this->log->log('no suitable default quota found for user ' . $this->uid . ': [' . $defaultQuota . ']', ILogger::DEBUG);
527
-			return;
528
-		}
529
-
530
-		$targetUser = $this->userManager->get($this->uid);
531
-		if ($targetUser instanceof IUser) {
532
-			$targetUser->setQuota($quota);
533
-		} else {
534
-			$this->log->log('trying to set a quota for user ' . $this->uid . ' but the user is missing', ILogger::INFO);
535
-		}
536
-	}
537
-
538
-	private function verifyQuotaValue($quotaValue) {
539
-		return $quotaValue === 'none' || $quotaValue === 'default' || \OC_Helper::computerFileSize($quotaValue) !== false;
540
-	}
541
-
542
-	/**
543
-	 * called by a post_login hook to save the avatar picture
544
-	 *
545
-	 * @param array $params
546
-	 */
547
-	public function updateAvatarPostLogin($params) {
548
-		if(isset($params['uid']) && $params['uid'] === $this->getUsername()) {
549
-			$this->updateAvatar();
550
-		}
551
-	}
552
-
553
-	/**
554
-	 * @brief attempts to get an image from LDAP and sets it as Nextcloud avatar
555
-	 * @return bool
556
-	 */
557
-	public function updateAvatar($force = false) {
558
-		if(!$force && $this->wasRefreshed('avatar')) {
559
-			return false;
560
-		}
561
-		$avatarImage = $this->getAvatarImage();
562
-		if($avatarImage === false) {
563
-			//not set, nothing left to do;
564
-			return false;
565
-		}
566
-		if(!$this->image->loadFromBase64(base64_encode($avatarImage))) {
567
-			return false;
568
-		}
569
-		return $this->setOwnCloudAvatar();
570
-	}
571
-
572
-	/**
573
-	 * @brief sets an image as Nextcloud avatar
574
-	 * @return bool
575
-	 */
576
-	private function setOwnCloudAvatar() {
577
-		if(!$this->image->valid()) {
578
-			$this->log->log('jpegPhoto data invalid for '.$this->dn, ILogger::ERROR);
579
-			return false;
580
-		}
581
-		//make sure it is a square and not bigger than 128x128
582
-		$size = min(array($this->image->width(), $this->image->height(), 128));
583
-		if(!$this->image->centerCrop($size)) {
584
-			$this->log->log('croping image for avatar failed for '.$this->dn, ILogger::ERROR);
585
-			return false;
586
-		}
587
-
588
-		if(!$this->fs->isLoaded()) {
589
-			$this->fs->setup($this->uid);
590
-		}
591
-
592
-		try {
593
-			$avatar = $this->avatarManager->getAvatar($this->uid);
594
-			$avatar->set($this->image);
595
-			return true;
596
-		} catch (\Exception $e) {
597
-			\OC::$server->getLogger()->logException($e, [
598
-				'message' => 'Could not set avatar for ' . $this->dn,
599
-				'level' => ILogger::INFO,
600
-				'app' => 'user_ldap',
601
-			]);
602
-		}
603
-		return false;
604
-	}
605
-
606
-	/**
607
-	 * called by a post_login hook to handle password expiry
608
-	 *
609
-	 * @param array $params
610
-	 */
611
-	public function handlePasswordExpiry($params) {
612
-		$ppolicyDN = $this->connection->ldapDefaultPPolicyDN;
613
-		if (empty($ppolicyDN) || ((int)$this->connection->turnOnPasswordChange !== 1)) {
614
-			return;//password expiry handling disabled
615
-		}
616
-		$uid = $params['uid'];
617
-		if(isset($uid) && $uid === $this->getUsername()) {
618
-			//retrieve relevant user attributes
619
-			$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!", ILogger::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", ILogger::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
+        \OCP\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 = (string)$ldapEntry[$attr][0];
199
+        }
200
+        $attr = strtolower($this->connection->ldapUserDisplayName2);
201
+        if(isset($ldapEntry[$attr])) {
202
+            $displayName2 = (string)$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
+        $attrs = array('jpegphoto', 'thumbnailphoto');
249
+        foreach ($attrs as $attr)  {
250
+            if(isset($ldapEntry[$attr])) {
251
+                $this->avatarImage = $ldapEntry[$attr][0];
252
+                // the call to the method that saves the avatar in the file
253
+                // system must be postponed after the login. It is to ensure
254
+                // external mounts are mounted properly (e.g. with login
255
+                // credentials from the session).
256
+                \OCP\Util::connectHook('OC_User', 'post_login', $this, 'updateAvatarPostLogin');
257
+                break;
258
+            }
259
+        }
260
+    }
261
+
262
+    /**
263
+     * @brief returns the LDAP DN of the user
264
+     * @return string
265
+     */
266
+    public function getDN() {
267
+        return $this->dn;
268
+    }
269
+
270
+    /**
271
+     * @brief returns the Nextcloud internal username of the user
272
+     * @return string
273
+     */
274
+    public function getUsername() {
275
+        return $this->uid;
276
+    }
277
+
278
+    /**
279
+     * returns the home directory of the user if specified by LDAP settings
280
+     * @param string $valueFromLDAP
281
+     * @return bool|string
282
+     * @throws \Exception
283
+     */
284
+    public function getHomePath($valueFromLDAP = null) {
285
+        $path = (string)$valueFromLDAP;
286
+        $attr = null;
287
+
288
+        if (is_null($valueFromLDAP)
289
+           && strpos($this->access->connection->homeFolderNamingRule, 'attr:') === 0
290
+           && $this->access->connection->homeFolderNamingRule !== 'attr:')
291
+        {
292
+            $attr = substr($this->access->connection->homeFolderNamingRule, strlen('attr:'));
293
+            $homedir = $this->access->readAttribute(
294
+                $this->access->username2dn($this->getUsername()), $attr);
295
+            if ($homedir && isset($homedir[0])) {
296
+                $path = $homedir[0];
297
+            }
298
+        }
299
+
300
+        if ($path !== '') {
301
+            //if attribute's value is an absolute path take this, otherwise append it to data dir
302
+            //check for / at the beginning or pattern c:\ resp. c:/
303
+            if(   '/' !== $path[0]
304
+               && !(3 < strlen($path) && ctype_alpha($path[0])
305
+                   && $path[1] === ':' && ('\\' === $path[2] || '/' === $path[2]))
306
+            ) {
307
+                $path = $this->config->getSystemValue('datadirectory',
308
+                        \OC::$SERVERROOT.'/data' ) . '/' . $path;
309
+            }
310
+            //we need it to store it in the DB as well in case a user gets
311
+            //deleted so we can clean up afterwards
312
+            $this->config->setUserValue(
313
+                $this->getUsername(), 'user_ldap', 'homePath', $path
314
+            );
315
+            return $path;
316
+        }
317
+
318
+        if(    !is_null($attr)
319
+            && $this->config->getAppValue('user_ldap', 'enforce_home_folder_naming_rule', true)
320
+        ) {
321
+            // a naming rule attribute is defined, but it doesn't exist for that LDAP user
322
+            throw new \Exception('Home dir attribute can\'t be read from LDAP for uid: ' . $this->getUsername());
323
+        }
324
+
325
+        //false will apply default behaviour as defined and done by OC_User
326
+        $this->config->setUserValue($this->getUsername(), 'user_ldap', 'homePath', '');
327
+        return false;
328
+    }
329
+
330
+    public function getMemberOfGroups() {
331
+        $cacheKey = 'getMemberOf'.$this->getUsername();
332
+        $memberOfGroups = $this->connection->getFromCache($cacheKey);
333
+        if(!is_null($memberOfGroups)) {
334
+            return $memberOfGroups;
335
+        }
336
+        $groupDNs = $this->access->readAttribute($this->getDN(), 'memberOf');
337
+        $this->connection->writeToCache($cacheKey, $groupDNs);
338
+        return $groupDNs;
339
+    }
340
+
341
+    /**
342
+     * @brief reads the image from LDAP that shall be used as Avatar
343
+     * @return string data (provided by LDAP) | false
344
+     */
345
+    public function getAvatarImage() {
346
+        if(!is_null($this->avatarImage)) {
347
+            return $this->avatarImage;
348
+        }
349
+
350
+        $this->avatarImage = false;
351
+        $attributes = array('jpegPhoto', 'thumbnailPhoto');
352
+        foreach($attributes as $attribute) {
353
+            $result = $this->access->readAttribute($this->dn, $attribute);
354
+            if($result !== false && is_array($result) && isset($result[0])) {
355
+                $this->avatarImage = $result[0];
356
+                break;
357
+            }
358
+        }
359
+
360
+        return $this->avatarImage;
361
+    }
362
+
363
+    /**
364
+     * @brief marks the user as having logged in at least once
365
+     * @return null
366
+     */
367
+    public function markLogin() {
368
+        $this->config->setUserValue(
369
+            $this->uid, 'user_ldap', self::USER_PREFKEY_FIRSTLOGIN, 1);
370
+    }
371
+
372
+    /**
373
+     * @brief marks the time when user features like email have been updated
374
+     * @return null
375
+     */
376
+    public function markRefreshTime() {
377
+        $this->config->setUserValue(
378
+            $this->uid, 'user_ldap', self::USER_PREFKEY_LASTREFRESH, time());
379
+    }
380
+
381
+    /**
382
+     * @brief checks whether user features needs to be updated again by
383
+     * comparing the difference of time of the last refresh to now with the
384
+     * desired interval
385
+     * @return bool
386
+     */
387
+    private function needsRefresh() {
388
+        $lastChecked = $this->config->getUserValue($this->uid, 'user_ldap',
389
+            self::USER_PREFKEY_LASTREFRESH, 0);
390
+
391
+        if((time() - (int)$lastChecked) < (int)$this->config->getAppValue('user_ldap', 'updateAttributesInterval', 86400)) {
392
+            return false;
393
+        }
394
+        return  true;
395
+    }
396
+
397
+    /**
398
+     * Stores a key-value pair in relation to this user
399
+     *
400
+     * @param string $key
401
+     * @param string $value
402
+     */
403
+    private function store($key, $value) {
404
+        $this->config->setUserValue($this->uid, 'user_ldap', $key, $value);
405
+    }
406
+
407
+    /**
408
+     * Composes the display name and stores it in the database. The final
409
+     * display name is returned.
410
+     *
411
+     * @param string $displayName
412
+     * @param string $displayName2
413
+     * @returns string the effective display name
414
+     */
415
+    public function composeAndStoreDisplayName($displayName, $displayName2 = '') {
416
+        $displayName2 = (string)$displayName2;
417
+        if($displayName2 !== '') {
418
+            $displayName .= ' (' . $displayName2 . ')';
419
+        }
420
+        $this->store('displayName', $displayName);
421
+        return $displayName;
422
+    }
423
+
424
+    /**
425
+     * Stores the LDAP Username in the Database
426
+     * @param string $userName
427
+     */
428
+    public function storeLDAPUserName($userName) {
429
+        $this->store('uid', $userName);
430
+    }
431
+
432
+    /**
433
+     * @brief checks whether an update method specified by feature was run
434
+     * already. If not, it will marked like this, because it is expected that
435
+     * the method will be run, when false is returned.
436
+     * @param string $feature email | quota | avatar (can be extended)
437
+     * @return bool
438
+     */
439
+    private function wasRefreshed($feature) {
440
+        if(isset($this->refreshedFeatures[$feature])) {
441
+            return true;
442
+        }
443
+        $this->refreshedFeatures[$feature] = 1;
444
+        return false;
445
+    }
446
+
447
+    /**
448
+     * fetches the email from LDAP and stores it as Nextcloud user value
449
+     * @param string $valueFromLDAP if known, to save an LDAP read request
450
+     * @return null
451
+     */
452
+    public function updateEmail($valueFromLDAP = null) {
453
+        if($this->wasRefreshed('email')) {
454
+            return;
455
+        }
456
+        $email = (string)$valueFromLDAP;
457
+        if(is_null($valueFromLDAP)) {
458
+            $emailAttribute = $this->connection->ldapEmailAttribute;
459
+            if ($emailAttribute !== '') {
460
+                $aEmail = $this->access->readAttribute($this->dn, $emailAttribute);
461
+                if(is_array($aEmail) && (count($aEmail) > 0)) {
462
+                    $email = (string)$aEmail[0];
463
+                }
464
+            }
465
+        }
466
+        if ($email !== '') {
467
+            $user = $this->userManager->get($this->uid);
468
+            if (!is_null($user)) {
469
+                $currentEmail = (string)$user->getEMailAddress();
470
+                if ($currentEmail !== $email) {
471
+                    $user->setEMailAddress($email);
472
+                }
473
+            }
474
+        }
475
+    }
476
+
477
+    /**
478
+     * Overall process goes as follow:
479
+     * 1. fetch the quota from LDAP and check if it's parseable with the "verifyQuotaValue" function
480
+     * 2. if the value can't be fetched, is empty or not parseable, use the default LDAP quota
481
+     * 3. if the default LDAP quota can't be parsed, use the Nextcloud's default quota (use 'default')
482
+     * 4. check if the target user exists and set the quota for the user.
483
+     *
484
+     * In order to improve performance and prevent an unwanted extra LDAP call, the $valueFromLDAP
485
+     * parameter can be passed with the value of the attribute. This value will be considered as the
486
+     * quota for the user coming from the LDAP server (step 1 of the process) It can be useful to
487
+     * fetch all the user's attributes in one call and use the fetched values in this function.
488
+     * The expected value for that parameter is a string describing the quota for the user. Valid
489
+     * values are 'none' (unlimited), 'default' (the Nextcloud's default quota), '1234' (quota in
490
+     * bytes), '1234 MB' (quota in MB - check the \OC_Helper::computerFileSize method for more info)
491
+     *
492
+     * fetches the quota from LDAP and stores it as Nextcloud user value
493
+     * @param string $valueFromLDAP the quota attribute's value can be passed,
494
+     * to save the readAttribute request
495
+     * @return null
496
+     */
497
+    public function updateQuota($valueFromLDAP = null) {
498
+        if($this->wasRefreshed('quota')) {
499
+            return;
500
+        }
501
+
502
+        $quotaAttribute = $this->connection->ldapQuotaAttribute;
503
+        $defaultQuota = $this->connection->ldapQuotaDefault;
504
+        if($quotaAttribute === '' && $defaultQuota === '') {
505
+            return;
506
+        }
507
+
508
+        $quota = false;
509
+        if(is_null($valueFromLDAP) && $quotaAttribute !== '') {
510
+            $aQuota = $this->access->readAttribute($this->dn, $quotaAttribute);
511
+            if($aQuota && (count($aQuota) > 0) && $this->verifyQuotaValue($aQuota[0])) {
512
+                $quota = $aQuota[0];
513
+            } else if(is_array($aQuota) && isset($aQuota[0])) {
514
+                $this->log->log('no suitable LDAP quota found for user ' . $this->uid . ': [' . $aQuota[0] . ']', ILogger::DEBUG);
515
+            }
516
+        } else if ($this->verifyQuotaValue($valueFromLDAP)) {
517
+            $quota = $valueFromLDAP;
518
+        } else {
519
+            $this->log->log('no suitable LDAP quota found for user ' . $this->uid . ': [' . $valueFromLDAP . ']', ILogger::DEBUG);
520
+        }
521
+
522
+        if ($quota === false && $this->verifyQuotaValue($defaultQuota)) {
523
+            // quota not found using the LDAP attribute (or not parseable). Try the default quota
524
+            $quota = $defaultQuota;
525
+        } else if($quota === false) {
526
+            $this->log->log('no suitable default quota found for user ' . $this->uid . ': [' . $defaultQuota . ']', ILogger::DEBUG);
527
+            return;
528
+        }
529
+
530
+        $targetUser = $this->userManager->get($this->uid);
531
+        if ($targetUser instanceof IUser) {
532
+            $targetUser->setQuota($quota);
533
+        } else {
534
+            $this->log->log('trying to set a quota for user ' . $this->uid . ' but the user is missing', ILogger::INFO);
535
+        }
536
+    }
537
+
538
+    private function verifyQuotaValue($quotaValue) {
539
+        return $quotaValue === 'none' || $quotaValue === 'default' || \OC_Helper::computerFileSize($quotaValue) !== false;
540
+    }
541
+
542
+    /**
543
+     * called by a post_login hook to save the avatar picture
544
+     *
545
+     * @param array $params
546
+     */
547
+    public function updateAvatarPostLogin($params) {
548
+        if(isset($params['uid']) && $params['uid'] === $this->getUsername()) {
549
+            $this->updateAvatar();
550
+        }
551
+    }
552
+
553
+    /**
554
+     * @brief attempts to get an image from LDAP and sets it as Nextcloud avatar
555
+     * @return bool
556
+     */
557
+    public function updateAvatar($force = false) {
558
+        if(!$force && $this->wasRefreshed('avatar')) {
559
+            return false;
560
+        }
561
+        $avatarImage = $this->getAvatarImage();
562
+        if($avatarImage === false) {
563
+            //not set, nothing left to do;
564
+            return false;
565
+        }
566
+        if(!$this->image->loadFromBase64(base64_encode($avatarImage))) {
567
+            return false;
568
+        }
569
+        return $this->setOwnCloudAvatar();
570
+    }
571
+
572
+    /**
573
+     * @brief sets an image as Nextcloud avatar
574
+     * @return bool
575
+     */
576
+    private function setOwnCloudAvatar() {
577
+        if(!$this->image->valid()) {
578
+            $this->log->log('jpegPhoto data invalid for '.$this->dn, ILogger::ERROR);
579
+            return false;
580
+        }
581
+        //make sure it is a square and not bigger than 128x128
582
+        $size = min(array($this->image->width(), $this->image->height(), 128));
583
+        if(!$this->image->centerCrop($size)) {
584
+            $this->log->log('croping image for avatar failed for '.$this->dn, ILogger::ERROR);
585
+            return false;
586
+        }
587
+
588
+        if(!$this->fs->isLoaded()) {
589
+            $this->fs->setup($this->uid);
590
+        }
591
+
592
+        try {
593
+            $avatar = $this->avatarManager->getAvatar($this->uid);
594
+            $avatar->set($this->image);
595
+            return true;
596
+        } catch (\Exception $e) {
597
+            \OC::$server->getLogger()->logException($e, [
598
+                'message' => 'Could not set avatar for ' . $this->dn,
599
+                'level' => ILogger::INFO,
600
+                'app' => 'user_ldap',
601
+            ]);
602
+        }
603
+        return false;
604
+    }
605
+
606
+    /**
607
+     * called by a post_login hook to handle password expiry
608
+     *
609
+     * @param array $params
610
+     */
611
+    public function handlePasswordExpiry($params) {
612
+        $ppolicyDN = $this->connection->ldapDefaultPPolicyDN;
613
+        if (empty($ppolicyDN) || ((int)$this->connection->turnOnPasswordChange !== 1)) {
614
+            return;//password expiry handling disabled
615
+        }
616
+        $uid = $params['uid'];
617
+        if(isset($uid) && $uid === $this->getUsername()) {
618
+            //retrieve relevant user attributes
619
+            $result = $this->access->search('objectclass=*', array($this->dn), ['pwdpolicysubentry', 'pwdgraceusetime', 'pwdreset', 'pwdchangedtime']);
620 620
 			
621
-			if(array_key_exists('pwdpolicysubentry', $result[0])) {
622
-				$pwdPolicySubentry = $result[0]['pwdpolicysubentry'];
623
-				if($pwdPolicySubentry && (count($pwdPolicySubentry) > 0)){
624
-					$ppolicyDN = $pwdPolicySubentry[0];//custom ppolicy DN
625
-				}
626
-			}
621
+            if(array_key_exists('pwdpolicysubentry', $result[0])) {
622
+                $pwdPolicySubentry = $result[0]['pwdpolicysubentry'];
623
+                if($pwdPolicySubentry && (count($pwdPolicySubentry) > 0)){
624
+                    $ppolicyDN = $pwdPolicySubentry[0];//custom ppolicy DN
625
+                }
626
+            }
627 627
 			
628
-			$pwdGraceUseTime = array_key_exists('pwdgraceusetime', $result[0]) ? $result[0]['pwdgraceusetime'] : null;
629
-			$pwdReset = array_key_exists('pwdreset', $result[0]) ? $result[0]['pwdreset'] : null;
630
-			$pwdChangedTime = array_key_exists('pwdchangedtime', $result[0]) ? $result[0]['pwdchangedtime'] : null;
628
+            $pwdGraceUseTime = array_key_exists('pwdgraceusetime', $result[0]) ? $result[0]['pwdgraceusetime'] : null;
629
+            $pwdReset = array_key_exists('pwdreset', $result[0]) ? $result[0]['pwdreset'] : null;
630
+            $pwdChangedTime = array_key_exists('pwdchangedtime', $result[0]) ? $result[0]['pwdchangedtime'] : null;
631 631
 			
632
-			//retrieve relevant password policy attributes
633
-			$cacheKey = 'ppolicyAttributes' . $ppolicyDN;
634
-			$result = $this->connection->getFromCache($cacheKey);
635
-			if(is_null($result)) {
636
-				$result = $this->access->search('objectclass=*', array($ppolicyDN), ['pwdgraceauthnlimit', 'pwdmaxage', 'pwdexpirewarning']);
637
-				$this->connection->writeToCache($cacheKey, $result);
638
-			}
632
+            //retrieve relevant password policy attributes
633
+            $cacheKey = 'ppolicyAttributes' . $ppolicyDN;
634
+            $result = $this->connection->getFromCache($cacheKey);
635
+            if(is_null($result)) {
636
+                $result = $this->access->search('objectclass=*', array($ppolicyDN), ['pwdgraceauthnlimit', 'pwdmaxage', 'pwdexpirewarning']);
637
+                $this->connection->writeToCache($cacheKey, $result);
638
+            }
639 639
 			
640
-			$pwdGraceAuthNLimit = array_key_exists('pwdgraceauthnlimit', $result[0]) ? $result[0]['pwdgraceauthnlimit'] : null;
641
-			$pwdMaxAge = array_key_exists('pwdmaxage', $result[0]) ? $result[0]['pwdmaxage'] : null;
642
-			$pwdExpireWarning = array_key_exists('pwdexpirewarning', $result[0]) ? $result[0]['pwdexpirewarning'] : null;
640
+            $pwdGraceAuthNLimit = array_key_exists('pwdgraceauthnlimit', $result[0]) ? $result[0]['pwdgraceauthnlimit'] : null;
641
+            $pwdMaxAge = array_key_exists('pwdmaxage', $result[0]) ? $result[0]['pwdmaxage'] : null;
642
+            $pwdExpireWarning = array_key_exists('pwdexpirewarning', $result[0]) ? $result[0]['pwdexpirewarning'] : null;
643 643
 			
644
-			//handle grace login
645
-			$pwdGraceUseTimeCount = count($pwdGraceUseTime);
646
-			if($pwdGraceUseTime && $pwdGraceUseTimeCount > 0) { //was this a grace login?
647
-				if($pwdGraceAuthNLimit 
648
-					&& (count($pwdGraceAuthNLimit) > 0)
649
-					&&($pwdGraceUseTimeCount < (int)$pwdGraceAuthNLimit[0])) { //at least one more grace login available?
650
-					$this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true');
651
-					header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
652
-					'user_ldap.renewPassword.showRenewPasswordForm', array('user' => $uid)));
653
-				} else { //no more grace login available
654
-					header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
655
-					'user_ldap.renewPassword.showLoginFormInvalidPassword', array('user' => $uid)));
656
-				}
657
-				exit();
658
-			}
659
-			//handle pwdReset attribute
660
-			if($pwdReset && (count($pwdReset) > 0) && $pwdReset[0] === 'TRUE') { //user must change his password
661
-				$this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true');
662
-				header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
663
-				'user_ldap.renewPassword.showRenewPasswordForm', array('user' => $uid)));
664
-				exit();
665
-			}
666
-			//handle password expiry warning
667
-			if($pwdChangedTime && (count($pwdChangedTime) > 0)) {
668
-				if($pwdMaxAge && (count($pwdMaxAge) > 0)
669
-					&& $pwdExpireWarning && (count($pwdExpireWarning) > 0)) {
670
-					$pwdMaxAgeInt = (int)$pwdMaxAge[0];
671
-					$pwdExpireWarningInt = (int)$pwdExpireWarning[0];
672
-					if($pwdMaxAgeInt > 0 && $pwdExpireWarningInt > 0){
673
-						$pwdChangedTimeDt = \DateTime::createFromFormat('YmdHisZ', $pwdChangedTime[0]);
674
-						$pwdChangedTimeDt->add(new \DateInterval('PT'.$pwdMaxAgeInt.'S'));
675
-						$currentDateTime = new \DateTime();
676
-						$secondsToExpiry = $pwdChangedTimeDt->getTimestamp() - $currentDateTime->getTimestamp();
677
-						if($secondsToExpiry <= $pwdExpireWarningInt) {
678
-							//remove last password expiry warning if any
679
-							$notification = $this->notificationManager->createNotification();
680
-							$notification->setApp('user_ldap')
681
-								->setUser($uid)
682
-								->setObject('pwd_exp_warn', $uid)
683
-							;
684
-							$this->notificationManager->markProcessed($notification);
685
-							//create new password expiry warning
686
-							$notification = $this->notificationManager->createNotification();
687
-							$notification->setApp('user_ldap')
688
-								->setUser($uid)
689
-								->setDateTime($currentDateTime)
690
-								->setObject('pwd_exp_warn', $uid) 
691
-								->setSubject('pwd_exp_warn_days', [(int) ceil($secondsToExpiry / 60 / 60 / 24)])
692
-							;
693
-							$this->notificationManager->notify($notification);
694
-						}
695
-					}
696
-				}
697
-			}
698
-		}
699
-	}
644
+            //handle grace login
645
+            $pwdGraceUseTimeCount = count($pwdGraceUseTime);
646
+            if($pwdGraceUseTime && $pwdGraceUseTimeCount > 0) { //was this a grace login?
647
+                if($pwdGraceAuthNLimit 
648
+                    && (count($pwdGraceAuthNLimit) > 0)
649
+                    &&($pwdGraceUseTimeCount < (int)$pwdGraceAuthNLimit[0])) { //at least one more grace login available?
650
+                    $this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true');
651
+                    header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
652
+                    'user_ldap.renewPassword.showRenewPasswordForm', array('user' => $uid)));
653
+                } else { //no more grace login available
654
+                    header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
655
+                    'user_ldap.renewPassword.showLoginFormInvalidPassword', array('user' => $uid)));
656
+                }
657
+                exit();
658
+            }
659
+            //handle pwdReset attribute
660
+            if($pwdReset && (count($pwdReset) > 0) && $pwdReset[0] === 'TRUE') { //user must change his password
661
+                $this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true');
662
+                header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
663
+                'user_ldap.renewPassword.showRenewPasswordForm', array('user' => $uid)));
664
+                exit();
665
+            }
666
+            //handle password expiry warning
667
+            if($pwdChangedTime && (count($pwdChangedTime) > 0)) {
668
+                if($pwdMaxAge && (count($pwdMaxAge) > 0)
669
+                    && $pwdExpireWarning && (count($pwdExpireWarning) > 0)) {
670
+                    $pwdMaxAgeInt = (int)$pwdMaxAge[0];
671
+                    $pwdExpireWarningInt = (int)$pwdExpireWarning[0];
672
+                    if($pwdMaxAgeInt > 0 && $pwdExpireWarningInt > 0){
673
+                        $pwdChangedTimeDt = \DateTime::createFromFormat('YmdHisZ', $pwdChangedTime[0]);
674
+                        $pwdChangedTimeDt->add(new \DateInterval('PT'.$pwdMaxAgeInt.'S'));
675
+                        $currentDateTime = new \DateTime();
676
+                        $secondsToExpiry = $pwdChangedTimeDt->getTimestamp() - $currentDateTime->getTimestamp();
677
+                        if($secondsToExpiry <= $pwdExpireWarningInt) {
678
+                            //remove last password expiry warning if any
679
+                            $notification = $this->notificationManager->createNotification();
680
+                            $notification->setApp('user_ldap')
681
+                                ->setUser($uid)
682
+                                ->setObject('pwd_exp_warn', $uid)
683
+                            ;
684
+                            $this->notificationManager->markProcessed($notification);
685
+                            //create new password expiry warning
686
+                            $notification = $this->notificationManager->createNotification();
687
+                            $notification->setApp('user_ldap')
688
+                                ->setUser($uid)
689
+                                ->setDateTime($currentDateTime)
690
+                                ->setObject('pwd_exp_warn', $uid) 
691
+                                ->setSubject('pwd_exp_warn_days', [(int) ceil($secondsToExpiry / 60 / 60 / 24)])
692
+                            ;
693
+                            $this->notificationManager->notify($notification);
694
+                        }
695
+                    }
696
+                }
697
+            }
698
+        }
699
+    }
700 700
 }
Please login to merge, or discard this patch.
Spacing   +72 added lines, -72 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,12 +194,12 @@  discard block
 block discarded – undo
194 194
 		//displayName
195 195
 		$displayName = $displayName2 = '';
196 196
 		$attr = strtolower($this->connection->ldapUserDisplayName);
197
-		if(isset($ldapEntry[$attr])) {
198
-			$displayName = (string)$ldapEntry[$attr][0];
197
+		if (isset($ldapEntry[$attr])) {
198
+			$displayName = (string) $ldapEntry[$attr][0];
199 199
 		}
200 200
 		$attr = strtolower($this->connection->ldapUserDisplayName2);
201
-		if(isset($ldapEntry[$attr])) {
202
-			$displayName2 = (string)$ldapEntry[$attr][0];
201
+		if (isset($ldapEntry[$attr])) {
202
+			$displayName2 = (string) $ldapEntry[$attr][0];
203 203
 		}
204 204
 		if ($displayName !== '') {
205 205
 			$this->composeAndStoreDisplayName($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,15 +239,15 @@  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);
246 246
 
247 247
 		//Avatar
248 248
 		$attrs = array('jpegphoto', 'thumbnailphoto');
249
-		foreach ($attrs as $attr)  {
250
-			if(isset($ldapEntry[$attr])) {
249
+		foreach ($attrs as $attr) {
250
+			if (isset($ldapEntry[$attr])) {
251 251
 				$this->avatarImage = $ldapEntry[$attr][0];
252 252
 				// the call to the method that saves the avatar in the file
253 253
 				// system must be postponed after the login. It is to ensure
@@ -282,7 +282,7 @@  discard block
 block discarded – undo
282 282
 	 * @throws \Exception
283 283
 	 */
284 284
 	public function getHomePath($valueFromLDAP = null) {
285
-		$path = (string)$valueFromLDAP;
285
+		$path = (string) $valueFromLDAP;
286 286
 		$attr = null;
287 287
 
288 288
 		if (is_null($valueFromLDAP)
@@ -300,12 +300,12 @@  discard block
 block discarded – undo
300 300
 		if ($path !== '') {
301 301
 			//if attribute's value is an absolute path take this, otherwise append it to data dir
302 302
 			//check for / at the beginning or pattern c:\ resp. c:/
303
-			if(   '/' !== $path[0]
303
+			if ('/' !== $path[0]
304 304
 			   && !(3 < strlen($path) && ctype_alpha($path[0])
305 305
 			       && $path[1] === ':' && ('\\' === $path[2] || '/' === $path[2]))
306 306
 			) {
307 307
 				$path = $this->config->getSystemValue('datadirectory',
308
-						\OC::$SERVERROOT.'/data' ) . '/' . $path;
308
+						\OC::$SERVERROOT.'/data').'/'.$path;
309 309
 			}
310 310
 			//we need it to store it in the DB as well in case a user gets
311 311
 			//deleted so we can clean up afterwards
@@ -315,11 +315,11 @@  discard block
 block discarded – undo
315 315
 			return $path;
316 316
 		}
317 317
 
318
-		if(    !is_null($attr)
318
+		if (!is_null($attr)
319 319
 			&& $this->config->getAppValue('user_ldap', 'enforce_home_folder_naming_rule', true)
320 320
 		) {
321 321
 			// a naming rule attribute is defined, but it doesn't exist for that LDAP user
322
-			throw new \Exception('Home dir attribute can\'t be read from LDAP for uid: ' . $this->getUsername());
322
+			throw new \Exception('Home dir attribute can\'t be read from LDAP for uid: '.$this->getUsername());
323 323
 		}
324 324
 
325 325
 		//false will apply default behaviour as defined and done by OC_User
@@ -330,7 +330,7 @@  discard block
 block discarded – undo
330 330
 	public function getMemberOfGroups() {
331 331
 		$cacheKey = 'getMemberOf'.$this->getUsername();
332 332
 		$memberOfGroups = $this->connection->getFromCache($cacheKey);
333
-		if(!is_null($memberOfGroups)) {
333
+		if (!is_null($memberOfGroups)) {
334 334
 			return $memberOfGroups;
335 335
 		}
336 336
 		$groupDNs = $this->access->readAttribute($this->getDN(), 'memberOf');
@@ -343,15 +343,15 @@  discard block
 block discarded – undo
343 343
 	 * @return string data (provided by LDAP) | false
344 344
 	 */
345 345
 	public function getAvatarImage() {
346
-		if(!is_null($this->avatarImage)) {
346
+		if (!is_null($this->avatarImage)) {
347 347
 			return $this->avatarImage;
348 348
 		}
349 349
 
350 350
 		$this->avatarImage = false;
351 351
 		$attributes = array('jpegPhoto', 'thumbnailPhoto');
352
-		foreach($attributes as $attribute) {
352
+		foreach ($attributes as $attribute) {
353 353
 			$result = $this->access->readAttribute($this->dn, $attribute);
354
-			if($result !== false && is_array($result) && isset($result[0])) {
354
+			if ($result !== false && is_array($result) && isset($result[0])) {
355 355
 				$this->avatarImage = $result[0];
356 356
 				break;
357 357
 			}
@@ -388,7 +388,7 @@  discard block
 block discarded – undo
388 388
 		$lastChecked = $this->config->getUserValue($this->uid, 'user_ldap',
389 389
 			self::USER_PREFKEY_LASTREFRESH, 0);
390 390
 
391
-		if((time() - (int)$lastChecked) < (int)$this->config->getAppValue('user_ldap', 'updateAttributesInterval', 86400)) {
391
+		if ((time() - (int) $lastChecked) < (int) $this->config->getAppValue('user_ldap', 'updateAttributesInterval', 86400)) {
392 392
 			return false;
393 393
 		}
394 394
 		return  true;
@@ -413,9 +413,9 @@  discard block
 block discarded – undo
413 413
 	 * @returns string the effective display name
414 414
 	 */
415 415
 	public function composeAndStoreDisplayName($displayName, $displayName2 = '') {
416
-		$displayName2 = (string)$displayName2;
417
-		if($displayName2 !== '') {
418
-			$displayName .= ' (' . $displayName2 . ')';
416
+		$displayName2 = (string) $displayName2;
417
+		if ($displayName2 !== '') {
418
+			$displayName .= ' ('.$displayName2.')';
419 419
 		}
420 420
 		$this->store('displayName', $displayName);
421 421
 		return $displayName;
@@ -437,7 +437,7 @@  discard block
 block discarded – undo
437 437
 	 * @return bool
438 438
 	 */
439 439
 	private function wasRefreshed($feature) {
440
-		if(isset($this->refreshedFeatures[$feature])) {
440
+		if (isset($this->refreshedFeatures[$feature])) {
441 441
 			return true;
442 442
 		}
443 443
 		$this->refreshedFeatures[$feature] = 1;
@@ -450,23 +450,23 @@  discard block
 block discarded – undo
450 450
 	 * @return null
451 451
 	 */
452 452
 	public function updateEmail($valueFromLDAP = null) {
453
-		if($this->wasRefreshed('email')) {
453
+		if ($this->wasRefreshed('email')) {
454 454
 			return;
455 455
 		}
456
-		$email = (string)$valueFromLDAP;
457
-		if(is_null($valueFromLDAP)) {
456
+		$email = (string) $valueFromLDAP;
457
+		if (is_null($valueFromLDAP)) {
458 458
 			$emailAttribute = $this->connection->ldapEmailAttribute;
459 459
 			if ($emailAttribute !== '') {
460 460
 				$aEmail = $this->access->readAttribute($this->dn, $emailAttribute);
461
-				if(is_array($aEmail) && (count($aEmail) > 0)) {
462
-					$email = (string)$aEmail[0];
461
+				if (is_array($aEmail) && (count($aEmail) > 0)) {
462
+					$email = (string) $aEmail[0];
463 463
 				}
464 464
 			}
465 465
 		}
466 466
 		if ($email !== '') {
467 467
 			$user = $this->userManager->get($this->uid);
468 468
 			if (!is_null($user)) {
469
-				$currentEmail = (string)$user->getEMailAddress();
469
+				$currentEmail = (string) $user->getEMailAddress();
470 470
 				if ($currentEmail !== $email) {
471 471
 					$user->setEMailAddress($email);
472 472
 				}
@@ -495,35 +495,35 @@  discard block
 block discarded – undo
495 495
 	 * @return null
496 496
 	 */
497 497
 	public function updateQuota($valueFromLDAP = null) {
498
-		if($this->wasRefreshed('quota')) {
498
+		if ($this->wasRefreshed('quota')) {
499 499
 			return;
500 500
 		}
501 501
 
502 502
 		$quotaAttribute = $this->connection->ldapQuotaAttribute;
503 503
 		$defaultQuota = $this->connection->ldapQuotaDefault;
504
-		if($quotaAttribute === '' && $defaultQuota === '') {
504
+		if ($quotaAttribute === '' && $defaultQuota === '') {
505 505
 			return;
506 506
 		}
507 507
 
508 508
 		$quota = false;
509
-		if(is_null($valueFromLDAP) && $quotaAttribute !== '') {
509
+		if (is_null($valueFromLDAP) && $quotaAttribute !== '') {
510 510
 			$aQuota = $this->access->readAttribute($this->dn, $quotaAttribute);
511
-			if($aQuota && (count($aQuota) > 0) && $this->verifyQuotaValue($aQuota[0])) {
511
+			if ($aQuota && (count($aQuota) > 0) && $this->verifyQuotaValue($aQuota[0])) {
512 512
 				$quota = $aQuota[0];
513
-			} else if(is_array($aQuota) && isset($aQuota[0])) {
514
-				$this->log->log('no suitable LDAP quota found for user ' . $this->uid . ': [' . $aQuota[0] . ']', ILogger::DEBUG);
513
+			} else if (is_array($aQuota) && isset($aQuota[0])) {
514
+				$this->log->log('no suitable LDAP quota found for user '.$this->uid.': ['.$aQuota[0].']', ILogger::DEBUG);
515 515
 			}
516 516
 		} else if ($this->verifyQuotaValue($valueFromLDAP)) {
517 517
 			$quota = $valueFromLDAP;
518 518
 		} else {
519
-			$this->log->log('no suitable LDAP quota found for user ' . $this->uid . ': [' . $valueFromLDAP . ']', ILogger::DEBUG);
519
+			$this->log->log('no suitable LDAP quota found for user '.$this->uid.': ['.$valueFromLDAP.']', ILogger::DEBUG);
520 520
 		}
521 521
 
522 522
 		if ($quota === false && $this->verifyQuotaValue($defaultQuota)) {
523 523
 			// quota not found using the LDAP attribute (or not parseable). Try the default quota
524 524
 			$quota = $defaultQuota;
525
-		} else if($quota === false) {
526
-			$this->log->log('no suitable default quota found for user ' . $this->uid . ': [' . $defaultQuota . ']', ILogger::DEBUG);
525
+		} else if ($quota === false) {
526
+			$this->log->log('no suitable default quota found for user '.$this->uid.': ['.$defaultQuota.']', ILogger::DEBUG);
527 527
 			return;
528 528
 		}
529 529
 
@@ -531,7 +531,7 @@  discard block
 block discarded – undo
531 531
 		if ($targetUser instanceof IUser) {
532 532
 			$targetUser->setQuota($quota);
533 533
 		} else {
534
-			$this->log->log('trying to set a quota for user ' . $this->uid . ' but the user is missing', ILogger::INFO);
534
+			$this->log->log('trying to set a quota for user '.$this->uid.' but the user is missing', ILogger::INFO);
535 535
 		}
536 536
 	}
537 537
 
@@ -545,7 +545,7 @@  discard block
 block discarded – undo
545 545
 	 * @param array $params
546 546
 	 */
547 547
 	public function updateAvatarPostLogin($params) {
548
-		if(isset($params['uid']) && $params['uid'] === $this->getUsername()) {
548
+		if (isset($params['uid']) && $params['uid'] === $this->getUsername()) {
549 549
 			$this->updateAvatar();
550 550
 		}
551 551
 	}
@@ -555,15 +555,15 @@  discard block
 block discarded – undo
555 555
 	 * @return bool
556 556
 	 */
557 557
 	public function updateAvatar($force = false) {
558
-		if(!$force && $this->wasRefreshed('avatar')) {
558
+		if (!$force && $this->wasRefreshed('avatar')) {
559 559
 			return false;
560 560
 		}
561 561
 		$avatarImage = $this->getAvatarImage();
562
-		if($avatarImage === false) {
562
+		if ($avatarImage === false) {
563 563
 			//not set, nothing left to do;
564 564
 			return false;
565 565
 		}
566
-		if(!$this->image->loadFromBase64(base64_encode($avatarImage))) {
566
+		if (!$this->image->loadFromBase64(base64_encode($avatarImage))) {
567 567
 			return false;
568 568
 		}
569 569
 		return $this->setOwnCloudAvatar();
@@ -574,18 +574,18 @@  discard block
 block discarded – undo
574 574
 	 * @return bool
575 575
 	 */
576 576
 	private function setOwnCloudAvatar() {
577
-		if(!$this->image->valid()) {
577
+		if (!$this->image->valid()) {
578 578
 			$this->log->log('jpegPhoto data invalid for '.$this->dn, ILogger::ERROR);
579 579
 			return false;
580 580
 		}
581 581
 		//make sure it is a square and not bigger than 128x128
582 582
 		$size = min(array($this->image->width(), $this->image->height(), 128));
583
-		if(!$this->image->centerCrop($size)) {
583
+		if (!$this->image->centerCrop($size)) {
584 584
 			$this->log->log('croping image for avatar failed for '.$this->dn, ILogger::ERROR);
585 585
 			return false;
586 586
 		}
587 587
 
588
-		if(!$this->fs->isLoaded()) {
588
+		if (!$this->fs->isLoaded()) {
589 589
 			$this->fs->setup($this->uid);
590 590
 		}
591 591
 
@@ -595,7 +595,7 @@  discard block
 block discarded – undo
595 595
 			return true;
596 596
 		} catch (\Exception $e) {
597 597
 			\OC::$server->getLogger()->logException($e, [
598
-				'message' => 'Could not set avatar for ' . $this->dn,
598
+				'message' => 'Could not set avatar for '.$this->dn,
599 599
 				'level' => ILogger::INFO,
600 600
 				'app' => 'user_ldap',
601 601
 			]);
@@ -610,18 +610,18 @@  discard block
 block discarded – undo
610 610
 	 */
611 611
 	public function handlePasswordExpiry($params) {
612 612
 		$ppolicyDN = $this->connection->ldapDefaultPPolicyDN;
613
-		if (empty($ppolicyDN) || ((int)$this->connection->turnOnPasswordChange !== 1)) {
614
-			return;//password expiry handling disabled
613
+		if (empty($ppolicyDN) || ((int) $this->connection->turnOnPasswordChange !== 1)) {
614
+			return; //password expiry handling disabled
615 615
 		}
616 616
 		$uid = $params['uid'];
617
-		if(isset($uid) && $uid === $this->getUsername()) {
617
+		if (isset($uid) && $uid === $this->getUsername()) {
618 618
 			//retrieve relevant user attributes
619 619
 			$result = $this->access->search('objectclass=*', array($this->dn), ['pwdpolicysubentry', 'pwdgraceusetime', 'pwdreset', 'pwdchangedtime']);
620 620
 			
621
-			if(array_key_exists('pwdpolicysubentry', $result[0])) {
621
+			if (array_key_exists('pwdpolicysubentry', $result[0])) {
622 622
 				$pwdPolicySubentry = $result[0]['pwdpolicysubentry'];
623
-				if($pwdPolicySubentry && (count($pwdPolicySubentry) > 0)){
624
-					$ppolicyDN = $pwdPolicySubentry[0];//custom ppolicy DN
623
+				if ($pwdPolicySubentry && (count($pwdPolicySubentry) > 0)) {
624
+					$ppolicyDN = $pwdPolicySubentry[0]; //custom ppolicy DN
625 625
 				}
626 626
 			}
627 627
 			
@@ -630,9 +630,9 @@  discard block
 block discarded – undo
630 630
 			$pwdChangedTime = array_key_exists('pwdchangedtime', $result[0]) ? $result[0]['pwdchangedtime'] : null;
631 631
 			
632 632
 			//retrieve relevant password policy attributes
633
-			$cacheKey = 'ppolicyAttributes' . $ppolicyDN;
633
+			$cacheKey = 'ppolicyAttributes'.$ppolicyDN;
634 634
 			$result = $this->connection->getFromCache($cacheKey);
635
-			if(is_null($result)) {
635
+			if (is_null($result)) {
636 636
 				$result = $this->access->search('objectclass=*', array($ppolicyDN), ['pwdgraceauthnlimit', 'pwdmaxage', 'pwdexpirewarning']);
637 637
 				$this->connection->writeToCache($cacheKey, $result);
638 638
 			}
@@ -643,10 +643,10 @@  discard block
 block discarded – undo
643 643
 			
644 644
 			//handle grace login
645 645
 			$pwdGraceUseTimeCount = count($pwdGraceUseTime);
646
-			if($pwdGraceUseTime && $pwdGraceUseTimeCount > 0) { //was this a grace login?
647
-				if($pwdGraceAuthNLimit 
646
+			if ($pwdGraceUseTime && $pwdGraceUseTimeCount > 0) { //was this a grace login?
647
+				if ($pwdGraceAuthNLimit 
648 648
 					&& (count($pwdGraceAuthNLimit) > 0)
649
-					&&($pwdGraceUseTimeCount < (int)$pwdGraceAuthNLimit[0])) { //at least one more grace login available?
649
+					&&($pwdGraceUseTimeCount < (int) $pwdGraceAuthNLimit[0])) { //at least one more grace login available?
650 650
 					$this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true');
651 651
 					header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
652 652
 					'user_ldap.renewPassword.showRenewPasswordForm', array('user' => $uid)));
@@ -657,24 +657,24 @@  discard block
 block discarded – undo
657 657
 				exit();
658 658
 			}
659 659
 			//handle pwdReset attribute
660
-			if($pwdReset && (count($pwdReset) > 0) && $pwdReset[0] === 'TRUE') { //user must change his password
660
+			if ($pwdReset && (count($pwdReset) > 0) && $pwdReset[0] === 'TRUE') { //user must change his password
661 661
 				$this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true');
662 662
 				header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
663 663
 				'user_ldap.renewPassword.showRenewPasswordForm', array('user' => $uid)));
664 664
 				exit();
665 665
 			}
666 666
 			//handle password expiry warning
667
-			if($pwdChangedTime && (count($pwdChangedTime) > 0)) {
668
-				if($pwdMaxAge && (count($pwdMaxAge) > 0)
667
+			if ($pwdChangedTime && (count($pwdChangedTime) > 0)) {
668
+				if ($pwdMaxAge && (count($pwdMaxAge) > 0)
669 669
 					&& $pwdExpireWarning && (count($pwdExpireWarning) > 0)) {
670
-					$pwdMaxAgeInt = (int)$pwdMaxAge[0];
671
-					$pwdExpireWarningInt = (int)$pwdExpireWarning[0];
672
-					if($pwdMaxAgeInt > 0 && $pwdExpireWarningInt > 0){
670
+					$pwdMaxAgeInt = (int) $pwdMaxAge[0];
671
+					$pwdExpireWarningInt = (int) $pwdExpireWarning[0];
672
+					if ($pwdMaxAgeInt > 0 && $pwdExpireWarningInt > 0) {
673 673
 						$pwdChangedTimeDt = \DateTime::createFromFormat('YmdHisZ', $pwdChangedTime[0]);
674 674
 						$pwdChangedTimeDt->add(new \DateInterval('PT'.$pwdMaxAgeInt.'S'));
675 675
 						$currentDateTime = new \DateTime();
676 676
 						$secondsToExpiry = $pwdChangedTimeDt->getTimestamp() - $currentDateTime->getTimestamp();
677
-						if($secondsToExpiry <= $pwdExpireWarningInt) {
677
+						if ($secondsToExpiry <= $pwdExpireWarningInt) {
678 678
 							//remove last password expiry warning if any
679 679
 							$notification = $this->notificationManager->createNotification();
680 680
 							$notification->setApp('user_ldap')
Please login to merge, or discard this patch.