Completed
Push — stable8.2 ( 0d8617...579f50 )
by Morris
12:04
created

User   D

Complexity

Total Complexity 80

Size/Duplication

Total Lines 485
Duplicated Lines 5.98 %

Coupling/Cohesion

Components 1
Dependencies 12

Test Coverage

Coverage 88.41%

Importance

Changes 2
Bugs 1 Features 0
Metric Value
wmc 80
c 2
b 1
f 0
lcom 1
cbo 12
dl 29
loc 485
ccs 206
cts 233
cp 0.8841
rs 4.0645

20 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 14 1
A update() 0 21 4
F processAttributes() 0 74 13
A getDN() 0 3 1
A getUsername() 0 3 1
C getHomePath() 0 45 15
A getMemberOfGroups() 0 9 2
B getAvatarImage() 0 17 6
A markLogin() 0 4 1
A markRefreshTime() 0 4 1
A needsRefresh() 0 10 2
A store() 0 3 1
A composeAndStoreDisplayName() 0 7 2
A storeLDAPUserName() 0 3 1
A wasRefreshed() 0 7 2
B updateEmail() 9 19 7
C updateQuota() 9 22 9
A updateAvatarPostLogin() 0 5 3
A updateAvatar() 0 12 3
B setOwnCloudAvatar() 11 28 5

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like User often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use User, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * @author Arthur Schiwon <[email protected]>
4
 * @author Morris Jobke <[email protected]>
5
 *
6
 * @copyright Copyright (c) 2015, ownCloud, Inc.
7
 * @license AGPL-3.0
8
 *
9
 * This code is free software: you can redistribute it and/or modify
10
 * it under the terms of the GNU Affero General Public License, version 3,
11
 * as published by the Free Software Foundation.
12
 *
13
 * This program is distributed in the hope that it will be useful,
14
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
 * GNU Affero General Public License for more details.
17
 *
18
 * You should have received a copy of the GNU Affero General Public License, version 3,
19
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
20
 *
21
 */
22
23
namespace OCA\user_ldap\lib\user;
24
25
use OCA\user_ldap\lib\user\IUserTools;
26
use OCA\user_ldap\lib\Connection;
27
use OCA\user_ldap\lib\FilesystemHelper;
28
use OCA\user_ldap\lib\LogWrapper;
29
30
/**
31
 * User
32
 *
33
 * represents an LDAP user, gets and holds user-specific information from LDAP
34
 */
