Passed
Push — master ( d682fe...3a99ef )
by Roeland
10:22
created
lib/private/User/Database.php 2 patches
Indentation   +409 added lines, -409 removed lines patch added patch discarded remove patch
@@ -75,415 +75,415 @@
 block discarded – undo
75 75
  * Class for user management in a SQL Database (e.g. MySQL, SQLite)
76 76
  */
77 77
 class Database extends ABackend
78
-	implements ICreateUserBackend,
79
-	           ISetPasswordBackend,
80
-	           ISetDisplayNameBackend,
81
-	           IGetDisplayNameBackend,
82
-	           ICheckPasswordBackend,
83
-	           IGetHomeBackend,
84
-	           ICountUsersBackend,
85
-	           IGetRealUIDBackend {
86
-	/** @var CappedMemoryCache */
87
-	private $cache;
88
-
89
-	/** @var EventDispatcherInterface */
90
-	private $eventDispatcher;
91
-
92
-	/** @var IDBConnection */
93
-	private $dbConn;
94
-
95
-	/** @var string */
96
-	private $table;
97
-
98
-	/**
99
-	 * \OC\User\Database constructor.
100
-	 *
101
-	 * @param EventDispatcherInterface $eventDispatcher
102
-	 * @param string $table
103
-	 */
104
-	public function __construct($eventDispatcher = null, $table = 'users') {
105
-		$this->cache = new CappedMemoryCache();
106
-		$this->table = $table;
107
-		$this->eventDispatcher = $eventDispatcher ? $eventDispatcher : \OC::$server->getEventDispatcher();
108
-	}
109
-
110
-	/**
111
-	 * FIXME: This function should not be required!
112
-	 */
113
-	private function fixDI() {
114
-		if ($this->dbConn === null) {
115
-			$this->dbConn = \OC::$server->getDatabaseConnection();
116
-		}
117
-	}
118
-
119
-	/**
120
-	 * Create a new user
121
-	 *
122
-	 * @param string $uid The username of the user to create
123
-	 * @param string $password The password of the new user
124
-	 * @return bool
125
-	 *
126
-	 * Creates a new user. Basic checking of username is done in OC_User
127
-	 * itself, not in its subclasses.
128
-	 */
129
-	public function createUser(string $uid, string $password): bool {
130
-		$this->fixDI();
131
-
132
-		if (!$this->userExists($uid)) {
133
-			$event = new GenericEvent($password);
134
-			$this->eventDispatcher->dispatch('OCP\PasswordPolicy::validate', $event);
135
-
136
-			$qb = $this->dbConn->getQueryBuilder();
137
-			$qb->insert($this->table)
138
-				->values([
139
-					'uid' => $qb->createNamedParameter($uid),
140
-					'password' => $qb->createNamedParameter(\OC::$server->getHasher()->hash($password)),
141
-					'uid_lower' => $qb->createNamedParameter(mb_strtolower($uid)),
142
-				]);
143
-
144
-			$result = $qb->execute();
145
-
146
-			// Clear cache
147
-			unset($this->cache[$uid]);
148
-
149
-			return $result ? true : false;
150
-		}
151
-
152
-		return false;
153
-	}
154
-
155
-	/**
156
-	 * delete a user
157
-	 *
158
-	 * @param string $uid The username of the user to delete
159
-	 * @return bool
160
-	 *
161
-	 * Deletes a user
162
-	 */
163
-	public function deleteUser($uid) {
164
-		$this->fixDI();
165
-
166
-		// Delete user-group-relation
167
-		$query = $this->dbConn->getQueryBuilder();
168
-		$query->delete($this->table)
169
-			->where($query->expr()->eq('uid_lower', $query->createNamedParameter(mb_strtolower($uid))));
170
-		$result = $query->execute();
171
-
172
-		if (isset($this->cache[$uid])) {
173
-			unset($this->cache[$uid]);
174
-		}
175
-
176
-		return $result ? true : false;
177
-	}
178
-
179
-	private function updatePassword(string $uid, string $passwordHash): bool {
180
-		$query = $this->dbConn->getQueryBuilder();
181
-		$query->update($this->table)
182
-			->set('password', $query->createNamedParameter($passwordHash))
183
-			->where($query->expr()->eq('uid_lower', $query->createNamedParameter(mb_strtolower($uid))));
184
-		$result = $query->execute();
185
-
186
-		return $result ? true : false;
187
-	}
188
-
189
-	/**
190
-	 * Set password
191
-	 *
192
-	 * @param string $uid The username
193
-	 * @param string $password The new password
194
-	 * @return bool
195
-	 *
196
-	 * Change the password of a user
197
-	 */
198
-	public function setPassword(string $uid, string $password): bool {
199
-		$this->fixDI();
200
-
201
-		if ($this->userExists($uid)) {
202
-			$event = new GenericEvent($password);
203
-			$this->eventDispatcher->dispatch('OCP\PasswordPolicy::validate', $event);
204
-
205
-			$hasher = \OC::$server->getHasher();
206
-			$hashedPassword = $hasher->hash($password);
207
-
208
-			return $this->updatePassword($uid, $hashedPassword);
209
-		}
210
-
211
-		return false;
212
-	}
213
-
214
-	/**
215
-	 * Set display name
216
-	 *
217
-	 * @param string $uid The username
218
-	 * @param string $displayName The new display name
219
-	 * @return bool
220
-	 *
221
-	 * Change the display name of a user
222
-	 */
223
-	public function setDisplayName(string $uid, string $displayName): bool {
224
-		$this->fixDI();
225
-
226
-		if ($this->userExists($uid)) {
227
-			$query = $this->dbConn->getQueryBuilder();
228
-			$query->update($this->table)
229
-				->set('displayname', $query->createNamedParameter($displayName))
230
-				->where($query->expr()->eq('uid_lower', $query->createNamedParameter(mb_strtolower($uid))));
231
-			$query->execute();
232
-
233
-			$this->cache[$uid]['displayname'] = $displayName;
234
-
235
-			return true;
236
-		}
237
-
238
-		return false;
239
-	}
240
-
241
-	/**
242
-	 * get display name of the user
243
-	 *
244
-	 * @param string $uid user ID of the user
245
-	 * @return string display name
246
-	 */
247
-	public function getDisplayName($uid): string {
248
-		$uid = (string)$uid;
249
-		$this->loadUser($uid);
250
-		return empty($this->cache[$uid]['displayname']) ? $uid : $this->cache[$uid]['displayname'];
251
-	}
252
-
253
-	/**
254
-	 * Get a list of all display names and user ids.
255
-	 *
256
-	 * @param string $search
257
-	 * @param string|null $limit
258
-	 * @param string|null $offset
259
-	 * @return array an array of all displayNames (value) and the corresponding uids (key)
260
-	 */
261
-	public function getDisplayNames($search = '', $limit = null, $offset = null) {
262
-		$this->fixDI();
263
-
264
-		$query = $this->dbConn->getQueryBuilder();
265
-
266
-		$query->select('uid', 'displayname')
267
-			->from($this->table, 'u')
268
-			->leftJoin('u', 'preferences', 'p', $query->expr()->andX(
269
-				$query->expr()->eq('userid', 'uid'),
270
-				$query->expr()->eq('appid', $query->expr()->literal('settings')),
271
-				$query->expr()->eq('configkey', $query->expr()->literal('email')))
272
-			)
273
-			// sqlite doesn't like re-using a single named parameter here
274
-			->where($query->expr()->iLike('uid', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%')))
275
-			->orWhere($query->expr()->iLike('displayname', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%')))
276
-			->orWhere($query->expr()->iLike('configvalue', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%')))
277
-			->orderBy($query->func()->lower('displayname'), 'ASC')
278
-			->orderBy('uid_lower', 'ASC')
279
-			->setMaxResults($limit)
280
-			->setFirstResult($offset);
281
-
282
-		$result = $query->execute();
283
-		$displayNames = [];
284
-		while ($row = $result->fetch()) {
285
-			$displayNames[(string)$row['uid']] = (string)$row['displayname'];
286
-		}
287
-
288
-		return $displayNames;
289
-	}
290
-
291
-	/**
292
-	 * Check if the password is correct
293
-	 *
294
-	 * @param string $uid The username
295
-	 * @param string $password The password
296
-	 * @return string
297
-	 *
298
-	 * Check if the password is correct without logging in the user
299
-	 * returns the user id or false
300
-	 */
301
-	public function checkPassword(string $uid, string $password) {
302
-		$this->fixDI();
303
-
304
-		$qb = $this->dbConn->getQueryBuilder();
305
-		$qb->select('uid', 'password')
306
-			->from($this->table)
307
-			->where(
308
-				$qb->expr()->eq(
309
-					'uid_lower', $qb->createNamedParameter(mb_strtolower($uid))
310
-				)
311
-			);
312
-		$result = $qb->execute();
313
-		$row = $result->fetch();
314
-		$result->closeCursor();
315
-
316
-		if ($row) {
317
-			$storedHash = $row['password'];
318
-			$newHash = '';
319
-			if (\OC::$server->getHasher()->verify($password, $storedHash, $newHash)) {
320
-				if (!empty($newHash)) {
321
-					$this->updatePassword($uid, $newHash);
322
-				}
323
-				return (string)$row['uid'];
324
-			}
325
-
326
-		}
327
-
328
-		return false;
329
-	}
330
-
331
-	/**
332
-	 * Load an user in the cache
333
-	 *
334
-	 * @param string $uid the username
335
-	 * @return boolean true if user was found, false otherwise
336
-	 */
337
-	private function loadUser($uid) {
338
-		$this->fixDI();
339
-
340
-		$uid = (string)$uid;
341
-		if (!isset($this->cache[$uid])) {
342
-			//guests $uid could be NULL or ''
343
-			if ($uid === '') {
344
-				$this->cache[$uid] = false;
345
-				return true;
346
-			}
347
-
348
-			$qb = $this->dbConn->getQueryBuilder();
349
-			$qb->select('uid', 'displayname')
350
-				->from($this->table)
351
-				->where(
352
-					$qb->expr()->eq(
353
-						'uid_lower', $qb->createNamedParameter(mb_strtolower($uid))
354
-					)
355
-				);
356
-			$result = $qb->execute();
357
-			$row = $result->fetch();
358
-			$result->closeCursor();
359
-
360
-			$this->cache[$uid] = false;
361
-
362
-			// "uid" is primary key, so there can only be a single result
363
-			if ($row !== false) {
364
-				$this->cache[$uid]['uid'] = (string)$row['uid'];
365
-				$this->cache[$uid]['displayname'] = (string)$row['displayname'];
366
-			} else {
367
-				return false;
368
-			}
369
-		}
370
-
371
-		return true;
372
-	}
373
-
374
-	/**
375
-	 * Get a list of all users
376
-	 *
377
-	 * @param string $search
378
-	 * @param null|int $limit
379
-	 * @param null|int $offset
380
-	 * @return string[] an array of all uids
381
-	 */
382
-	public function getUsers($search = '', $limit = null, $offset = null) {
383
-		$users = $this->getDisplayNames($search, $limit, $offset);
384
-		$userIds = array_map(function ($uid) {
385
-			return (string)$uid;
386
-		}, array_keys($users));
387
-		sort($userIds, SORT_STRING | SORT_FLAG_CASE);
388
-		return $userIds;
389
-	}
390
-
391
-	/**
392
-	 * check if a user exists
393
-	 *
394
-	 * @param string $uid the username
395
-	 * @return boolean
396
-	 */
397
-	public function userExists($uid) {
398
-		$this->loadUser($uid);
399
-		return $this->cache[$uid] !== false;
400
-	}
401
-
402
-	/**
403
-	 * get the user's home directory
404
-	 *
405
-	 * @param string $uid the username
406
-	 * @return string|false
407
-	 */
408
-	public function getHome(string $uid) {
409
-		if ($this->userExists($uid)) {
410
-			return \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/' . $uid;
411
-		}
412
-
413
-		return false;
414
-	}
415
-
416
-	/**
417
-	 * @return bool
418
-	 */
419
-	public function hasUserListings() {
420
-		return true;
421
-	}
422
-
423
-	/**
424
-	 * counts the users in the database
425
-	 *
426
-	 * @return int|bool
427
-	 */
428
-	public function countUsers() {
429
-		$this->fixDI();
430
-
431
-		$query = $this->dbConn->getQueryBuilder();
432
-		$query->select($query->func()->count('uid'))
433
-			->from($this->table);
434
-		$result = $query->execute();
435
-
436
-		return $result->fetchColumn();
437
-	}
438
-
439
-	/**
440
-	 * returns the username for the given login name in the correct casing
441
-	 *
442
-	 * @param string $loginName
443
-	 * @return string|false
444
-	 */
445
-	public function loginName2UserName($loginName) {
446
-		if ($this->userExists($loginName)) {
447
-			return $this->cache[$loginName]['uid'];
448
-		}
449
-
450
-		return false;
451
-	}
452
-
453
-	/**
454
-	 * Backend name to be shown in user management
455
-	 *
456
-	 * @return string the name of the backend to be shown
457
-	 */
458
-	public function getBackendName() {
459
-		return 'Database';
460
-	}
461
-
462
-	public static function preLoginNameUsedAsUserName($param) {
463
-		if (!isset($param['uid'])) {
464
-			throw new \Exception('key uid is expected to be set in $param');
465
-		}
466
-
467
-		$backends = \OC::$server->getUserManager()->getBackends();
468
-		foreach ($backends as $backend) {
469
-			if ($backend instanceof Database) {
470
-				/** @var \OC\User\Database $backend */
471
-				$uid = $backend->loginName2UserName($param['uid']);
472
-				if ($uid !== false) {
473
-					$param['uid'] = $uid;
474
-					return;
475
-				}
476
-			}
477
-		}
478
-	}
479
-
480
-	public function getRealUID(string $uid): string {
481
-		if (!$this->userExists($uid)) {
482
-			throw new \RuntimeException($uid . ' does not exist');
483
-		}
484
-
485
-		return $this->cache[$uid]['uid'];
486
-	}
78
+    implements ICreateUserBackend,
79
+                ISetPasswordBackend,
80
+                ISetDisplayNameBackend,
81
+                IGetDisplayNameBackend,
82
+                ICheckPasswordBackend,
83
+                IGetHomeBackend,
84
+                ICountUsersBackend,
85
+                IGetRealUIDBackend {
86
+    /** @var CappedMemoryCache */
87
+    private $cache;
88
+
89
+    /** @var EventDispatcherInterface */
90
+    private $eventDispatcher;
91
+
92
+    /** @var IDBConnection */
93
+    private $dbConn;
94
+
95
+    /** @var string */
96
+    private $table;
97
+
98
+    /**
99
+     * \OC\User\Database constructor.
100
+     *
101
+     * @param EventDispatcherInterface $eventDispatcher
102
+     * @param string $table
103
+     */
104
+    public function __construct($eventDispatcher = null, $table = 'users') {
105
+        $this->cache = new CappedMemoryCache();
106
+        $this->table = $table;
107
+        $this->eventDispatcher = $eventDispatcher ? $eventDispatcher : \OC::$server->getEventDispatcher();
108
+    }
109
+
110
+    /**
111
+     * FIXME: This function should not be required!
112
+     */
113
+    private function fixDI() {
114
+        if ($this->dbConn === null) {
115
+            $this->dbConn = \OC::$server->getDatabaseConnection();
116
+        }
117
+    }
118
+
119
+    /**
120
+     * Create a new user
121
+     *
122
+     * @param string $uid The username of the user to create
123
+     * @param string $password The password of the new user
124
+     * @return bool
125
+     *
126
+     * Creates a new user. Basic checking of username is done in OC_User
127
+     * itself, not in its subclasses.
128
+     */
129
+    public function createUser(string $uid, string $password): bool {
130
+        $this->fixDI();
131
+
132
+        if (!$this->userExists($uid)) {
133
+            $event = new GenericEvent($password);
134
+            $this->eventDispatcher->dispatch('OCP\PasswordPolicy::validate', $event);
135
+
136
+            $qb = $this->dbConn->getQueryBuilder();
137
+            $qb->insert($this->table)
138
+                ->values([
139
+                    'uid' => $qb->createNamedParameter($uid),
140
+                    'password' => $qb->createNamedParameter(\OC::$server->getHasher()->hash($password)),
141
+                    'uid_lower' => $qb->createNamedParameter(mb_strtolower($uid)),
142
+                ]);
143
+
144
+            $result = $qb->execute();
145
+
146
+            // Clear cache
147
+            unset($this->cache[$uid]);
148
+
149
+            return $result ? true : false;
150
+        }
151
+
152
+        return false;
153
+    }
154
+
155
+    /**
156
+     * delete a user
157
+     *
158
+     * @param string $uid The username of the user to delete
159
+     * @return bool
160
+     *
161
+     * Deletes a user
162
+     */
163
+    public function deleteUser($uid) {
164
+        $this->fixDI();
165
+
166
+        // Delete user-group-relation
167
+        $query = $this->dbConn->getQueryBuilder();
168
+        $query->delete($this->table)
169
+            ->where($query->expr()->eq('uid_lower', $query->createNamedParameter(mb_strtolower($uid))));
170
+        $result = $query->execute();
171
+
172
+        if (isset($this->cache[$uid])) {
173
+            unset($this->cache[$uid]);
174
+        }
175
+
176
+        return $result ? true : false;
177
+    }
178
+
179
+    private function updatePassword(string $uid, string $passwordHash): bool {
180
+        $query = $this->dbConn->getQueryBuilder();
181
+        $query->update($this->table)
182
+            ->set('password', $query->createNamedParameter($passwordHash))
183
+            ->where($query->expr()->eq('uid_lower', $query->createNamedParameter(mb_strtolower($uid))));
184
+        $result = $query->execute();
185
+
186
+        return $result ? true : false;
187
+    }
188
+
189
+    /**
190
+     * Set password
191
+     *
192
+     * @param string $uid The username
193
+     * @param string $password The new password
194
+     * @return bool
195
+     *
196
+     * Change the password of a user
197
+     */
198
+    public function setPassword(string $uid, string $password): bool {
199
+        $this->fixDI();
200
+
201
+        if ($this->userExists($uid)) {
202
+            $event = new GenericEvent($password);
203
+            $this->eventDispatcher->dispatch('OCP\PasswordPolicy::validate', $event);
204
+
205
+            $hasher = \OC::$server->getHasher();
206
+            $hashedPassword = $hasher->hash($password);
207
+
208
+            return $this->updatePassword($uid, $hashedPassword);
209
+        }
210
+
211
+        return false;
212
+    }
213
+
214
+    /**
215
+     * Set display name
216
+     *
217
+     * @param string $uid The username
218
+     * @param string $displayName The new display name
219
+     * @return bool
220
+     *
221
+     * Change the display name of a user
222
+     */
223
+    public function setDisplayName(string $uid, string $displayName): bool {
224
+        $this->fixDI();
225
+
226
+        if ($this->userExists($uid)) {
227
+            $query = $this->dbConn->getQueryBuilder();
228
+            $query->update($this->table)
229
+                ->set('displayname', $query->createNamedParameter($displayName))
230
+                ->where($query->expr()->eq('uid_lower', $query->createNamedParameter(mb_strtolower($uid))));
231
+            $query->execute();
232
+
233
+            $this->cache[$uid]['displayname'] = $displayName;
234
+
235
+            return true;
236
+        }
237
+
238
+        return false;
239
+    }
240
+
241
+    /**
242
+     * get display name of the user
243
+     *
244
+     * @param string $uid user ID of the user
245
+     * @return string display name
246
+     */
247
+    public function getDisplayName($uid): string {
248
+        $uid = (string)$uid;
249
+        $this->loadUser($uid);
250
+        return empty($this->cache[$uid]['displayname']) ? $uid : $this->cache[$uid]['displayname'];
251
+    }
252
+
253
+    /**
254
+     * Get a list of all display names and user ids.
255
+     *
256
+     * @param string $search
257
+     * @param string|null $limit
258
+     * @param string|null $offset
259
+     * @return array an array of all displayNames (value) and the corresponding uids (key)
260
+     */
261
+    public function getDisplayNames($search = '', $limit = null, $offset = null) {
262
+        $this->fixDI();
263
+
264
+        $query = $this->dbConn->getQueryBuilder();
265
+
266
+        $query->select('uid', 'displayname')
267
+            ->from($this->table, 'u')
268
+            ->leftJoin('u', 'preferences', 'p', $query->expr()->andX(
269
+                $query->expr()->eq('userid', 'uid'),
270
+                $query->expr()->eq('appid', $query->expr()->literal('settings')),
271
+                $query->expr()->eq('configkey', $query->expr()->literal('email')))
272
+            )
273
+            // sqlite doesn't like re-using a single named parameter here
274
+            ->where($query->expr()->iLike('uid', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%')))
275
+            ->orWhere($query->expr()->iLike('displayname', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%')))
276
+            ->orWhere($query->expr()->iLike('configvalue', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%')))
277
+            ->orderBy($query->func()->lower('displayname'), 'ASC')
278
+            ->orderBy('uid_lower', 'ASC')
279
+            ->setMaxResults($limit)
280
+            ->setFirstResult($offset);
281
+
282
+        $result = $query->execute();
283
+        $displayNames = [];
284
+        while ($row = $result->fetch()) {
285
+            $displayNames[(string)$row['uid']] = (string)$row['displayname'];
286
+        }
287
+
288
+        return $displayNames;
289
+    }
290
+
291
+    /**
292
+     * Check if the password is correct
293
+     *
294
+     * @param string $uid The username
295
+     * @param string $password The password
296
+     * @return string
297
+     *
298
+     * Check if the password is correct without logging in the user
299
+     * returns the user id or false
300
+     */
301
+    public function checkPassword(string $uid, string $password) {
302
+        $this->fixDI();
303
+
304
+        $qb = $this->dbConn->getQueryBuilder();
305
+        $qb->select('uid', 'password')
306
+            ->from($this->table)
307
+            ->where(
308
+                $qb->expr()->eq(
309
+                    'uid_lower', $qb->createNamedParameter(mb_strtolower($uid))
310
+                )
311
+            );
312
+        $result = $qb->execute();
313
+        $row = $result->fetch();
314
+        $result->closeCursor();
315
+
316
+        if ($row) {
317
+            $storedHash = $row['password'];
318
+            $newHash = '';
319
+            if (\OC::$server->getHasher()->verify($password, $storedHash, $newHash)) {
320
+                if (!empty($newHash)) {
321
+                    $this->updatePassword($uid, $newHash);
322
+                }
323
+                return (string)$row['uid'];
324
+            }
325
+
326
+        }
327
+
328
+        return false;
329
+    }
330
+
331
+    /**
332
+     * Load an user in the cache
333
+     *
334
+     * @param string $uid the username
335
+     * @return boolean true if user was found, false otherwise
336
+     */
337
+    private function loadUser($uid) {
338
+        $this->fixDI();
339
+
340
+        $uid = (string)$uid;
341
+        if (!isset($this->cache[$uid])) {
342
+            //guests $uid could be NULL or ''
343
+            if ($uid === '') {
344
+                $this->cache[$uid] = false;
345
+                return true;
346
+            }
347
+
348
+            $qb = $this->dbConn->getQueryBuilder();
349
+            $qb->select('uid', 'displayname')
350
+                ->from($this->table)
351
+                ->where(
352
+                    $qb->expr()->eq(
353
+                        'uid_lower', $qb->createNamedParameter(mb_strtolower($uid))
354
+                    )
355
+                );
356
+            $result = $qb->execute();
357
+            $row = $result->fetch();
358
+            $result->closeCursor();
359
+
360
+            $this->cache[$uid] = false;
361
+
362
+            // "uid" is primary key, so there can only be a single result
363
+            if ($row !== false) {
364
+                $this->cache[$uid]['uid'] = (string)$row['uid'];
365
+                $this->cache[$uid]['displayname'] = (string)$row['displayname'];
366
+            } else {
367
+                return false;
368
+            }
369
+        }
370
+
371
+        return true;
372
+    }
373
+
374
+    /**
375
+     * Get a list of all users
376
+     *
377
+     * @param string $search
378
+     * @param null|int $limit
379
+     * @param null|int $offset
380
+     * @return string[] an array of all uids
381
+     */
382
+    public function getUsers($search = '', $limit = null, $offset = null) {
383
+        $users = $this->getDisplayNames($search, $limit, $offset);
384
+        $userIds = array_map(function ($uid) {
385
+            return (string)$uid;
386
+        }, array_keys($users));
387
+        sort($userIds, SORT_STRING | SORT_FLAG_CASE);
388
+        return $userIds;
389
+    }
390
+
391
+    /**
392
+     * check if a user exists
393
+     *
394
+     * @param string $uid the username
395
+     * @return boolean
396
+     */
397
+    public function userExists($uid) {
398
+        $this->loadUser($uid);
399
+        return $this->cache[$uid] !== false;
400
+    }
401
+
402
+    /**
403
+     * get the user's home directory
404
+     *
405
+     * @param string $uid the username
406
+     * @return string|false
407
+     */
408
+    public function getHome(string $uid) {
409
+        if ($this->userExists($uid)) {
410
+            return \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/' . $uid;
411
+        }
412
+
413
+        return false;
414
+    }
415
+
416
+    /**
417
+     * @return bool
418
+     */
419
+    public function hasUserListings() {
420
+        return true;
421
+    }
422
+
423
+    /**
424
+     * counts the users in the database
425
+     *
426
+     * @return int|bool
427
+     */
428
+    public function countUsers() {
429
+        $this->fixDI();
430
+
431
+        $query = $this->dbConn->getQueryBuilder();
432
+        $query->select($query->func()->count('uid'))
433
+            ->from($this->table);
434
+        $result = $query->execute();
435
+
436
+        return $result->fetchColumn();
437
+    }
438
+
439
+    /**
440
+     * returns the username for the given login name in the correct casing
441
+     *
442
+     * @param string $loginName
443
+     * @return string|false
444
+     */
445
+    public function loginName2UserName($loginName) {
446
+        if ($this->userExists($loginName)) {
447
+            return $this->cache[$loginName]['uid'];
448
+        }
449
+
450
+        return false;
451
+    }
452
+
453
+    /**
454
+     * Backend name to be shown in user management
455
+     *
456
+     * @return string the name of the backend to be shown
457
+     */
458
+    public function getBackendName() {
459
+        return 'Database';
460
+    }
461
+
462
+    public static function preLoginNameUsedAsUserName($param) {
463
+        if (!isset($param['uid'])) {
464
+            throw new \Exception('key uid is expected to be set in $param');
465
+        }
466
+
467
+        $backends = \OC::$server->getUserManager()->getBackends();
468
+        foreach ($backends as $backend) {
469
+            if ($backend instanceof Database) {
470
+                /** @var \OC\User\Database $backend */
471
+                $uid = $backend->loginName2UserName($param['uid']);
472
+                if ($uid !== false) {
473
+                    $param['uid'] = $uid;
474
+                    return;
475
+                }
476
+            }
477
+        }
478
+    }
479
+
480
+    public function getRealUID(string $uid): string {
481
+        if (!$this->userExists($uid)) {
482
+            throw new \RuntimeException($uid . ' does not exist');
483
+        }
484
+
485
+        return $this->cache[$uid]['uid'];
486
+    }
487 487
 
488 488
 
489 489
 }
Please login to merge, or discard this patch.
Spacing   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -245,7 +245,7 @@  discard block
 block discarded – undo
245 245
 	 * @return string display name
246 246
 	 */
247 247
 	public function getDisplayName($uid): string {
248
-		$uid = (string)$uid;
248
+		$uid = (string) $uid;
249 249
 		$this->loadUser($uid);
250 250
 		return empty($this->cache[$uid]['displayname']) ? $uid : $this->cache[$uid]['displayname'];
251 251
 	}
@@ -271,9 +271,9 @@  discard block
 block discarded – undo
271 271
 				$query->expr()->eq('configkey', $query->expr()->literal('email')))
272 272
 			)
273 273
 			// sqlite doesn't like re-using a single named parameter here
274
-			->where($query->expr()->iLike('uid', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%')))
275
-			->orWhere($query->expr()->iLike('displayname', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%')))
276
-			->orWhere($query->expr()->iLike('configvalue', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%')))
274
+			->where($query->expr()->iLike('uid', $query->createPositionalParameter('%'.$this->dbConn->escapeLikeParameter($search).'%')))
275
+			->orWhere($query->expr()->iLike('displayname', $query->createPositionalParameter('%'.$this->dbConn->escapeLikeParameter($search).'%')))
276
+			->orWhere($query->expr()->iLike('configvalue', $query->createPositionalParameter('%'.$this->dbConn->escapeLikeParameter($search).'%')))
277 277
 			->orderBy($query->func()->lower('displayname'), 'ASC')
278 278
 			->orderBy('uid_lower', 'ASC')
279 279
 			->setMaxResults($limit)
@@ -282,7 +282,7 @@  discard block
 block discarded – undo
282 282
 		$result = $query->execute();
283 283
 		$displayNames = [];
284 284
 		while ($row = $result->fetch()) {
285
-			$displayNames[(string)$row['uid']] = (string)$row['displayname'];
285
+			$displayNames[(string) $row['uid']] = (string) $row['displayname'];
286 286
 		}
287 287
 
288 288
 		return $displayNames;
@@ -320,7 +320,7 @@  discard block
 block discarded – undo
320 320
 				if (!empty($newHash)) {
321 321
 					$this->updatePassword($uid, $newHash);
322 322
 				}
323
-				return (string)$row['uid'];
323
+				return (string) $row['uid'];
324 324
 			}
325 325
 
326 326
 		}
@@ -337,7 +337,7 @@  discard block
 block discarded – undo
337 337
 	private function loadUser($uid) {
338 338
 		$this->fixDI();
339 339
 
340
-		$uid = (string)$uid;
340
+		$uid = (string) $uid;
341 341
 		if (!isset($this->cache[$uid])) {
342 342
 			//guests $uid could be NULL or ''
343 343
 			if ($uid === '') {
@@ -361,8 +361,8 @@  discard block
 block discarded – undo
361 361
 
362 362
 			// "uid" is primary key, so there can only be a single result
363 363
 			if ($row !== false) {
364
-				$this->cache[$uid]['uid'] = (string)$row['uid'];
365
-				$this->cache[$uid]['displayname'] = (string)$row['displayname'];
364
+				$this->cache[$uid]['uid'] = (string) $row['uid'];
365
+				$this->cache[$uid]['displayname'] = (string) $row['displayname'];
366 366
 			} else {
367 367
 				return false;
368 368
 			}
@@ -381,8 +381,8 @@  discard block
 block discarded – undo
381 381
 	 */
382 382
 	public function getUsers($search = '', $limit = null, $offset = null) {
383 383
 		$users = $this->getDisplayNames($search, $limit, $offset);
384
-		$userIds = array_map(function ($uid) {
385
-			return (string)$uid;
384
+		$userIds = array_map(function($uid) {
385
+			return (string) $uid;
386 386
 		}, array_keys($users));
387 387
 		sort($userIds, SORT_STRING | SORT_FLAG_CASE);
388 388
 		return $userIds;
@@ -407,7 +407,7 @@  discard block
 block discarded – undo
407 407
 	 */
408 408
 	public function getHome(string $uid) {
409 409
 		if ($this->userExists($uid)) {
410
-			return \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/' . $uid;
410
+			return \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT.'/data').'/'.$uid;
411 411
 		}
412 412
 
413 413
 		return false;
@@ -479,7 +479,7 @@  discard block
 block discarded – undo
479 479
 
480 480
 	public function getRealUID(string $uid): string {
481 481
 		if (!$this->userExists($uid)) {
482
-			throw new \RuntimeException($uid . ' does not exist');
482
+			throw new \RuntimeException($uid.' does not exist');
483 483
 		}
484 484
 
485 485
 		return $this->cache[$uid]['uid'];
Please login to merge, or discard this patch.
lib/private/User/Manager.php 1 patch
Indentation   +553 added lines, -553 removed lines patch added patch discarded remove patch
@@ -60,561 +60,561 @@
 block discarded – undo
60 60
  * @package OC\User
61 61
  */
62 62
 class Manager extends PublicEmitter implements IUserManager {
63
-	/**
64
-	 * @var \OCP\UserInterface[] $backends
65
-	 */
66
-	private $backends = array();
67
-
68
-	/**
69
-	 * @var \OC\User\User[] $cachedUsers
70
-	 */
71
-	private $cachedUsers = array();
72
-
73
-	/** @var IConfig */
74
-	private $config;
75
-	/** @var EventDispatcherInterface */
76
-	private $dispatcher;
77
-
78
-	public function __construct(IConfig $config, EventDispatcherInterface $dispatcher) {
79
-		$this->config = $config;
80
-		$this->dispatcher = $dispatcher;
81
-		$cachedUsers = &$this->cachedUsers;
82
-		$this->listen('\OC\User', 'postDelete', function ($user) use (&$cachedUsers) {
83
-			/** @var \OC\User\User $user */
84
-			unset($cachedUsers[$user->getUID()]);
85
-		});
86
-	}
87
-
88
-	/**
89
-	 * Get the active backends
90
-	 * @return \OCP\UserInterface[]
91
-	 */
92
-	public function getBackends() {
93
-		return $this->backends;
94
-	}
95
-
96
-	/**
97
-	 * register a user backend
98
-	 *
99
-	 * @param \OCP\UserInterface $backend
100
-	 */
101
-	public function registerBackend($backend) {
102
-		$this->backends[] = $backend;
103
-	}
104
-
105
-	/**
106
-	 * remove a user backend
107
-	 *
108
-	 * @param \OCP\UserInterface $backend
109
-	 */
110
-	public function removeBackend($backend) {
111
-		$this->cachedUsers = array();
112
-		if (($i = array_search($backend, $this->backends)) !== false) {
113
-			unset($this->backends[$i]);
114
-		}
115
-	}
116
-
117
-	/**
118
-	 * remove all user backends
119
-	 */
120
-	public function clearBackends() {
121
-		$this->cachedUsers = array();
122
-		$this->backends = array();
123
-	}
124
-
125
-	/**
126
-	 * get a user by user id
127
-	 *
128
-	 * @param string $uid
129
-	 * @return \OC\User\User|null Either the user or null if the specified user does not exist
130
-	 */
131
-	public function get($uid) {
132
-		if (is_null($uid) || $uid === '' || $uid === false) {
133
-			return null;
134
-		}
135
-		if (isset($this->cachedUsers[$uid])) { //check the cache first to prevent having to loop over the backends
136
-			return $this->cachedUsers[$uid];
137
-		}
138
-		foreach ($this->backends as $backend) {
139
-			if ($backend->userExists($uid)) {
140
-				return $this->getUserObject($uid, $backend);
141
-			}
142
-		}
143
-		return null;
144
-	}
145
-
146
-	/**
147
-	 * get or construct the user object
148
-	 *
149
-	 * @param string $uid
150
-	 * @param \OCP\UserInterface $backend
151
-	 * @param bool $cacheUser If false the newly created user object will not be cached
152
-	 * @return \OC\User\User
153
-	 */
154
-	protected function getUserObject($uid, $backend, $cacheUser = true) {
155
-		if ($backend instanceof IGetRealUIDBackend) {
156
-			$uid = $backend->getRealUID($uid);
157
-		}
158
-
159
-		if (isset($this->cachedUsers[$uid])) {
160
-			return $this->cachedUsers[$uid];
161
-		}
162
-
163
-		$user = new User($uid, $backend, $this->dispatcher, $this, $this->config);
164
-		if ($cacheUser) {
165
-			$this->cachedUsers[$uid] = $user;
166
-		}
167
-		return $user;
168
-	}
169
-
170
-	/**
171
-	 * check if a user exists
172
-	 *
173
-	 * @param string $uid
174
-	 * @return bool
175
-	 */
176
-	public function userExists($uid) {
177
-		$user = $this->get($uid);
178
-		return ($user !== null);
179
-	}
180
-
181
-	/**
182
-	 * Check if the password is valid for the user
183
-	 *
184
-	 * @param string $loginName
185
-	 * @param string $password
186
-	 * @return mixed the User object on success, false otherwise
187
-	 */
188
-	public function checkPassword($loginName, $password) {
189
-		$result = $this->checkPasswordNoLogging($loginName, $password);
190
-
191
-		if ($result === false) {
192
-			\OC::$server->getLogger()->warning('Login failed: \''. $loginName .'\' (Remote IP: \''. \OC::$server->getRequest()->getRemoteAddress(). '\')', ['app' => 'core']);
193
-		}
194
-
195
-		return $result;
196
-	}
197
-
198
-	/**
199
-	 * Check if the password is valid for the user
200
-	 *
201
-	 * @internal
202
-	 * @param string $loginName
203
-	 * @param string $password
204
-	 * @return IUser|false the User object on success, false otherwise
205
-	 */
206
-	public function checkPasswordNoLogging($loginName, $password) {
207
-		$loginName = str_replace("\0", '', $loginName);
208
-		$password = str_replace("\0", '', $password);
209
-
210
-		foreach ($this->backends as $backend) {
211
-			if ($backend->implementsActions(Backend::CHECK_PASSWORD)) {
212
-				$uid = $backend->checkPassword($loginName, $password);
213
-				if ($uid !== false) {
214
-					return $this->getUserObject($uid, $backend);
215
-				}
216
-			}
217
-		}
218
-
219
-		return false;
220
-	}
221
-
222
-	/**
223
-	 * search by user id
224
-	 *
225
-	 * @param string $pattern
226
-	 * @param int $limit
227
-	 * @param int $offset
228
-	 * @return \OC\User\User[]
229
-	 */
230
-	public function search($pattern, $limit = null, $offset = null) {
231
-		$users = array();
232
-		foreach ($this->backends as $backend) {
233
-			$backendUsers = $backend->getUsers($pattern, $limit, $offset);
234
-			if (is_array($backendUsers)) {
235
-				foreach ($backendUsers as $uid) {
236
-					$users[$uid] = $this->getUserObject($uid, $backend);
237
-				}
238
-			}
239
-		}
240
-
241
-		uasort($users, function ($a, $b) {
242
-			/**
243
-			 * @var \OC\User\User $a
244
-			 * @var \OC\User\User $b
245
-			 */
246
-			return strcasecmp($a->getUID(), $b->getUID());
247
-		});
248
-		return $users;
249
-	}
250
-
251
-	/**
252
-	 * search by displayName
253
-	 *
254
-	 * @param string $pattern
255
-	 * @param int $limit
256
-	 * @param int $offset
257
-	 * @return \OC\User\User[]
258
-	 */
259
-	public function searchDisplayName($pattern, $limit = null, $offset = null) {
260
-		$users = array();
261
-		foreach ($this->backends as $backend) {
262
-			$backendUsers = $backend->getDisplayNames($pattern, $limit, $offset);
263
-			if (is_array($backendUsers)) {
264
-				foreach ($backendUsers as $uid => $displayName) {
265
-					$users[] = $this->getUserObject($uid, $backend);
266
-				}
267
-			}
268
-		}
269
-
270
-		usort($users, function ($a, $b) {
271
-			/**
272
-			 * @var \OC\User\User $a
273
-			 * @var \OC\User\User $b
274
-			 */
275
-			return strcasecmp($a->getDisplayName(), $b->getDisplayName());
276
-		});
277
-		return $users;
278
-	}
279
-
280
-	/**
281
-	 * @param string $uid
282
-	 * @param string $password
283
-	 * @throws \InvalidArgumentException
284
-	 * @return bool|IUser the created user or false
285
-	 */
286
-	public function createUser($uid, $password) {
287
-		if (!$this->verifyUid($uid)) {
288
-			return false;
289
-		}
290
-
291
-		$localBackends = [];
292
-		foreach ($this->backends as $backend) {
293
-			if ($backend instanceof Database) {
294
-				// First check if there is another user backend
295
-				$localBackends[] = $backend;
296
-				continue;
297
-			}
298
-
299
-			if ($backend->implementsActions(Backend::CREATE_USER)) {
300
-				return $this->createUserFromBackend($uid, $password, $backend);
301
-			}
302
-		}
303
-
304
-		foreach ($localBackends as $backend) {
305
-			if ($backend->implementsActions(Backend::CREATE_USER)) {
306
-				return $this->createUserFromBackend($uid, $password, $backend);
307
-			}
308
-		}
309
-
310
-		return false;
311
-	}
312
-
313
-	/**
314
-	 * @param string $uid
315
-	 * @param string $password
316
-	 * @param UserInterface $backend
317
-	 * @return IUser|null
318
-	 * @throws \InvalidArgumentException
319
-	 */
320
-	public function createUserFromBackend($uid, $password, UserInterface $backend) {
321
-		$l = \OC::$server->getL10N('lib');
322
-
323
-		// Check the name for bad characters
324
-		// Allowed are: "a-z", "A-Z", "0-9" and "_.@-'"
325
-		if (preg_match('/[^a-zA-Z0-9 _\.@\-\']/', $uid)) {
326
-			throw new \InvalidArgumentException($l->t('Only the following characters are allowed in a username:'
327
-				. ' "a-z", "A-Z", "0-9", and "_.@-\'"'));
328
-		}
329
-		// No empty username
330
-		if (trim($uid) === '') {
331
-			throw new \InvalidArgumentException($l->t('A valid username must be provided'));
332
-		}
333
-		// No whitespace at the beginning or at the end
334
-		if (trim($uid) !== $uid) {
335
-			throw new \InvalidArgumentException($l->t('Username contains whitespace at the beginning or at the end'));
336
-		}
337
-		// Username only consists of 1 or 2 dots (directory traversal)
338
-		if ($uid === '.' || $uid === '..') {
339
-			throw new \InvalidArgumentException($l->t('Username must not consist of dots only'));
340
-		}
341
-		// No empty password
342
-		if (trim($password) === '') {
343
-			throw new \InvalidArgumentException($l->t('A valid password must be provided'));
344
-		}
345
-
346
-		// Check if user already exists
347
-		if ($this->userExists($uid)) {
348
-			throw new \InvalidArgumentException($l->t('The username is already being used'));
349
-		}
350
-
351
-		$this->emit('\OC\User', 'preCreateUser', [$uid, $password]);
352
-		$state = $backend->createUser($uid, $password);
353
-		if($state === false) {
354
-			throw new \InvalidArgumentException($l->t('Could not create user'));
355
-		}
356
-		$user = $this->getUserObject($uid, $backend);
357
-		if ($user instanceof IUser) {
358
-			$this->emit('\OC\User', 'postCreateUser', [$user, $password]);
359
-		}
360
-		return $user;
361
-	}
362
-
363
-	/**
364
-	 * returns how many users per backend exist (if supported by backend)
365
-	 *
366
-	 * @param boolean $hasLoggedIn when true only users that have a lastLogin
367
-	 *                entry in the preferences table will be affected
368
-	 * @return array|int an array of backend class as key and count number as value
369
-	 *                if $hasLoggedIn is true only an int is returned
370
-	 */
371
-	public function countUsers($hasLoggedIn = false) {
372
-		if ($hasLoggedIn) {
373
-			return $this->countSeenUsers();
374
-		}
375
-		$userCountStatistics = [];
376
-		foreach ($this->backends as $backend) {
377
-			if ($backend->implementsActions(Backend::COUNT_USERS)) {
378
-				$backendUsers = $backend->countUsers();
379
-				if($backendUsers !== false) {
380
-					if($backend instanceof IUserBackend) {
381
-						$name = $backend->getBackendName();
382
-					} else {
383
-						$name = get_class($backend);
384
-					}
385
-					if(isset($userCountStatistics[$name])) {
386
-						$userCountStatistics[$name] += $backendUsers;
387
-					} else {
388
-						$userCountStatistics[$name] = $backendUsers;
389
-					}
390
-				}
391
-			}
392
-		}
393
-		return $userCountStatistics;
394
-	}
395
-
396
-	/**
397
-	 * returns how many users per backend exist in the requested groups (if supported by backend)
398
-	 *
399
-	 * @param IGroup[] $groups an array of gid to search in
400
-	 * @return array|int an array of backend class as key and count number as value
401
-	 *                if $hasLoggedIn is true only an int is returned
402
-	 */
403
-	public function countUsersOfGroups(array $groups) {
404
-		$users = [];
405
-		foreach($groups as $group) {
406
-			$usersIds = array_map(function($user) {
407
-				return $user->getUID();
408
-			}, $group->getUsers());
409
-			$users = array_merge($users, $usersIds);
410
-		}
411
-		return count(array_unique($users));
412
-	}
413
-
414
-	/**
415
-	 * The callback is executed for each user on each backend.
416
-	 * If the callback returns false no further users will be retrieved.
417
-	 *
418
-	 * @param \Closure $callback
419
-	 * @param string $search
420
-	 * @param boolean $onlySeen when true only users that have a lastLogin entry
421
-	 *                in the preferences table will be affected
422
-	 * @since 9.0.0
423
-	 */
424
-	public function callForAllUsers(\Closure $callback, $search = '', $onlySeen = false) {
425
-		if ($onlySeen) {
426
-			$this->callForSeenUsers($callback);
427
-		} else {
428
-			foreach ($this->getBackends() as $backend) {
429
-				$limit = 500;
430
-				$offset = 0;
431
-				do {
432
-					$users = $backend->getUsers($search, $limit, $offset);
433
-					foreach ($users as $uid) {
434
-						if (!$backend->userExists($uid)) {
435
-							continue;
436
-						}
437
-						$user = $this->getUserObject($uid, $backend, false);
438
-						$return = $callback($user);
439
-						if ($return === false) {
440
-							break;
441
-						}
442
-					}
443
-					$offset += $limit;
444
-				} while (count($users) >= $limit);
445
-			}
446
-		}
447
-	}
448
-
449
-	/**
450
-	 * returns how many users are disabled
451
-	 *
452
-	 * @return int
453
-	 * @since 12.0.0
454
-	 */
455
-	public function countDisabledUsers(): int {
456
-		$queryBuilder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
457
-		$queryBuilder->select($queryBuilder->func()->count('*'))
458
-			->from('preferences')
459
-			->where($queryBuilder->expr()->eq('appid', $queryBuilder->createNamedParameter('core')))
460
-			->andWhere($queryBuilder->expr()->eq('configkey', $queryBuilder->createNamedParameter('enabled')))
461
-			->andWhere($queryBuilder->expr()->eq('configvalue', $queryBuilder->createNamedParameter('false'), IQueryBuilder::PARAM_STR));
63
+    /**
64
+     * @var \OCP\UserInterface[] $backends
65
+     */
66
+    private $backends = array();
67
+
68
+    /**
69
+     * @var \OC\User\User[] $cachedUsers
70
+     */
71
+    private $cachedUsers = array();
72
+
73
+    /** @var IConfig */
74
+    private $config;
75
+    /** @var EventDispatcherInterface */
76
+    private $dispatcher;
77
+
78
+    public function __construct(IConfig $config, EventDispatcherInterface $dispatcher) {
79
+        $this->config = $config;
80
+        $this->dispatcher = $dispatcher;
81
+        $cachedUsers = &$this->cachedUsers;
82
+        $this->listen('\OC\User', 'postDelete', function ($user) use (&$cachedUsers) {
83
+            /** @var \OC\User\User $user */
84
+            unset($cachedUsers[$user->getUID()]);
85
+        });
86
+    }
87
+
88
+    /**
89
+     * Get the active backends
90
+     * @return \OCP\UserInterface[]
91
+     */
92
+    public function getBackends() {
93
+        return $this->backends;
94
+    }
95
+
96
+    /**
97
+     * register a user backend
98
+     *
99
+     * @param \OCP\UserInterface $backend
100
+     */
101
+    public function registerBackend($backend) {
102
+        $this->backends[] = $backend;
103
+    }
104
+
105
+    /**
106
+     * remove a user backend
107
+     *
108
+     * @param \OCP\UserInterface $backend
109
+     */
110
+    public function removeBackend($backend) {
111
+        $this->cachedUsers = array();
112
+        if (($i = array_search($backend, $this->backends)) !== false) {
113
+            unset($this->backends[$i]);
114
+        }
115
+    }
116
+
117
+    /**
118
+     * remove all user backends
119
+     */
120
+    public function clearBackends() {
121
+        $this->cachedUsers = array();
122
+        $this->backends = array();
123
+    }
124
+
125
+    /**
126
+     * get a user by user id
127
+     *
128
+     * @param string $uid
129
+     * @return \OC\User\User|null Either the user or null if the specified user does not exist
130
+     */
131
+    public function get($uid) {
132
+        if (is_null($uid) || $uid === '' || $uid === false) {
133
+            return null;
134
+        }
135
+        if (isset($this->cachedUsers[$uid])) { //check the cache first to prevent having to loop over the backends
136
+            return $this->cachedUsers[$uid];
137
+        }
138
+        foreach ($this->backends as $backend) {
139
+            if ($backend->userExists($uid)) {
140
+                return $this->getUserObject($uid, $backend);
141
+            }
142
+        }
143
+        return null;
144
+    }
145
+
146
+    /**
147
+     * get or construct the user object
148
+     *
149
+     * @param string $uid
150
+     * @param \OCP\UserInterface $backend
151
+     * @param bool $cacheUser If false the newly created user object will not be cached
152
+     * @return \OC\User\User
153
+     */
154
+    protected function getUserObject($uid, $backend, $cacheUser = true) {
155
+        if ($backend instanceof IGetRealUIDBackend) {
156
+            $uid = $backend->getRealUID($uid);
157
+        }
158
+
159
+        if (isset($this->cachedUsers[$uid])) {
160
+            return $this->cachedUsers[$uid];
161
+        }
162
+
163
+        $user = new User($uid, $backend, $this->dispatcher, $this, $this->config);
164
+        if ($cacheUser) {
165
+            $this->cachedUsers[$uid] = $user;
166
+        }
167
+        return $user;
168
+    }
169
+
170
+    /**
171
+     * check if a user exists
172
+     *
173
+     * @param string $uid
174
+     * @return bool
175
+     */
176
+    public function userExists($uid) {
177
+        $user = $this->get($uid);
178
+        return ($user !== null);
179
+    }
180
+
181
+    /**
182
+     * Check if the password is valid for the user
183
+     *
184
+     * @param string $loginName
185
+     * @param string $password
186
+     * @return mixed the User object on success, false otherwise
187
+     */
188
+    public function checkPassword($loginName, $password) {
189
+        $result = $this->checkPasswordNoLogging($loginName, $password);
190
+
191
+        if ($result === false) {
192
+            \OC::$server->getLogger()->warning('Login failed: \''. $loginName .'\' (Remote IP: \''. \OC::$server->getRequest()->getRemoteAddress(). '\')', ['app' => 'core']);
193
+        }
194
+
195
+        return $result;
196
+    }
197
+
198
+    /**
199
+     * Check if the password is valid for the user
200
+     *
201
+     * @internal
202
+     * @param string $loginName
203
+     * @param string $password
204
+     * @return IUser|false the User object on success, false otherwise
205
+     */
206
+    public function checkPasswordNoLogging($loginName, $password) {
207
+        $loginName = str_replace("\0", '', $loginName);
208
+        $password = str_replace("\0", '', $password);
209
+
210
+        foreach ($this->backends as $backend) {
211
+            if ($backend->implementsActions(Backend::CHECK_PASSWORD)) {
212
+                $uid = $backend->checkPassword($loginName, $password);
213
+                if ($uid !== false) {
214
+                    return $this->getUserObject($uid, $backend);
215
+                }
216
+            }
217
+        }
218
+
219
+        return false;
220
+    }
221
+
222
+    /**
223
+     * search by user id
224
+     *
225
+     * @param string $pattern
226
+     * @param int $limit
227
+     * @param int $offset
228
+     * @return \OC\User\User[]
229
+     */
230
+    public function search($pattern, $limit = null, $offset = null) {
231
+        $users = array();
232
+        foreach ($this->backends as $backend) {
233
+            $backendUsers = $backend->getUsers($pattern, $limit, $offset);
234
+            if (is_array($backendUsers)) {
235
+                foreach ($backendUsers as $uid) {
236
+                    $users[$uid] = $this->getUserObject($uid, $backend);
237
+                }
238
+            }
239
+        }
240
+
241
+        uasort($users, function ($a, $b) {
242
+            /**
243
+             * @var \OC\User\User $a
244
+             * @var \OC\User\User $b
245
+             */
246
+            return strcasecmp($a->getUID(), $b->getUID());
247
+        });
248
+        return $users;
249
+    }
250
+
251
+    /**
252
+     * search by displayName
253
+     *
254
+     * @param string $pattern
255
+     * @param int $limit
256
+     * @param int $offset
257
+     * @return \OC\User\User[]
258
+     */
259
+    public function searchDisplayName($pattern, $limit = null, $offset = null) {
260
+        $users = array();
261
+        foreach ($this->backends as $backend) {
262
+            $backendUsers = $backend->getDisplayNames($pattern, $limit, $offset);
263
+            if (is_array($backendUsers)) {
264
+                foreach ($backendUsers as $uid => $displayName) {
265
+                    $users[] = $this->getUserObject($uid, $backend);
266
+                }
267
+            }
268
+        }
269
+
270
+        usort($users, function ($a, $b) {
271
+            /**
272
+             * @var \OC\User\User $a
273
+             * @var \OC\User\User $b
274
+             */
275
+            return strcasecmp($a->getDisplayName(), $b->getDisplayName());
276
+        });
277
+        return $users;
278
+    }
279
+
280
+    /**
281
+     * @param string $uid
282
+     * @param string $password
283
+     * @throws \InvalidArgumentException
284
+     * @return bool|IUser the created user or false
285
+     */
286
+    public function createUser($uid, $password) {
287
+        if (!$this->verifyUid($uid)) {
288
+            return false;
289
+        }
290
+
291
+        $localBackends = [];
292
+        foreach ($this->backends as $backend) {
293
+            if ($backend instanceof Database) {
294
+                // First check if there is another user backend
295
+                $localBackends[] = $backend;
296
+                continue;
297
+            }
298
+
299
+            if ($backend->implementsActions(Backend::CREATE_USER)) {
300
+                return $this->createUserFromBackend($uid, $password, $backend);
301
+            }
302
+        }
303
+
304
+        foreach ($localBackends as $backend) {
305
+            if ($backend->implementsActions(Backend::CREATE_USER)) {
306
+                return $this->createUserFromBackend($uid, $password, $backend);
307
+            }
308
+        }
309
+
310
+        return false;
311
+    }
312
+
313
+    /**
314
+     * @param string $uid
315
+     * @param string $password
316
+     * @param UserInterface $backend
317
+     * @return IUser|null
318
+     * @throws \InvalidArgumentException
319
+     */
320
+    public function createUserFromBackend($uid, $password, UserInterface $backend) {
321
+        $l = \OC::$server->getL10N('lib');
322
+
323
+        // Check the name for bad characters
324
+        // Allowed are: "a-z", "A-Z", "0-9" and "_.@-'"
325
+        if (preg_match('/[^a-zA-Z0-9 _\.@\-\']/', $uid)) {
326
+            throw new \InvalidArgumentException($l->t('Only the following characters are allowed in a username:'
327
+                . ' "a-z", "A-Z", "0-9", and "_.@-\'"'));
328
+        }
329
+        // No empty username
330
+        if (trim($uid) === '') {
331
+            throw new \InvalidArgumentException($l->t('A valid username must be provided'));
332
+        }
333
+        // No whitespace at the beginning or at the end
334
+        if (trim($uid) !== $uid) {
335
+            throw new \InvalidArgumentException($l->t('Username contains whitespace at the beginning or at the end'));
336
+        }
337
+        // Username only consists of 1 or 2 dots (directory traversal)
338
+        if ($uid === '.' || $uid === '..') {
339
+            throw new \InvalidArgumentException($l->t('Username must not consist of dots only'));
340
+        }
341
+        // No empty password
342
+        if (trim($password) === '') {
343
+            throw new \InvalidArgumentException($l->t('A valid password must be provided'));
344
+        }
345
+
346
+        // Check if user already exists
347
+        if ($this->userExists($uid)) {
348
+            throw new \InvalidArgumentException($l->t('The username is already being used'));
349
+        }
350
+
351
+        $this->emit('\OC\User', 'preCreateUser', [$uid, $password]);
352
+        $state = $backend->createUser($uid, $password);
353
+        if($state === false) {
354
+            throw new \InvalidArgumentException($l->t('Could not create user'));
355
+        }
356
+        $user = $this->getUserObject($uid, $backend);
357
+        if ($user instanceof IUser) {
358
+            $this->emit('\OC\User', 'postCreateUser', [$user, $password]);
359
+        }
360
+        return $user;
361
+    }
362
+
363
+    /**
364
+     * returns how many users per backend exist (if supported by backend)
365
+     *
366
+     * @param boolean $hasLoggedIn when true only users that have a lastLogin
367
+     *                entry in the preferences table will be affected
368
+     * @return array|int an array of backend class as key and count number as value
369
+     *                if $hasLoggedIn is true only an int is returned
370
+     */
371
+    public function countUsers($hasLoggedIn = false) {
372
+        if ($hasLoggedIn) {
373
+            return $this->countSeenUsers();
374
+        }
375
+        $userCountStatistics = [];
376
+        foreach ($this->backends as $backend) {
377
+            if ($backend->implementsActions(Backend::COUNT_USERS)) {
378
+                $backendUsers = $backend->countUsers();
379
+                if($backendUsers !== false) {
380
+                    if($backend instanceof IUserBackend) {
381
+                        $name = $backend->getBackendName();
382
+                    } else {
383
+                        $name = get_class($backend);
384
+                    }
385
+                    if(isset($userCountStatistics[$name])) {
386
+                        $userCountStatistics[$name] += $backendUsers;
387
+                    } else {
388
+                        $userCountStatistics[$name] = $backendUsers;
389
+                    }
390
+                }
391
+            }
392
+        }
393
+        return $userCountStatistics;
394
+    }
395
+
396
+    /**
397
+     * returns how many users per backend exist in the requested groups (if supported by backend)
398
+     *
399
+     * @param IGroup[] $groups an array of gid to search in
400
+     * @return array|int an array of backend class as key and count number as value
401
+     *                if $hasLoggedIn is true only an int is returned
402
+     */
403
+    public function countUsersOfGroups(array $groups) {
404
+        $users = [];
405
+        foreach($groups as $group) {
406
+            $usersIds = array_map(function($user) {
407
+                return $user->getUID();
408
+            }, $group->getUsers());
409
+            $users = array_merge($users, $usersIds);
410
+        }
411
+        return count(array_unique($users));
412
+    }
413
+
414
+    /**
415
+     * The callback is executed for each user on each backend.
416
+     * If the callback returns false no further users will be retrieved.
417
+     *
418
+     * @param \Closure $callback
419
+     * @param string $search
420
+     * @param boolean $onlySeen when true only users that have a lastLogin entry
421
+     *                in the preferences table will be affected
422
+     * @since 9.0.0
423
+     */
424
+    public function callForAllUsers(\Closure $callback, $search = '', $onlySeen = false) {
425
+        if ($onlySeen) {
426
+            $this->callForSeenUsers($callback);
427
+        } else {
428
+            foreach ($this->getBackends() as $backend) {
429
+                $limit = 500;
430
+                $offset = 0;
431
+                do {
432
+                    $users = $backend->getUsers($search, $limit, $offset);
433
+                    foreach ($users as $uid) {
434
+                        if (!$backend->userExists($uid)) {
435
+                            continue;
436
+                        }
437
+                        $user = $this->getUserObject($uid, $backend, false);
438
+                        $return = $callback($user);
439
+                        if ($return === false) {
440
+                            break;
441
+                        }
442
+                    }
443
+                    $offset += $limit;
444
+                } while (count($users) >= $limit);
445
+            }
446
+        }
447
+    }
448
+
449
+    /**
450
+     * returns how many users are disabled
451
+     *
452
+     * @return int
453
+     * @since 12.0.0
454
+     */
455
+    public function countDisabledUsers(): int {
456
+        $queryBuilder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
457
+        $queryBuilder->select($queryBuilder->func()->count('*'))
458
+            ->from('preferences')
459
+            ->where($queryBuilder->expr()->eq('appid', $queryBuilder->createNamedParameter('core')))
460
+            ->andWhere($queryBuilder->expr()->eq('configkey', $queryBuilder->createNamedParameter('enabled')))
461
+            ->andWhere($queryBuilder->expr()->eq('configvalue', $queryBuilder->createNamedParameter('false'), IQueryBuilder::PARAM_STR));
462 462
 
463 463
 		
464
-		$result = $queryBuilder->execute();
465
-		$count = $result->fetchColumn();
466
-		$result->closeCursor();
464
+        $result = $queryBuilder->execute();
465
+        $count = $result->fetchColumn();
466
+        $result->closeCursor();
467 467
 		
468
-		if ($count !== false) {
469
-			$count = (int)$count;
470
-		} else {
471
-			$count = 0;
472
-		}
473
-
474
-		return $count;
475
-	}
476
-
477
-	/**
478
-	 * returns how many users are disabled in the requested groups
479
-	 *
480
-	 * @param array $groups groupids to search
481
-	 * @return int
482
-	 * @since 14.0.0
483
-	 */
484
-	public function countDisabledUsersOfGroups(array $groups): int {
485
-		$queryBuilder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
486
-		$queryBuilder->select($queryBuilder->createFunction('COUNT(DISTINCT ' . $queryBuilder->getColumnName('uid') . ')'))
487
-			->from('preferences', 'p')
488
-			->innerJoin('p', 'group_user', 'g', $queryBuilder->expr()->eq('p.userid', 'g.uid'))
489
-			->where($queryBuilder->expr()->eq('appid', $queryBuilder->createNamedParameter('core')))
490
-			->andWhere($queryBuilder->expr()->eq('configkey', $queryBuilder->createNamedParameter('enabled')))
491
-			->andWhere($queryBuilder->expr()->eq('configvalue', $queryBuilder->createNamedParameter('false'), IQueryBuilder::PARAM_STR))
492
-			->andWhere($queryBuilder->expr()->in('gid', $queryBuilder->createNamedParameter($groups, IQueryBuilder::PARAM_STR_ARRAY)));
493
-
494
-		$result = $queryBuilder->execute();
495
-		$count = $result->fetchColumn();
496
-		$result->closeCursor();
468
+        if ($count !== false) {
469
+            $count = (int)$count;
470
+        } else {
471
+            $count = 0;
472
+        }
473
+
474
+        return $count;
475
+    }
476
+
477
+    /**
478
+     * returns how many users are disabled in the requested groups
479
+     *
480
+     * @param array $groups groupids to search
481
+     * @return int
482
+     * @since 14.0.0
483
+     */
484
+    public function countDisabledUsersOfGroups(array $groups): int {
485
+        $queryBuilder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
486
+        $queryBuilder->select($queryBuilder->createFunction('COUNT(DISTINCT ' . $queryBuilder->getColumnName('uid') . ')'))
487
+            ->from('preferences', 'p')
488
+            ->innerJoin('p', 'group_user', 'g', $queryBuilder->expr()->eq('p.userid', 'g.uid'))
489
+            ->where($queryBuilder->expr()->eq('appid', $queryBuilder->createNamedParameter('core')))
490
+            ->andWhere($queryBuilder->expr()->eq('configkey', $queryBuilder->createNamedParameter('enabled')))
491
+            ->andWhere($queryBuilder->expr()->eq('configvalue', $queryBuilder->createNamedParameter('false'), IQueryBuilder::PARAM_STR))
492
+            ->andWhere($queryBuilder->expr()->in('gid', $queryBuilder->createNamedParameter($groups, IQueryBuilder::PARAM_STR_ARRAY)));
493
+
494
+        $result = $queryBuilder->execute();
495
+        $count = $result->fetchColumn();
496
+        $result->closeCursor();
497 497
 		
498
-		if ($count !== false) {
499
-			$count = (int)$count;
500
-		} else {
501
-			$count = 0;
502
-		}
503
-
504
-		return $count;
505
-	}
506
-
507
-	/**
508
-	 * returns how many users have logged in once
509
-	 *
510
-	 * @return int
511
-	 * @since 11.0.0
512
-	 */
513
-	public function countSeenUsers() {
514
-		$queryBuilder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
515
-		$queryBuilder->select($queryBuilder->func()->count('*'))
516
-			->from('preferences')
517
-			->where($queryBuilder->expr()->eq('appid', $queryBuilder->createNamedParameter('login')))
518
-			->andWhere($queryBuilder->expr()->eq('configkey', $queryBuilder->createNamedParameter('lastLogin')))
519
-			->andWhere($queryBuilder->expr()->isNotNull('configvalue'));
520
-
521
-		$query = $queryBuilder->execute();
522
-
523
-		$result = (int)$query->fetchColumn();
524
-		$query->closeCursor();
525
-
526
-		return $result;
527
-	}
528
-
529
-	/**
530
-	 * @param \Closure $callback
531
-	 * @since 11.0.0
532
-	 */
533
-	public function callForSeenUsers(\Closure $callback) {
534
-		$limit = 1000;
535
-		$offset = 0;
536
-		do {
537
-			$userIds = $this->getSeenUserIds($limit, $offset);
538
-			$offset += $limit;
539
-			foreach ($userIds as $userId) {
540
-				foreach ($this->backends as $backend) {
541
-					if ($backend->userExists($userId)) {
542
-						$user = $this->getUserObject($userId, $backend, false);
543
-						$return = $callback($user);
544
-						if ($return === false) {
545
-							return;
546
-						}
547
-						break;
548
-					}
549
-				}
550
-			}
551
-		} while (count($userIds) >= $limit);
552
-	}
553
-
554
-	/**
555
-	 * Getting all userIds that have a listLogin value requires checking the
556
-	 * value in php because on oracle you cannot use a clob in a where clause,
557
-	 * preventing us from doing a not null or length(value) > 0 check.
558
-	 *
559
-	 * @param int $limit
560
-	 * @param int $offset
561
-	 * @return string[] with user ids
562
-	 */
563
-	private function getSeenUserIds($limit = null, $offset = null) {
564
-		$queryBuilder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
565
-		$queryBuilder->select(['userid'])
566
-			->from('preferences')
567
-			->where($queryBuilder->expr()->eq(
568
-				'appid', $queryBuilder->createNamedParameter('login'))
569
-			)
570
-			->andWhere($queryBuilder->expr()->eq(
571
-				'configkey', $queryBuilder->createNamedParameter('lastLogin'))
572
-			)
573
-			->andWhere($queryBuilder->expr()->isNotNull('configvalue')
574
-			);
575
-
576
-		if ($limit !== null) {
577
-			$queryBuilder->setMaxResults($limit);
578
-		}
579
-		if ($offset !== null) {
580
-			$queryBuilder->setFirstResult($offset);
581
-		}
582
-		$query = $queryBuilder->execute();
583
-		$result = [];
584
-
585
-		while ($row = $query->fetch()) {
586
-			$result[] = $row['userid'];
587
-		}
588
-
589
-		$query->closeCursor();
590
-
591
-		return $result;
592
-	}
593
-
594
-	/**
595
-	 * @param string $email
596
-	 * @return IUser[]
597
-	 * @since 9.1.0
598
-	 */
599
-	public function getByEmail($email) {
600
-		$userIds = $this->config->getUsersForUserValueCaseInsensitive('settings', 'email', $email);
601
-
602
-		$users = array_map(function($uid) {
603
-			return $this->get($uid);
604
-		}, $userIds);
605
-
606
-		return array_values(array_filter($users, function($u) {
607
-			return ($u instanceof IUser);
608
-		}));
609
-	}
610
-
611
-	private function verifyUid(string $uid): bool {
612
-		$appdata = 'appdata_' . $this->config->getSystemValueString('instanceid');
613
-
614
-		if ($uid === '.htaccess' || $uid === 'files_external' || $uid === '.ocdata' || $uid === 'owncloud.log' || $uid === 'nextcloud.log' || $uid === $appdata) {
615
-			return false;
616
-		}
617
-
618
-		return true;
619
-	}
498
+        if ($count !== false) {
499
+            $count = (int)$count;
500
+        } else {
501
+            $count = 0;
502
+        }
503
+
504
+        return $count;
505
+    }
506
+
507
+    /**
508
+     * returns how many users have logged in once
509
+     *
510
+     * @return int
511
+     * @since 11.0.0
512
+     */
513
+    public function countSeenUsers() {
514
+        $queryBuilder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
515
+        $queryBuilder->select($queryBuilder->func()->count('*'))
516
+            ->from('preferences')
517
+            ->where($queryBuilder->expr()->eq('appid', $queryBuilder->createNamedParameter('login')))
518
+            ->andWhere($queryBuilder->expr()->eq('configkey', $queryBuilder->createNamedParameter('lastLogin')))
519
+            ->andWhere($queryBuilder->expr()->isNotNull('configvalue'));
520
+
521
+        $query = $queryBuilder->execute();
522
+
523
+        $result = (int)$query->fetchColumn();
524
+        $query->closeCursor();
525
+
526
+        return $result;
527
+    }
528
+
529
+    /**
530
+     * @param \Closure $callback
531
+     * @since 11.0.0
532
+     */
533
+    public function callForSeenUsers(\Closure $callback) {
534
+        $limit = 1000;
535
+        $offset = 0;
536
+        do {
537
+            $userIds = $this->getSeenUserIds($limit, $offset);
538
+            $offset += $limit;
539
+            foreach ($userIds as $userId) {
540
+                foreach ($this->backends as $backend) {
541
+                    if ($backend->userExists($userId)) {
542
+                        $user = $this->getUserObject($userId, $backend, false);
543
+                        $return = $callback($user);
544
+                        if ($return === false) {
545
+                            return;
546
+                        }
547
+                        break;
548
+                    }
549
+                }
550
+            }
551
+        } while (count($userIds) >= $limit);
552
+    }
553
+
554
+    /**
555
+     * Getting all userIds that have a listLogin value requires checking the
556
+     * value in php because on oracle you cannot use a clob in a where clause,
557
+     * preventing us from doing a not null or length(value) > 0 check.
558
+     *
559
+     * @param int $limit
560
+     * @param int $offset
561
+     * @return string[] with user ids
562
+     */
563
+    private function getSeenUserIds($limit = null, $offset = null) {
564
+        $queryBuilder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
565
+        $queryBuilder->select(['userid'])
566
+            ->from('preferences')
567
+            ->where($queryBuilder->expr()->eq(
568
+                'appid', $queryBuilder->createNamedParameter('login'))
569
+            )
570
+            ->andWhere($queryBuilder->expr()->eq(
571
+                'configkey', $queryBuilder->createNamedParameter('lastLogin'))
572
+            )
573
+            ->andWhere($queryBuilder->expr()->isNotNull('configvalue')
574
+            );
575
+
576
+        if ($limit !== null) {
577
+            $queryBuilder->setMaxResults($limit);
578
+        }
579
+        if ($offset !== null) {
580
+            $queryBuilder->setFirstResult($offset);
581
+        }
582
+        $query = $queryBuilder->execute();
583
+        $result = [];
584
+
585
+        while ($row = $query->fetch()) {
586
+            $result[] = $row['userid'];
587
+        }
588
+
589
+        $query->closeCursor();
590
+
591
+        return $result;
592
+    }
593
+
594
+    /**
595
+     * @param string $email
596
+     * @return IUser[]
597
+     * @since 9.1.0
598
+     */
599
+    public function getByEmail($email) {
600
+        $userIds = $this->config->getUsersForUserValueCaseInsensitive('settings', 'email', $email);
601
+
602
+        $users = array_map(function($uid) {
603
+            return $this->get($uid);
604
+        }, $userIds);
605
+
606
+        return array_values(array_filter($users, function($u) {
607
+            return ($u instanceof IUser);
608
+        }));
609
+    }
610
+
611
+    private function verifyUid(string $uid): bool {
612
+        $appdata = 'appdata_' . $this->config->getSystemValueString('instanceid');
613
+
614
+        if ($uid === '.htaccess' || $uid === 'files_external' || $uid === '.ocdata' || $uid === 'owncloud.log' || $uid === 'nextcloud.log' || $uid === $appdata) {
615
+            return false;
616
+        }
617
+
618
+        return true;
619
+    }
620 620
 }
Please login to merge, or discard this patch.
lib/public/User/Backend/IGetRealUIDBackend.php 1 patch
Indentation   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -29,16 +29,16 @@
 block discarded – undo
29 29
  */
30 30
 interface IGetRealUIDBackend {
31 31
 
32
-	/**
33
-	 * Some backends accept different UIDs than what is the internal UID to be used.
34
-	 * For example the database backend accepts differnt cased UIDs in all the functions
35
-	 * but the internal UID that is to be used should be correctly cased.
36
-	 *
37
-	 * This little function makes sure that the used UID will be correct hen using the user object
38
-	 *
39
-	 * @since 17.0.0
40
-	 * @param string $uid
41
-	 * @return string
42
-	 */
43
-	public function getRealUID(string $uid): string;
32
+    /**
33
+     * Some backends accept different UIDs than what is the internal UID to be used.
34
+     * For example the database backend accepts differnt cased UIDs in all the functions
35
+     * but the internal UID that is to be used should be correctly cased.
36
+     *
37
+     * This little function makes sure that the used UID will be correct hen using the user object
38
+     *
39
+     * @since 17.0.0
40
+     * @param string $uid
41
+     * @return string
42
+     */
43
+    public function getRealUID(string $uid): string;
44 44
 }
Please login to merge, or discard this patch.