Passed
Push — master ( 5bc2a6...18bafe )
by Joas
14:06 queued 11s
created
lib/private/User/Database.php 2 patches
Indentation   +455 added lines, -455 removed lines patch added patch discarded remove patch
@@ -64,459 +64,459 @@
 block discarded – undo
64 64
  * Class for user management in a SQL Database (e.g. MySQL, SQLite)
65 65
  */
66 66
 class Database extends ABackend implements
67
-	ICreateUserBackend,
68
-			   ISetPasswordBackend,
69
-			   ISetDisplayNameBackend,
70
-			   IGetDisplayNameBackend,
71
-			   ICheckPasswordBackend,
72
-			   IGetHomeBackend,
73
-			   ICountUsersBackend,
74
-			   ISearchKnownUsersBackend,
75
-			   IGetRealUIDBackend {
76
-	/** @var CappedMemoryCache */
77
-	private $cache;
78
-
79
-	/** @var IEventDispatcher */
80
-	private $eventDispatcher;
81
-
82
-	/** @var IDBConnection */
83
-	private $dbConn;
84
-
85
-	/** @var string */
86
-	private $table;
87
-
88
-	/**
89
-	 * \OC\User\Database constructor.
90
-	 *
91
-	 * @param IEventDispatcher $eventDispatcher
92
-	 * @param string $table
93
-	 */
94
-	public function __construct($eventDispatcher = null, $table = 'users') {
95
-		$this->cache = new CappedMemoryCache();
96
-		$this->table = $table;
97
-		$this->eventDispatcher = $eventDispatcher ? $eventDispatcher : \OC::$server->query(IEventDispatcher::class);
98
-	}
99
-
100
-	/**
101
-	 * FIXME: This function should not be required!
102
-	 */
103
-	private function fixDI() {
104
-		if ($this->dbConn === null) {
105
-			$this->dbConn = \OC::$server->getDatabaseConnection();
106
-		}
107
-	}
108
-
109
-	/**
110
-	 * Create a new user
111
-	 *
112
-	 * @param string $uid The username of the user to create
113
-	 * @param string $password The password of the new user
114
-	 * @return bool
115
-	 *
116
-	 * Creates a new user. Basic checking of username is done in OC_User
117
-	 * itself, not in its subclasses.
118
-	 */
119
-	public function createUser(string $uid, string $password): bool {
120
-		$this->fixDI();
121
-
122
-		if (!$this->userExists($uid)) {
123
-			$this->eventDispatcher->dispatchTyped(new ValidatePasswordPolicyEvent($password));
124
-
125
-			$qb = $this->dbConn->getQueryBuilder();
126
-			$qb->insert($this->table)
127
-				->values([
128
-					'uid' => $qb->createNamedParameter($uid),
129
-					'password' => $qb->createNamedParameter(\OC::$server->getHasher()->hash($password)),
130
-					'uid_lower' => $qb->createNamedParameter(mb_strtolower($uid)),
131
-				]);
132
-
133
-			$result = $qb->execute();
134
-
135
-			// Clear cache
136
-			unset($this->cache[$uid]);
137
-
138
-			return $result ? true : false;
139
-		}
140
-
141
-		return false;
142
-	}
143
-
144
-	/**
145
-	 * delete a user
146
-	 *
147
-	 * @param string $uid The username of the user to delete
148
-	 * @return bool
149
-	 *
150
-	 * Deletes a user
151
-	 */
152
-	public function deleteUser($uid) {
153
-		$this->fixDI();
154
-
155
-		// Delete user-group-relation
156
-		$query = $this->dbConn->getQueryBuilder();
157
-		$query->delete($this->table)
158
-			->where($query->expr()->eq('uid_lower', $query->createNamedParameter(mb_strtolower($uid))));
159
-		$result = $query->execute();
160
-
161
-		if (isset($this->cache[$uid])) {
162
-			unset($this->cache[$uid]);
163
-		}
164
-
165
-		return $result ? true : false;
166
-	}
167
-
168
-	private function updatePassword(string $uid, string $passwordHash): bool {
169
-		$query = $this->dbConn->getQueryBuilder();
170
-		$query->update($this->table)
171
-			->set('password', $query->createNamedParameter($passwordHash))
172
-			->where($query->expr()->eq('uid_lower', $query->createNamedParameter(mb_strtolower($uid))));
173
-		$result = $query->execute();
174
-
175
-		return $result ? true : false;
176
-	}
177
-
178
-	/**
179
-	 * Set password
180
-	 *
181
-	 * @param string $uid The username
182
-	 * @param string $password The new password
183
-	 * @return bool
184
-	 *
185
-	 * Change the password of a user
186
-	 */
187
-	public function setPassword(string $uid, string $password): bool {
188
-		$this->fixDI();
189
-
190
-		if ($this->userExists($uid)) {
191
-			$this->eventDispatcher->dispatchTyped(new ValidatePasswordPolicyEvent($password));
192
-
193
-			$hasher = \OC::$server->getHasher();
194
-			$hashedPassword = $hasher->hash($password);
195
-
196
-			$return = $this->updatePassword($uid, $hashedPassword);
197
-
198
-			if ($return) {
199
-				$this->cache[$uid]['password'] = $hashedPassword;
200
-			}
201
-
202
-			return $return;
203
-		}
204
-
205
-		return false;
206
-	}
207
-
208
-	/**
209
-	 * Set display name
210
-	 *
211
-	 * @param string $uid The username
212
-	 * @param string $displayName The new display name
213
-	 * @return bool
214
-	 *
215
-	 * Change the display name of a user
216
-	 */
217
-	public function setDisplayName(string $uid, string $displayName): bool {
218
-		$this->fixDI();
219
-
220
-		if ($this->userExists($uid)) {
221
-			$query = $this->dbConn->getQueryBuilder();
222
-			$query->update($this->table)
223
-				->set('displayname', $query->createNamedParameter($displayName))
224
-				->where($query->expr()->eq('uid_lower', $query->createNamedParameter(mb_strtolower($uid))));
225
-			$query->execute();
226
-
227
-			$this->cache[$uid]['displayname'] = $displayName;
228
-
229
-			return true;
230
-		}
231
-
232
-		return false;
233
-	}
234
-
235
-	/**
236
-	 * get display name of the user
237
-	 *
238
-	 * @param string $uid user ID of the user
239
-	 * @return string display name
240
-	 */
241
-	public function getDisplayName($uid): string {
242
-		$uid = (string)$uid;
243
-		$this->loadUser($uid);
244
-		return empty($this->cache[$uid]['displayname']) ? $uid : $this->cache[$uid]['displayname'];
245
-	}
246
-
247
-	/**
248
-	 * Get a list of all display names and user ids.
249
-	 *
250
-	 * @param string $search
251
-	 * @param int|null $limit
252
-	 * @param int|null $offset
253
-	 * @return array an array of all displayNames (value) and the corresponding uids (key)
254
-	 */
255
-	public function getDisplayNames($search = '', $limit = null, $offset = null) {
256
-		$limit = $this->fixLimit($limit);
257
-
258
-		$this->fixDI();
259
-
260
-		$query = $this->dbConn->getQueryBuilder();
261
-
262
-		$query->select('uid', 'displayname')
263
-			->from($this->table, 'u')
264
-			->leftJoin('u', 'preferences', 'p', $query->expr()->andX(
265
-				$query->expr()->eq('userid', 'uid'),
266
-				$query->expr()->eq('appid', $query->expr()->literal('settings')),
267
-				$query->expr()->eq('configkey', $query->expr()->literal('email')))
268
-			)
269
-			// sqlite doesn't like re-using a single named parameter here
270
-			->where($query->expr()->iLike('uid', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%')))
271
-			->orWhere($query->expr()->iLike('displayname', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%')))
272
-			->orWhere($query->expr()->iLike('configvalue', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%')))
273
-			->orderBy($query->func()->lower('displayname'), 'ASC')
274
-			->addOrderBy('uid_lower', 'ASC')
275
-			->setMaxResults($limit)
276
-			->setFirstResult($offset);
277
-
278
-		$result = $query->execute();
279
-		$displayNames = [];
280
-		while ($row = $result->fetch()) {
281
-			$displayNames[(string)$row['uid']] = (string)$row['displayname'];
282
-		}
283
-
284
-		return $displayNames;
285
-	}
286
-
287
-	/**
288
-	 * @param string $searcher
289
-	 * @param string $pattern
290
-	 * @param int|null $limit
291
-	 * @param int|null $offset
292
-	 * @return array
293
-	 * @since 21.0.1
294
-	 */
295
-	public function searchKnownUsersByDisplayName(string $searcher, string $pattern, ?int $limit = null, ?int $offset = null): array {
296
-		$limit = $this->fixLimit($limit);
297
-
298
-		$this->fixDI();
299
-
300
-		$query = $this->dbConn->getQueryBuilder();
301
-
302
-		$query->select('u.uid', 'u.displayname')
303
-			->from($this->table, 'u')
304
-			->leftJoin('u', 'known_users', 'k', $query->expr()->andX(
305
-				$query->expr()->eq('k.known_user', 'u.uid'),
306
-				$query->expr()->eq('k.known_to', $query->createNamedParameter($searcher))
307
-			))
308
-			->where($query->expr()->eq('k.known_to', $query->createNamedParameter($searcher)))
309
-			->andWhere($query->expr()->orX(
310
-				$query->expr()->iLike('u.uid', $query->createNamedParameter('%' . $this->dbConn->escapeLikeParameter($pattern) . '%')),
311
-				$query->expr()->iLike('u.displayname', $query->createNamedParameter('%' . $this->dbConn->escapeLikeParameter($pattern) . '%'))
312
-			))
313
-			->orderBy('u.displayname', 'ASC')
314
-			->addOrderBy('u.uid_lower', 'ASC')
315
-			->setMaxResults($limit)
316
-			->setFirstResult($offset);
317
-
318
-		$result = $query->execute();
319
-		$displayNames = [];
320
-		while ($row = $result->fetch()) {
321
-			$displayNames[(string)$row['uid']] = (string)$row['displayname'];
322
-		}
323
-
324
-		return $displayNames;
325
-	}
326
-
327
-	/**
328
-	 * Check if the password is correct
329
-	 *
330
-	 * @param string $loginName The loginname
331
-	 * @param string $password The password
332
-	 * @return string
333
-	 *
334
-	 * Check if the password is correct without logging in the user
335
-	 * returns the user id or false
336
-	 */
337
-	public function checkPassword(string $loginName, string $password) {
338
-		$found = $this->loadUser($loginName);
339
-
340
-		if ($found && is_array($this->cache[$loginName])) {
341
-			$storedHash = $this->cache[$loginName]['password'];
342
-			$newHash = '';
343
-			if (\OC::$server->getHasher()->verify($password, $storedHash, $newHash)) {
344
-				if (!empty($newHash)) {
345
-					$this->updatePassword($loginName, $newHash);
346
-				}
347
-				return (string)$this->cache[$loginName]['uid'];
348
-			}
349
-		}
350
-
351
-		return false;
352
-	}
353
-
354
-	/**
355
-	 * Load an user in the cache
356
-	 *
357
-	 * @param string $uid the username
358
-	 * @return boolean true if user was found, false otherwise
359
-	 */
360
-	private function loadUser($uid) {
361
-		$this->fixDI();
362
-
363
-		$uid = (string)$uid;
364
-		if (!isset($this->cache[$uid])) {
365
-			//guests $uid could be NULL or ''
366
-			if ($uid === '') {
367
-				$this->cache[$uid] = false;
368
-				return true;
369
-			}
370
-
371
-			$qb = $this->dbConn->getQueryBuilder();
372
-			$qb->select('uid', 'displayname', 'password')
373
-				->from($this->table)
374
-				->where(
375
-					$qb->expr()->eq(
376
-						'uid_lower', $qb->createNamedParameter(mb_strtolower($uid))
377
-					)
378
-				);
379
-			$result = $qb->execute();
380
-			$row = $result->fetch();
381
-			$result->closeCursor();
382
-
383
-			// "uid" is primary key, so there can only be a single result
384
-			if ($row !== false) {
385
-				$this->cache[$uid] = [
386
-					'uid' => (string)$row['uid'],
387
-					'displayname' => (string)$row['displayname'],
388
-					'password' => (string)$row['password'],
389
-				];
390
-			} else {
391
-				$this->cache[$uid] = false;
392
-				return false;
393
-			}
394
-		}
395
-
396
-		return true;
397
-	}
398
-
399
-	/**
400
-	 * Get a list of all users
401
-	 *
402
-	 * @param string $search
403
-	 * @param null|int $limit
404
-	 * @param null|int $offset
405
-	 * @return string[] an array of all uids
406
-	 */
407
-	public function getUsers($search = '', $limit = null, $offset = null) {
408
-		$limit = $this->fixLimit($limit);
409
-
410
-		$users = $this->getDisplayNames($search, $limit, $offset);
411
-		$userIds = array_map(function ($uid) {
412
-			return (string)$uid;
413
-		}, array_keys($users));
414
-		sort($userIds, SORT_STRING | SORT_FLAG_CASE);
415
-		return $userIds;
416
-	}
417
-
418
-	/**
419
-	 * check if a user exists
420
-	 *
421
-	 * @param string $uid the username
422
-	 * @return boolean
423
-	 */
424
-	public function userExists($uid) {
425
-		$this->loadUser($uid);
426
-		return $this->cache[$uid] !== false;
427
-	}
428
-
429
-	/**
430
-	 * get the user's home directory
431
-	 *
432
-	 * @param string $uid the username
433
-	 * @return string|false
434
-	 */
435
-	public function getHome(string $uid) {
436
-		if ($this->userExists($uid)) {
437
-			return \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/' . $uid;
438
-		}
439
-
440
-		return false;
441
-	}
442
-
443
-	/**
444
-	 * @return bool
445
-	 */
446
-	public function hasUserListings() {
447
-		return true;
448
-	}
449
-
450
-	/**
451
-	 * counts the users in the database
452
-	 *
453
-	 * @return int|bool
454
-	 */
455
-	public function countUsers() {
456
-		$this->fixDI();
457
-
458
-		$query = $this->dbConn->getQueryBuilder();
459
-		$query->select($query->func()->count('uid'))
460
-			->from($this->table);
461
-		$result = $query->execute();
462
-
463
-		return $result->fetchOne();
464
-	}
465
-
466
-	/**
467
-	 * returns the username for the given login name in the correct casing
468
-	 *
469
-	 * @param string $loginName
470
-	 * @return string|false
471
-	 */
472
-	public function loginName2UserName($loginName) {
473
-		if ($this->userExists($loginName)) {
474
-			return $this->cache[$loginName]['uid'];
475
-		}
476
-
477
-		return false;
478
-	}
479
-
480
-	/**
481
-	 * Backend name to be shown in user management
482
-	 *
483
-	 * @return string the name of the backend to be shown
484
-	 */
485
-	public function getBackendName() {
486
-		return 'Database';
487
-	}
488
-
489
-	public static function preLoginNameUsedAsUserName($param) {
490
-		if (!isset($param['uid'])) {
491
-			throw new \Exception('key uid is expected to be set in $param');
492
-		}
493
-
494
-		$backends = \OC::$server->getUserManager()->getBackends();
495
-		foreach ($backends as $backend) {
496
-			if ($backend instanceof Database) {
497
-				/** @var \OC\User\Database $backend */
498
-				$uid = $backend->loginName2UserName($param['uid']);
499
-				if ($uid !== false) {
500
-					$param['uid'] = $uid;
501
-					return;
502
-				}
503
-			}
504
-		}
505
-	}
506
-
507
-	public function getRealUID(string $uid): string {
508
-		if (!$this->userExists($uid)) {
509
-			throw new \RuntimeException($uid . ' does not exist');
510
-		}
511
-
512
-		return $this->cache[$uid]['uid'];
513
-	}
514
-
515
-	private function fixLimit($limit) {
516
-		if (is_int($limit) && $limit >= 0) {
517
-			return $limit;
518
-		}
519
-
520
-		return null;
521
-	}
67
+    ICreateUserBackend,
68
+                ISetPasswordBackend,
69
+                ISetDisplayNameBackend,
70
+                IGetDisplayNameBackend,
71
+                ICheckPasswordBackend,
72
+                IGetHomeBackend,
73
+                ICountUsersBackend,
74
+                ISearchKnownUsersBackend,
75
+                IGetRealUIDBackend {
76
+    /** @var CappedMemoryCache */
77
+    private $cache;
78
+
79
+    /** @var IEventDispatcher */
80
+    private $eventDispatcher;
81
+
82
+    /** @var IDBConnection */
83
+    private $dbConn;
84
+
85
+    /** @var string */
86
+    private $table;
87
+
88
+    /**
89
+     * \OC\User\Database constructor.
90
+     *
91
+     * @param IEventDispatcher $eventDispatcher
92
+     * @param string $table
93
+     */
94
+    public function __construct($eventDispatcher = null, $table = 'users') {
95
+        $this->cache = new CappedMemoryCache();
96
+        $this->table = $table;
97
+        $this->eventDispatcher = $eventDispatcher ? $eventDispatcher : \OC::$server->query(IEventDispatcher::class);
98
+    }
99
+
100
+    /**
101
+     * FIXME: This function should not be required!
102
+     */
103
+    private function fixDI() {
104
+        if ($this->dbConn === null) {
105
+            $this->dbConn = \OC::$server->getDatabaseConnection();
106
+        }
107
+    }
108
+
109
+    /**
110
+     * Create a new user
111
+     *
112
+     * @param string $uid The username of the user to create
113
+     * @param string $password The password of the new user
114
+     * @return bool
115
+     *
116
+     * Creates a new user. Basic checking of username is done in OC_User
117
+     * itself, not in its subclasses.
118
+     */
119
+    public function createUser(string $uid, string $password): bool {
120
+        $this->fixDI();
121
+
122
+        if (!$this->userExists($uid)) {
123
+            $this->eventDispatcher->dispatchTyped(new ValidatePasswordPolicyEvent($password));
124
+
125
+            $qb = $this->dbConn->getQueryBuilder();
126
+            $qb->insert($this->table)
127
+                ->values([
128
+                    'uid' => $qb->createNamedParameter($uid),
129
+                    'password' => $qb->createNamedParameter(\OC::$server->getHasher()->hash($password)),
130
+                    'uid_lower' => $qb->createNamedParameter(mb_strtolower($uid)),
131
+                ]);
132
+
133
+            $result = $qb->execute();
134
+
135
+            // Clear cache
136
+            unset($this->cache[$uid]);
137
+
138
+            return $result ? true : false;
139
+        }
140
+
141
+        return false;
142
+    }
143
+
144
+    /**
145
+     * delete a user
146
+     *
147
+     * @param string $uid The username of the user to delete
148
+     * @return bool
149
+     *
150
+     * Deletes a user
151
+     */
152
+    public function deleteUser($uid) {
153
+        $this->fixDI();
154
+
155
+        // Delete user-group-relation
156
+        $query = $this->dbConn->getQueryBuilder();
157
+        $query->delete($this->table)
158
+            ->where($query->expr()->eq('uid_lower', $query->createNamedParameter(mb_strtolower($uid))));
159
+        $result = $query->execute();
160
+
161
+        if (isset($this->cache[$uid])) {
162
+            unset($this->cache[$uid]);
163
+        }
164
+
165
+        return $result ? true : false;
166
+    }
167
+
168
+    private function updatePassword(string $uid, string $passwordHash): bool {
169
+        $query = $this->dbConn->getQueryBuilder();
170
+        $query->update($this->table)
171
+            ->set('password', $query->createNamedParameter($passwordHash))
172
+            ->where($query->expr()->eq('uid_lower', $query->createNamedParameter(mb_strtolower($uid))));
173
+        $result = $query->execute();
174
+
175
+        return $result ? true : false;
176
+    }
177
+
178
+    /**
179
+     * Set password
180
+     *
181
+     * @param string $uid The username
182
+     * @param string $password The new password
183
+     * @return bool
184
+     *
185
+     * Change the password of a user
186
+     */
187
+    public function setPassword(string $uid, string $password): bool {
188
+        $this->fixDI();
189
+
190
+        if ($this->userExists($uid)) {
191
+            $this->eventDispatcher->dispatchTyped(new ValidatePasswordPolicyEvent($password));
192
+
193
+            $hasher = \OC::$server->getHasher();
194
+            $hashedPassword = $hasher->hash($password);
195
+
196
+            $return = $this->updatePassword($uid, $hashedPassword);
197
+
198
+            if ($return) {
199
+                $this->cache[$uid]['password'] = $hashedPassword;
200
+            }
201
+
202
+            return $return;
203
+        }
204
+
205
+        return false;
206
+    }
207
+
208
+    /**
209
+     * Set display name
210
+     *
211
+     * @param string $uid The username
212
+     * @param string $displayName The new display name
213
+     * @return bool
214
+     *
215
+     * Change the display name of a user
216
+     */
217
+    public function setDisplayName(string $uid, string $displayName): bool {
218
+        $this->fixDI();
219
+
220
+        if ($this->userExists($uid)) {
221
+            $query = $this->dbConn->getQueryBuilder();
222
+            $query->update($this->table)
223
+                ->set('displayname', $query->createNamedParameter($displayName))
224
+                ->where($query->expr()->eq('uid_lower', $query->createNamedParameter(mb_strtolower($uid))));
225
+            $query->execute();
226
+
227
+            $this->cache[$uid]['displayname'] = $displayName;
228
+
229
+            return true;
230
+        }
231
+
232
+        return false;
233
+    }
234
+
235
+    /**
236
+     * get display name of the user
237
+     *
238
+     * @param string $uid user ID of the user
239
+     * @return string display name
240
+     */
241
+    public function getDisplayName($uid): string {
242
+        $uid = (string)$uid;
243
+        $this->loadUser($uid);
244
+        return empty($this->cache[$uid]['displayname']) ? $uid : $this->cache[$uid]['displayname'];
245
+    }
246
+
247
+    /**
248
+     * Get a list of all display names and user ids.
249
+     *
250
+     * @param string $search
251
+     * @param int|null $limit
252
+     * @param int|null $offset
253
+     * @return array an array of all displayNames (value) and the corresponding uids (key)
254
+     */
255
+    public function getDisplayNames($search = '', $limit = null, $offset = null) {
256
+        $limit = $this->fixLimit($limit);
257
+
258
+        $this->fixDI();
259
+
260
+        $query = $this->dbConn->getQueryBuilder();
261
+
262
+        $query->select('uid', 'displayname')
263
+            ->from($this->table, 'u')
264
+            ->leftJoin('u', 'preferences', 'p', $query->expr()->andX(
265
+                $query->expr()->eq('userid', 'uid'),
266
+                $query->expr()->eq('appid', $query->expr()->literal('settings')),
267
+                $query->expr()->eq('configkey', $query->expr()->literal('email')))
268
+            )
269
+            // sqlite doesn't like re-using a single named parameter here
270
+            ->where($query->expr()->iLike('uid', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%')))
271
+            ->orWhere($query->expr()->iLike('displayname', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%')))
272
+            ->orWhere($query->expr()->iLike('configvalue', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%')))
273
+            ->orderBy($query->func()->lower('displayname'), 'ASC')
274
+            ->addOrderBy('uid_lower', 'ASC')
275
+            ->setMaxResults($limit)
276
+            ->setFirstResult($offset);
277
+
278
+        $result = $query->execute();
279
+        $displayNames = [];
280
+        while ($row = $result->fetch()) {
281
+            $displayNames[(string)$row['uid']] = (string)$row['displayname'];
282
+        }
283
+
284
+        return $displayNames;
285
+    }
286
+
287
+    /**
288
+     * @param string $searcher
289
+     * @param string $pattern
290
+     * @param int|null $limit
291
+     * @param int|null $offset
292
+     * @return array
293
+     * @since 21.0.1
294
+     */
295
+    public function searchKnownUsersByDisplayName(string $searcher, string $pattern, ?int $limit = null, ?int $offset = null): array {
296
+        $limit = $this->fixLimit($limit);
297
+
298
+        $this->fixDI();
299
+
300
+        $query = $this->dbConn->getQueryBuilder();
301
+
302
+        $query->select('u.uid', 'u.displayname')
303
+            ->from($this->table, 'u')
304
+            ->leftJoin('u', 'known_users', 'k', $query->expr()->andX(
305
+                $query->expr()->eq('k.known_user', 'u.uid'),
306
+                $query->expr()->eq('k.known_to', $query->createNamedParameter($searcher))
307
+            ))
308
+            ->where($query->expr()->eq('k.known_to', $query->createNamedParameter($searcher)))
309
+            ->andWhere($query->expr()->orX(
310
+                $query->expr()->iLike('u.uid', $query->createNamedParameter('%' . $this->dbConn->escapeLikeParameter($pattern) . '%')),
311
+                $query->expr()->iLike('u.displayname', $query->createNamedParameter('%' . $this->dbConn->escapeLikeParameter($pattern) . '%'))
312
+            ))
313
+            ->orderBy('u.displayname', 'ASC')
314
+            ->addOrderBy('u.uid_lower', 'ASC')
315
+            ->setMaxResults($limit)
316
+            ->setFirstResult($offset);
317
+
318
+        $result = $query->execute();
319
+        $displayNames = [];
320
+        while ($row = $result->fetch()) {
321
+            $displayNames[(string)$row['uid']] = (string)$row['displayname'];
322
+        }
323
+
324
+        return $displayNames;
325
+    }
326
+
327
+    /**
328
+     * Check if the password is correct
329
+     *
330
+     * @param string $loginName The loginname
331
+     * @param string $password The password
332
+     * @return string
333
+     *
334
+     * Check if the password is correct without logging in the user
335
+     * returns the user id or false
336
+     */
337
+    public function checkPassword(string $loginName, string $password) {
338
+        $found = $this->loadUser($loginName);
339
+
340
+        if ($found && is_array($this->cache[$loginName])) {
341
+            $storedHash = $this->cache[$loginName]['password'];
342
+            $newHash = '';
343
+            if (\OC::$server->getHasher()->verify($password, $storedHash, $newHash)) {
344
+                if (!empty($newHash)) {
345
+                    $this->updatePassword($loginName, $newHash);
346
+                }
347
+                return (string)$this->cache[$loginName]['uid'];
348
+            }
349
+        }
350
+
351
+        return false;
352
+    }
353
+
354
+    /**
355
+     * Load an user in the cache
356
+     *
357
+     * @param string $uid the username
358
+     * @return boolean true if user was found, false otherwise
359
+     */
360
+    private function loadUser($uid) {
361
+        $this->fixDI();
362
+
363
+        $uid = (string)$uid;
364
+        if (!isset($this->cache[$uid])) {
365
+            //guests $uid could be NULL or ''
366
+            if ($uid === '') {
367
+                $this->cache[$uid] = false;
368
+                return true;
369
+            }
370
+
371
+            $qb = $this->dbConn->getQueryBuilder();
372
+            $qb->select('uid', 'displayname', 'password')
373
+                ->from($this->table)
374
+                ->where(
375
+                    $qb->expr()->eq(
376
+                        'uid_lower', $qb->createNamedParameter(mb_strtolower($uid))
377
+                    )
378
+                );
379
+            $result = $qb->execute();
380
+            $row = $result->fetch();
381
+            $result->closeCursor();
382
+
383
+            // "uid" is primary key, so there can only be a single result
384
+            if ($row !== false) {
385
+                $this->cache[$uid] = [
386
+                    'uid' => (string)$row['uid'],
387
+                    'displayname' => (string)$row['displayname'],
388
+                    'password' => (string)$row['password'],
389
+                ];
390
+            } else {
391
+                $this->cache[$uid] = false;
392
+                return false;
393
+            }
394
+        }
395
+
396
+        return true;
397
+    }
398
+
399
+    /**
400
+     * Get a list of all users
401
+     *
402
+     * @param string $search
403
+     * @param null|int $limit
404
+     * @param null|int $offset
405
+     * @return string[] an array of all uids
406
+     */
407
+    public function getUsers($search = '', $limit = null, $offset = null) {
408
+        $limit = $this->fixLimit($limit);
409
+
410
+        $users = $this->getDisplayNames($search, $limit, $offset);
411
+        $userIds = array_map(function ($uid) {
412
+            return (string)$uid;
413
+        }, array_keys($users));
414
+        sort($userIds, SORT_STRING | SORT_FLAG_CASE);
415
+        return $userIds;
416
+    }
417
+
418
+    /**
419
+     * check if a user exists
420
+     *
421
+     * @param string $uid the username
422
+     * @return boolean
423
+     */
424
+    public function userExists($uid) {
425
+        $this->loadUser($uid);
426
+        return $this->cache[$uid] !== false;
427
+    }
428
+
429
+    /**
430
+     * get the user's home directory
431
+     *
432
+     * @param string $uid the username
433
+     * @return string|false
434
+     */
435
+    public function getHome(string $uid) {
436
+        if ($this->userExists($uid)) {
437
+            return \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/' . $uid;
438
+        }
439
+
440
+        return false;
441
+    }
442
+
443
+    /**
444
+     * @return bool
445
+     */
446
+    public function hasUserListings() {
447
+        return true;
448
+    }
449
+
450
+    /**
451
+     * counts the users in the database
452
+     *
453
+     * @return int|bool
454
+     */
455
+    public function countUsers() {
456
+        $this->fixDI();
457
+
458
+        $query = $this->dbConn->getQueryBuilder();
459
+        $query->select($query->func()->count('uid'))
460
+            ->from($this->table);
461
+        $result = $query->execute();
462
+
463
+        return $result->fetchOne();
464
+    }
465
+
466
+    /**
467
+     * returns the username for the given login name in the correct casing
468
+     *
469
+     * @param string $loginName
470
+     * @return string|false
471
+     */
472
+    public function loginName2UserName($loginName) {
473
+        if ($this->userExists($loginName)) {
474
+            return $this->cache[$loginName]['uid'];
475
+        }
476
+
477
+        return false;
478
+    }
479
+
480
+    /**
481
+     * Backend name to be shown in user management
482
+     *
483
+     * @return string the name of the backend to be shown
484
+     */
485
+    public function getBackendName() {
486
+        return 'Database';
487
+    }
488
+
489
+    public static function preLoginNameUsedAsUserName($param) {
490
+        if (!isset($param['uid'])) {
491
+            throw new \Exception('key uid is expected to be set in $param');
492
+        }
493
+
494
+        $backends = \OC::$server->getUserManager()->getBackends();
495
+        foreach ($backends as $backend) {
496
+            if ($backend instanceof Database) {
497
+                /** @var \OC\User\Database $backend */
498
+                $uid = $backend->loginName2UserName($param['uid']);
499
+                if ($uid !== false) {
500
+                    $param['uid'] = $uid;
501
+                    return;
502
+                }
503
+            }
504
+        }
505
+    }
506
+
507
+    public function getRealUID(string $uid): string {
508
+        if (!$this->userExists($uid)) {
509
+            throw new \RuntimeException($uid . ' does not exist');
510
+        }
511
+
512
+        return $this->cache[$uid]['uid'];
513
+    }
514
+
515
+    private function fixLimit($limit) {
516
+        if (is_int($limit) && $limit >= 0) {
517
+            return $limit;
518
+        }
519
+
520
+        return null;
521
+    }
522 522
 }
Please login to merge, or discard this patch.
Spacing   +17 added lines, -17 removed lines patch added patch discarded remove patch
@@ -239,7 +239,7 @@  discard block
 block discarded – undo
239 239
 	 * @return string display name
240 240
 	 */
241 241
 	public function getDisplayName($uid): string {
242
-		$uid = (string)$uid;
242
+		$uid = (string) $uid;
243 243
 		$this->loadUser($uid);
244 244
 		return empty($this->cache[$uid]['displayname']) ? $uid : $this->cache[$uid]['displayname'];
245 245
 	}
@@ -267,9 +267,9 @@  discard block
 block discarded – undo
267 267
 				$query->expr()->eq('configkey', $query->expr()->literal('email')))
268 268
 			)
269 269
 			// sqlite doesn't like re-using a single named parameter here
270
-			->where($query->expr()->iLike('uid', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%')))
271
-			->orWhere($query->expr()->iLike('displayname', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%')))
272
-			->orWhere($query->expr()->iLike('configvalue', $query->createPositionalParameter('%' . $this->dbConn->escapeLikeParameter($search) . '%')))
270
+			->where($query->expr()->iLike('uid', $query->createPositionalParameter('%'.$this->dbConn->escapeLikeParameter($search).'%')))
271
+			->orWhere($query->expr()->iLike('displayname', $query->createPositionalParameter('%'.$this->dbConn->escapeLikeParameter($search).'%')))
272
+			->orWhere($query->expr()->iLike('configvalue', $query->createPositionalParameter('%'.$this->dbConn->escapeLikeParameter($search).'%')))
273 273
 			->orderBy($query->func()->lower('displayname'), 'ASC')
274 274
 			->addOrderBy('uid_lower', 'ASC')
275 275
 			->setMaxResults($limit)
@@ -278,7 +278,7 @@  discard block
 block discarded – undo
278 278
 		$result = $query->execute();
279 279
 		$displayNames = [];
280 280
 		while ($row = $result->fetch()) {
281
-			$displayNames[(string)$row['uid']] = (string)$row['displayname'];
281
+			$displayNames[(string) $row['uid']] = (string) $row['displayname'];
282 282
 		}
283 283
 
284 284
 		return $displayNames;
@@ -307,8 +307,8 @@  discard block
 block discarded – undo
307 307
 			))
308 308
 			->where($query->expr()->eq('k.known_to', $query->createNamedParameter($searcher)))
309 309
 			->andWhere($query->expr()->orX(
310
-				$query->expr()->iLike('u.uid', $query->createNamedParameter('%' . $this->dbConn->escapeLikeParameter($pattern) . '%')),
311
-				$query->expr()->iLike('u.displayname', $query->createNamedParameter('%' . $this->dbConn->escapeLikeParameter($pattern) . '%'))
310
+				$query->expr()->iLike('u.uid', $query->createNamedParameter('%'.$this->dbConn->escapeLikeParameter($pattern).'%')),
311
+				$query->expr()->iLike('u.displayname', $query->createNamedParameter('%'.$this->dbConn->escapeLikeParameter($pattern).'%'))
312 312
 			))
313 313
 			->orderBy('u.displayname', 'ASC')
314 314
 			->addOrderBy('u.uid_lower', 'ASC')
@@ -318,7 +318,7 @@  discard block
 block discarded – undo
318 318
 		$result = $query->execute();
319 319
 		$displayNames = [];
320 320
 		while ($row = $result->fetch()) {
321
-			$displayNames[(string)$row['uid']] = (string)$row['displayname'];
321
+			$displayNames[(string) $row['uid']] = (string) $row['displayname'];
322 322
 		}
323 323
 
324 324
 		return $displayNames;
@@ -344,7 +344,7 @@  discard block
 block discarded – undo
344 344
 				if (!empty($newHash)) {
345 345
 					$this->updatePassword($loginName, $newHash);
346 346
 				}
347
-				return (string)$this->cache[$loginName]['uid'];
347
+				return (string) $this->cache[$loginName]['uid'];
348 348
 			}
349 349
 		}
350 350
 
@@ -360,7 +360,7 @@  discard block
 block discarded – undo
360 360
 	private function loadUser($uid) {
361 361
 		$this->fixDI();
362 362
 
363
-		$uid = (string)$uid;
363
+		$uid = (string) $uid;
364 364
 		if (!isset($this->cache[$uid])) {
365 365
 			//guests $uid could be NULL or ''
366 366
 			if ($uid === '') {
@@ -383,9 +383,9 @@  discard block
 block discarded – undo
383 383
 			// "uid" is primary key, so there can only be a single result
384 384
 			if ($row !== false) {
385 385
 				$this->cache[$uid] = [
386
-					'uid' => (string)$row['uid'],
387
-					'displayname' => (string)$row['displayname'],
388
-					'password' => (string)$row['password'],
386
+					'uid' => (string) $row['uid'],
387
+					'displayname' => (string) $row['displayname'],
388
+					'password' => (string) $row['password'],
389 389
 				];
390 390
 			} else {
391 391
 				$this->cache[$uid] = false;
@@ -408,8 +408,8 @@  discard block
 block discarded – undo
408 408
 		$limit = $this->fixLimit($limit);
409 409
 
410 410
 		$users = $this->getDisplayNames($search, $limit, $offset);
411
-		$userIds = array_map(function ($uid) {
412
-			return (string)$uid;
411
+		$userIds = array_map(function($uid) {
412
+			return (string) $uid;
413 413
 		}, array_keys($users));
414 414
 		sort($userIds, SORT_STRING | SORT_FLAG_CASE);
415 415
 		return $userIds;
@@ -434,7 +434,7 @@  discard block
 block discarded – undo
434 434
 	 */
435 435
 	public function getHome(string $uid) {
436 436
 		if ($this->userExists($uid)) {
437
-			return \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT . '/data') . '/' . $uid;
437
+			return \OC::$server->getConfig()->getSystemValue('datadirectory', \OC::$SERVERROOT.'/data').'/'.$uid;
438 438
 		}
439 439
 
440 440
 		return false;
@@ -506,7 +506,7 @@  discard block
 block discarded – undo
506 506
 
507 507
 	public function getRealUID(string $uid): string {
508 508
 		if (!$this->userExists($uid)) {
509
-			throw new \RuntimeException($uid . ' does not exist');
509
+			throw new \RuntimeException($uid.' does not exist');
510 510
 		}
511 511
 
512 512
 		return $this->cache[$uid]['uid'];
Please login to merge, or discard this patch.