Completed
Push — stable9 ( 18a92c...76d761 )
by Morris
142:57 queued 131:11
created

User::updateEmail()   C

Complexity

Conditions 8
Paths 13

Size

Total Lines 22
Code Lines 15

Duplication

Lines 9
Ratio 40.91 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 8
eloc 15
c 1
b 0
f 0
nc 13
nop 1
dl 9
loc 22
rs 6.6037
1
<?php
2
/**
3
 * @copyright Copyright (c) 2016, ownCloud, Inc.
4
 *
5
 * @author Arthur Schiwon <[email protected]>
6
 * @author Joas Schilling <[email protected]>
7
 * @author Morris Jobke <[email protected]>
8
 * @author Thomas Müller <[email protected]>
9
 *
10
 * @license AGPL-3.0
11
 *
12
 * This code is free software: you can redistribute it and/or modify
13
 * it under the terms of the GNU Affero General Public License, version 3,
14
 * as published by the Free Software Foundation.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
 * GNU Affero General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU Affero General Public License, version 3,
22
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
23
 *
24
 */
25
26
namespace OCA\user_ldap\lib\user;
27
28
use OCA\user_ldap\lib\user\IUserTools;
29
use OCA\user_ldap\lib\Connection;
30
use OCA\user_ldap\lib\FilesystemHelper;
31
use OCA\user_ldap\lib\LogWrapper;
32
use OCP\IAvatarManager;
33
use OCP\IConfig;
34
use OCP\IUserManager;
35
36
/**
37
 * User
38
 *
39
 * represents an LDAP user, gets and holds user-specific information from LDAP
40
 */