35
class User {
36
	/**
37
	 * @var IUserTools
38
	 */
39
	protected $access;
40
	/**
41
	 * @var Connection
42
	 */
43
	protected $connection;
44
	/**
45
	 * @var \OCP\IConfig
46
	 */
47
	protected $config;
48
	/**
49
	 * @var FilesystemHelper
50
	 */
51
	protected $fs;
52
	/**
53
	 * @var \OCP\Image
54
	 */
55
	protected $image;
56
	/**
57
	 * @var LogWrapper
58
	 */
59
	protected $log;
60
	/**
61
	 * @var \OCP\IAvatarManager
62
	 */
63
	protected $avatarManager;
64
65
	/**
66
	 * @var string
67
	 */
68
	protected $dn;
69
	/**
70
	 * @var string
71
	 */
72
	protected $uid;
73
	/**
74
	 * @var string[]
75
	 */
76
	protected $refreshedFeatures = array();
77
	/**
78
	 * @var string
79
	 */
80
	protected $avatarImage;
81
82
	/**
83
	 * DB config keys for user preferences
84
	 */
85
	const USER_PREFKEY_FIRSTLOGIN  = 'firstLoginAccomplished';
86
	const USER_PREFKEY_LASTREFRESH = 'lastFeatureRefresh';
87
88
	/**
89
	 * @brief constructor, make sure the subclasses call this one!
90
	 * @param string the internal username
91
	 * @param string the LDAP DN
92
	 * @param IUserTools $access an instance that implements IUserTools for
93
	 * LDAP interaction
94
	 * @param \OCP\IConfig
95
	 * @param FilesystemHelper
96
	 * @param \OCP\Image any empty instance
97
	 * @param LogWrapper
98
	 * @param \OCP\IAvatarManager
99
	 */
100 43
	public function __construct($username, $dn, IUserTools $access,
101
		\OCP\IConfig $config, FilesystemHelper $fs, \OCP\Image $image,
102
		LogWrapper $log, \OCP\IAvatarManager $avatarManager) {
103
104 43
		$this->access        = $access;
105 43
		$this->connection    = $access->getConnection();
106 43
		$this->config        = $config;
107 43
		$this->fs            = $fs;
108 43
		$this->dn            = $dn;
109 43
		$this->uid           = $username;
110 43
		$this->image         = $image;
111 43
		$this->log           = $log;
112 43
		$this->avatarManager = $avatarManager;
113 43
	}
114
115
	/**
116
	 * @brief updates properties like email, quota or avatar provided by LDAP
117
	 * @return null
118
	 */
119 9
	public function update() {
120 9
		if(is_null($this->dn)) {
121
			return null;
122
		}
123
124 9
		$hasLoggedIn = $this->config->getUserValue($this->uid, 'user_ldap',
125 9
				self::USER_PREFKEY_FIRSTLOGIN, 0);
126
127 9
		if($this->needsRefresh()) {
128 8
			$this->updateEmail();
129 8
			$this->updateQuota();
130 8
			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...
131
				//we do not need to try it, when the user has not been logged in
132
				//before, because the file system will not be ready.
133 7
				$this->updateAvatar();
134
				//in order to get an avatar as soon as possible, mark the user
135
				//as refreshed only when updating the avatar did happen
136 7
				$this->markRefreshTime();
137 7
			}
138 8
		}
139 9
	}
140
141
	/**
142
	 * processes results from LDAP for attributes as returned by getAttributesToRead()
143
	 * @param array $ldapEntry the user entry as retrieved from LDAP
144
	 */
145 3
	public function processAttributes($ldapEntry) {
146 3
		$this->markRefreshTime();
147
		//Quota
148 3
		$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...
149 3
		if(isset($ldapEntry[$attr])) {
150 1
			$this->updateQuota($ldapEntry[$attr][0]);
151 1
		}
152 3
		unset($attr);
153
154
		//Email
155 3
		$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...
156 3
		if(isset($ldapEntry[$attr])) {
157 1
			$this->updateEmail($ldapEntry[$attr][0]);
158 1
		}
159 3
		unset($attr);
160
161
		//displayName
162 3
		$displayName = $displayName2 = '';
163 3
		$attr = strtolower($this->connection->ldapUserDisplayName);
164 3
		if(isset($ldapEntry[$attr])) {
165 1
			$displayName = $ldapEntry[$attr][0];
166 1
		}
167 3
		$attr = strtolower($this->connection->ldapUserDisplayName2);
168 3
		if(isset($ldapEntry[$attr])) {
169
			$displayName2 = $ldapEntry[$attr][0];
170
		}
171 3
		if(!empty($displayName)) {
172 1
			$this->composeAndStoreDisplayName($displayName);
173 1
			$this->access->cacheUserDisplayName(
174 1
				$this->getUsername(),
175 1
				$displayName,
176
				$displayName2
177 1
			);
178 1
		}
179 3
		unset($attr);
180
181
		// LDAP Username, needed for s2s sharing
182 3
		if(isset($ldapEntry['uid'])) {
183 1
			$this->storeLDAPUserName($ldapEntry['uid'][0]);
184 3
		} else if(isset($ldapEntry['samaccountname'])) {
185
			$this->storeLDAPUserName($ldapEntry['samaccountname'][0]);
186
		}
187
188
		//homePath
189 3
		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...
190 1
			$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...
191 1
			if(isset($ldapEntry[$attr])) {
192 1
				$this->access->cacheUserHome(
193 1
					$this->getUsername(), $this->getHomePath($ldapEntry[$attr][0]));
194 1
			}
195 1
		}
