Passed
Push — master ( 6331f1...762a8b )
by Joas
11:56 queued 10s
created

Manager::createUser()   B

Complexity

Conditions 7
Paths 11

Size

Total Lines 25
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 13
nc 11
nop 2
dl 0
loc 25
rs 8.8333
c 0
b 0
f 0
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 Jörn Friedrich Dreyer <[email protected]>
8
 * @author Lukas Reschke <[email protected]>
9
 * @author Michael U <[email protected]>
10
 * @author Morris Jobke <[email protected]>
11
 * @author Robin Appelman <[email protected]>
12
 * @author Roeland Jago Douma <[email protected]>
13
 * @author Thomas Müller <[email protected]>
14
 * @author Vincent Chan <[email protected]>
15
 *
16
 * @license AGPL-3.0
17
 *
18
 * This code is free software: you can redistribute it and/or modify
19
 * it under the terms of the GNU Affero General Public License, version 3,
20
 * as published by the Free Software Foundation.
21
 *
22
 * This program is distributed in the hope that it will be useful,
23
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25
 * GNU Affero General Public License for more details.
26
 *
27
 * You should have received a copy of the GNU Affero General Public License, version 3,
28
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
29
 *
30
 */
31
32
namespace OC\User;
33
34
use OC\Hooks\PublicEmitter;
35
use OCP\DB\QueryBuilder\IQueryBuilder;
36
use OCP\IUser;
37
use OCP\IGroup;
38
use OCP\IUserBackend;
39
use OCP\IUserManager;
40
use OCP\IConfig;
41
use OCP\UserInterface;
42
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
43
44
/**
45
 * Class Manager
46
 *
47
 * Hooks available in scope \OC\User:
48
 * - preSetPassword(\OC\User\User $user, string $password, string $recoverPassword)
49
 * - postSetPassword(\OC\User\User $user, string $password, string $recoverPassword)
50
 * - preDelete(\OC\User\User $user)
51
 * - postDelete(\OC\User\User $user)
52
 * - preCreateUser(string $uid, string $password)
53
 * - postCreateUser(\OC\User\User $user, string $password)
54
 * - change(\OC\User\User $user)
55
 * - assignedUserId(string $uid)
56
 * - preUnassignedUserId(string $uid)
57
 * - postUnassignedUserId(string $uid)
58
 *
59
 * @package OC\User
60
 */
