Completed
Pull Request — master (#6678)
by Blizzz
12:19
created
apps/user_ldap/lib/User/User.php 2 patches
Indentation   +642 added lines, -642 removed lines patch added patch discarded remove patch
@@ -43,652 +43,652 @@
 block discarded – undo
43 43
  * represents an LDAP user, gets and holds user-specific information from LDAP
44 44
  */
45 45
 class User {
46
-	/**
47
-	 * @var IUserTools
48
-	 */
49
-	protected $access;
50
-	/**
51
-	 * @var Connection
52
-	 */
53
-	protected $connection;
54
-	/**
55
-	 * @var IConfig
56
-	 */
57
-	protected $config;
58
-	/**
59
-	 * @var FilesystemHelper
60
-	 */
61
-	protected $fs;
62
-	/**
63
-	 * @var Image
64
-	 */
65
-	protected $image;
66
-	/**
67
-	 * @var LogWrapper
68
-	 */
69
-	protected $log;
70
-	/**
71
-	 * @var IAvatarManager
72
-	 */
73
-	protected $avatarManager;
74
-	/**
75
-	 * @var IUserManager
76
-	 */
77
-	protected $userManager;
78
-	/**
79
-	 * @var INotificationManager
80
-	 */
81
-	protected $notificationManager;
82
-	/**
83
-	 * @var string
84
-	 */
85
-	protected $dn;
86
-	/**
87
-	 * @var string
88
-	 */
89
-	protected $uid;
90
-	/**
91
-	 * @var string[]
92
-	 */
93
-	protected $refreshedFeatures = array();
94
-	/**
95
-	 * @var string
96
-	 */
97
-	protected $avatarImage;
98
-
99
-	/**
100
-	 * DB config keys for user preferences
101
-	 */
102
-	const USER_PREFKEY_FIRSTLOGIN  = 'firstLoginAccomplished';
103
-	const USER_PREFKEY_LASTREFRESH = 'lastFeatureRefresh';
104
-
105
-	/**
106
-	 * @brief constructor, make sure the subclasses call this one!
107
-	 * @param string $username the internal username
108
-	 * @param string $dn the LDAP DN
109
-	 * @param IUserTools $access an instance that implements IUserTools for
110
-	 * LDAP interaction
111
-	 * @param IConfig $config
112
-	 * @param FilesystemHelper $fs
113
-	 * @param Image $image any empty instance
114
-	 * @param LogWrapper $log
115
-	 * @param IAvatarManager $avatarManager
116
-	 * @param IUserManager $userManager
117
-	 * @param INotificationManager $notificationManager
118
-	 */
119
-	public function __construct($username, $dn, IUserTools $access,
120
-		IConfig $config, FilesystemHelper $fs, Image $image,
121
-		LogWrapper $log, IAvatarManager $avatarManager, IUserManager $userManager,
122
-		INotificationManager $notificationManager) {
46
+    /**
47
+     * @var IUserTools
48
+     */
49
+    protected $access;
50
+    /**
51
+     * @var Connection
52
+     */
53
+    protected $connection;
54
+    /**
55
+     * @var IConfig
56
+     */
57
+    protected $config;
58
+    /**
59
+     * @var FilesystemHelper
60
+     */
61
+    protected $fs;
62
+    /**
63
+     * @var Image
64
+     */
65
+    protected $image;
66
+    /**
67
+     * @var LogWrapper
68
+     */
69
+    protected $log;
70
+    /**
71
+     * @var IAvatarManager
72
+     */
73
+    protected $avatarManager;
74
+    /**
75
+     * @var IUserManager
76
+     */
77
+    protected $userManager;
78
+    /**
79
+     * @var INotificationManager
80
+     */
81
+    protected $notificationManager;
82
+    /**
83
+     * @var string
84
+     */
85
+    protected $dn;
86
+    /**
87
+     * @var string
88
+     */
89
+    protected $uid;
90
+    /**
91
+     * @var string[]
92
+     */
93
+    protected $refreshedFeatures = array();
94
+    /**
95
+     * @var string
96
+     */
97
+    protected $avatarImage;
98
+
99
+    /**
100
+     * DB config keys for user preferences
101
+     */
102
+    const USER_PREFKEY_FIRSTLOGIN  = 'firstLoginAccomplished';
103
+    const USER_PREFKEY_LASTREFRESH = 'lastFeatureRefresh';
104
+
105
+    /**
106
+     * @brief constructor, make sure the subclasses call this one!
107
+     * @param string $username the internal username
108
+     * @param string $dn the LDAP DN
109
+     * @param IUserTools $access an instance that implements IUserTools for
110
+     * LDAP interaction
111
+     * @param IConfig $config
112
+     * @param FilesystemHelper $fs
113
+     * @param Image $image any empty instance
114
+     * @param LogWrapper $log
115
+     * @param IAvatarManager $avatarManager
116
+     * @param IUserManager $userManager
117
+     * @param INotificationManager $notificationManager
118
+     */
119
+    public function __construct($username, $dn, IUserTools $access,
120
+        IConfig $config, FilesystemHelper $fs, Image $image,
121
+        LogWrapper $log, IAvatarManager $avatarManager, IUserManager $userManager,
122
+        INotificationManager $notificationManager) {
123 123
 	
124
-		if ($username === null) {
125
-			$log->log("uid for '$dn' must not be null!", Util::ERROR);
126
-			throw new \InvalidArgumentException('uid must not be null!');
127
-		} else if ($username === '') {
128
-			$log->log("uid for '$dn' must not be an empty string", Util::ERROR);
129
-			throw new \InvalidArgumentException('uid must not be an empty string!');
130
-		}
131
-
132
-		$this->access              = $access;
133
-		$this->connection          = $access->getConnection();
134
-		$this->config              = $config;
135
-		$this->fs                  = $fs;
136
-		$this->dn                  = $dn;
137
-		$this->uid                 = $username;
138
-		$this->image               = $image;
139
-		$this->log                 = $log;
140
-		$this->avatarManager       = $avatarManager;
141
-		$this->userManager         = $userManager;
142
-		$this->notificationManager = $notificationManager;
143
-
144
-		\OCP\Util::connectHook('OC_User', 'post_login', $this, 'handlePasswordExpiry');
145
-	}
146
-
147
-	/**
148
-	 * @brief updates properties like email, quota or avatar provided by LDAP
149
-	 * @return null
150
-	 */
151
-	public function update() {
152
-		if(is_null($this->dn)) {
153
-			return null;
154
-		}
155
-
156
-		$hasLoggedIn = $this->config->getUserValue($this->uid, 'user_ldap',
157
-				self::USER_PREFKEY_FIRSTLOGIN, 0);
158
-
159
-		if($this->needsRefresh()) {
160
-			$this->updateEmail();
161
-			$this->updateQuota();
162
-			if($hasLoggedIn !== 0) {
163
-				//we do not need to try it, when the user has not been logged in
164
-				//before, because the file system will not be ready.
165
-				$this->updateAvatar();
166
-				//in order to get an avatar as soon as possible, mark the user
167
-				//as refreshed only when updating the avatar did happen
168
-				$this->markRefreshTime();
169
-			}
170
-		}
171
-	}
172
-
173
-	/**
174
-	 * processes results from LDAP for attributes as returned by getAttributesToRead()
175
-	 * @param array $ldapEntry the user entry as retrieved from LDAP
176
-	 */
177
-	public function processAttributes($ldapEntry) {
178
-		$this->markRefreshTime();
179
-		//Quota
180
-		$attr = strtolower($this->connection->ldapQuotaAttribute);
181
-		if(isset($ldapEntry[$attr])) {
182
-			$this->updateQuota($ldapEntry[$attr][0]);
183
-		} else {
184
-			if ($this->connection->ldapQuotaDefault !== '') {
185
-				$this->updateQuota();
186
-			}
187
-		}
188
-		unset($attr);
189
-
190
-		//Email
191
-		$attr = strtolower($this->connection->ldapEmailAttribute);
192
-		if(isset($ldapEntry[$attr])) {
193
-			$this->updateEmail($ldapEntry[$attr][0]);
194
-		}
195
-		unset($attr);
196
-
197
-		//displayName
198
-		$displayName = $displayName2 = '';
199
-		$attr = strtolower($this->connection->ldapUserDisplayName);
200
-		if(isset($ldapEntry[$attr])) {
201
-			$displayName = strval($ldapEntry[$attr][0]);
202
-		}
203
-		$attr = strtolower($this->connection->ldapUserDisplayName2);
204
-		if(isset($ldapEntry[$attr])) {
205
-			$displayName2 = strval($ldapEntry[$attr][0]);
206
-		}
207
-		if ($displayName !== '') {
208
-			$this->composeAndStoreDisplayName($displayName);
209
-			$this->access->cacheUserDisplayName(
210
-				$this->getUsername(),
211
-				$displayName,
212
-				$displayName2
213
-			);
214
-		}
215
-		unset($attr);
216
-
217
-		// LDAP Username, needed for s2s sharing
218
-		if(isset($ldapEntry['uid'])) {
219
-			$this->storeLDAPUserName($ldapEntry['uid'][0]);
220
-		} else if(isset($ldapEntry['samaccountname'])) {
221
-			$this->storeLDAPUserName($ldapEntry['samaccountname'][0]);
222
-		}
223
-
224
-		//homePath
225
-		if(strpos($this->connection->homeFolderNamingRule, 'attr:') === 0) {
226
-			$attr = strtolower(substr($this->connection->homeFolderNamingRule, strlen('attr:')));
227
-			if(isset($ldapEntry[$attr])) {
228
-				$this->access->cacheUserHome(
229
-					$this->getUsername(), $this->getHomePath($ldapEntry[$attr][0]));
230
-			}
231
-		}
232
-
233
-		//memberOf groups
234
-		$cacheKey = 'getMemberOf'.$this->getUsername();
235
-		$groups = false;
236
-		if(isset($ldapEntry['memberof'])) {
237
-			$groups = $ldapEntry['memberof'];
238
-		}
239
-		$this->connection->writeToCache($cacheKey, $groups);
240
-
241
-		//Avatar
242
-		$attrs = array('jpegphoto', 'thumbnailphoto');
243
-		foreach ($attrs as $attr)  {
244
-			if(isset($ldapEntry[$attr])) {
245
-				$this->avatarImage = $ldapEntry[$attr][0];
246
-				// the call to the method that saves the avatar in the file
247
-				// system must be postponed after the login. It is to ensure
248
-				// external mounts are mounted properly (e.g. with login
249
-				// credentials from the session).
250
-				\OCP\Util::connectHook('OC_User', 'post_login', $this, 'updateAvatarPostLogin');
251
-				break;
252
-			}
253
-		}
254
-	}
255
-
256
-	/**
257
-	 * @brief returns the LDAP DN of the user
258
-	 * @return string
259
-	 */
260
-	public function getDN() {
261
-		return $this->dn;
262
-	}
263
-
264
-	/**
265
-	 * @brief returns the Nextcloud internal username of the user
266
-	 * @return string
267
-	 */
268
-	public function getUsername() {
269
-		return $this->uid;
270
-	}
271
-
272
-	/**
273
-	 * returns the home directory of the user if specified by LDAP settings
274
-	 * @param string $valueFromLDAP
275
-	 * @return bool|string
276
-	 * @throws \Exception
277
-	 */
278
-	public function getHomePath($valueFromLDAP = null) {
279
-		$path = strval($valueFromLDAP);
280
-		$attr = null;
281
-
282
-		if (is_null($valueFromLDAP)
283
-		   && strpos($this->access->connection->homeFolderNamingRule, 'attr:') === 0
284
-		   && $this->access->connection->homeFolderNamingRule !== 'attr:')
285
-		{
286
-			$attr = substr($this->access->connection->homeFolderNamingRule, strlen('attr:'));
287
-			$homedir = $this->access->readAttribute(
288
-				$this->access->username2dn($this->getUsername()), $attr);
289
-			if ($homedir && isset($homedir[0])) {
290
-				$path = $homedir[0];
291
-			}
292
-		}
293
-
294
-		if ($path !== '') {
295
-			//if attribute's value is an absolute path take this, otherwise append it to data dir
296
-			//check for / at the beginning or pattern c:\ resp. c:/
297
-			if(   '/' !== $path[0]
298
-			   && !(3 < strlen($path) && ctype_alpha($path[0])
299
-			       && $path[1] === ':' && ('\\' === $path[2] || '/' === $path[2]))
300
-			) {
301
-				$path = $this->config->getSystemValue('datadirectory',
302
-						\OC::$SERVERROOT.'/data' ) . '/' . $path;
303
-			}
304
-			//we need it to store it in the DB as well in case a user gets
305
-			//deleted so we can clean up afterwards
306
-			$this->config->setUserValue(
307
-				$this->getUsername(), 'user_ldap', 'homePath', $path
308
-			);
309
-			return $path;
310
-		}
311
-
312
-		if(    !is_null($attr)
313
-			&& $this->config->getAppValue('user_ldap', 'enforce_home_folder_naming_rule', true)
314
-		) {
315
-			// a naming rule attribute is defined, but it doesn't exist for that LDAP user
316
-			throw new \Exception('Home dir attribute can\'t be read from LDAP for uid: ' . $this->getUsername());
317
-		}
318
-
319
-		//false will apply default behaviour as defined and done by OC_User
320
-		$this->config->setUserValue($this->getUsername(), 'user_ldap', 'homePath', '');
321
-		return false;
322
-	}
323
-
324
-	public function getMemberOfGroups() {
325
-		$cacheKey = 'getMemberOf'.$this->getUsername();
326
-		$memberOfGroups = $this->connection->getFromCache($cacheKey);
327
-		if(!is_null($memberOfGroups)) {
328
-			return $memberOfGroups;
329
-		}
330
-		$groupDNs = $this->access->readAttribute($this->getDN(), 'memberOf');
331
-		$this->connection->writeToCache($cacheKey, $groupDNs);
332
-		return $groupDNs;
333
-	}
334
-
335
-	/**
336
-	 * @brief reads the image from LDAP that shall be used as Avatar
337
-	 * @return string data (provided by LDAP) | false
338
-	 */
339
-	public function getAvatarImage() {
340
-		if(!is_null($this->avatarImage)) {
341
-			return $this->avatarImage;
342
-		}
343
-
344
-		$this->avatarImage = false;
345
-		$attributes = array('jpegPhoto', 'thumbnailPhoto');
346
-		foreach($attributes as $attribute) {
347
-			$result = $this->access->readAttribute($this->dn, $attribute);
348
-			if($result !== false && is_array($result) && isset($result[0])) {
349
-				$this->avatarImage = $result[0];
350
-				break;
351
-			}
352
-		}
353
-
354
-		return $this->avatarImage;
355
-	}
356
-
357
-	/**
358
-	 * @brief marks the user as having logged in at least once
359
-	 * @return null
360
-	 */
361
-	public function markLogin() {
362
-		$this->config->setUserValue(
363
-			$this->uid, 'user_ldap', self::USER_PREFKEY_FIRSTLOGIN, 1);
364
-	}
365
-
366
-	/**
367
-	 * @brief marks the time when user features like email have been updated
368
-	 * @return null
369
-	 */
370
-	public function markRefreshTime() {
371
-		$this->config->setUserValue(
372
-			$this->uid, 'user_ldap', self::USER_PREFKEY_LASTREFRESH, time());
373
-	}
374
-
375
-	/**
376
-	 * @brief checks whether user features needs to be updated again by
377
-	 * comparing the difference of time of the last refresh to now with the
378
-	 * desired interval
379
-	 * @return bool
380
-	 */
381
-	private function needsRefresh() {
382
-		$lastChecked = $this->config->getUserValue($this->uid, 'user_ldap',
383
-			self::USER_PREFKEY_LASTREFRESH, 0);
384
-
385
-		if((time() - intval($lastChecked)) < intval($this->config->getAppValue('user_ldap', 'updateAttributesInterval', 86400)) ) {
386
-			return false;
387
-		}
388
-		return  true;
389
-	}
390
-
391
-	/**
392
-	 * Stores a key-value pair in relation to this user
393
-	 *
394
-	 * @param string $key
395
-	 * @param string $value
396
-	 */
397
-	private function store($key, $value) {
398
-		$this->config->setUserValue($this->uid, 'user_ldap', $key, $value);
399
-	}
400
-
401
-	/**
402
-	 * Composes the display name and stores it in the database. The final
403
-	 * display name is returned.
404
-	 *
405
-	 * @param string $displayName
406
-	 * @param string $displayName2
407
-	 * @returns string the effective display name
408
-	 */
409
-	public function composeAndStoreDisplayName($displayName, $displayName2 = '') {
410
-		$displayName2 = strval($displayName2);
411
-		if($displayName2 !== '') {
412
-			$displayName .= ' (' . $displayName2 . ')';
413
-		}
414
-		$this->store('displayName', $displayName);
415
-		return $displayName;
416
-	}
417
-
418
-	/**
419
-	 * Stores the LDAP Username in the Database
420
-	 * @param string $userName
421
-	 */
422
-	public function storeLDAPUserName($userName) {
423
-		$this->store('uid', $userName);
424
-	}
425
-
426
-	/**
427
-	 * @brief checks whether an update method specified by feature was run
428
-	 * already. If not, it will marked like this, because it is expected that
429
-	 * the method will be run, when false is returned.
430
-	 * @param string $feature email | quota | avatar (can be extended)
431
-	 * @return bool
432
-	 */
433
-	private function wasRefreshed($feature) {
434
-		if(isset($this->refreshedFeatures[$feature])) {
435
-			return true;
436
-		}
437
-		$this->refreshedFeatures[$feature] = 1;
438
-		return false;
439
-	}
440
-
441
-	/**
442
-	 * fetches the email from LDAP and stores it as Nextcloud user value
443
-	 * @param string $valueFromLDAP if known, to save an LDAP read request
444
-	 * @return null
445
-	 */
446
-	public function updateEmail($valueFromLDAP = null) {
447
-		if($this->wasRefreshed('email')) {
448
-			return;
449
-		}
450
-		$email = strval($valueFromLDAP);
451
-		if(is_null($valueFromLDAP)) {
452
-			$emailAttribute = $this->connection->ldapEmailAttribute;
453
-			if ($emailAttribute !== '') {
454
-				$aEmail = $this->access->readAttribute($this->dn, $emailAttribute);
455
-				if(is_array($aEmail) && (count($aEmail) > 0)) {
456
-					$email = strval($aEmail[0]);
457
-				}
458
-			}
459
-		}
460
-		if ($email !== '') {
461
-			$user = $this->userManager->get($this->uid);
462
-			if (!is_null($user)) {
463
-				$currentEmail = strval($user->getEMailAddress());
464
-				if ($currentEmail !== $email) {
465
-					$user->setEMailAddress($email);
466
-				}
467
-			}
468
-		}
469
-	}
470
-
471
-	/**
472
-	 * Overall process goes as follow:
473
-	 * 1. fetch the quota from LDAP and check if it's parseable with the "verifyQuotaValue" function
474
-	 * 2. if the value can't be fetched, is empty or not parseable, use the default LDAP quota
475
-	 * 3. if the default LDAP quota can't be parsed, use the Nextcloud's default quota (use 'default')
476
-	 * 4. check if the target user exists and set the quota for the user.
477
-	 *
478
-	 * In order to improve performance and prevent an unwanted extra LDAP call, the $valueFromLDAP
479
-	 * parameter can be passed with the value of the attribute. This value will be considered as the
480
-	 * quota for the user coming from the LDAP server (step 1 of the process) It can be useful to
481
-	 * fetch all the user's attributes in one call and use the fetched values in this function.
482
-	 * The expected value for that parameter is a string describing the quota for the user. Valid
483
-	 * values are 'none' (unlimited), 'default' (the Nextcloud's default quota), '1234' (quota in
484
-	 * bytes), '1234 MB' (quota in MB - check the \OC_Helper::computerFileSize method for more info)
485
-	 *
486
-	 * fetches the quota from LDAP and stores it as Nextcloud user value
487
-	 * @param string $valueFromLDAP the quota attribute's value can be passed,
488
-	 * to save the readAttribute request
489
-	 * @return null
490
-	 */
491
-	public function updateQuota($valueFromLDAP = null) {
492
-		if($this->wasRefreshed('quota')) {
493
-			return;
494
-		}
495
-
496
-		$quota = false;
497
-		if(is_null($valueFromLDAP)) {
498
-			$quotaAttribute = $this->connection->ldapQuotaAttribute;
499
-			if ($quotaAttribute !== '') {
500
-				$aQuota = $this->access->readAttribute($this->dn, $quotaAttribute);
501
-				if($aQuota && (count($aQuota) > 0)) {
502
-					if ($this->verifyQuotaValue($aQuota[0])) {
503
-						$quota = $aQuota[0];
504
-					} else {
505
-						$this->log->log('not suitable LDAP quota found for user ' . $this->uid . ': [' . $aQuota[0] . ']', \OCP\Util::WARN);
506
-					}
507
-				}
508
-			}
509
-		} else {
510
-			if ($this->verifyQuotaValue($valueFromLDAP)) {
511
-				$quota = $valueFromLDAP;
512
-			} else {
513
-				$this->log->log('not suitable LDAP quota found for user ' . $this->uid . ': [' . $valueFromLDAP . ']', \OCP\Util::WARN);
514
-			}
515
-		}
516
-
517
-		if ($quota === false) {
518
-			// quota not found using the LDAP attribute (or not parseable). Try the default quota
519
-			$defaultQuota = $this->connection->ldapQuotaDefault;
520
-			if ($this->verifyQuotaValue($defaultQuota)) {
521
-				$quota = $defaultQuota;
522
-			}
523
-		}
524
-
525
-		$targetUser = $this->userManager->get($this->uid);
526
-		if ($targetUser) {
527
-			if($quota !== false) {
528
-				$targetUser->setQuota($quota);
529
-			} else {
530
-				$this->log->log('not suitable default quota found for user ' . $this->uid . ': [' . $defaultQuota . ']', \OCP\Util::WARN);
531
-				$targetUser->setQuota('default');
532
-			}
533
-		} else {
534
-			$this->log->log('trying to set a quota for user ' . $this->uid . ' but the user is missing', \OCP\Util::ERROR);
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 null
556
-	 */
557
-	public function updateAvatar() {
558
-		if($this->wasRefreshed('avatar')) {
559
-			return;
560
-		}
561
-		$avatarImage = $this->getAvatarImage();
562
-		if($avatarImage === false) {
563
-			//not set, nothing left to do;
564
-			return;
565
-		}
566
-		$this->image->loadFromBase64(base64_encode($avatarImage));
567
-		$this->setOwnCloudAvatar();
568
-	}
569
-
570
-	/**
571
-	 * @brief sets an image as Nextcloud avatar
572
-	 * @return null
573
-	 */
574
-	private function setOwnCloudAvatar() {
575
-		if(!$this->image->valid()) {
576
-			$this->log->log('jpegPhoto data invalid for '.$this->dn, \OCP\Util::ERROR);
577
-			return;
578
-		}
579
-		//make sure it is a square and not bigger than 128x128
580
-		$size = min(array($this->image->width(), $this->image->height(), 128));
581
-		if(!$this->image->centerCrop($size)) {
582
-			$this->log->log('croping image for avatar failed for '.$this->dn, \OCP\Util::ERROR);
583
-			return;
584
-		}
585
-
586
-		if(!$this->fs->isLoaded()) {
587
-			$this->fs->setup($this->uid);
588
-		}
589
-
590
-		try {
591
-			$avatar = $this->avatarManager->getAvatar($this->uid);
592
-			$avatar->set($this->image);
593
-		} catch (\Exception $e) {
594
-			\OC::$server->getLogger()->notice(
595
-				'Could not set avatar for ' . $this->dn	. ', because: ' . $e->getMessage(),
596
-				['app' => 'user_ldap']);
597
-		}
598
-	}
599
-
600
-	/**
601
-	 * called by a post_login hook to handle password expiry
602
-	 *
603
-	 * @param array $params
604
-	 */
605
-	public function handlePasswordExpiry($params) {
606
-		$ppolicyDN = $this->connection->ldapDefaultPPolicyDN;
607
-		if (empty($ppolicyDN) || (intval($this->connection->turnOnPasswordChange) !== 1)) {
608
-			return;//password expiry handling disabled
609
-		}
610
-		$uid = $params['uid'];
611
-		if(isset($uid) && $uid === $this->getUsername()) {
612
-			//retrieve relevant user attributes
613
-			$result = $this->access->search('objectclass=*', $this->dn, ['pwdpolicysubentry', 'pwdgraceusetime', 'pwdreset', 'pwdchangedtime']);
124
+        if ($username === null) {
125
+            $log->log("uid for '$dn' must not be null!", Util::ERROR);
126
+            throw new \InvalidArgumentException('uid must not be null!');
127
+        } else if ($username === '') {
128
+            $log->log("uid for '$dn' must not be an empty string", Util::ERROR);
129
+            throw new \InvalidArgumentException('uid must not be an empty string!');
130
+        }
131
+
132
+        $this->access              = $access;
133
+        $this->connection          = $access->getConnection();
134
+        $this->config              = $config;
135
+        $this->fs                  = $fs;
136
+        $this->dn                  = $dn;
137
+        $this->uid                 = $username;
138
+        $this->image               = $image;
139
+        $this->log                 = $log;
140
+        $this->avatarManager       = $avatarManager;
141
+        $this->userManager         = $userManager;
142
+        $this->notificationManager = $notificationManager;
143
+
144
+        \OCP\Util::connectHook('OC_User', 'post_login', $this, 'handlePasswordExpiry');
145
+    }
146
+
147
+    /**
148
+     * @brief updates properties like email, quota or avatar provided by LDAP
149
+     * @return null
150
+     */
151
+    public function update() {
152
+        if(is_null($this->dn)) {
153
+            return null;
154
+        }
155
+
156
+        $hasLoggedIn = $this->config->getUserValue($this->uid, 'user_ldap',
157
+                self::USER_PREFKEY_FIRSTLOGIN, 0);
158
+
159
+        if($this->needsRefresh()) {
160
+            $this->updateEmail();
161
+            $this->updateQuota();
162
+            if($hasLoggedIn !== 0) {
163
+                //we do not need to try it, when the user has not been logged in
164
+                //before, because the file system will not be ready.
165
+                $this->updateAvatar();
166
+                //in order to get an avatar as soon as possible, mark the user
167
+                //as refreshed only when updating the avatar did happen
168
+                $this->markRefreshTime();
169
+            }
170
+        }
171
+    }
172
+
173
+    /**
174
+     * processes results from LDAP for attributes as returned by getAttributesToRead()
175
+     * @param array $ldapEntry the user entry as retrieved from LDAP
176
+     */
177
+    public function processAttributes($ldapEntry) {
178
+        $this->markRefreshTime();
179
+        //Quota
180
+        $attr = strtolower($this->connection->ldapQuotaAttribute);
181
+        if(isset($ldapEntry[$attr])) {
182
+            $this->updateQuota($ldapEntry[$attr][0]);
183
+        } else {
184
+            if ($this->connection->ldapQuotaDefault !== '') {
185
+                $this->updateQuota();
186
+            }
187
+        }
188
+        unset($attr);
189
+
190
+        //Email
191
+        $attr = strtolower($this->connection->ldapEmailAttribute);
192
+        if(isset($ldapEntry[$attr])) {
193
+            $this->updateEmail($ldapEntry[$attr][0]);
194
+        }
195
+        unset($attr);
196
+
197
+        //displayName
198
+        $displayName = $displayName2 = '';
199
+        $attr = strtolower($this->connection->ldapUserDisplayName);
200
+        if(isset($ldapEntry[$attr])) {
201
+            $displayName = strval($ldapEntry[$attr][0]);
202
+        }
203
+        $attr = strtolower($this->connection->ldapUserDisplayName2);
204
+        if(isset($ldapEntry[$attr])) {
205
+            $displayName2 = strval($ldapEntry[$attr][0]);
206
+        }
207
+        if ($displayName !== '') {
208
+            $this->composeAndStoreDisplayName($displayName);
209
+            $this->access->cacheUserDisplayName(
210
+                $this->getUsername(),
211
+                $displayName,
212
+                $displayName2
213
+            );
214
+        }
215
+        unset($attr);
216
+
217
+        // LDAP Username, needed for s2s sharing
218
+        if(isset($ldapEntry['uid'])) {
219
+            $this->storeLDAPUserName($ldapEntry['uid'][0]);
220
+        } else if(isset($ldapEntry['samaccountname'])) {
221
+            $this->storeLDAPUserName($ldapEntry['samaccountname'][0]);
222
+        }
223
+
224
+        //homePath
225
+        if(strpos($this->connection->homeFolderNamingRule, 'attr:') === 0) {
226
+            $attr = strtolower(substr($this->connection->homeFolderNamingRule, strlen('attr:')));
227
+            if(isset($ldapEntry[$attr])) {
228
+                $this->access->cacheUserHome(
229
+                    $this->getUsername(), $this->getHomePath($ldapEntry[$attr][0]));
230
+            }
231
+        }
232
+
233
+        //memberOf groups
234
+        $cacheKey = 'getMemberOf'.$this->getUsername();
235
+        $groups = false;
236
+        if(isset($ldapEntry['memberof'])) {
237
+            $groups = $ldapEntry['memberof'];
238
+        }
239
+        $this->connection->writeToCache($cacheKey, $groups);
240
+
241
+        //Avatar
242
+        $attrs = array('jpegphoto', 'thumbnailphoto');
243
+        foreach ($attrs as $attr)  {
244
+            if(isset($ldapEntry[$attr])) {
245
+                $this->avatarImage = $ldapEntry[$attr][0];
246
+                // the call to the method that saves the avatar in the file
247
+                // system must be postponed after the login. It is to ensure
248
+                // external mounts are mounted properly (e.g. with login
249
+                // credentials from the session).
250
+                \OCP\Util::connectHook('OC_User', 'post_login', $this, 'updateAvatarPostLogin');
251
+                break;
252
+            }
253
+        }
254
+    }
255
+
256
+    /**
257
+     * @brief returns the LDAP DN of the user
258
+     * @return string
259
+     */
260
+    public function getDN() {
261
+        return $this->dn;
262
+    }
263
+
264
+    /**
265
+     * @brief returns the Nextcloud internal username of the user
266
+     * @return string
267
+     */
268
+    public function getUsername() {
269
+        return $this->uid;
270
+    }
271
+
272
+    /**
273
+     * returns the home directory of the user if specified by LDAP settings
274
+     * @param string $valueFromLDAP
275
+     * @return bool|string
276
+     * @throws \Exception
277
+     */
278
+    public function getHomePath($valueFromLDAP = null) {
279
+        $path = strval($valueFromLDAP);
280
+        $attr = null;
281
+
282
+        if (is_null($valueFromLDAP)
283
+           && strpos($this->access->connection->homeFolderNamingRule, 'attr:') === 0
284
+           && $this->access->connection->homeFolderNamingRule !== 'attr:')
285
+        {
286
+            $attr = substr($this->access->connection->homeFolderNamingRule, strlen('attr:'));
287
+            $homedir = $this->access->readAttribute(
288
+                $this->access->username2dn($this->getUsername()), $attr);
289
+            if ($homedir && isset($homedir[0])) {
290
+                $path = $homedir[0];
291
+            }
292
+        }
293
+
294
+        if ($path !== '') {
295
+            //if attribute's value is an absolute path take this, otherwise append it to data dir
296
+            //check for / at the beginning or pattern c:\ resp. c:/
297
+            if(   '/' !== $path[0]
298
+               && !(3 < strlen($path) && ctype_alpha($path[0])
299
+                   && $path[1] === ':' && ('\\' === $path[2] || '/' === $path[2]))
300
+            ) {
301
+                $path = $this->config->getSystemValue('datadirectory',
302
+                        \OC::$SERVERROOT.'/data' ) . '/' . $path;
303
+            }
304
+            //we need it to store it in the DB as well in case a user gets
305
+            //deleted so we can clean up afterwards
306
+            $this->config->setUserValue(
307
+                $this->getUsername(), 'user_ldap', 'homePath', $path
308
+            );
309
+            return $path;
310
+        }
311
+
312
+        if(    !is_null($attr)
313
+            && $this->config->getAppValue('user_ldap', 'enforce_home_folder_naming_rule', true)
314
+        ) {
315
+            // a naming rule attribute is defined, but it doesn't exist for that LDAP user
316
+            throw new \Exception('Home dir attribute can\'t be read from LDAP for uid: ' . $this->getUsername());
317
+        }
318
+
319
+        //false will apply default behaviour as defined and done by OC_User
320
+        $this->config->setUserValue($this->getUsername(), 'user_ldap', 'homePath', '');
321
+        return false;
322
+    }
323
+
324
+    public function getMemberOfGroups() {
325
+        $cacheKey = 'getMemberOf'.$this->getUsername();
326
+        $memberOfGroups = $this->connection->getFromCache($cacheKey);
327
+        if(!is_null($memberOfGroups)) {
328
+            return $memberOfGroups;
329
+        }
330
+        $groupDNs = $this->access->readAttribute($this->getDN(), 'memberOf');
331
+        $this->connection->writeToCache($cacheKey, $groupDNs);
332
+        return $groupDNs;
333
+    }
334
+
335
+    /**
336
+     * @brief reads the image from LDAP that shall be used as Avatar
337
+     * @return string data (provided by LDAP) | false
338
+     */
339
+    public function getAvatarImage() {
340
+        if(!is_null($this->avatarImage)) {
341
+            return $this->avatarImage;
342
+        }
343
+
344
+        $this->avatarImage = false;
345
+        $attributes = array('jpegPhoto', 'thumbnailPhoto');
346
+        foreach($attributes as $attribute) {
347
+            $result = $this->access->readAttribute($this->dn, $attribute);
348
+            if($result !== false && is_array($result) && isset($result[0])) {
349
+                $this->avatarImage = $result[0];
350
+                break;
351
+            }
352
+        }
353
+
354
+        return $this->avatarImage;
355
+    }
356
+
357
+    /**
358
+     * @brief marks the user as having logged in at least once
359
+     * @return null
360
+     */
361
+    public function markLogin() {
362
+        $this->config->setUserValue(
363
+            $this->uid, 'user_ldap', self::USER_PREFKEY_FIRSTLOGIN, 1);
364
+    }
365
+
366
+    /**
367
+     * @brief marks the time when user features like email have been updated
368
+     * @return null
369
+     */
370
+    public function markRefreshTime() {
371
+        $this->config->setUserValue(
372
+            $this->uid, 'user_ldap', self::USER_PREFKEY_LASTREFRESH, time());
373
+    }
374
+
375
+    /**
376
+     * @brief checks whether user features needs to be updated again by
377
+     * comparing the difference of time of the last refresh to now with the
378
+     * desired interval
379
+     * @return bool
380
+     */
381
+    private function needsRefresh() {
382
+        $lastChecked = $this->config->getUserValue($this->uid, 'user_ldap',
383
+            self::USER_PREFKEY_LASTREFRESH, 0);
384
+
385
+        if((time() - intval($lastChecked)) < intval($this->config->getAppValue('user_ldap', 'updateAttributesInterval', 86400)) ) {
386
+            return false;
387
+        }
388
+        return  true;
389
+    }
390
+
391
+    /**
392
+     * Stores a key-value pair in relation to this user
393
+     *
394
+     * @param string $key
395
+     * @param string $value
396
+     */
397
+    private function store($key, $value) {
398
+        $this->config->setUserValue($this->uid, 'user_ldap', $key, $value);
399
+    }
400
+
401
+    /**
402
+     * Composes the display name and stores it in the database. The final
403
+     * display name is returned.
404
+     *
405
+     * @param string $displayName
406
+     * @param string $displayName2
407
+     * @returns string the effective display name
408
+     */
409
+    public function composeAndStoreDisplayName($displayName, $displayName2 = '') {
410
+        $displayName2 = strval($displayName2);
411
+        if($displayName2 !== '') {
412
+            $displayName .= ' (' . $displayName2 . ')';
413
+        }
414
+        $this->store('displayName', $displayName);
415
+        return $displayName;
416
+    }
417
+
418
+    /**
419
+     * Stores the LDAP Username in the Database
420
+     * @param string $userName
421
+     */
422
+    public function storeLDAPUserName($userName) {
423
+        $this->store('uid', $userName);
424
+    }
425
+
426
+    /**
427
+     * @brief checks whether an update method specified by feature was run
428
+     * already. If not, it will marked like this, because it is expected that
429
+     * the method will be run, when false is returned.
430
+     * @param string $feature email | quota | avatar (can be extended)
431
+     * @return bool
432
+     */
433
+    private function wasRefreshed($feature) {
434
+        if(isset($this->refreshedFeatures[$feature])) {
435
+            return true;
436
+        }
437
+        $this->refreshedFeatures[$feature] = 1;
438
+        return false;
439
+    }
440
+
441
+    /**
442
+     * fetches the email from LDAP and stores it as Nextcloud user value
443
+     * @param string $valueFromLDAP if known, to save an LDAP read request
444
+     * @return null
445
+     */
446
+    public function updateEmail($valueFromLDAP = null) {
447
+        if($this->wasRefreshed('email')) {
448
+            return;
449
+        }
450
+        $email = strval($valueFromLDAP);
451
+        if(is_null($valueFromLDAP)) {
452
+            $emailAttribute = $this->connection->ldapEmailAttribute;
453
+            if ($emailAttribute !== '') {
454
+                $aEmail = $this->access->readAttribute($this->dn, $emailAttribute);
455
+                if(is_array($aEmail) && (count($aEmail) > 0)) {
456
+                    $email = strval($aEmail[0]);
457
+                }
458
+            }
459
+        }
460
+        if ($email !== '') {
461
+            $user = $this->userManager->get($this->uid);
462
+            if (!is_null($user)) {
463
+                $currentEmail = strval($user->getEMailAddress());
464
+                if ($currentEmail !== $email) {
465
+                    $user->setEMailAddress($email);
466
+                }
467
+            }
468
+        }
469
+    }
470
+
471
+    /**
472
+     * Overall process goes as follow:
473
+     * 1. fetch the quota from LDAP and check if it's parseable with the "verifyQuotaValue" function
474
+     * 2. if the value can't be fetched, is empty or not parseable, use the default LDAP quota
475
+     * 3. if the default LDAP quota can't be parsed, use the Nextcloud's default quota (use 'default')
476
+     * 4. check if the target user exists and set the quota for the user.
477
+     *
478
+     * In order to improve performance and prevent an unwanted extra LDAP call, the $valueFromLDAP
479
+     * parameter can be passed with the value of the attribute. This value will be considered as the
480
+     * quota for the user coming from the LDAP server (step 1 of the process) It can be useful to
481
+     * fetch all the user's attributes in one call and use the fetched values in this function.
482
+     * The expected value for that parameter is a string describing the quota for the user. Valid
483
+     * values are 'none' (unlimited), 'default' (the Nextcloud's default quota), '1234' (quota in
484
+     * bytes), '1234 MB' (quota in MB - check the \OC_Helper::computerFileSize method for more info)
485
+     *
486
+     * fetches the quota from LDAP and stores it as Nextcloud user value
487
+     * @param string $valueFromLDAP the quota attribute's value can be passed,
488
+     * to save the readAttribute request
489
+     * @return null
490
+     */
491
+    public function updateQuota($valueFromLDAP = null) {
492
+        if($this->wasRefreshed('quota')) {
493
+            return;
494
+        }
495
+
496
+        $quota = false;
497
+        if(is_null($valueFromLDAP)) {
498
+            $quotaAttribute = $this->connection->ldapQuotaAttribute;
499
+            if ($quotaAttribute !== '') {
500
+                $aQuota = $this->access->readAttribute($this->dn, $quotaAttribute);
501
+                if($aQuota && (count($aQuota) > 0)) {
502
+                    if ($this->verifyQuotaValue($aQuota[0])) {
503
+                        $quota = $aQuota[0];
504
+                    } else {
505
+                        $this->log->log('not suitable LDAP quota found for user ' . $this->uid . ': [' . $aQuota[0] . ']', \OCP\Util::WARN);
506
+                    }
507
+                }
508
+            }
509
+        } else {
510
+            if ($this->verifyQuotaValue($valueFromLDAP)) {
511
+                $quota = $valueFromLDAP;
512
+            } else {
513
+                $this->log->log('not suitable LDAP quota found for user ' . $this->uid . ': [' . $valueFromLDAP . ']', \OCP\Util::WARN);
514
+            }
515
+        }
516
+
517
+        if ($quota === false) {
518
+            // quota not found using the LDAP attribute (or not parseable). Try the default quota
519
+            $defaultQuota = $this->connection->ldapQuotaDefault;
520
+            if ($this->verifyQuotaValue($defaultQuota)) {
521
+                $quota = $defaultQuota;
522
+            }
523
+        }
524
+
525
+        $targetUser = $this->userManager->get($this->uid);
526
+        if ($targetUser) {
527
+            if($quota !== false) {
528
+                $targetUser->setQuota($quota);
529
+            } else {
530
+                $this->log->log('not suitable default quota found for user ' . $this->uid . ': [' . $defaultQuota . ']', \OCP\Util::WARN);
531
+                $targetUser->setQuota('default');
532
+            }
533
+        } else {
534
+            $this->log->log('trying to set a quota for user ' . $this->uid . ' but the user is missing', \OCP\Util::ERROR);
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 null
556
+     */
557
+    public function updateAvatar() {
558
+        if($this->wasRefreshed('avatar')) {
559
+            return;
560
+        }
561
+        $avatarImage = $this->getAvatarImage();
562
+        if($avatarImage === false) {
563
+            //not set, nothing left to do;
564
+            return;
565
+        }
566
+        $this->image->loadFromBase64(base64_encode($avatarImage));
567
+        $this->setOwnCloudAvatar();
568
+    }
569
+
570
+    /**
571
+     * @brief sets an image as Nextcloud avatar
572
+     * @return null
573
+     */
574
+    private function setOwnCloudAvatar() {
575
+        if(!$this->image->valid()) {
576
+            $this->log->log('jpegPhoto data invalid for '.$this->dn, \OCP\Util::ERROR);
577
+            return;
578
+        }
579
+        //make sure it is a square and not bigger than 128x128
580
+        $size = min(array($this->image->width(), $this->image->height(), 128));
581
+        if(!$this->image->centerCrop($size)) {
582
+            $this->log->log('croping image for avatar failed for '.$this->dn, \OCP\Util::ERROR);
583
+            return;
584
+        }
585
+
586
+        if(!$this->fs->isLoaded()) {
587
+            $this->fs->setup($this->uid);
588
+        }
589
+
590
+        try {
591
+            $avatar = $this->avatarManager->getAvatar($this->uid);
592
+            $avatar->set($this->image);
593
+        } catch (\Exception $e) {
594
+            \OC::$server->getLogger()->notice(
595
+                'Could not set avatar for ' . $this->dn	. ', because: ' . $e->getMessage(),
596
+                ['app' => 'user_ldap']);
597
+        }
598
+    }
599
+
600
+    /**
601
+     * called by a post_login hook to handle password expiry
602
+     *
603
+     * @param array $params
604
+     */
605
+    public function handlePasswordExpiry($params) {
606
+        $ppolicyDN = $this->connection->ldapDefaultPPolicyDN;
607
+        if (empty($ppolicyDN) || (intval($this->connection->turnOnPasswordChange) !== 1)) {
608
+            return;//password expiry handling disabled
609
+        }
610
+        $uid = $params['uid'];
611
+        if(isset($uid) && $uid === $this->getUsername()) {
612
+            //retrieve relevant user attributes
613
+            $result = $this->access->search('objectclass=*', $this->dn, ['pwdpolicysubentry', 'pwdgraceusetime', 'pwdreset', 'pwdchangedtime']);
614 614
 			
615
-			if(array_key_exists('pwdpolicysubentry', $result[0])) {
616
-				$pwdPolicySubentry = $result[0]['pwdpolicysubentry'];
617
-				if($pwdPolicySubentry && (count($pwdPolicySubentry) > 0)){
618
-					$ppolicyDN = $pwdPolicySubentry[0];//custom ppolicy DN
619
-				}
620
-			}
615
+            if(array_key_exists('pwdpolicysubentry', $result[0])) {
616
+                $pwdPolicySubentry = $result[0]['pwdpolicysubentry'];
617
+                if($pwdPolicySubentry && (count($pwdPolicySubentry) > 0)){
618
+                    $ppolicyDN = $pwdPolicySubentry[0];//custom ppolicy DN
619
+                }
620
+            }
621 621
 			
622
-			$pwdGraceUseTime = array_key_exists('pwdgraceusetime', $result[0]) ? $result[0]['pwdgraceusetime'] : null;
623
-			$pwdReset = array_key_exists('pwdreset', $result[0]) ? $result[0]['pwdreset'] : null;
624
-			$pwdChangedTime = array_key_exists('pwdchangedtime', $result[0]) ? $result[0]['pwdchangedtime'] : null;
622
+            $pwdGraceUseTime = array_key_exists('pwdgraceusetime', $result[0]) ? $result[0]['pwdgraceusetime'] : null;
623
+            $pwdReset = array_key_exists('pwdreset', $result[0]) ? $result[0]['pwdreset'] : null;
624
+            $pwdChangedTime = array_key_exists('pwdchangedtime', $result[0]) ? $result[0]['pwdchangedtime'] : null;
625 625
 			
626
-			//retrieve relevant password policy attributes
627
-			$cacheKey = 'ppolicyAttributes' . $ppolicyDN;
628
-			$result = $this->connection->getFromCache($cacheKey);
629
-			if(is_null($result)) {
630
-				$result = $this->access->search('objectclass=*', $ppolicyDN, ['pwdgraceauthnlimit', 'pwdmaxage', 'pwdexpirewarning']);
631
-				$this->connection->writeToCache($cacheKey, $result);
632
-			}
626
+            //retrieve relevant password policy attributes
627
+            $cacheKey = 'ppolicyAttributes' . $ppolicyDN;
628
+            $result = $this->connection->getFromCache($cacheKey);
629
+            if(is_null($result)) {
630
+                $result = $this->access->search('objectclass=*', $ppolicyDN, ['pwdgraceauthnlimit', 'pwdmaxage', 'pwdexpirewarning']);
631
+                $this->connection->writeToCache($cacheKey, $result);
632
+            }
633 633
 			
634
-			$pwdGraceAuthNLimit = array_key_exists('pwdgraceauthnlimit', $result[0]) ? $result[0]['pwdgraceauthnlimit'] : null;
635
-			$pwdMaxAge = array_key_exists('pwdmaxage', $result[0]) ? $result[0]['pwdmaxage'] : null;
636
-			$pwdExpireWarning = array_key_exists('pwdexpirewarning', $result[0]) ? $result[0]['pwdexpirewarning'] : null;
634
+            $pwdGraceAuthNLimit = array_key_exists('pwdgraceauthnlimit', $result[0]) ? $result[0]['pwdgraceauthnlimit'] : null;
635
+            $pwdMaxAge = array_key_exists('pwdmaxage', $result[0]) ? $result[0]['pwdmaxage'] : null;
636
+            $pwdExpireWarning = array_key_exists('pwdexpirewarning', $result[0]) ? $result[0]['pwdexpirewarning'] : null;
637 637
 			
638
-			//handle grace login
639
-			$pwdGraceUseTimeCount = count($pwdGraceUseTime);
640
-			if($pwdGraceUseTime && $pwdGraceUseTimeCount > 0) { //was this a grace login?
641
-				if($pwdGraceAuthNLimit 
642
-					&& (count($pwdGraceAuthNLimit) > 0)
643
-					&&($pwdGraceUseTimeCount < intval($pwdGraceAuthNLimit[0]))) { //at least one more grace login available?
644
-					$this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true');
645
-					header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
646
-					'user_ldap.renewPassword.showRenewPasswordForm', array('user' => $uid)));
647
-				} else { //no more grace login available
648
-					header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
649
-					'user_ldap.renewPassword.showLoginFormInvalidPassword', array('user' => $uid)));
650
-				}
651
-				exit();
652
-			}
653
-			//handle pwdReset attribute
654
-			if($pwdReset && (count($pwdReset) > 0) && $pwdReset[0] === 'TRUE') { //user must change his password
655
-				$this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true');
656
-				header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
657
-				'user_ldap.renewPassword.showRenewPasswordForm', array('user' => $uid)));
658
-				exit();
659
-			}
660
-			//handle password expiry warning
661
-			if($pwdChangedTime && (count($pwdChangedTime) > 0)) {
662
-				if($pwdMaxAge && (count($pwdMaxAge) > 0)
663
-					&& $pwdExpireWarning && (count($pwdExpireWarning) > 0)) {
664
-					$pwdMaxAgeInt = intval($pwdMaxAge[0]);
665
-					$pwdExpireWarningInt = intval($pwdExpireWarning[0]);
666
-					if($pwdMaxAgeInt > 0 && $pwdExpireWarningInt > 0){
667
-						$pwdChangedTimeDt = \DateTime::createFromFormat('YmdHisZ', $pwdChangedTime[0]);
668
-						$pwdChangedTimeDt->add(new \DateInterval('PT'.$pwdMaxAgeInt.'S'));
669
-						$currentDateTime = new \DateTime();
670
-						$secondsToExpiry = $pwdChangedTimeDt->getTimestamp() - $currentDateTime->getTimestamp();
671
-						if($secondsToExpiry <= $pwdExpireWarningInt) {
672
-							//remove last password expiry warning if any
673
-							$notification = $this->notificationManager->createNotification();
674
-							$notification->setApp('user_ldap')
675
-								->setUser($uid)
676
-								->setObject('pwd_exp_warn', $uid)
677
-							;
678
-							$this->notificationManager->markProcessed($notification);
679
-							//create new password expiry warning
680
-							$notification = $this->notificationManager->createNotification();
681
-							$notification->setApp('user_ldap')
682
-								->setUser($uid)
683
-								->setDateTime($currentDateTime)
684
-								->setObject('pwd_exp_warn', $uid) 
685
-								->setSubject('pwd_exp_warn_days', [(int) ceil($secondsToExpiry / 60 / 60 / 24)])
686
-							;
687
-							$this->notificationManager->notify($notification);
688
-						}
689
-					}
690
-				}
691
-			}
692
-		}
693
-	}
638
+            //handle grace login
639
+            $pwdGraceUseTimeCount = count($pwdGraceUseTime);
640
+            if($pwdGraceUseTime && $pwdGraceUseTimeCount > 0) { //was this a grace login?
641
+                if($pwdGraceAuthNLimit 
642
+                    && (count($pwdGraceAuthNLimit) > 0)
643
+                    &&($pwdGraceUseTimeCount < intval($pwdGraceAuthNLimit[0]))) { //at least one more grace login available?
644
+                    $this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true');
645
+                    header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
646
+                    'user_ldap.renewPassword.showRenewPasswordForm', array('user' => $uid)));
647
+                } else { //no more grace login available
648
+                    header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
649
+                    'user_ldap.renewPassword.showLoginFormInvalidPassword', array('user' => $uid)));
650
+                }
651
+                exit();
652
+            }
653
+            //handle pwdReset attribute
654
+            if($pwdReset && (count($pwdReset) > 0) && $pwdReset[0] === 'TRUE') { //user must change his password
655
+                $this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true');
656
+                header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
657
+                'user_ldap.renewPassword.showRenewPasswordForm', array('user' => $uid)));
658
+                exit();
659
+            }
660
+            //handle password expiry warning
661
+            if($pwdChangedTime && (count($pwdChangedTime) > 0)) {
662
+                if($pwdMaxAge && (count($pwdMaxAge) > 0)
663
+                    && $pwdExpireWarning && (count($pwdExpireWarning) > 0)) {
664
+                    $pwdMaxAgeInt = intval($pwdMaxAge[0]);
665
+                    $pwdExpireWarningInt = intval($pwdExpireWarning[0]);
666
+                    if($pwdMaxAgeInt > 0 && $pwdExpireWarningInt > 0){
667
+                        $pwdChangedTimeDt = \DateTime::createFromFormat('YmdHisZ', $pwdChangedTime[0]);
668
+                        $pwdChangedTimeDt->add(new \DateInterval('PT'.$pwdMaxAgeInt.'S'));
669
+                        $currentDateTime = new \DateTime();
670
+                        $secondsToExpiry = $pwdChangedTimeDt->getTimestamp() - $currentDateTime->getTimestamp();
671
+                        if($secondsToExpiry <= $pwdExpireWarningInt) {
672
+                            //remove last password expiry warning if any
673
+                            $notification = $this->notificationManager->createNotification();
674
+                            $notification->setApp('user_ldap')
675
+                                ->setUser($uid)
676
+                                ->setObject('pwd_exp_warn', $uid)
677
+                            ;
678
+                            $this->notificationManager->markProcessed($notification);
679
+                            //create new password expiry warning
680
+                            $notification = $this->notificationManager->createNotification();
681
+                            $notification->setApp('user_ldap')
682
+                                ->setUser($uid)
683
+                                ->setDateTime($currentDateTime)
684
+                                ->setObject('pwd_exp_warn', $uid) 
685
+                                ->setSubject('pwd_exp_warn_days', [(int) ceil($secondsToExpiry / 60 / 60 / 24)])
686
+                            ;
687
+                            $this->notificationManager->notify($notification);
688
+                        }
689
+                    }
690
+                }
691
+            }
692
+        }
693
+    }
694 694
 }