196
197
		//memberOf groups
198 3
		$cacheKey = 'getMemberOf'.$this->getUsername();
199 3
		$groups = false;
200 3
		if(isset($ldapEntry['memberof'])) {
201 1
			$groups = $ldapEntry['memberof'];
202 1
		}
203 3
		$this->connection->writeToCache($cacheKey, $groups);
204
205
		//Avatar
206 3
		$attrs = array('jpegphoto', 'thumbnailphoto');
207 3
		foreach ($attrs as $attr)  {
208 3
			if(isset($ldapEntry[$attr])) {
209 1
				$this->avatarImage = $ldapEntry[$attr][0];
210 1
				// the call to the method that saves the avatar in the file
211 1
				// system must be postponed after the login. It is to ensure
212
				// external mounts are mounted properly (e.g. with login
213 3
				// credentials from the session).
214 3
				\OCP\Util::connectHook('OC_User', 'post_login', $this, 'updateAvatarPostLogin');
215
				break;
216
			}
217
		}
218
	}
219
220 10
	/**
221 10
	 * @brief returns the LDAP DN of the user
222
	 * @return string
223
	 */
224
	public function getDN() {
225
		return $this->dn;
226
	}
227
228 12
	/**
229 12
	 * @brief returns the ownCloud internal username of the user
230
	 * @return string
231
	 */
232
	public function getUsername() {
233
		return $this->uid;
234
	}
235
236
	/**
237
	 * returns the home directory of the user if specified by LDAP settings
238 6
	 * @param string $valueFromLDAP
239 6
	 * @return bool|string
240 6
	 * @throws \Exception
241
	 */
