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