41
class User {
42
	/**
43
	 * @var IUserTools
44
	 */
45
	protected $access;
46
	/**
47
	 * @var Connection
48
	 */
49
	protected $connection;
50
	/**
51
	 * @var IConfig
52
	 */
53
	protected $config;
54
	/**
55
	 * @var FilesystemHelper
56
	 */
57
	protected $fs;
58
	/**
59
	 * @var \OCP\Image
60
	 */
61
	protected $image;
62
	/**
63
	 * @var LogWrapper
64
	 */
65
	protected $log;
66
	/**
67
	 * @var IAvatarManager
68
	 */
69
	protected $avatarManager;
70
	/**
71
	 * @var IUserManager
72
	 */
73
	protected $userManager;
74
	/**
75
	 * @var string
76
	 */
77
	protected $dn;
78
	/**
79
	 * @var string
80
	 */
81
	protected $uid;
82
	/**
83
	 * @var string[]
84
	 */
85
	protected $refreshedFeatures = array();
86
	/**
87
	 * @var string
88
	 */
89
	protected $avatarImage;
90
91
	/**
92
	 * DB config keys for user preferences
93
	 */
94
	const USER_PREFKEY_FIRSTLOGIN  = 'firstLoginAccomplished';
95
	const USER_PREFKEY_LASTREFRESH = 'lastFeatureRefresh';
96
97
	/**
98
	 * @brief constructor, make sure the subclasses call this one!
99
	 * @param string $username the internal username
100
	 * @param string $dn the LDAP DN
101
	 * @param IUserTools $access an instance that implements IUserTools for
102
	 * LDAP interaction
103
	 * @param IConfig $config
104
	 * @param FilesystemHelper $fs
105
	 * @param \OCP\Image $image any empty instance
106
	 * @param LogWrapper $log
107
	 * @param IAvatarManager $avatarManager
108
	 * @param IUserManager $userManager
109
	 */
110
	public function __construct($username, $dn, IUserTools $access,
111
		IConfig $config, FilesystemHelper $fs, \OCP\Image $image,
112
		LogWrapper $log, IAvatarManager $avatarManager, IUserManager $userManager) {
113
114
		$this->access        = $access;
115
		$this->connection    = $access->getConnection();
116
		$this->config        = $config;
117
		$this->fs            = $fs;
118
		$this->dn            = $dn;
119
		$this->uid           = $username;
120
		$this->image         = $image;
121
		$this->log           = $log;
122
		$this->avatarManager = $avatarManager;
123
		$this->userManager   = $userManager;
124
	}
125
126
	/**
127
	 * @brief updates properties like email, quota or avatar provided by LDAP
128
	 * @return null
129
	 */
130
	public function update() {
131
		if(is_null($this->dn)) {
132
			return null;
133
		}
134
135
		$hasLoggedIn = $this->config->getUserValue($this->uid, 'user_ldap',
136
				self::USER_PREFKEY_FIRSTLOGIN, 0);
137
138
		if($this->needsRefresh()) {
139
			$this->updateEmail();
140
			$this->updateQuota();
141
			if($hasLoggedIn !== 0) {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison !== seems to always evaluate to true as the types of $hasLoggedIn (string) and 0 (integer) can never be identical. Maybe you want to use a loose comparison != instead?
Loading history...
142
				//we do not need to try it, when the user has not been logged in
143
				//before, because the file system will not be ready.
144
				$this->updateAvatar();
145
				//in order to get an avatar as soon as possible, mark the user
146
				//as refreshed only when updating the avatar did happen
147
				$this->markRefreshTime();
148
			}
149
		}
150
	}
151
152
	/**
153
	 * processes results from LDAP for attributes as returned by getAttributesToRead()
154
	 * @param array $ldapEntry the user entry as retrieved from LDAP
155
	 */
156
	public function processAttributes($ldapEntry) {
157
		$this->markRefreshTime();
158
		//Quota
159
		$attr = strtolower($this->connection->ldapQuotaAttribute);
0 ignored issues
show
Documentation introduced by
The property ldapQuotaAttribute does not exist on object<OCA\user_ldap\lib\Connection>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
160
		if(isset($ldapEntry[$attr])) {
161
			$this->updateQuota($ldapEntry[$attr][0]);
162
		}
163
		unset($attr);
164
165
		//Email
166
		$attr = strtolower($this->connection->ldapEmailAttribute);
0 ignored issues
show
Documentation introduced by
The property ldapEmailAttribute does not exist on object<OCA\user_ldap\lib\Connection>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
167
		if(isset($ldapEntry[$attr])) {
168
			$this->updateEmail($ldapEntry[$attr][0]);
169
		}
170
		unset($attr);
171
172
		//displayName
173
		$displayName = $displayName2 = '';
174
		$attr = strtolower($this->connection->ldapUserDisplayName);
175
		if(isset($ldapEntry[$attr])) {
176
			$displayName = $ldapEntry[$attr][0];
177
		}
178
		$attr = strtolower($this->connection->ldapUserDisplayName2);
179
		if(isset($ldapEntry[$attr])) {
180
			$displayName2 = $ldapEntry[$attr][0];
181
		}
182
		if(!empty($displayName)) {
183
			$this->composeAndStoreDisplayName($displayName);
184
			$this->access->cacheUserDisplayName(
185
				$this->getUsername(),
186
				$displayName,
187
				$displayName2
188
			);
189
		}
190
		unset($attr);
191
192
		// LDAP Username, needed for s2s sharing
193
		if(isset($ldapEntry['uid'])) {
194
			$this->storeLDAPUserName($ldapEntry['uid'][0]);
195
		} else if(isset($ldapEntry['samaccountname'])) {
196
			$this->storeLDAPUserName($ldapEntry['samaccountname'][0]);
197
		}
198
199
		//homePath
200
		if(strpos($this->connection->homeFolderNamingRule, 'attr:') === 0) {
0 ignored issues
show
Documentation introduced by
The property homeFolderNamingRule does not exist on object<OCA\user_ldap\lib\Connection>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
201
			$attr = strtolower(substr($this->connection->homeFolderNamingRule, strlen('attr:')));
0 ignored issues
show
Documentation introduced by
The property homeFolderNamingRule does not exist on object<OCA\user_ldap\lib\Connection>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
202
			if(isset($ldapEntry[$attr])) {
203
				$this->access->cacheUserHome(
204
					$this->getUsername(), $this->getHomePath($ldapEntry[$attr][0]));
205
			}
206
		}
207
208
		//memberOf groups
209
		$cacheKey = 'getMemberOf'.$this->getUsername();
210
		$groups = false;
211
		if(isset($ldapEntry['memberof'])) {
212
			$groups = $ldapEntry['memberof'];
213
		}
214
		$this->connection->writeToCache($cacheKey, $groups);
215
216
		//Avatar
217
		$attrs = array('jpegphoto', 'thumbnailphoto');
218
		foreach ($attrs as $attr)  {
219
			if(isset($ldapEntry[$attr])) {
220
				$this->avatarImage = $ldapEntry[$attr][0];
221
				// the call to the method that saves the avatar in the file
222
				// system must be postponed after the login. It is to ensure
223
				// external mounts are mounted properly (e.g. with login
224
				// credentials from the session).
225
				\OCP\Util::connectHook('OC_User', 'post_login', $this, 'updateAvatarPostLogin');
226
				break;
227
			}
228
		}
229
	}
230
231
	/**
232
	 * @brief returns the LDAP DN of the user
233
	 * @return string
234
	 */
235
	public function getDN() {
236
		return $this->dn;
237
	}
238
239
	/**
240
	 * @brief returns the ownCloud internal username of the user
241
	 * @return string
242
	 */
243
	public function getUsername() {
244
		return $this->uid;
245
	}
246
247
	/**
248
	 * returns the home directory of the user if specified by LDAP settings
249
	 * @param string $valueFromLDAP
250
	 * @return bool|string
251
	 * @throws \Exception
252
	 */
253
	public function getHomePath($valueFromLDAP = null) {
254
		$path = $valueFromLDAP;
255
		$attr = null;
256
257
		if(   is_null($path)
258
		   && strpos($this->access->connection->homeFolderNamingRule, 'attr:') === 0
0 ignored issues
show
Bug introduced by
Accessing connection on the interface OCA\user_ldap\lib\user\IUserTools suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
259
		   && $this->access->connection->homeFolderNamingRule !== 'attr:')
0 ignored issues
show
Bug introduced by
Accessing connection on the interface OCA\user_ldap\lib\user\IUserTools suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
260
		{
261
			$attr = substr($this->access->connection->homeFolderNamingRule, strlen('attr:'));
0 ignored issues
show
Bug introduced by
Accessing connection on the interface OCA\user_ldap\lib\user\IUserTools suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
262
			$homedir = $this->access->readAttribute(
263
				$this->access->username2dn($this->getUsername()), $attr);
264
			if ($homedir && isset($homedir[0])) {
265
				$path = $homedir[0];
266
			}
267
		}
268
269
		if(!empty($path)) {
270
			//if attribute's value is an absolute path take this, otherwise append it to data dir
271
			//check for / at the beginning or pattern c:\ resp. c:/
272
			if(   '/' !== $path[0]
273
			   && !(3 < strlen($path) && ctype_alpha($path[0])
274
			       && $path[1] === ':' && ('\\' === $path[2] || '/' === $path[2]))
275
			) {
276
				$path = $this->config->getSystemValue('datadirectory',
277
						\OC::$SERVERROOT.'/data' ) . '/' . $path;
278
			}
279
			//we need it to store it in the DB as well in case a user gets
280
			//deleted so we can clean up afterwards
281
			$this->config->setUserValue(
282
				$this->getUsername(), 'user_ldap', 'homePath', $path
283
			);
284
			return $path;
285
		}
286
287
		if(    !is_null($attr)
288
			&& $this->config->getAppValue('user_ldap', 'enforce_home_folder_naming_rule', true)
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
289
		) {
290
			// a naming rule attribute is defined, but it doesn't exist for that LDAP user
291
			throw new \Exception('Home dir attribute can\'t be read from LDAP for uid: ' . $this->getUsername());
292
		}
293
294
		//false will apply default behaviour as defined and done by OC_User
295
		$this->config->setUserValue($this->getUsername(), 'user_ldap', 'homePath', '');
296
		return false;
297
	}
298
299
	public function getMemberOfGroups() {
300
		$cacheKey = 'getMemberOf'.$this->getUsername();
301
		$memberOfGroups = $this->connection->getFromCache($cacheKey);
302
		if(!is_null($memberOfGroups)) {
303
			return $memberOfGroups;
304
		}
305
		$groupDNs = $this->access->readAttribute($this->getDN(), 'memberOf');
306
		$this->connection->writeToCache($cacheKey, $groupDNs);
307
		return $groupDNs;
308
	}
309
310
	/**
311
	 * @brief reads the image from LDAP that shall be used as Avatar
312
	 * @return string data (provided by LDAP) | false
313
	 */
314
	public function getAvatarImage() {
315
		if(!is_null($this->avatarImage)) {
316
			return $this->avatarImage;
317
		}
318
319
		$this->avatarImage = false;
0 ignored issues
show
Documentation Bug introduced by
The property $avatarImage was declared of type string, but false is of type false. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
320
		$attributes = array('jpegPhoto', 'thumbnailPhoto');
321
		foreach($attributes as $attribute) {
322
			$result = $this->access->readAttribute($this->dn, $attribute);
323
			if($result !== false && is_array($result) && isset($result[0])) {
324
				$this->avatarImage = $result[0];
325
				break;
326
			}
327
		}
328
329
		return $this->avatarImage;
330
	}
331
332
	/**
333
	 * @brief marks the user as having logged in at least once
334
	 * @return null
335
	 */
336
	public function markLogin() {
337
		$this->config->setUserValue(
338
			$this->uid, 'user_ldap', self::USER_PREFKEY_FIRSTLOGIN, 1);
339
	}
340
341
	/**
342
	 * @brief marks the time when user features like email have been updated
343
	 * @return null
344
	 */
345
	public function markRefreshTime() {
346
		$this->config->setUserValue(
347
			$this->uid, 'user_ldap', self::USER_PREFKEY_LASTREFRESH, time());
348
	}
349
350
	/**
351
	 * @brief checks whether user features needs to be updated again by
352
	 * comparing the difference of time of the last refresh to now with the
353
	 * desired interval
354
	 * @return bool
355
	 */
356
	private function needsRefresh() {
357
		$lastChecked = $this->config->getUserValue($this->uid, 'user_ldap',
358
			self::USER_PREFKEY_LASTREFRESH, 0);
359
360
		//TODO make interval configurable
361
		if((time() - intval($lastChecked)) < 86400 ) {
362
			return false;
363
		}
364
		return  true;
365
	}
366
367
	/**
368
	 * Stores a key-value pair in relation to this user
369
	 *
370
	 * @param string $key
371
	 * @param string $value
372
	 */
373
	private function store($key, $value) {
374
		$this->config->setUserValue($this->uid, 'user_ldap', $key, $value);
375
	}
376
377
	/**
378
	 * Composes the display name and stores it in the database. The final
379
	 * display name is returned.
380
	 *
381
	 * @param string $displayName
382
	 * @param string $displayName2
383
	 * @returns string the effective display name
384
	 */
385
	public function composeAndStoreDisplayName($displayName, $displayName2 = '') {
386
		if(!empty($displayName2)) {
387
			$displayName .= ' (' . $displayName2 . ')';
388
		}
389
		$this->store('displayName', $displayName);
390
		return $displayName;
391
	}
392
393
	/**
394
	 * Stores the LDAP Username in the Database
395
	 * @param string $userName
396
	 */
397
	public function storeLDAPUserName($userName) {
398
		$this->store('uid', $userName);
399
	}
400
401
	/**
402
	 * @brief checks whether an update method specified by feature was run
403
	 * already. If not, it will marked like this, because it is expected that
404
	 * the method will be run, when false is returned.
405
	 * @param string $feature email | quota | avatar (can be extended)
406
	 * @return bool
407
	 */
408
	private function wasRefreshed($feature) {
409
		if(isset($this->refreshedFeatures[$feature])) {
410
			return true;
411
		}
412
		$this->refreshedFeatures[$feature] = 1;
413
		return false;
414
	}
415
416
	/**
417
	 * fetches the email from LDAP and stores it as ownCloud user value
418
	 * @param string $valueFromLDAP if known, to save an LDAP read request
419
	 * @return null
420
	 */
421
	public function updateEmail($valueFromLDAP = null) {
422
		if($this->wasRefreshed('email')) {
423
			return;
424
		}
425
		$email = $valueFromLDAP;
426 View Code Duplication
		if(is_null($valueFromLDAP)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
427
			$emailAttribute = $this->connection->ldapEmailAttribute;
0 ignored issues
show
Documentation introduced by
The property ldapEmailAttribute does not exist on object<OCA\user_ldap\lib\Connection>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
428
			if(!empty($emailAttribute)) {
429
				$aEmail = $this->access->readAttribute($this->dn, $emailAttribute);
430
				if(is_array($aEmail) && (count($aEmail) > 0)) {
431
					$email = $aEmail[0];
432
				}
433
			}
434
		}
435
		if(!is_null($email)) {
436
			$user = $this->userManager->get($this->uid);
437
			$currentEmail = $user->getEMailAddress();
438
			if ($currentEmail !== $email) {
439
				$user->setEMailAddress($email);
440
			}
441
		}
442
	}
443
444
	/**
445
	 * fetches the quota from LDAP and stores it as ownCloud user value
446
	 * @param string $valueFromLDAP the quota attribute's value can be passed,
447
	 * to save the readAttribute request
448
	 * @return null
449
	 */
450
	public function updateQuota($valueFromLDAP = null) {
451
		if($this->wasRefreshed('quota')) {
452
			return;
453
		}
454
		//can be null
455
		$quotaDefault = $this->connection->ldapQuotaDefault;
0 ignored issues
show
Documentation introduced by
The property ldapQuotaDefault does not exist on object<OCA\user_ldap\lib\Connection>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
456
		$quota = $quotaDefault !== '' ? $quotaDefault : null;
457
		$quota = !is_null($valueFromLDAP) ? $valueFromLDAP : $quota;
458
459 View Code Duplication
		if(is_null($valueFromLDAP)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
460
			$quotaAttribute = $this->connection->ldapQuotaAttribute;
0 ignored issues
show
Documentation introduced by
The property ldapQuotaAttribute does not exist on object<OCA\user_ldap\lib\Connection>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
461
			if(!empty($quotaAttribute)) {
462
				$aQuota = $this->access->readAttribute($this->dn, $quotaAttribute);
463
				if($aQuota && (count($aQuota) > 0)) {
464
					$quota = $aQuota[0];
465
				}
466
			}
467
		}
468
		if(!is_null($quota)) {
469
			$user = $this->userManager->get($this->uid)->setQuota($quota);
0 ignored issues
show
Unused Code introduced by
$user is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
470
		}
471
	}
472
473
	/**
474
	 * called by a post_login hook to save the avatar picture
475
	 *
476
	 * @param array $params
477
	 */
478
	public function updateAvatarPostLogin($params) {
479
		if(isset($params['uid']) && $params['uid'] === $this->getUsername()) {
480
			$this->updateAvatar();
481
		}
482
	}
483
484
	/**
485
	 * @brief attempts to get an image from LDAP and sets it as ownCloud avatar
486
	 * @return null
487
	 */
488
	public function updateAvatar() {
489
		if($this->wasRefreshed('avatar')) {
490
			return;
491
		}
492
		$avatarImage = $this->getAvatarImage();
493
		if($avatarImage === false) {
494
			//not set, nothing left to do;
495
			return;
496
		}
497
		$this->image->loadFromBase64(base64_encode($avatarImage));
498
		$this->setOwnCloudAvatar();
499
	}
500
501
	/**
502
	 * @brief sets an image as ownCloud avatar
503
	 * @return null
504
	 */
505
	private function setOwnCloudAvatar() {
506 View Code Duplication
		if(!$this->image->valid()) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
507
			$this->log->log('user_ldap', 'jpegPhoto data invalid for '.$this->dn,
508
				\OCP\Util::ERROR);
0 ignored issues
show
Unused Code introduced by
The call to LogWrapper::log() has too many arguments starting with \OCP\Util::ERROR.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
509
			return;
510
		}
511
		//make sure it is a square and not bigger than 128x128
512
		$size = min(array($this->image->width(), $this->image->height(), 128));
513 View Code Duplication
		if(!$this->image->centerCrop($size)) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
514
			$this->log->log('user_ldap',
515
				'croping image for avatar failed for '.$this->dn,
516
				\OCP\Util::ERROR);
0 ignored issues
show
Unused Code introduced by
The call to LogWrapper::log() has too many arguments starting with \OCP\Util::ERROR.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
517
			return;
518
		}
519
520
		if(!$this->fs->isLoaded()) {
521
			$this->fs->setup($this->uid);
522
		}
523
524
		try {
525
			$avatar = $this->avatarManager->getAvatar($this->uid);
526
			$avatar->set($this->image);
527
		} catch (\Exception $e) {
528
			\OC::$server->getLogger()->notice(
529
				'Could not set avatar for ' . $this->dn	. ', because: ' . $e->getMessage(),
530
				['app' => 'user_ldap']);
531
		}
532
	}
533
534
}
535