242 6
	public function getHomePath($valueFromLDAP = null) {
243 6
		$path = $valueFromLDAP;
244 6
		$attr = null;
245 6
246 4
		if(   is_null($path)
247 4
		   && 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...
248 4
		   && $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...
249 4
		{
250 2
			$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...
251 2
			$homedir = $this->access->readAttribute(
252 4
				$this->access->username2dn($this->getUsername()), $attr);
253
			if ($homedir && isset($homedir[0])) {
254 6
				$path = $homedir[0];
255
			}
256
		}
257 2
258 2
		if(!empty($path)) {
259 1
			//if attribute's value is an absolute path take this, otherwise append it to data dir
260 2
			//check for / at the beginning or pattern c:\ resp. c:/
261 1
			if(   '/' !== $path[0]
262 1
			   && !(3 < strlen($path) && ctype_alpha($path[0])
263 1
			       && $path[1] === ':' && ('\\' === $path[2] || '/' === $path[2]))
264
			) {
265
				$path = $this->config->getSystemValue('datadirectory',
266 2
						\OC::$SERVERROOT.'/data' ) . '/' . $path;
267 2
			}
268 2
			//we need it to store it in the DB as well in case a user gets
269 2
			//deleted so we can clean up afterwards
270
			$this->config->setUserValue(
271
				$this->getUsername(), 'user_ldap', 'homePath', $path
272 4
			);
273 4
			return $path;
274 4
		}
275
276 1
		if(    !is_null($attr)
277
			&& $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...
278
		) {
279
			// a naming rule attribute is defined, but it doesn't exist for that LDAP user
280 3
			throw new \Exception('Home dir attribute can\'t be read from LDAP for uid: ' . $this->getUsername());
281 3
		}
282
283
		//false will apply default behaviour as defined and done by OC_User
284
		$this->config->setUserValue($this->getUsername(), 'user_ldap', 'homePath', '');
285
		return false;
286
	}
287
288
	public function getMemberOfGroups() {
289
		$cacheKey = 'getMemberOf'.$this->getUsername();
290
		if($this->connection->isCached($cacheKey)) {
291
			return $this->connection->getFromCache($cacheKey);
292
		}
293
		$groupDNs = $this->access->readAttribute($this->getDN(), 'memberOf');
294
		$this->connection->writeToCache($cacheKey, $groupDNs);
295
		return $groupDNs;
296
	}
297
298 11
	/**
299 11
	 * @brief reads the image from LDAP that shall be used as Avatar
300 1
	 * @return string data (provided by LDAP) | false
301
	 */
302
	public function getAvatarImage() {
303 11
		if(!is_null($this->avatarImage)) {
304 11
			return $this->avatarImage;
305 11
		}
306 11
307 11
		$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...
308 3
		$attributes = array('jpegPhoto', 'thumbnailPhoto');
309 3
		foreach($attributes as $attribute) {
310
			$result = $this->access->readAttribute($this->dn, $attribute);
311 11
			if($result !== false && is_array($result) && isset($result[0])) {
312
				$this->avatarImage = $result[0];
313 11
				break;
314
			}
315
		}
316
317
		return $this->avatarImage;
318
	}
319
320 3
	/**
321 3
	 * @brief marks the user as having logged in at least once
322 3
	 * @return null
323 3
	 */
324
	public function markLogin() {
325
		$this->config->setUserValue(
326
			$this->uid, 'user_ldap', self::USER_PREFKEY_FIRSTLOGIN, 1);
327
	}
328
329 9
	/**
330 9
	 * @brief marks the time when user features like email have been updated
331 9
	 * @return null
332 9
	 */
333
	public function markRefreshTime() {
334
		$this->config->setUserValue(
335
			$this->uid, 'user_ldap', self::USER_PREFKEY_LASTREFRESH, time());
336
	}
337
338
	/**
339
	 * @brief checks whether user features needs to be updated again by
340 9
	 * comparing the difference of time of the last refresh to now with the
341 9
	 * desired interval
342 9
	 * @return bool
343
	 */
344
	private function needsRefresh() {
345 9
		$lastChecked = $this->config->getUserValue($this->uid, 'user_ldap',
346 1
			self::USER_PREFKEY_LASTREFRESH, 0);
347
348 8
		//TODO make interval configurable
349
		if((time() - intval($lastChecked)) < 86400 ) {
350
			return false;
351
		}
352
		return  true;
353
	}
354
355
	/**
356
	 * Stores a key-value pair in relation to this user
357 5
	 *
358 5
	 * @param string $key
359 5
	 * @param string $value
360
	 */
361
	private function store($key, $value) {
362
		$this->config->setUserValue($this->uid, 'user_ldap', $key, $value);
363
	}
364
365
	/**
366
	 * Composes the display name and stores it in the database. The final
367
	 * display name is returned.
368
	 *
369 5
	 * @param string $displayName
370 5
	 * @param string $displayName2
371 1
	 * @returns string the effective display name
372 1
	 */
373 5
	public function composeAndStoreDisplayName($displayName, $displayName2 = '') {
374 5
		if(!empty($displayName2)) {
375
			$displayName .= ' (' . $displayName2 . ')';
376
		}
377
		$this->store('displayName', $displayName);
378
		return $displayName;
379
	}
380
381
	/**
382
	 * Stores the LDAP Username in the Database
383
	 * @param string $userName
384
	 */
385
	public function storeLDAPUserName($userName) {
386
		$this->store('uid', $userName);
387
	}
388
389
	/**
390
	 * @brief checks whether an update method specified by feature was run
391
	 * already. If not, it will marked like this, because it is expected that
392 20
	 * the method will be run, when false is returned.
393 20
	 * @param string email | quota | avatar (can be extended)
394 1
	 * @return bool
395
	 */
396 20
	private function wasRefreshed($feature) {
397 20
		if(isset($this->refreshedFeatures[$feature])) {
398
			return true;
399
		}
400
		$this->refreshedFeatures[$feature] = 1;
401
		return false;
402
	}
403
404
	/**
405 11
	 * fetches the email from LDAP and stores it as ownCloud user value
406 11
	 * @param string $valueFromLDAP if known, to save an LDAP read request
407 1
	 * @return null
408
	 */
409 11
	public function updateEmail($valueFromLDAP = null) {
410 11
		if($this->wasRefreshed('email')) {
411 11
			return;
412 11
		}
413 2
		$email = $valueFromLDAP;
414 2 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...
415 1
			$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...
416 1
			if(!empty($emailAttribute)) {
417 2
				$aEmail = $this->access->readAttribute($this->dn, $emailAttribute);
418 11
				if(is_array($aEmail) && (count($aEmail) > 0)) {
419 11
					$email = $aEmail[0];
420 1
				}
421 1
			}
422 1
		}
423 11
		if(!is_null($email)) {
424
			$this->config->setUserValue(
425
				$this->uid, 'settings', 'email', $email);
426
		}
427
	}