Please login to merge, or discard this patch.
Spacing   +58 added lines, -58 removed lines patch added patch discarded remove patch
@@ -149,17 +149,17 @@  discard block
 block discarded – undo
149 149
 	 * @return null
150 150
 	 */
151 151
 	public function update() {
152
-		if(is_null($this->dn)) {
152
+		if (is_null($this->dn)) {
153 153
 			return null;
154 154
 		}
155 155
 
156 156
 		$hasLoggedIn = $this->config->getUserValue($this->uid, 'user_ldap',
157 157
 				self::USER_PREFKEY_FIRSTLOGIN, 0);
158 158
 
159
-		if($this->needsRefresh()) {
159
+		if ($this->needsRefresh()) {
160 160
 			$this->updateEmail();
161 161
 			$this->updateQuota();
162
-			if($hasLoggedIn !== 0) {
162
+			if ($hasLoggedIn !== 0) {
163 163
 				//we do not need to try it, when the user has not been logged in
164 164
 				//before, because the file system will not be ready.
165 165
 				$this->updateAvatar();
@@ -178,7 +178,7 @@  discard block
 block discarded – undo
178 178
 		$this->markRefreshTime();
179 179
 		//Quota
180 180
 		$attr = strtolower($this->connection->ldapQuotaAttribute);
181
-		if(isset($ldapEntry[$attr])) {
181
+		if (isset($ldapEntry[$attr])) {
182 182
 			$this->updateQuota($ldapEntry[$attr][0]);
183 183
 		} else {
184 184
 			if ($this->connection->ldapQuotaDefault !== '') {
@@ -189,7 +189,7 @@  discard block
 block discarded – undo
189 189
 
190 190
 		//Email
191 191
 		$attr = strtolower($this->connection->ldapEmailAttribute);
192
-		if(isset($ldapEntry[$attr])) {
192
+		if (isset($ldapEntry[$attr])) {
193 193
 			$this->updateEmail($ldapEntry[$attr][0]);
194 194
 		}
195 195
 		unset($attr);
@@ -197,11 +197,11 @@  discard block
 block discarded – undo
197 197
 		//displayName
198 198
 		$displayName = $displayName2 = '';
199 199
 		$attr = strtolower($this->connection->ldapUserDisplayName);
200
-		if(isset($ldapEntry[$attr])) {
200
+		if (isset($ldapEntry[$attr])) {
201 201
 			$displayName = strval($ldapEntry[$attr][0]);
202 202
 		}
203 203
 		$attr = strtolower($this->connection->ldapUserDisplayName2);
204
-		if(isset($ldapEntry[$attr])) {
204
+		if (isset($ldapEntry[$attr])) {
205 205
 			$displayName2 = strval($ldapEntry[$attr][0]);
206 206
 		}
207 207
 		if ($displayName !== '') {
@@ -215,16 +215,16 @@  discard block
 block discarded – undo
215 215
 		unset($attr);
216 216
 
217 217
 		// LDAP Username, needed for s2s sharing
218
-		if(isset($ldapEntry['uid'])) {
218
+		if (isset($ldapEntry['uid'])) {
219 219
 			$this->storeLDAPUserName($ldapEntry['uid'][0]);
220
-		} else if(isset($ldapEntry['samaccountname'])) {
220
+		} else if (isset($ldapEntry['samaccountname'])) {
221 221
 			$this->storeLDAPUserName($ldapEntry['samaccountname'][0]);
222 222
 		}
223 223
 
224 224
 		//homePath
225
-		if(strpos($this->connection->homeFolderNamingRule, 'attr:') === 0) {
225
+		if (strpos($this->connection->homeFolderNamingRule, 'attr:') === 0) {
226 226
 			$attr = strtolower(substr($this->connection->homeFolderNamingRule, strlen('attr:')));
227
-			if(isset($ldapEntry[$attr])) {
227
+			if (isset($ldapEntry[$attr])) {
228 228
 				$this->access->cacheUserHome(
229 229
 					$this->getUsername(), $this->getHomePath($ldapEntry[$attr][0]));
230 230
 			}
@@ -233,15 +233,15 @@  discard block
 block discarded – undo
233 233
 		//memberOf groups
234 234
 		$cacheKey = 'getMemberOf'.$this->getUsername();
235 235
 		$groups = false;
236
-		if(isset($ldapEntry['memberof'])) {
236
+		if (isset($ldapEntry['memberof'])) {
237 237
 			$groups = $ldapEntry['memberof'];
238 238
 		}
239 239
 		$this->connection->writeToCache($cacheKey, $groups);
240 240
 
241 241
 		//Avatar
242 242
 		$attrs = array('jpegphoto', 'thumbnailphoto');
243
-		foreach ($attrs as $attr)  {
244
-			if(isset($ldapEntry[$attr])) {
243
+		foreach ($attrs as $attr) {
244
+			if (isset($ldapEntry[$attr])) {
245 245
 				$this->avatarImage = $ldapEntry[$attr][0];
246 246
 				// the call to the method that saves the avatar in the file
247 247
 				// system must be postponed after the login. It is to ensure
@@ -294,12 +294,12 @@  discard block
 block discarded – undo
294 294
 		if ($path !== '') {
295 295
 			//if attribute's value is an absolute path take this, otherwise append it to data dir
296 296
 			//check for / at the beginning or pattern c:\ resp. c:/
297
-			if(   '/' !== $path[0]
297
+			if ('/' !== $path[0]
298 298
 			   && !(3 < strlen($path) && ctype_alpha($path[0])
299 299
 			       && $path[1] === ':' && ('\\' === $path[2] || '/' === $path[2]))
300 300
 			) {
301 301
 				$path = $this->config->getSystemValue('datadirectory',
302
-						\OC::$SERVERROOT.'/data' ) . '/' . $path;
302
+						\OC::$SERVERROOT.'/data').'/'.$path;
303 303
 			}
304 304
 			//we need it to store it in the DB as well in case a user gets
305 305
 			//deleted so we can clean up afterwards
@@ -309,11 +309,11 @@  discard block
 block discarded – undo
309 309
 			return $path;
310 310
 		}
311 311
 
312
-		if(    !is_null($attr)
312
+		if (!is_null($attr)
313 313
 			&& $this->config->getAppValue('user_ldap', 'enforce_home_folder_naming_rule', true)
314 314
 		) {
315 315
 			// a naming rule attribute is defined, but it doesn't exist for that LDAP user
316
-			throw new \Exception('Home dir attribute can\'t be read from LDAP for uid: ' . $this->getUsername());
316
+			throw new \Exception('Home dir attribute can\'t be read from LDAP for uid: '.$this->getUsername());
317 317
 		}
318 318
 
319 319
 		//false will apply default behaviour as defined and done by OC_User
@@ -324,7 +324,7 @@  discard block
 block discarded – undo
324 324
 	public function getMemberOfGroups() {
325 325
 		$cacheKey = 'getMemberOf'.$this->getUsername();
326 326
 		$memberOfGroups = $this->connection->getFromCache($cacheKey);
327
-		if(!is_null($memberOfGroups)) {
327
+		if (!is_null($memberOfGroups)) {
328 328
 			return $memberOfGroups;
329 329
 		}
330 330
 		$groupDNs = $this->access->readAttribute($this->getDN(), 'memberOf');
@@ -337,15 +337,15 @@  discard block
 block discarded – undo
337 337
 	 * @return string data (provided by LDAP) | false
338 338
 	 */
339 339
 	public function getAvatarImage() {
340
-		if(!is_null($this->avatarImage)) {
340
+		if (!is_null($this->avatarImage)) {
341 341
 			return $this->avatarImage;
342 342
 		}
343 343
 
344 344
 		$this->avatarImage = false;
345 345
 		$attributes = array('jpegPhoto', 'thumbnailPhoto');
346
-		foreach($attributes as $attribute) {
346
+		foreach ($attributes as $attribute) {
347 347
 			$result = $this->access->readAttribute($this->dn, $attribute);
348
-			if($result !== false && is_array($result) && isset($result[0])) {
348
+			if ($result !== false && is_array($result) && isset($result[0])) {
349 349
 				$this->avatarImage = $result[0];
350 350
 				break;
351 351
 			}
@@ -382,7 +382,7 @@  discard block
 block discarded – undo
382 382
 		$lastChecked = $this->config->getUserValue($this->uid, 'user_ldap',
383 383
 			self::USER_PREFKEY_LASTREFRESH, 0);
384 384
 
385
-		if((time() - intval($lastChecked)) < intval($this->config->getAppValue('user_ldap', 'updateAttributesInterval', 86400)) ) {
385
+		if ((time() - intval($lastChecked)) < intval($this->config->getAppValue('user_ldap', 'updateAttributesInterval', 86400))) {
386 386
 			return false;
387 387
 		}
388 388
 		return  true;
@@ -408,8 +408,8 @@  discard block
 block discarded – undo
408 408
 	 */
409 409
 	public function composeAndStoreDisplayName($displayName, $displayName2 = '') {
410 410
 		$displayName2 = strval($displayName2);
411
-		if($displayName2 !== '') {
412
-			$displayName .= ' (' . $displayName2 . ')';
411
+		if ($displayName2 !== '') {
412
+			$displayName .= ' ('.$displayName2.')';
413 413
 		}
414 414
 		$this->store('displayName', $displayName);
415 415
 		return $displayName;
@@ -431,7 +431,7 @@  discard block
 block discarded – undo
431 431
 	 * @return bool
432 432
 	 */
433 433
 	private function wasRefreshed($feature) {
434
-		if(isset($this->refreshedFeatures[$feature])) {
434
+		if (isset($this->refreshedFeatures[$feature])) {
435 435
 			return true;
436 436
 		}
437 437
 		$this->refreshedFeatures[$feature] = 1;
@@ -444,15 +444,15 @@  discard block
 block discarded – undo
444 444
 	 * @return null
445 445
 	 */
446 446
 	public function updateEmail($valueFromLDAP = null) {
447
-		if($this->wasRefreshed('email')) {
447
+		if ($this->wasRefreshed('email')) {
448 448
 			return;
449 449
 		}
450 450
 		$email = strval($valueFromLDAP);
451
-		if(is_null($valueFromLDAP)) {
451
+		if (is_null($valueFromLDAP)) {
452 452
 			$emailAttribute = $this->connection->ldapEmailAttribute;
453 453
 			if ($emailAttribute !== '') {
454 454
 				$aEmail = $this->access->readAttribute($this->dn, $emailAttribute);
455
-				if(is_array($aEmail) && (count($aEmail) > 0)) {
455
+				if (is_array($aEmail) && (count($aEmail) > 0)) {
456 456
 					$email = strval($aEmail[0]);
457 457
 				}
458 458
 			}
@@ -489,20 +489,20 @@  discard block
 block discarded – undo
489 489
 	 * @return null
490 490
 	 */
491 491
 	public function updateQuota($valueFromLDAP = null) {
492
-		if($this->wasRefreshed('quota')) {
492
+		if ($this->wasRefreshed('quota')) {
493 493
 			return;
494 494
 		}
495 495
 
496 496
 		$quota = false;
497
-		if(is_null($valueFromLDAP)) {
497
+		if (is_null($valueFromLDAP)) {
498 498
 			$quotaAttribute = $this->connection->ldapQuotaAttribute;
499 499
 			if ($quotaAttribute !== '') {
500 500
 				$aQuota = $this->access->readAttribute($this->dn, $quotaAttribute);
501
-				if($aQuota && (count($aQuota) > 0)) {
501
+				if ($aQuota && (count($aQuota) > 0)) {
502 502
 					if ($this->verifyQuotaValue($aQuota[0])) {
503 503
 						$quota = $aQuota[0];
504 504
 					} else {
505
-						$this->log->log('not suitable LDAP quota found for user ' . $this->uid . ': [' . $aQuota[0] . ']', \OCP\Util::WARN);
505
+						$this->log->log('not suitable LDAP quota found for user '.$this->uid.': ['.$aQuota[0].']', \OCP\Util::WARN);
506 506
 					}
507 507
 				}
508 508
 			}
@@ -510,7 +510,7 @@  discard block
 block discarded – undo
510 510
 			if ($this->verifyQuotaValue($valueFromLDAP)) {
511 511
 				$quota = $valueFromLDAP;
512 512
 			} else {
513
-				$this->log->log('not suitable LDAP quota found for user ' . $this->uid . ': [' . $valueFromLDAP . ']', \OCP\Util::WARN);
513
+				$this->log->log('not suitable LDAP quota found for user '.$this->uid.': ['.$valueFromLDAP.']', \OCP\Util::WARN);
514 514
 			}
515 515
 		}
516 516
 
@@ -524,14 +524,14 @@  discard block
 block discarded – undo
524 524
 
525 525
 		$targetUser = $this->userManager->get($this->uid);
526 526
 		if ($targetUser) {
527
-			if($quota !== false) {
527
+			if ($quota !== false) {
528 528
 				$targetUser->setQuota($quota);
529 529
 			} else {
530
-				$this->log->log('not suitable default quota found for user ' . $this->uid . ': [' . $defaultQuota . ']', \OCP\Util::WARN);
530
+				$this->log->log('not suitable default quota found for user '.$this->uid.': ['.$defaultQuota.']', \OCP\Util::WARN);
531 531
 				$targetUser->setQuota('default');
532 532
 			}
533 533
 		} else {
534
-			$this->log->log('trying to set a quota for user ' . $this->uid . ' but the user is missing', \OCP\Util::ERROR);
534
+			$this->log->log('trying to set a quota for user '.$this->uid.' but the user is missing', \OCP\Util::ERROR);
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,11 +555,11 @@  discard block
 block discarded – undo
555 555
 	 * @return null
556 556
 	 */
557 557
 	public function updateAvatar() {
558
-		if($this->wasRefreshed('avatar')) {
558
+		if ($this->wasRefreshed('avatar')) {
559 559
 			return;
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;
565 565
 		}
@@ -572,18 +572,18 @@  discard block
 block discarded – undo
572 572
 	 * @return null
573 573
 	 */
574 574
 	private function setOwnCloudAvatar() {
575
-		if(!$this->image->valid()) {
575
+		if (!$this->image->valid()) {
576 576
 			$this->log->log('jpegPhoto data invalid for '.$this->dn, \OCP\Util::ERROR);
577 577
 			return;
578 578
 		}
579 579
 		//make sure it is a square and not bigger than 128x128
580 580
 		$size = min(array($this->image->width(), $this->image->height(), 128));
581
-		if(!$this->image->centerCrop($size)) {
581
+		if (!$this->image->centerCrop($size)) {
582 582
 			$this->log->log('croping image for avatar failed for '.$this->dn, \OCP\Util::ERROR);
583 583
 			return;
584 584
 		}
585 585
 
586
-		if(!$this->fs->isLoaded()) {
586
+		if (!$this->fs->isLoaded()) {
587 587
 			$this->fs->setup($this->uid);
588 588
 		}
589 589
 
@@ -592,7 +592,7 @@  discard block
 block discarded – undo
592 592
 			$avatar->set($this->image);
593 593
 		} catch (\Exception $e) {
594 594
 			\OC::$server->getLogger()->notice(
595
-				'Could not set avatar for ' . $this->dn	. ', because: ' . $e->getMessage(),
595
+				'Could not set avatar for '.$this->dn.', because: '.$e->getMessage(),
596 596
 				['app' => 'user_ldap']);
597 597
 		}
598 598
 	}
@@ -605,17 +605,17 @@  discard block
 block discarded – undo
605 605
 	public function handlePasswordExpiry($params) {
606 606
 		$ppolicyDN = $this->connection->ldapDefaultPPolicyDN;
607 607
 		if (empty($ppolicyDN) || (intval($this->connection->turnOnPasswordChange) !== 1)) {
608
-			return;//password expiry handling disabled
608
+			return; //password expiry handling disabled
609 609
 		}
610 610
 		$uid = $params['uid'];
611
-		if(isset($uid) && $uid === $this->getUsername()) {
611
+		if (isset($uid) && $uid === $this->getUsername()) {
612 612
 			//retrieve relevant user attributes
613 613
 			$result = $this->access->search('objectclass=*', $this->dn, ['pwdpolicysubentry', 'pwdgraceusetime', 'pwdreset', 'pwdchangedtime']);
614 614
 			
615
-			if(array_key_exists('pwdpolicysubentry', $result[0])) {
615
+			if (array_key_exists('pwdpolicysubentry', $result[0])) {
616 616
 				$pwdPolicySubentry = $result[0]['pwdpolicysubentry'];
617
-				if($pwdPolicySubentry && (count($pwdPolicySubentry) > 0)){
618
-					$ppolicyDN = $pwdPolicySubentry[0];//custom ppolicy DN
617
+				if ($pwdPolicySubentry && (count($pwdPolicySubentry) > 0)) {
618
+					$ppolicyDN = $pwdPolicySubentry[0]; //custom ppolicy DN
619 619
 				}
620 620
 			}
621 621
 			
@@ -624,9 +624,9 @@  discard block
 block discarded – undo
624 624
 			$pwdChangedTime = array_key_exists('pwdchangedtime', $result[0]) ? $result[0]['pwdchangedtime'] : null;
625 625
 			
626 626
 			//retrieve relevant password policy attributes
627
-			$cacheKey = 'ppolicyAttributes' . $ppolicyDN;
627
+			$cacheKey = 'ppolicyAttributes'.$ppolicyDN;
628 628
 			$result = $this->connection->getFromCache($cacheKey);
629
-			if(is_null($result)) {
629
+			if (is_null($result)) {
630 630
 				$result = $this->access->search('objectclass=*', $ppolicyDN, ['pwdgraceauthnlimit', 'pwdmaxage', 'pwdexpirewarning']);
631 631
 				$this->connection->writeToCache($cacheKey, $result);
632 632
 			}
@@ -637,8 +637,8 @@  discard block
 block discarded – undo
637 637
 			
638 638
 			//handle grace login
639 639
 			$pwdGraceUseTimeCount = count($pwdGraceUseTime);
640
-			if($pwdGraceUseTime && $pwdGraceUseTimeCount > 0) { //was this a grace login?
641
-				if($pwdGraceAuthNLimit 
640
+			if ($pwdGraceUseTime && $pwdGraceUseTimeCount > 0) { //was this a grace login?
641
+				if ($pwdGraceAuthNLimit 
642 642
 					&& (count($pwdGraceAuthNLimit) > 0)
643 643
 					&&($pwdGraceUseTimeCount < intval($pwdGraceAuthNLimit[0]))) { //at least one more grace login available?
644 644
 					$this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true');
@@ -651,24 +651,24 @@  discard block
 block discarded – undo
651 651
 				exit();
652 652
 			}
653 653
 			//handle pwdReset attribute
654
-			if($pwdReset && (count($pwdReset) > 0) && $pwdReset[0] === 'TRUE') { //user must change his password
654
+			if ($pwdReset && (count($pwdReset) > 0) && $pwdReset[0] === 'TRUE') { //user must change his password
655 655
 				$this->config->setUserValue($uid, 'user_ldap', 'needsPasswordReset', 'true');
656 656
 				header('Location: '.\OC::$server->getURLGenerator()->linkToRouteAbsolute(
657 657
 				'user_ldap.renewPassword.showRenewPasswordForm', array('user' => $uid)));
658 658
 				exit();
659 659
 			}
660 660
 			//handle password expiry warning
661
-			if($pwdChangedTime && (count($pwdChangedTime) > 0)) {
662
-				if($pwdMaxAge && (count($pwdMaxAge) > 0)
661
+			if ($pwdChangedTime && (count($pwdChangedTime) > 0)) {
662
+				if ($pwdMaxAge && (count($pwdMaxAge) > 0)
663 663
 					&& $pwdExpireWarning && (count($pwdExpireWarning) > 0)) {
664 664
 					$pwdMaxAgeInt = intval($pwdMaxAge[0]);
665 665
 					$pwdExpireWarningInt = intval($pwdExpireWarning[0]);
666
-					if($pwdMaxAgeInt > 0 && $pwdExpireWarningInt > 0){
666
+					if ($pwdMaxAgeInt > 0 && $pwdExpireWarningInt > 0) {
667 667
 						$pwdChangedTimeDt = \DateTime::createFromFormat('YmdHisZ', $pwdChangedTime[0]);
668 668
 						$pwdChangedTimeDt->add(new \DateInterval('PT'.$pwdMaxAgeInt.'S'));
669 669
 						$currentDateTime = new \DateTime();
670 670
 						$secondsToExpiry = $pwdChangedTimeDt->getTimestamp() - $currentDateTime->getTimestamp();
671
-						if($secondsToExpiry <= $pwdExpireWarningInt) {
671
+						if ($secondsToExpiry <= $pwdExpireWarningInt) {
672 672
 							//remove last password expiry warning if any
673 673
 							$notification = $this->notificationManager->createNotification();
674 674
 							$notification->setApp('user_ldap')
Please login to merge, or discard this patch.