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