61
class Manager extends PublicEmitter implements IUserManager {
62
	/**
63
	 * @var \OCP\UserInterface[] $backends
64
	 */
65
	private $backends = array();
66
67
	/**
68
	 * @var \OC\User\User[] $cachedUsers
69
	 */
70
	private $cachedUsers = array();
71
72
	/** @var IConfig */
73
	private $config;
74
	/** @var EventDispatcherInterface */
75
	private $dispatcher;
76
77
	public function __construct(IConfig $config, EventDispatcherInterface $dispatcher) {
78
		$this->config = $config;
79
		$this->dispatcher = $dispatcher;
80
		$cachedUsers = &$this->cachedUsers;
81
		$this->listen('\OC\User', 'postDelete', function ($user) use (&$cachedUsers) {
82
			/** @var \OC\User\User $user */
83
			unset($cachedUsers[$user->getUID()]);
84
		});
85
	}
86
87
	/**
88
	 * Get the active backends
89
	 * @return \OCP\UserInterface[]
90
	 */
91
	public function getBackends() {
92
		return $this->backends;
93
	}
94
95
	/**
96
	 * register a user backend
97
	 *
98
	 * @param \OCP\UserInterface $backend
99
	 */
100
	public function registerBackend($backend) {
101
		$this->backends[] = $backend;
102
	}
103
104
	/**
105
	 * remove a user backend
106
	 *
107
	 * @param \OCP\UserInterface $backend
108
	 */
109
	public function removeBackend($backend) {
110
		$this->cachedUsers = array();
111
		if (($i = array_search($backend, $this->backends)) !== false) {
112
			unset($this->backends[$i]);
113
		}
114
	}
115
116
	/**
117
	 * remove all user backends
118
	 */
119
	public function clearBackends() {
120
		$this->cachedUsers = array();
121
		$this->backends = array();
122
	}
123
124
	/**
125
	 * get a user by user id
126
	 *
127
	 * @param string $uid
128
	 * @return \OC\User\User|null Either the user or null if the specified user does not exist
129
	 */
130
	public function get($uid) {
131
		if (is_null($uid) || $uid === '' || $uid === false) {
132
			return null;
133
		}
134
		if (isset($this->cachedUsers[$uid])) { //check the cache first to prevent having to loop over the backends
135
			return $this->cachedUsers[$uid];
136
		}
137
		foreach ($this->backends as $backend) {
138
			if ($backend->userExists($uid)) {
139
				return $this->getUserObject($uid, $backend);
140
			}
141
		}
142
		return null;
143
	}
144
145
	/**
146
	 * get or construct the user object
147
	 *
148
	 * @param string $uid
149
	 * @param \OCP\UserInterface $backend
150
	 * @param bool $cacheUser If false the newly created user object will not be cached
151
	 * @return \OC\User\User
152
	 */
153
	protected function getUserObject($uid, $backend, $cacheUser = true) {
154
		if (isset($this->cachedUsers[$uid])) {
155
			return $this->cachedUsers[$uid];
156
		}
157
158
		$user = new User($uid, $backend, $this->dispatcher, $this, $this->config);
159
		if ($cacheUser) {
160
			$this->cachedUsers[$uid] = $user;
161
		}
162
		return $user;
163
	}
164
165
	/**
166
	 * check if a user exists
167
	 *
168
	 * @param string $uid
169
	 * @return bool
170
	 */
171
	public function userExists($uid) {
172
		$user = $this->get($uid);
173
		return ($user !== null);
174
	}
175
176
	/**
177
	 * Check if the password is valid for the user
178
	 *
179
	 * @param string $loginName
180
	 * @param string $password
181
	 * @return mixed the User object on success, false otherwise
182
	 */
183
	public function checkPassword($loginName, $password) {
184
		$result = $this->checkPasswordNoLogging($loginName, $password);
185
186
		if ($result === false) {
187
			\OC::$server->getLogger()->warning('Login failed: \''. $loginName .'\' (Remote IP: \''. \OC::$server->getRequest()->getRemoteAddress(). '\')', ['app' => 'core']);
188
		}
189
190
		return $result;
191
	}
192
193
	/**
194
	 * Check if the password is valid for the user
195
	 *
196
	 * @internal
197
	 * @param string $loginName
198
	 * @param string $password
199
	 * @return mixed the User object on success, false otherwise
200
	 */
201
	public function checkPasswordNoLogging($loginName, $password) {
202
		$loginName = str_replace("\0", '', $loginName);
203
		$password = str_replace("\0", '', $password);
204
205
		foreach ($this->backends as $backend) {
206
			if ($backend->implementsActions(Backend::CHECK_PASSWORD)) {
0 ignored issues
show
Deprecated Code introduced by
The function OCP\UserInterface::implementsActions() has been deprecated: 14.0.0 Switch to the interfaces from OCP\User\Backend ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

206
			if (/** @scrutinizer ignore-deprecated */ $backend->implementsActions(Backend::CHECK_PASSWORD)) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
207
				$uid = $backend->checkPassword($loginName, $password);
0 ignored issues
show
Bug introduced by
The method checkPassword() does not exist on OCP\UserInterface. It seems like you code against a sub-type of said class. However, the method does not exist in OC\User\Backend or OCP\User\Backend\ABackend. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

207
				/** @scrutinizer ignore-call */ 
208
    $uid = $backend->checkPassword($loginName, $password);
Loading history...
208
				if ($uid !== false) {
209
					return $this->getUserObject($uid, $backend);
210
				}
211
			}
212
		}
213
214
		return false;
215
	}
216
217
	/**
218
	 * search by user id
219
	 *
220
	 * @param string $pattern
221
	 * @param int $limit
222
	 * @param int $offset
223
	 * @return \OC\User\User[]
224
	 */
225
	public function search($pattern, $limit = null, $offset = null) {
226
		$users = array();
227
		foreach ($this->backends as $backend) {
228
			$backendUsers = $backend->getUsers($pattern, $limit, $offset);
229
			if (is_array($backendUsers)) {
230
				foreach ($backendUsers as $uid) {
231
					$users[$uid] = $this->getUserObject($uid, $backend);
232
				}
233
			}
234
		}
235
236
		uasort($users, function ($a, $b) {
237
			/**
238
			 * @var \OC\User\User $a
239
			 * @var \OC\User\User $b
240
			 */
241
			return strcasecmp($a->getUID(), $b->getUID());
242
		});
243
		return $users;
244
	}
245
246
	/**
247
	 * search by displayName
248
	 *
249
	 * @param string $pattern
250
	 * @param int $limit
251
	 * @param int $offset
252
	 * @return \OC\User\User[]
253
	 */
254
	public function searchDisplayName($pattern, $limit = null, $offset = null) {
255
		$users = array();
256
		foreach ($this->backends as $backend) {
257
			$backendUsers = $backend->getDisplayNames($pattern, $limit, $offset);
258
			if (is_array($backendUsers)) {
259
				foreach ($backendUsers as $uid => $displayName) {
260
					$users[] = $this->getUserObject($uid, $backend);
261
				}
262
			}
263
		}
264
265
		usort($users, function ($a, $b) {
266
			/**
267
			 * @var \OC\User\User $a
268
			 * @var \OC\User\User $b
269
			 */
270
			return strcasecmp($a->getDisplayName(), $b->getDisplayName());
271
		});
272
		return $users;
273
	}
274
275
	/**
276
	 * @param string $uid
277
	 * @param string $password
278
	 * @throws \InvalidArgumentException
279
	 * @return bool|IUser the created user or false
280
	 */
281
	public function createUser($uid, $password) {
282
		if (!$this->verifyUid($uid)) {
283
			return false;
284
		}
285
286
		$localBackends = [];
287
		foreach ($this->backends as $backend) {
288
			if ($backend instanceof Database) {
289
				// First check if there is another user backend
290
				$localBackends[] = $backend;
291
				continue;
292
			}
293
294
			if ($backend->implementsActions(Backend::CREATE_USER)) {
0 ignored issues
show
Deprecated Code introduced by
The function OCP\UserInterface::implementsActions() has been deprecated: 14.0.0 Switch to the interfaces from OCP\User\Backend ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

294
			if (/** @scrutinizer ignore-deprecated */ $backend->implementsActions(Backend::CREATE_USER)) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
295
				return $this->createUserFromBackend($uid, $password, $backend);
296
			}
297
		}
298
299
		foreach ($localBackends as $backend) {
300
			if ($backend->implementsActions(Backend::CREATE_USER)) {
301
				return $this->createUserFromBackend($uid, $password, $backend);
302
			}
303
		}
304
305
		return false;
306
	}
307
308
	/**
309
	 * @param string $uid
310
	 * @param string $password
311
	 * @param UserInterface $backend
312
	 * @return IUser|null
313
	 * @throws \InvalidArgumentException
314
	 */
315
	public function createUserFromBackend($uid, $password, UserInterface $backend) {
316
		$l = \OC::$server->getL10N('lib');
317
318
		// Check the name for bad characters
319
		// Allowed are: "a-z", "A-Z", "0-9" and "_.@-'"
320
		if (preg_match('/[^a-zA-Z0-9 _\.@\-\']/', $uid)) {
321
			throw new \InvalidArgumentException($l->t('Only the following characters are allowed in a username:'
322
				. ' "a-z", "A-Z", "0-9", and "_.@-\'"'));
323
		}
324
		// No empty username
325
		if (trim($uid) === '') {
326
			throw new \InvalidArgumentException($l->t('A valid username must be provided'));
327
		}
328
		// No whitespace at the beginning or at the end
329
		if (trim($uid) !== $uid) {
330
			throw new \InvalidArgumentException($l->t('Username contains whitespace at the beginning or at the end'));
331
		}
332
		// Username only consists of 1 or 2 dots (directory traversal)
333
		if ($uid === '.' || $uid === '..') {
334
			throw new \InvalidArgumentException($l->t('Username must not consist of dots only'));
335
		}
336
		// No empty password
337
		if (trim($password) === '') {
338
			throw new \InvalidArgumentException($l->t('A valid password must be provided'));
339
		}
340
341
		// Check if user already exists
342
		if ($this->userExists($uid)) {
343
			throw new \InvalidArgumentException($l->t('The username is already being used'));
344
		}
345
346
		$this->emit('\OC\User', 'preCreateUser', [$uid, $password]);
347
		$state = $backend->createUser($uid, $password);
0 ignored issues
show
Bug introduced by
The method createUser() does not exist on OCP\UserInterface. It seems like you code against a sub-type of said class. However, the method does not exist in OC\User\Backend or OCP\User\Backend\ABackend. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

347
		/** @scrutinizer ignore-call */ 
348
  $state = $backend->createUser($uid, $password);
Loading history...
348
		if($state === false) {
349
			throw new \InvalidArgumentException($l->t('Could not create user'));
350
		}
351
		$user = $this->getUserObject($uid, $backend);
352
		if ($user instanceof IUser) {
0 ignored issues
show
introduced by
$user is always a sub-type of OCP\IUser.
Loading history...
353
			$this->emit('\OC\User', 'postCreateUser', [$user, $password]);
354
		}
355
		return $user;
356
	}
357
358
	/**
359
	 * returns how many users per backend exist (if supported by backend)
360
	 *
361
	 * @param boolean $hasLoggedIn when true only users that have a lastLogin
362
	 *                entry in the preferences table will be affected
363
	 * @return array|int an array of backend class as key and count number as value
364
	 *                if $hasLoggedIn is true only an int is returned
365
	 */
366
	public function countUsers($hasLoggedIn = false) {
367
		if ($hasLoggedIn) {
368
			return $this->countSeenUsers();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->countSeenUsers() returns the type integer which is incompatible with the return type mandated by OCP\IUserManager::countUsers() of array.

In the issue above, the returned value is violating the contract defined by the mentioned interface.

Let's take a look at an example:

interface HasName {
    /** @return string */
    public function getName();
}

class Name {
    public $name;
}

class User implements HasName {
    /** @return string|Name */
    public function getName() {
        return new Name('foo'); // This is a violation of the ``HasName`` interface
                                // which only allows a string value to be returned.
    }
}
Loading history...
369
		}
370
		$userCountStatistics = [];
371
		foreach ($this->backends as $backend) {
372
			if ($backend->implementsActions(Backend::COUNT_USERS)) {
0 ignored issues
show
Deprecated Code introduced by
The function OCP\UserInterface::implementsActions() has been deprecated: 14.0.0 Switch to the interfaces from OCP\User\Backend ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

372
			if (/** @scrutinizer ignore-deprecated */ $backend->implementsActions(Backend::COUNT_USERS)) {

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
373
				$backendUsers = $backend->countUsers();
0 ignored issues
show
Bug introduced by
The method countUsers() does not exist on OCP\UserInterface. It seems like you code against a sub-type of said class. However, the method does not exist in OC\User\Backend or OCP\User\Backend\ABackend. Are you sure you never get one of those? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

373
				/** @scrutinizer ignore-call */ 
374
    $backendUsers = $backend->countUsers();
Loading history...
374
				if($backendUsers !== false) {
375
					if($backend instanceof IUserBackend) {
376
						$name = $backend->getBackendName();
377
					} else {
378
						$name = get_class($backend);
379
					}
380
					if(isset($userCountStatistics[$name])) {
381
						$userCountStatistics[$name] += $backendUsers;
382
					} else {
383
						$userCountStatistics[$name] = $backendUsers;
384
					}
385
				}
386
			}
387
		}
388
		return $userCountStatistics;
389
	}
390
391
	/**
392
	 * returns how many users per backend exist in the requested groups (if supported by backend)
393
	 *
394
	 * @param IGroup[] $groups an array of gid to search in
395
	 * @return array|int an array of backend class as key and count number as value
396
	 *                if $hasLoggedIn is true only an int is returned
397
	 */
398
	public function countUsersOfGroups(array $groups) {
399
		$users = [];
400
		foreach($groups as $group) {
401
			$usersIds = array_map(function($user) {
402
				return $user->getUID();
403
			}, $group->getUsers());
404
			$users = array_merge($users, $usersIds);
405
		}
406
		return count(array_unique($users));
407
	}
408
409
	/**
410
	 * The callback is executed for each user on each backend.
411
	 * If the callback returns false no further users will be retrieved.
412
	 *
413
	 * @param \Closure $callback
414
	 * @param string $search
415
	 * @param boolean $onlySeen when true only users that have a lastLogin entry
416
	 *                in the preferences table will be affected
417
	 * @since 9.0.0
418
	 */
419
	public function callForAllUsers(\Closure $callback, $search = '', $onlySeen = false) {
420
		if ($onlySeen) {
421
			$this->callForSeenUsers($callback);
422
		} else {
423
			foreach ($this->getBackends() as $backend) {
424
				$limit = 500;
425
				$offset = 0;
426
				do {
427
					$users = $backend->getUsers($search, $limit, $offset);
428
					foreach ($users as $uid) {
429
						if (!$backend->userExists($uid)) {
430
							continue;
431
						}
432
						$user = $this->getUserObject($uid, $backend, false);
433
						$return = $callback($user);
434
						if ($return === false) {
435
							break;
436
						}
437
					}
438
					$offset += $limit;
439
				} while (count($users) >= $limit);
440
			}
441
		}
442
	}
443
444
	/**
445
	 * returns how many users are disabled
446
	 *
447
	 * @return int
448
	 * @since 12.0.0
449
	 */
450
	public function countDisabledUsers(): int {
451
		$queryBuilder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
452
		$queryBuilder->select($queryBuilder->func()->count('*'))
453
			->from('preferences')
454
			->where($queryBuilder->expr()->eq('appid', $queryBuilder->createNamedParameter('core')))
455
			->andWhere($queryBuilder->expr()->eq('configkey', $queryBuilder->createNamedParameter('enabled')))
456
			->andWhere($queryBuilder->expr()->eq('configvalue', $queryBuilder->createNamedParameter('false'), IQueryBuilder::PARAM_STR));
457
458
		
459
		$result = $queryBuilder->execute();
460
		$count = $result->fetchColumn();
461
		$result->closeCursor();
462
		
463
		if ($count !== false) {
464
			$count = (int)$count;
465
		} else {
466
			$count = 0;
467
		}
468
469
		return $count;
470
	}
471
472
	/**
473
	 * returns how many users are disabled in the requested groups
474
	 *
475
	 * @param array $groups groupids to search
476
	 * @return int
477
	 * @since 14.0.0
478
	 */
479
	public function countDisabledUsersOfGroups(array $groups): int {
480
		$queryBuilder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
481
		$queryBuilder->select($queryBuilder->createFunction('COUNT(DISTINCT ' . $queryBuilder->getColumnName('uid') . ')'))
482
			->from('preferences', 'p')
483
			->innerJoin('p', 'group_user', 'g', $queryBuilder->expr()->eq('p.userid', 'g.uid'))
484
			->where($queryBuilder->expr()->eq('appid', $queryBuilder->createNamedParameter('core')))
485
			->andWhere($queryBuilder->expr()->eq('configkey', $queryBuilder->createNamedParameter('enabled')))
486
			->andWhere($queryBuilder->expr()->eq('configvalue', $queryBuilder->createNamedParameter('false'), IQueryBuilder::PARAM_STR))
487
			->andWhere($queryBuilder->expr()->in('gid', $queryBuilder->createNamedParameter($groups, IQueryBuilder::PARAM_STR_ARRAY)));
488
489
		$result = $queryBuilder->execute();
490
		$count = $result->fetchColumn();
491
		$result->closeCursor();
492
		
493
		if ($count !== false) {
494
			$count = (int)$count;
495
		} else {
496
			$count = 0;
497
		}
498
499
		return $count;
500
	}
501
502
	/**
503
	 * returns how many users have logged in once
504
	 *
505
	 * @return int
506
	 * @since 11.0.0
507
	 */
508
	public function countSeenUsers() {
509
		$queryBuilder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
510
		$queryBuilder->select($queryBuilder->func()->count('*'))
511
			->from('preferences')
512
			->where($queryBuilder->expr()->eq('appid', $queryBuilder->createNamedParameter('login')))
513
			->andWhere($queryBuilder->expr()->eq('configkey', $queryBuilder->createNamedParameter('lastLogin')))
514
			->andWhere($queryBuilder->expr()->isNotNull('configvalue'));
515
516
		$query = $queryBuilder->execute();
517
518
		$result = (int)$query->fetchColumn();
519
		$query->closeCursor();
520
521
		return $result;
522
	}
523
524
	/**
525
	 * @param \Closure $callback
526
	 * @since 11.0.0
527
	 */
528
	public function callForSeenUsers(\Closure $callback) {
529
		$limit = 1000;
530
		$offset = 0;
531
		do {
532
			$userIds = $this->getSeenUserIds($limit, $offset);
533
			$offset += $limit;
534
			foreach ($userIds as $userId) {
535
				foreach ($this->backends as $backend) {
536
					if ($backend->userExists($userId)) {
537
						$user = $this->getUserObject($userId, $backend, false);
538
						$return = $callback($user);
539
						if ($return === false) {
540
							return;
541
						}
542
						break;
543
					}
544
				}
545
			}
546
		} while (count($userIds) >= $limit);
547
	}
548
549
	/**
550
	 * Getting all userIds that have a listLogin value requires checking the
551
	 * value in php because on oracle you cannot use a clob in a where clause,
552
	 * preventing us from doing a not null or length(value) > 0 check.
553
	 *
554
	 * @param int $limit
555
	 * @param int $offset
556
	 * @return string[] with user ids
557
	 */
558
	private function getSeenUserIds($limit = null, $offset = null) {
559
		$queryBuilder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
560
		$queryBuilder->select(['userid'])
561
			->from('preferences')
562
			->where($queryBuilder->expr()->eq(
563
				'appid', $queryBuilder->createNamedParameter('login'))
564
			)
565
			->andWhere($queryBuilder->expr()->eq(
566
				'configkey', $queryBuilder->createNamedParameter('lastLogin'))
567
			)
568
			->andWhere($queryBuilder->expr()->isNotNull('configvalue')
569
			);
570
571
		if ($limit !== null) {
572
			$queryBuilder->setMaxResults($limit);
573
		}
574
		if ($offset !== null) {
575
			$queryBuilder->setFirstResult($offset);
576
		}
577
		$query = $queryBuilder->execute();
578
		$result = [];
579
580
		while ($row = $query->fetch()) {
581
			$result[] = $row['userid'];
582
		}
583
584
		$query->closeCursor();
585
586
		return $result;
587
	}
588
589
	/**
590
	 * @param string $email
591
	 * @return IUser[]
592
	 * @since 9.1.0
593
	 */
594
	public function getByEmail($email) {
595
		$userIds = $this->config->getUsersForUserValueCaseInsensitive('settings', 'email', $email);
0 ignored issues
show
Bug introduced by
The method getUsersForUserValueCaseInsensitive() does not exist on OCP\IConfig. Did you maybe mean getUsersForUserValue()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

595
		/** @scrutinizer ignore-call */ 
596
  $userIds = $this->config->getUsersForUserValueCaseInsensitive('settings', 'email', $email);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
596
597
		$users = array_map(function($uid) {
598
			return $this->get($uid);
599
		}, $userIds);
600
601
		return array_values(array_filter($users, function($u) {
602
			return ($u instanceof IUser);
603
		}));
604
	}
605
606
	private function verifyUid(string $uid): bool {
607
		$appdata = 'appdata_' . $this->config->getSystemValueString('instanceid');
608
609
		if ($uid === '.htaccess' || $uid === 'files_external' || $uid === '.ocdata' || $uid === 'owncloud.log' || $uid === 'nextcloud.log' || $uid === $appdata) {
610
			return false;
611
		}
612
613
		return true;
614
	}
615
}
616