428
429
	/**
430
	 * fetches the quota from LDAP and stores it as ownCloud user value
431 14
	 * @param string $valueFromLDAP the quota attribute's value can be passed,
432 14
	 * to save the readAttribute request
433 1
	 * @return null
434
	 */
435
	public function updateQuota($valueFromLDAP = null) {
436 14
		if($this->wasRefreshed('quota')) {
437 14
			return;
438 14
		}
439
		//can be null
440 14
		$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...
441 13
		$quota = $quotaDefault !== '' ? $quotaDefault : null;
442 13
		$quota = !is_null($valueFromLDAP) ? $valueFromLDAP : $quota;
443 4
444 4 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...
445 2
			$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...
446 2
			if(!empty($quotaAttribute)) {
447 4
				$aQuota = $this->access->readAttribute($this->dn, $quotaAttribute);
448 13
				if($aQuota && (count($aQuota) > 0)) {
449 14
					$quota = $aQuota[0];
450 4
				}
451 4
			}
452 14
		}
453
		if(!is_null($quota)) {
454
			$this->config->setUserValue($this->uid, 'files', 'quota', $quota);
455
		}
456
	}
457
458 10
	/**
459 10
	 * called by a post_login hook to save the avatar picture
460 1
	 *
461
	 * @param array $params
462 10
	 */
463 10
	public function updateAvatarPostLogin($params) {
464
		if(isset($params['uid']) && $params['uid'] === $this->getUsername()) {
465 8
			$this->updateAvatar();
466
		}
467 2
	}
468 2
469 2
	/**
470
	 * @brief attempts to get an image from LDAP and sets it as ownCloud avatar
471
	 * @return null
472
	 */
473
	public function updateAvatar() {
474
		if($this->wasRefreshed('avatar')) {
475 2
			return;
476 2
		}
477
		$avatarImage = $this->getAvatarImage();
478
		if($avatarImage === false) {
479
			//not set, nothing left to do;
480
			return;
481
		}
482 2
		$this->image->loadFromBase64(base64_encode($avatarImage));
483 2
		$this->setOwnCloudAvatar();
484
	}
485
486
	/**
487
	 * @brief sets an image as ownCloud avatar
488
	 * @return null
489
	 */
490 2
	private function setOwnCloudAvatar() {
491 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...
492
			$this->log->log('user_ldap', 'jpegPhoto data invalid for '.$this->dn,
493
				\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...
494
			return;
495 2
		}
496 2
		//make sure it is a square and not bigger than 128x128
497 2
		$size = min(array($this->image->width(), $this->image->height(), 128));
498 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...
499
			$this->log->log('user_ldap',
500
				'croping image for avatar failed for '.$this->dn,
501
				\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...
502 2
			return;
503
		}
504
505
		if(!$this->fs->isLoaded()) {
506
			$this->fs->setup($this->uid);
507
		}
508
509
		try {
510
			$avatar = $this->avatarManager->getAvatar($this->uid);
511
			$avatar->set($this->image);
512
		} catch (\Exception $e) {
513
			\OC::$server->getLogger()->notice(
514
				'Could not set avatar for ' . $this->dn	. ', because: ' . $e->getMessage(),
515
				['app' => 'user_ldap']);
516
		}
517
	}
518
519
}
520