Completed
Pull Request — master (#3043)
by Joas
14:44
created
lib/private/User/Manager.php 2 patches
Indentation   +432 added lines, -432 removed lines patch added patch discarded remove patch
@@ -54,436 +54,436 @@
 block discarded – undo
54 54
  * @package OC\User
55 55
  */
56 56
 class Manager extends PublicEmitter implements IUserManager {
57
-	/**
58
-	 * @var \OCP\UserInterface[] $backends
59
-	 */
60
-	private $backends = array();
61
-
62
-	/**
63
-	 * @var \OC\User\User[] $cachedUsers
64
-	 */
65
-	private $cachedUsers = array();
66
-
67
-	/**
68
-	 * @var \OCP\IConfig $config
69
-	 */
70
-	private $config;
71
-
72
-	/**
73
-	 * @param \OCP\IConfig $config
74
-	 */
75
-	public function __construct(IConfig $config) {
76
-		$this->config = $config;
77
-		$cachedUsers = &$this->cachedUsers;
78
-		$this->listen('\OC\User', 'postDelete', function ($user) use (&$cachedUsers) {
79
-			/** @var \OC\User\User $user */
80
-			unset($cachedUsers[$user->getUID()]);
81
-		});
82
-	}
83
-
84
-	/**
85
-	 * Get the active backends
86
-	 * @return \OCP\UserInterface[]
87
-	 */
88
-	public function getBackends() {
89
-		return $this->backends;
90
-	}
91
-
92
-	/**
93
-	 * register a user backend
94
-	 *
95
-	 * @param \OCP\UserInterface $backend
96
-	 */
97
-	public function registerBackend($backend) {
98
-		$this->backends[] = $backend;
99
-	}
100
-
101
-	/**
102
-	 * remove a user backend
103
-	 *
104
-	 * @param \OCP\UserInterface $backend
105
-	 */
106
-	public function removeBackend($backend) {
107
-		$this->cachedUsers = array();
108
-		if (($i = array_search($backend, $this->backends)) !== false) {
109
-			unset($this->backends[$i]);
110
-		}
111
-	}
112
-
113
-	/**
114
-	 * remove all user backends
115
-	 */
116
-	public function clearBackends() {
117
-		$this->cachedUsers = array();
118
-		$this->backends = array();
119
-	}
120
-
121
-	/**
122
-	 * get a user by user id
123
-	 *
124
-	 * @param string $uid
125
-	 * @return \OC\User\User|null Either the user or null if the specified user does not exist
126
-	 */
127
-	public function get($uid) {
128
-		if (isset($this->cachedUsers[$uid])) { //check the cache first to prevent having to loop over the backends
129
-			return $this->cachedUsers[$uid];
130
-		}
131
-		foreach ($this->backends as $backend) {
132
-			if ($backend->userExists($uid)) {
133
-				return $this->getUserObject($uid, $backend);
134
-			}
135
-		}
136
-		return null;
137
-	}
138
-
139
-	/**
140
-	 * get or construct the user object
141
-	 *
142
-	 * @param string $uid
143
-	 * @param \OCP\UserInterface $backend
144
-	 * @param bool $cacheUser If false the newly created user object will not be cached
145
-	 * @return \OC\User\User
146
-	 */
147
-	protected function getUserObject($uid, $backend, $cacheUser = true) {
148
-		if (isset($this->cachedUsers[$uid])) {
149
-			return $this->cachedUsers[$uid];
150
-		}
151
-
152
-		if (method_exists($backend, 'loginName2UserName')) {
153
-			$loginName = $backend->loginName2UserName($uid);
154
-			if ($loginName !== false) {
155
-				$uid = $loginName;
156
-			}
157
-			if (isset($this->cachedUsers[$uid])) {
158
-				return $this->cachedUsers[$uid];
159
-			}
160
-		}
161
-
162
-		$user = new User($uid, $backend, $this, $this->config);
163
-		if ($cacheUser) {
164
-			$this->cachedUsers[$uid] = $user;
165
-		}
166
-		return $user;
167
-	}
168
-
169
-	/**
170
-	 * check if a user exists
171
-	 *
172
-	 * @param string $uid
173
-	 * @return bool
174
-	 */
175
-	public function userExists($uid) {
176
-		$user = $this->get($uid);
177
-		return ($user !== null);
178
-	}
179
-
180
-	/**
181
-	 * Check if the password is valid for the user
182
-	 *
183
-	 * @param string $loginName
184
-	 * @param string $password
185
-	 * @return mixed the User object on success, false otherwise
186
-	 */
187
-	public function checkPassword($loginName, $password) {
188
-		$result = $this->checkPasswordNoLogging($loginName, $password);
189
-
190
-		if ($result === false) {
191
-			\OC::$server->getLogger()->warning('Login failed: \''. $loginName .'\' (Remote IP: \''. \OC::$server->getRequest()->getRemoteAddress(). '\')', ['app' => 'core']);
192
-		}
193
-
194
-		return $result;
195
-	}
196
-
197
-	/**
198
-	 * Check if the password is valid for the user
199
-	 *
200
-	 * @internal
201
-	 * @param string $loginName
202
-	 * @param string $password
203
-	 * @return mixed the User object on success, false otherwise
204
-	 */
205
-	public function checkPasswordNoLogging($loginName, $password) {
206
-		$loginName = str_replace("\0", '', $loginName);
207
-		$password = str_replace("\0", '', $password);
208
-
209
-		foreach ($this->backends as $backend) {
210
-			if ($backend->implementsActions(Backend::CHECK_PASSWORD)) {
211
-				$uid = $backend->checkPassword($loginName, $password);
212
-				if ($uid !== false) {
213
-					return $this->getUserObject($uid, $backend);
214
-				}
215
-			}
216
-		}
217
-
218
-		return false;
219
-	}
220
-
221
-	/**
222
-	 * search by user id
223
-	 *
224
-	 * @param string $pattern
225
-	 * @param int $limit
226
-	 * @param int $offset
227
-	 * @return \OC\User\User[]
228
-	 */
229
-	public function search($pattern, $limit = null, $offset = null) {
230
-		$users = array();
231
-		foreach ($this->backends as $backend) {
232
-			$backendUsers = $backend->getUsers($pattern, $limit, $offset);
233
-			if (is_array($backendUsers)) {
234
-				foreach ($backendUsers as $uid) {
235
-					$users[$uid] = $this->getUserObject($uid, $backend);
236
-				}
237
-			}
238
-		}
239
-
240
-		uasort($users, function ($a, $b) {
241
-			/**
242
-			 * @var \OC\User\User $a
243
-			 * @var \OC\User\User $b
244
-			 */
245
-			return strcmp($a->getUID(), $b->getUID());
246
-		});
247
-		return $users;
248
-	}
249
-
250
-	/**
251
-	 * search by displayName
252
-	 *
253
-	 * @param string $pattern
254
-	 * @param int $limit
255
-	 * @param int $offset
256
-	 * @return \OC\User\User[]
257
-	 */
258
-	public function searchDisplayName($pattern, $limit = null, $offset = null) {
259
-		$users = array();
260
-		foreach ($this->backends as $backend) {
261
-			$backendUsers = $backend->getDisplayNames($pattern, $limit, $offset);
262
-			if (is_array($backendUsers)) {
263
-				foreach ($backendUsers as $uid => $displayName) {
264
-					$users[] = $this->getUserObject($uid, $backend);
265
-				}
266
-			}
267
-		}
268
-
269
-		usort($users, function ($a, $b) {
270
-			/**
271
-			 * @var \OC\User\User $a
272
-			 * @var \OC\User\User $b
273
-			 */
274
-			return strcmp(strtolower($a->getDisplayName()), strtolower($b->getDisplayName()));
275
-		});
276
-		return $users;
277
-	}
278
-
279
-	/**
280
-	 * @param string $uid
281
-	 * @param string $password
282
-	 * @throws \Exception
283
-	 * @return bool|\OC\User\User the created user or false
284
-	 */
285
-	public function createUser($uid, $password) {
286
-		$l = \OC::$server->getL10N('lib');
287
-		// Check the name for bad characters
288
-		// Allowed are: "a-z", "A-Z", "0-9" and "_.@-'"
289
-		if (preg_match('/[^a-zA-Z0-9 _\.@\-\']/', $uid)) {
290
-			throw new \Exception($l->t('Only the following characters are allowed in a username:'
291
-				. ' "a-z", "A-Z", "0-9", and "_.@-\'"'));
292
-		}
293
-		// No empty username
294
-		if (trim($uid) == '') {
295
-			throw new \Exception($l->t('A valid username must be provided'));
296
-		}
297
-		// No whitespace at the beginning or at the end
298
-		if (strlen(trim($uid, "\t\n\r\0\x0B\xe2\x80\x8b")) !== strlen(trim($uid))) {
299
-			throw new \Exception($l->t('Username contains whitespace at the beginning or at the end'));
300
-		}
301
-		// No empty password
302
-		if (trim($password) == '') {
303
-			throw new \Exception($l->t('A valid password must be provided'));
304
-		}
305
-
306
-		// Check if user already exists
307
-		if ($this->userExists($uid)) {
308
-			throw new \Exception($l->t('The username is already being used'));
309
-		}
310
-
311
-		$this->emit('\OC\User', 'preCreateUser', array($uid, $password));
312
-		foreach ($this->backends as $backend) {
313
-			if ($backend->implementsActions(Backend::CREATE_USER)) {
314
-				$backend->createUser($uid, $password);
315
-				$user = $this->getUserObject($uid, $backend);
316
-				$this->emit('\OC\User', 'postCreateUser', array($user, $password));
317
-				return $user;
318
-			}
319
-		}
320
-		return false;
321
-	}
322
-
323
-	/**
324
-	 * returns how many users per backend exist (if supported by backend)
325
-	 *
326
-	 * @param boolean $hasLoggedIn when true only users that have a lastLogin
327
-	 *                entry in the preferences table will be affected
328
-	 * @return array|int an array of backend class as key and count number as value
329
-	 *                if $hasLoggedIn is true only an int is returned
330
-	 */
331
-	public function countUsers($hasLoggedIn = false) {
332
-		if ($hasLoggedIn) {
333
-			return $this->countSeenUsers();
334
-		}
335
-		$userCountStatistics = [];
336
-		foreach ($this->backends as $backend) {
337
-			if ($backend->implementsActions(Backend::COUNT_USERS)) {
338
-				$backendUsers = $backend->countUsers();
339
-				if($backendUsers !== false) {
340
-					if($backend instanceof IUserBackend) {
341
-						$name = $backend->getBackendName();
342
-					} else {
343
-						$name = get_class($backend);
344
-					}
345
-					if(isset($userCountStatistics[$name])) {
346
-						$userCountStatistics[$name] += $backendUsers;
347
-					} else {
348
-						$userCountStatistics[$name] = $backendUsers;
349
-					}
350
-				}
351
-			}
352
-		}
353
-		return $userCountStatistics;
354
-	}
355
-
356
-	/**
357
-	 * The callback is executed for each user on each backend.
358
-	 * If the callback returns false no further users will be retrieved.
359
-	 *
360
-	 * @param \Closure $callback
361
-	 * @param string $search
362
-	 * @param boolean $onlySeen when true only users that have a lastLogin entry
363
-	 *                in the preferences table will be affected
364
-	 * @since 9.0.0
365
-	 */
366
-	public function callForAllUsers(\Closure $callback, $search = '', $onlySeen = false) {
367
-		if ($onlySeen) {
368
-			$this->callForSeenUsers($callback);
369
-		} else {
370
-			foreach ($this->getBackends() as $backend) {
371
-				$limit = 500;
372
-				$offset = 0;
373
-				do {
374
-					$users = $backend->getUsers($search, $limit, $offset);
375
-					foreach ($users as $uid) {
376
-						if (!$backend->userExists($uid)) {
377
-							continue;
378
-						}
379
-						$user = $this->getUserObject($uid, $backend, false);
380
-						$return = $callback($user);
381
-						if ($return === false) {
382
-							break;
383
-						}
384
-					}
385
-					$offset += $limit;
386
-				} while (count($users) >= $limit);
387
-			}
388
-		}
389
-	}
390
-
391
-	/**
392
-	 * returns how many users have logged in once
393
-	 *
394
-	 * @return int
395
-	 * @since 11.0.0
396
-	 */
397
-	public function countSeenUsers() {
398
-		$queryBuilder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
399
-		$queryBuilder->select($queryBuilder->createFunction('COUNT(*)'))
400
-			->from('preferences')
401
-			->where($queryBuilder->expr()->eq('appid', $queryBuilder->createNamedParameter('login')))
402
-			->andWhere($queryBuilder->expr()->eq('configkey', $queryBuilder->createNamedParameter('lastLogin')))
403
-			->andWhere($queryBuilder->expr()->isNotNull('configvalue'));
404
-
405
-		$query = $queryBuilder->execute();
406
-
407
-		$result = (int)$query->fetchColumn();
408
-		$query->closeCursor();
409
-
410
-		return $result;
411
-	}
412
-
413
-	/**
414
-	 * @param \Closure $callback
415
-	 * @since 11.0.0
416
-	 */
417
-	public function callForSeenUsers(\Closure $callback) {
418
-		$limit = 1000;
419
-		$offset = 0;
420
-		do {
421
-			$userIds = $this->getSeenUserIds($limit, $offset);
422
-			$offset += $limit;
423
-			foreach ($userIds as $userId) {
424
-				foreach ($this->backends as $backend) {
425
-					if ($backend->userExists($userId)) {
426
-						$user = $this->getUserObject($userId, $backend, false);
427
-						$return = $callback($user);
428
-						if ($return === false) {
429
-							return;
430
-						}
431
-					}
432
-				}
433
-			}
434
-		} while (count($userIds) >= $limit);
435
-	}
436
-
437
-	/**
438
-	 * Getting all userIds that have a listLogin value requires checking the
439
-	 * value in php because on oracle you cannot use a clob in a where clause,
440
-	 * preventing us from doing a not null or length(value) > 0 check.
441
-	 * 
442
-	 * @param int $limit
443
-	 * @param int $offset
444
-	 * @return string[] with user ids
445
-	 */
446
-	private function getSeenUserIds($limit = null, $offset = null) {
447
-		$queryBuilder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
448
-		$queryBuilder->select(['userid'])
449
-			->from('preferences')
450
-			->where($queryBuilder->expr()->eq(
451
-				'appid', $queryBuilder->createNamedParameter('login'))
452
-			)
453
-			->andWhere($queryBuilder->expr()->eq(
454
-				'configkey', $queryBuilder->createNamedParameter('lastLogin'))
455
-			)
456
-			->andWhere($queryBuilder->expr()->isNotNull('configvalue')
457
-			);
458
-
459
-		if ($limit !== null) {
460
-			$queryBuilder->setMaxResults($limit);
461
-		}
462
-		if ($offset !== null) {
463
-			$queryBuilder->setFirstResult($offset);
464
-		}
465
-		$query = $queryBuilder->execute();
466
-		$result = [];
467
-
468
-		while ($row = $query->fetch()) {
469
-			$result[] = $row['userid'];
470
-		}
471
-
472
-		$query->closeCursor();
473
-
474
-		return $result;
475
-	}
476
-
477
-	/**
478
-	 * @param string $email
479
-	 * @return IUser[]
480
-	 * @since 9.1.0
481
-	 */
482
-	public function getByEmail($email) {
483
-		$userIds = $this->config->getUsersForUserValue('settings', 'email', $email);
484
-
485
-		return array_map(function($uid) {
486
-			return $this->get($uid);
487
-		}, $userIds);
488
-	}
57
+    /**
58
+     * @var \OCP\UserInterface[] $backends
59
+     */
60
+    private $backends = array();
61
+
62
+    /**
63
+     * @var \OC\User\User[] $cachedUsers
64
+     */
65
+    private $cachedUsers = array();
66
+
67
+    /**
68
+     * @var \OCP\IConfig $config
69
+     */
70
+    private $config;
71
+
72
+    /**
73
+     * @param \OCP\IConfig $config
74
+     */
75
+    public function __construct(IConfig $config) {
76
+        $this->config = $config;
77
+        $cachedUsers = &$this->cachedUsers;
78
+        $this->listen('\OC\User', 'postDelete', function ($user) use (&$cachedUsers) {
79
+            /** @var \OC\User\User $user */
80
+            unset($cachedUsers[$user->getUID()]);
81
+        });
82
+    }
83
+
84
+    /**
85
+     * Get the active backends
86
+     * @return \OCP\UserInterface[]
87
+     */
88
+    public function getBackends() {
89
+        return $this->backends;
90
+    }
91
+
92
+    /**
93
+     * register a user backend
94
+     *
95
+     * @param \OCP\UserInterface $backend
96
+     */
97
+    public function registerBackend($backend) {
98
+        $this->backends[] = $backend;
99
+    }
100
+
101
+    /**
102
+     * remove a user backend
103
+     *
104
+     * @param \OCP\UserInterface $backend
105
+     */
106
+    public function removeBackend($backend) {
107
+        $this->cachedUsers = array();
108
+        if (($i = array_search($backend, $this->backends)) !== false) {
109
+            unset($this->backends[$i]);
110
+        }
111
+    }
112
+
113
+    /**
114
+     * remove all user backends
115
+     */
116
+    public function clearBackends() {
117
+        $this->cachedUsers = array();
118
+        $this->backends = array();
119
+    }
120
+
121
+    /**
122
+     * get a user by user id
123
+     *
124
+     * @param string $uid
125
+     * @return \OC\User\User|null Either the user or null if the specified user does not exist
126
+     */
127
+    public function get($uid) {
128
+        if (isset($this->cachedUsers[$uid])) { //check the cache first to prevent having to loop over the backends
129
+            return $this->cachedUsers[$uid];
130
+        }
131
+        foreach ($this->backends as $backend) {
132
+            if ($backend->userExists($uid)) {
133
+                return $this->getUserObject($uid, $backend);
134
+            }
135
+        }
136
+        return null;
137
+    }
138
+
139
+    /**
140
+     * get or construct the user object
141
+     *
142
+     * @param string $uid
143
+     * @param \OCP\UserInterface $backend
144
+     * @param bool $cacheUser If false the newly created user object will not be cached
145
+     * @return \OC\User\User
146
+     */
147
+    protected function getUserObject($uid, $backend, $cacheUser = true) {
148
+        if (isset($this->cachedUsers[$uid])) {
149
+            return $this->cachedUsers[$uid];
150
+        }
151
+
152
+        if (method_exists($backend, 'loginName2UserName')) {
153
+            $loginName = $backend->loginName2UserName($uid);
154
+            if ($loginName !== false) {
155
+                $uid = $loginName;
156
+            }
157
+            if (isset($this->cachedUsers[$uid])) {
158
+                return $this->cachedUsers[$uid];
159
+            }
160
+        }
161
+
162
+        $user = new User($uid, $backend, $this, $this->config);
163
+        if ($cacheUser) {
164
+            $this->cachedUsers[$uid] = $user;
165
+        }
166
+        return $user;
167
+    }
168
+
169
+    /**
170
+     * check if a user exists
171
+     *
172
+     * @param string $uid
173
+     * @return bool
174
+     */
175
+    public function userExists($uid) {
176
+        $user = $this->get($uid);
177
+        return ($user !== null);
178
+    }
179
+
180
+    /**
181
+     * Check if the password is valid for the user
182
+     *
183
+     * @param string $loginName
184
+     * @param string $password
185
+     * @return mixed the User object on success, false otherwise
186
+     */
187
+    public function checkPassword($loginName, $password) {
188
+        $result = $this->checkPasswordNoLogging($loginName, $password);
189
+
190
+        if ($result === false) {
191
+            \OC::$server->getLogger()->warning('Login failed: \''. $loginName .'\' (Remote IP: \''. \OC::$server->getRequest()->getRemoteAddress(). '\')', ['app' => 'core']);
192
+        }
193
+
194
+        return $result;
195
+    }
196
+
197
+    /**
198
+     * Check if the password is valid for the user
199
+     *
200
+     * @internal
201
+     * @param string $loginName
202
+     * @param string $password
203
+     * @return mixed the User object on success, false otherwise
204
+     */
205
+    public function checkPasswordNoLogging($loginName, $password) {
206
+        $loginName = str_replace("\0", '', $loginName);
207
+        $password = str_replace("\0", '', $password);
208
+
209
+        foreach ($this->backends as $backend) {
210
+            if ($backend->implementsActions(Backend::CHECK_PASSWORD)) {
211
+                $uid = $backend->checkPassword($loginName, $password);
212
+                if ($uid !== false) {
213
+                    return $this->getUserObject($uid, $backend);
214
+                }
215
+            }
216
+        }
217
+
218
+        return false;
219
+    }
220
+
221
+    /**
222
+     * search by user id
223
+     *
224
+     * @param string $pattern
225
+     * @param int $limit
226
+     * @param int $offset
227
+     * @return \OC\User\User[]
228
+     */
229
+    public function search($pattern, $limit = null, $offset = null) {
230
+        $users = array();
231
+        foreach ($this->backends as $backend) {
232
+            $backendUsers = $backend->getUsers($pattern, $limit, $offset);
233
+            if (is_array($backendUsers)) {
234
+                foreach ($backendUsers as $uid) {
235
+                    $users[$uid] = $this->getUserObject($uid, $backend);
236
+                }
237
+            }
238
+        }
239
+
240
+        uasort($users, function ($a, $b) {
241
+            /**
242
+             * @var \OC\User\User $a
243
+             * @var \OC\User\User $b
244
+             */
245
+            return strcmp($a->getUID(), $b->getUID());
246
+        });
247
+        return $users;
248
+    }
249
+
250
+    /**
251
+     * search by displayName
252
+     *
253
+     * @param string $pattern
254
+     * @param int $limit
255
+     * @param int $offset
256
+     * @return \OC\User\User[]
257
+     */
258
+    public function searchDisplayName($pattern, $limit = null, $offset = null) {
259
+        $users = array();
260
+        foreach ($this->backends as $backend) {
261
+            $backendUsers = $backend->getDisplayNames($pattern, $limit, $offset);
262
+            if (is_array($backendUsers)) {
263
+                foreach ($backendUsers as $uid => $displayName) {
264
+                    $users[] = $this->getUserObject($uid, $backend);
265
+                }
266
+            }
267
+        }
268
+
269
+        usort($users, function ($a, $b) {
270
+            /**
271
+             * @var \OC\User\User $a
272
+             * @var \OC\User\User $b
273
+             */
274
+            return strcmp(strtolower($a->getDisplayName()), strtolower($b->getDisplayName()));
275
+        });
276
+        return $users;
277
+    }
278
+
279
+    /**
280
+     * @param string $uid
281
+     * @param string $password
282
+     * @throws \Exception
283
+     * @return bool|\OC\User\User the created user or false
284
+     */
285
+    public function createUser($uid, $password) {
286
+        $l = \OC::$server->getL10N('lib');
287
+        // Check the name for bad characters
288
+        // Allowed are: "a-z", "A-Z", "0-9" and "_.@-'"
289
+        if (preg_match('/[^a-zA-Z0-9 _\.@\-\']/', $uid)) {
290
+            throw new \Exception($l->t('Only the following characters are allowed in a username:'
291
+                . ' "a-z", "A-Z", "0-9", and "_.@-\'"'));
292
+        }
293
+        // No empty username
294
+        if (trim($uid) == '') {
295
+            throw new \Exception($l->t('A valid username must be provided'));
296
+        }
297
+        // No whitespace at the beginning or at the end
298
+        if (strlen(trim($uid, "\t\n\r\0\x0B\xe2\x80\x8b")) !== strlen(trim($uid))) {
299
+            throw new \Exception($l->t('Username contains whitespace at the beginning or at the end'));
300
+        }
301
+        // No empty password
302
+        if (trim($password) == '') {
303
+            throw new \Exception($l->t('A valid password must be provided'));
304
+        }
305
+
306
+        // Check if user already exists
307
+        if ($this->userExists($uid)) {
308
+            throw new \Exception($l->t('The username is already being used'));
309
+        }
310
+
311
+        $this->emit('\OC\User', 'preCreateUser', array($uid, $password));
312
+        foreach ($this->backends as $backend) {
313
+            if ($backend->implementsActions(Backend::CREATE_USER)) {
314
+                $backend->createUser($uid, $password);
315
+                $user = $this->getUserObject($uid, $backend);
316
+                $this->emit('\OC\User', 'postCreateUser', array($user, $password));
317
+                return $user;
318
+            }
319
+        }
320
+        return false;
321
+    }
322
+
323
+    /**
324
+     * returns how many users per backend exist (if supported by backend)
325
+     *
326
+     * @param boolean $hasLoggedIn when true only users that have a lastLogin
327
+     *                entry in the preferences table will be affected
328
+     * @return array|int an array of backend class as key and count number as value
329
+     *                if $hasLoggedIn is true only an int is returned
330
+     */
331
+    public function countUsers($hasLoggedIn = false) {
332
+        if ($hasLoggedIn) {
333
+            return $this->countSeenUsers();
334
+        }
335
+        $userCountStatistics = [];
336
+        foreach ($this->backends as $backend) {
337
+            if ($backend->implementsActions(Backend::COUNT_USERS)) {
338
+                $backendUsers = $backend->countUsers();
339
+                if($backendUsers !== false) {
340
+                    if($backend instanceof IUserBackend) {
341
+                        $name = $backend->getBackendName();
342
+                    } else {
343
+                        $name = get_class($backend);
344
+                    }
345
+                    if(isset($userCountStatistics[$name])) {
346
+                        $userCountStatistics[$name] += $backendUsers;
347
+                    } else {
348
+                        $userCountStatistics[$name] = $backendUsers;
349
+                    }
350
+                }
351
+            }
352
+        }
353
+        return $userCountStatistics;
354
+    }
355
+
356
+    /**
357
+     * The callback is executed for each user on each backend.
358
+     * If the callback returns false no further users will be retrieved.
359
+     *
360
+     * @param \Closure $callback
361
+     * @param string $search
362
+     * @param boolean $onlySeen when true only users that have a lastLogin entry
363
+     *                in the preferences table will be affected
364
+     * @since 9.0.0
365
+     */
366
+    public function callForAllUsers(\Closure $callback, $search = '', $onlySeen = false) {
367
+        if ($onlySeen) {
368
+            $this->callForSeenUsers($callback);
369
+        } else {
370
+            foreach ($this->getBackends() as $backend) {
371
+                $limit = 500;
372
+                $offset = 0;
373
+                do {
374
+                    $users = $backend->getUsers($search, $limit, $offset);
375
+                    foreach ($users as $uid) {
376
+                        if (!$backend->userExists($uid)) {
377
+                            continue;
378
+                        }
379
+                        $user = $this->getUserObject($uid, $backend, false);
380
+                        $return = $callback($user);
381
+                        if ($return === false) {
382
+                            break;
383
+                        }
384
+                    }
385
+                    $offset += $limit;
386
+                } while (count($users) >= $limit);
387
+            }
388
+        }
389
+    }
390
+
391
+    /**
392
+     * returns how many users have logged in once
393
+     *
394
+     * @return int
395
+     * @since 11.0.0
396
+     */
397
+    public function countSeenUsers() {
398
+        $queryBuilder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
399
+        $queryBuilder->select($queryBuilder->createFunction('COUNT(*)'))
400
+            ->from('preferences')
401
+            ->where($queryBuilder->expr()->eq('appid', $queryBuilder->createNamedParameter('login')))
402
+            ->andWhere($queryBuilder->expr()->eq('configkey', $queryBuilder->createNamedParameter('lastLogin')))
403
+            ->andWhere($queryBuilder->expr()->isNotNull('configvalue'));
404
+
405
+        $query = $queryBuilder->execute();
406
+
407
+        $result = (int)$query->fetchColumn();
408
+        $query->closeCursor();
409
+
410
+        return $result;
411
+    }
412
+
413
+    /**
414
+     * @param \Closure $callback
415
+     * @since 11.0.0
416
+     */
417
+    public function callForSeenUsers(\Closure $callback) {
418
+        $limit = 1000;
419
+        $offset = 0;
420
+        do {
421
+            $userIds = $this->getSeenUserIds($limit, $offset);
422
+            $offset += $limit;
423
+            foreach ($userIds as $userId) {
424
+                foreach ($this->backends as $backend) {
425
+                    if ($backend->userExists($userId)) {
426
+                        $user = $this->getUserObject($userId, $backend, false);
427
+                        $return = $callback($user);
428
+                        if ($return === false) {
429
+                            return;
430
+                        }
431
+                    }
432
+                }
433
+            }
434
+        } while (count($userIds) >= $limit);
435
+    }
436
+
437
+    /**
438
+     * Getting all userIds that have a listLogin value requires checking the
439
+     * value in php because on oracle you cannot use a clob in a where clause,
440
+     * preventing us from doing a not null or length(value) > 0 check.
441
+     * 
442
+     * @param int $limit
443
+     * @param int $offset
444
+     * @return string[] with user ids
445
+     */
446
+    private function getSeenUserIds($limit = null, $offset = null) {
447
+        $queryBuilder = \OC::$server->getDatabaseConnection()->getQueryBuilder();
448
+        $queryBuilder->select(['userid'])
449
+            ->from('preferences')
450
+            ->where($queryBuilder->expr()->eq(
451
+                'appid', $queryBuilder->createNamedParameter('login'))
452
+            )
453
+            ->andWhere($queryBuilder->expr()->eq(
454
+                'configkey', $queryBuilder->createNamedParameter('lastLogin'))
455
+            )
456
+            ->andWhere($queryBuilder->expr()->isNotNull('configvalue')
457
+            );
458
+
459
+        if ($limit !== null) {
460
+            $queryBuilder->setMaxResults($limit);
461
+        }
462
+        if ($offset !== null) {
463
+            $queryBuilder->setFirstResult($offset);
464
+        }
465
+        $query = $queryBuilder->execute();
466
+        $result = [];
467
+
468
+        while ($row = $query->fetch()) {
469
+            $result[] = $row['userid'];
470
+        }
471
+
472
+        $query->closeCursor();
473
+
474
+        return $result;
475
+    }
476
+
477
+    /**
478
+     * @param string $email
479
+     * @return IUser[]
480
+     * @since 9.1.0
481
+     */
482
+    public function getByEmail($email) {
483
+        $userIds = $this->config->getUsersForUserValue('settings', 'email', $email);
484
+
485
+        return array_map(function($uid) {
486
+            return $this->get($uid);
487
+        }, $userIds);
488
+    }
489 489
 }
Please login to merge, or discard this patch.
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -75,7 +75,7 @@  discard block
 block discarded – undo
75 75
 	public function __construct(IConfig $config) {
76 76
 		$this->config = $config;
77 77
 		$cachedUsers = &$this->cachedUsers;
78
-		$this->listen('\OC\User', 'postDelete', function ($user) use (&$cachedUsers) {
78
+		$this->listen('\OC\User', 'postDelete', function($user) use (&$cachedUsers) {
79 79
 			/** @var \OC\User\User $user */
80 80
 			unset($cachedUsers[$user->getUID()]);
81 81
 		});
@@ -188,7 +188,7 @@  discard block
 block discarded – undo
188 188
 		$result = $this->checkPasswordNoLogging($loginName, $password);
189 189
 
190 190
 		if ($result === false) {
191
-			\OC::$server->getLogger()->warning('Login failed: \''. $loginName .'\' (Remote IP: \''. \OC::$server->getRequest()->getRemoteAddress(). '\')', ['app' => 'core']);
191
+			\OC::$server->getLogger()->warning('Login failed: \''.$loginName.'\' (Remote IP: \''.\OC::$server->getRequest()->getRemoteAddress().'\')', ['app' => 'core']);
192 192
 		}
193 193
 
194 194
 		return $result;
@@ -237,7 +237,7 @@  discard block
 block discarded – undo
237 237
 			}
238 238
 		}
239 239
 
240
-		uasort($users, function ($a, $b) {
240
+		uasort($users, function($a, $b) {
241 241
 			/**
242 242
 			 * @var \OC\User\User $a
243 243
 			 * @var \OC\User\User $b
@@ -266,7 +266,7 @@  discard block
 block discarded – undo
266 266
 			}
267 267
 		}
268 268
 
269
-		usort($users, function ($a, $b) {
269
+		usort($users, function($a, $b) {
270 270
 			/**
271 271
 			 * @var \OC\User\User $a
272 272
 			 * @var \OC\User\User $b
@@ -336,13 +336,13 @@  discard block
 block discarded – undo
336 336
 		foreach ($this->backends as $backend) {
337 337
 			if ($backend->implementsActions(Backend::COUNT_USERS)) {
338 338
 				$backendUsers = $backend->countUsers();
339
-				if($backendUsers !== false) {
340
-					if($backend instanceof IUserBackend) {
339
+				if ($backendUsers !== false) {
340
+					if ($backend instanceof IUserBackend) {
341 341
 						$name = $backend->getBackendName();
342 342
 					} else {
343 343
 						$name = get_class($backend);
344 344
 					}
345
-					if(isset($userCountStatistics[$name])) {
345
+					if (isset($userCountStatistics[$name])) {
346 346
 						$userCountStatistics[$name] += $backendUsers;
347 347
 					} else {
348 348
 						$userCountStatistics[$name] = $backendUsers;
@@ -404,7 +404,7 @@  discard block
 block discarded – undo
404 404
 
405 405
 		$query = $queryBuilder->execute();
406 406
 
407
-		$result = (int)$query->fetchColumn();
407
+		$result = (int) $query->fetchColumn();
408 408
 		$query->closeCursor();
409 409
 
410 410
 		return $result;
Please login to merge, or discard this patch.
core/Controller/LoginController.php 2 patches
Indentation   +249 added lines, -249 removed lines patch added patch discarded remove patch
@@ -50,281 +50,281 @@
 block discarded – undo
50 50
 use OC\Hooks\PublicEmitter;
51 51
 
52 52
 class LoginController extends Controller {
53
-	/** @var IUserManager */
54
-	private $userManager;
55
-	/** @var IConfig */
56
-	private $config;
57
-	/** @var ISession */
58
-	private $session;
59
-	/** @var IUserSession|Session */
60
-	private $userSession;
61
-	/** @var IURLGenerator */
62
-	private $urlGenerator;
63
-	/** @var ILogger */
64
-	private $logger;
65
-	/** @var Manager */
66
-	private $twoFactorManager;
67
-	/** @var Throttler */
68
-	private $throttler;
53
+    /** @var IUserManager */
54
+    private $userManager;
55
+    /** @var IConfig */
56
+    private $config;
57
+    /** @var ISession */
58
+    private $session;
59
+    /** @var IUserSession|Session */
60
+    private $userSession;
61
+    /** @var IURLGenerator */
62
+    private $urlGenerator;
63
+    /** @var ILogger */
64
+    private $logger;
65
+    /** @var Manager */
66
+    private $twoFactorManager;
67
+    /** @var Throttler */
68
+    private $throttler;
69 69
 
70
-	/**
71
-	 * @param string $appName
72
-	 * @param IRequest $request
73
-	 * @param IUserManager $userManager
74
-	 * @param IConfig $config
75
-	 * @param ISession $session
76
-	 * @param IUserSession $userSession
77
-	 * @param IURLGenerator $urlGenerator
78
-	 * @param ILogger $logger
79
-	 * @param Manager $twoFactorManager
80
-	 * @param Throttler $throttler
81
-	 */
82
-	public function __construct($appName,
83
-						 IRequest $request,
84
-						 IUserManager $userManager,
85
-						 IConfig $config,
86
-						 ISession $session,
87
-						 IUserSession $userSession,
88
-						 IURLGenerator $urlGenerator,
89
-						 ILogger $logger,
90
-						 Manager $twoFactorManager,
91
-						 Throttler $throttler) {
92
-		parent::__construct($appName, $request);
93
-		$this->userManager = $userManager;
94
-		$this->config = $config;
95
-		$this->session = $session;
96
-		$this->userSession = $userSession;
97
-		$this->urlGenerator = $urlGenerator;
98
-		$this->logger = $logger;
99
-		$this->twoFactorManager = $twoFactorManager;
100
-		$this->throttler = $throttler;
101
-	}
70
+    /**
71
+     * @param string $appName
72
+     * @param IRequest $request
73
+     * @param IUserManager $userManager
74
+     * @param IConfig $config
75
+     * @param ISession $session
76
+     * @param IUserSession $userSession
77
+     * @param IURLGenerator $urlGenerator
78
+     * @param ILogger $logger
79
+     * @param Manager $twoFactorManager
80
+     * @param Throttler $throttler
81
+     */
82
+    public function __construct($appName,
83
+                            IRequest $request,
84
+                            IUserManager $userManager,
85
+                            IConfig $config,
86
+                            ISession $session,
87
+                            IUserSession $userSession,
88
+                            IURLGenerator $urlGenerator,
89
+                            ILogger $logger,
90
+                            Manager $twoFactorManager,
91
+                            Throttler $throttler) {
92
+        parent::__construct($appName, $request);
93
+        $this->userManager = $userManager;
94
+        $this->config = $config;
95
+        $this->session = $session;
96
+        $this->userSession = $userSession;
97
+        $this->urlGenerator = $urlGenerator;
98
+        $this->logger = $logger;
99
+        $this->twoFactorManager = $twoFactorManager;
100
+        $this->throttler = $throttler;
101
+    }
102 102
 
103
-	/**
104
-	 * @NoAdminRequired
105
-	 * @UseSession
106
-	 *
107
-	 * @return RedirectResponse
108
-	 */
109
-	public function logout() {
110
-		$loginToken = $this->request->getCookie('nc_token');
111
-		if (!is_null($loginToken)) {
112
-			$this->config->deleteUserValue($this->userSession->getUser()->getUID(), 'login_token', $loginToken);
113
-		}
114
-		$this->userSession->logout();
103
+    /**
104
+     * @NoAdminRequired
105
+     * @UseSession
106
+     *
107
+     * @return RedirectResponse
108
+     */
109
+    public function logout() {
110
+        $loginToken = $this->request->getCookie('nc_token');
111
+        if (!is_null($loginToken)) {
112
+            $this->config->deleteUserValue($this->userSession->getUser()->getUID(), 'login_token', $loginToken);
113
+        }
114
+        $this->userSession->logout();
115 115
 
116
-		return new RedirectResponse($this->urlGenerator->linkToRouteAbsolute('core.login.showLoginForm'));
117
-	}
116
+        return new RedirectResponse($this->urlGenerator->linkToRouteAbsolute('core.login.showLoginForm'));
117
+    }
118 118
 
119
-	/**
120
-	 * @PublicPage
121
-	 * @NoCSRFRequired
122
-	 * @UseSession
123
-	 *
124
-	 * @param string $user
125
-	 * @param string $redirect_url
126
-	 * @param string $remember_login
127
-	 *
128
-	 * @return TemplateResponse|RedirectResponse
129
-	 */
130
-	public function showLoginForm($user, $redirect_url, $remember_login) {
131
-		if ($this->userSession->isLoggedIn()) {
132
-			return new RedirectResponse(OC_Util::getDefaultPageUrl());
133
-		}
119
+    /**
120
+     * @PublicPage
121
+     * @NoCSRFRequired
122
+     * @UseSession
123
+     *
124
+     * @param string $user
125
+     * @param string $redirect_url
126
+     * @param string $remember_login
127
+     *
128
+     * @return TemplateResponse|RedirectResponse
129
+     */
130
+    public function showLoginForm($user, $redirect_url, $remember_login) {
131
+        if ($this->userSession->isLoggedIn()) {
132
+            return new RedirectResponse(OC_Util::getDefaultPageUrl());
133
+        }
134 134
 
135
-		$parameters = array();
136
-		$loginMessages = $this->session->get('loginMessages');
137
-		$errors = [];
138
-		$messages = [];
139
-		if (is_array($loginMessages)) {
140
-			list($errors, $messages) = $loginMessages;
141
-		}
142
-		$this->session->remove('loginMessages');
143
-		foreach ($errors as $value) {
144
-			$parameters[$value] = true;
145
-		}
135
+        $parameters = array();
136
+        $loginMessages = $this->session->get('loginMessages');
137
+        $errors = [];
138
+        $messages = [];
139
+        if (is_array($loginMessages)) {
140
+            list($errors, $messages) = $loginMessages;
141
+        }
142
+        $this->session->remove('loginMessages');
143
+        foreach ($errors as $value) {
144
+            $parameters[$value] = true;
145
+        }
146 146
 
147
-		$parameters['messages'] = $messages;
148
-		if (!is_null($user) && $user !== '') {
149
-			$parameters['loginName'] = $user;
150
-			$parameters['user_autofocus'] = false;
151
-		} else {
152
-			$parameters['loginName'] = '';
153
-			$parameters['user_autofocus'] = true;
154
-		}
155
-		if (!empty($redirect_url)) {
156
-			$parameters['redirect_url'] = $redirect_url;
157
-		}
147
+        $parameters['messages'] = $messages;
148
+        if (!is_null($user) && $user !== '') {
149
+            $parameters['loginName'] = $user;
150
+            $parameters['user_autofocus'] = false;
151
+        } else {
152
+            $parameters['loginName'] = '';
153
+            $parameters['user_autofocus'] = true;
154
+        }
155
+        if (!empty($redirect_url)) {
156
+            $parameters['redirect_url'] = $redirect_url;
157
+        }
158 158
 
159
-		$parameters['canResetPassword'] = true;
160
-		$parameters['resetPasswordLink'] = $this->config->getSystemValue('lost_password_link', '');
161
-		if (!$parameters['resetPasswordLink']) {
162
-			if (!is_null($user) && $user !== '') {
163
-				$userObj = $this->userManager->get($user);
164
-				if ($userObj instanceof IUser) {
165
-					$parameters['canResetPassword'] = $userObj->canChangePassword();
166
-				}
167
-			}
168
-		}
159
+        $parameters['canResetPassword'] = true;
160
+        $parameters['resetPasswordLink'] = $this->config->getSystemValue('lost_password_link', '');
161
+        if (!$parameters['resetPasswordLink']) {
162
+            if (!is_null($user) && $user !== '') {
163
+                $userObj = $this->userManager->get($user);
164
+                if ($userObj instanceof IUser) {
165
+                    $parameters['canResetPassword'] = $userObj->canChangePassword();
166
+                }
167
+            }
168
+        }
169 169
 
170
-		$parameters['alt_login'] = OC_App::getAlternativeLogIns();
171
-		$parameters['rememberLoginState'] = !empty($remember_login) ? $remember_login : 0;
170
+        $parameters['alt_login'] = OC_App::getAlternativeLogIns();
171
+        $parameters['rememberLoginState'] = !empty($remember_login) ? $remember_login : 0;
172 172
 
173
-		if (!is_null($user) && $user !== '') {
174
-			$parameters['loginName'] = $user;
175
-			$parameters['user_autofocus'] = false;
176
-		} else {
177
-			$parameters['loginName'] = '';
178
-			$parameters['user_autofocus'] = true;
179
-		}
173
+        if (!is_null($user) && $user !== '') {
174
+            $parameters['loginName'] = $user;
175
+            $parameters['user_autofocus'] = false;
176
+        } else {
177
+            $parameters['loginName'] = '';
178
+            $parameters['user_autofocus'] = true;
179
+        }
180 180
 
181
-		return new TemplateResponse(
182
-			$this->appName, 'login', $parameters, 'guest'
183
-		);
184
-	}
181
+        return new TemplateResponse(
182
+            $this->appName, 'login', $parameters, 'guest'
183
+        );
184
+    }
185 185
 
186
-	/**
187
-	 * @param string $redirectUrl
188
-	 * @return RedirectResponse
189
-	 */
190
-	private function generateRedirect($redirectUrl) {
191
-		if (!is_null($redirectUrl) && $this->userSession->isLoggedIn()) {
192
-			$location = $this->urlGenerator->getAbsoluteURL(urldecode($redirectUrl));
193
-			// Deny the redirect if the URL contains a @
194
-			// This prevents unvalidated redirects like ?redirect_url=:[email protected]
195
-			if (strpos($location, '@') === false) {
196
-				return new RedirectResponse($location);
197
-			}
198
-		}
199
-		return new RedirectResponse(OC_Util::getDefaultPageUrl());
200
-	}
186
+    /**
187
+     * @param string $redirectUrl
188
+     * @return RedirectResponse
189
+     */
190
+    private function generateRedirect($redirectUrl) {
191
+        if (!is_null($redirectUrl) && $this->userSession->isLoggedIn()) {
192
+            $location = $this->urlGenerator->getAbsoluteURL(urldecode($redirectUrl));
193
+            // Deny the redirect if the URL contains a @
194
+            // This prevents unvalidated redirects like ?redirect_url=:[email protected]
195
+            if (strpos($location, '@') === false) {
196
+                return new RedirectResponse($location);
197
+            }
198
+        }
199
+        return new RedirectResponse(OC_Util::getDefaultPageUrl());
200
+    }
201 201
 
202
-	/**
203
-	 * @PublicPage
204
-	 * @UseSession
205
-	 * @NoCSRFRequired
206
-	 *
207
-	 * @param string $user
208
-	 * @param string $password
209
-	 * @param string $redirect_url
210
-	 * @param boolean $remember_login
211
-	 * @param string $timezone
212
-	 * @param string $timezone_offset
213
-	 * @return RedirectResponse
214
-	 */
215
-	public function tryLogin($user, $password, $redirect_url, $remember_login = false, $timezone = '', $timezone_offset = '') {
216
-		$currentDelay = $this->throttler->getDelay($this->request->getRemoteAddress(), 'login');
217
-		$this->throttler->sleepDelay($this->request->getRemoteAddress(), 'login');
202
+    /**
203
+     * @PublicPage
204
+     * @UseSession
205
+     * @NoCSRFRequired
206
+     *
207
+     * @param string $user
208
+     * @param string $password
209
+     * @param string $redirect_url
210
+     * @param boolean $remember_login
211
+     * @param string $timezone
212
+     * @param string $timezone_offset
213
+     * @return RedirectResponse
214
+     */
215
+    public function tryLogin($user, $password, $redirect_url, $remember_login = false, $timezone = '', $timezone_offset = '') {
216
+        $currentDelay = $this->throttler->getDelay($this->request->getRemoteAddress(), 'login');
217
+        $this->throttler->sleepDelay($this->request->getRemoteAddress(), 'login');
218 218
 
219
-		// If the user is already logged in and the CSRF check does not pass then
220
-		// simply redirect the user to the correct page as required. This is the
221
-		// case when an user has already logged-in, in another tab.
222
-		if(!$this->request->passesCSRFCheck()) {
223
-			return $this->generateRedirect($redirect_url);
224
-		}
219
+        // If the user is already logged in and the CSRF check does not pass then
220
+        // simply redirect the user to the correct page as required. This is the
221
+        // case when an user has already logged-in, in another tab.
222
+        if(!$this->request->passesCSRFCheck()) {
223
+            return $this->generateRedirect($redirect_url);
224
+        }
225 225
 
226
-		if ($this->userManager instanceof PublicEmitter) {
227
-			$this->userManager->emit('\OC\User', 'preLogin', array($user, $password));
228
-		}
226
+        if ($this->userManager instanceof PublicEmitter) {
227
+            $this->userManager->emit('\OC\User', 'preLogin', array($user, $password));
228
+        }
229 229
 
230
-		$originalUser = $user;
231
-		// TODO: Add all the insane error handling
232
-		/* @var $loginResult IUser */
233
-		$loginResult = $this->userManager->checkPasswordNoLogging($user, $password);
234
-		if ($loginResult === false) {
235
-			$users = $this->userManager->getByEmail($user);
236
-			// we only allow login by email if unique
237
-			if (count($users) === 1) {
238
-				$user = $users[0]->getUID();
239
-				$loginResult = $this->userManager->checkPassword($user, $password);
240
-			} else {
241
-				$this->logger->warning('Login failed: \''. $user .'\' (Remote IP: \''. $this->request->getRemoteAddress(). '\')', ['app' => 'core']);
242
-			}
243
-		}
244
-		if ($loginResult === false) {
245
-			$this->throttler->registerAttempt('login', $this->request->getRemoteAddress(), ['user' => $originalUser]);
246
-			if($currentDelay === 0) {
247
-				$this->throttler->sleepDelay($this->request->getRemoteAddress(), 'login');
248
-			}
249
-			$this->session->set('loginMessages', [
250
-				['invalidpassword'], []
251
-			]);
252
-			// Read current user and append if possible - we need to return the unmodified user otherwise we will leak the login name
253
-			$args = !is_null($user) ? ['user' => $originalUser] : [];
254
-			return new RedirectResponse($this->urlGenerator->linkToRoute('core.login.showLoginForm', $args));
255
-		}
256
-		// TODO: remove password checks from above and let the user session handle failures
257
-		// requires https://github.com/owncloud/core/pull/24616
258
-		$this->userSession->login($user, $password);
259
-		$this->userSession->createSessionToken($this->request, $loginResult->getUID(), $user, $password, (int)$remember_login);
230
+        $originalUser = $user;
231
+        // TODO: Add all the insane error handling
232
+        /* @var $loginResult IUser */
233
+        $loginResult = $this->userManager->checkPasswordNoLogging($user, $password);
234
+        if ($loginResult === false) {
235
+            $users = $this->userManager->getByEmail($user);
236
+            // we only allow login by email if unique
237
+            if (count($users) === 1) {
238
+                $user = $users[0]->getUID();
239
+                $loginResult = $this->userManager->checkPassword($user, $password);
240
+            } else {
241
+                $this->logger->warning('Login failed: \''. $user .'\' (Remote IP: \''. $this->request->getRemoteAddress(). '\')', ['app' => 'core']);
242
+            }
243
+        }
244
+        if ($loginResult === false) {
245
+            $this->throttler->registerAttempt('login', $this->request->getRemoteAddress(), ['user' => $originalUser]);
246
+            if($currentDelay === 0) {
247
+                $this->throttler->sleepDelay($this->request->getRemoteAddress(), 'login');
248
+            }
249
+            $this->session->set('loginMessages', [
250
+                ['invalidpassword'], []
251
+            ]);
252
+            // Read current user and append if possible - we need to return the unmodified user otherwise we will leak the login name
253
+            $args = !is_null($user) ? ['user' => $originalUser] : [];
254
+            return new RedirectResponse($this->urlGenerator->linkToRoute('core.login.showLoginForm', $args));
255
+        }
256
+        // TODO: remove password checks from above and let the user session handle failures
257
+        // requires https://github.com/owncloud/core/pull/24616
258
+        $this->userSession->login($user, $password);
259
+        $this->userSession->createSessionToken($this->request, $loginResult->getUID(), $user, $password, (int)$remember_login);
260 260
 
261
-		// User has successfully logged in, now remove the password reset link, when it is available
262
-		$this->config->deleteUserValue($loginResult->getUID(), 'core', 'lostpassword');
261
+        // User has successfully logged in, now remove the password reset link, when it is available
262
+        $this->config->deleteUserValue($loginResult->getUID(), 'core', 'lostpassword');
263 263
 
264
-		$this->session->set('last-password-confirm', $loginResult->getLastLogin());
264
+        $this->session->set('last-password-confirm', $loginResult->getLastLogin());
265 265
 
266
-		if ($timezone_offset !== '') {
267
-			$this->config->setUserValue($loginResult->getUID(), 'core', 'timezone', $timezone);
268
-			$this->session->set('timezone', $timezone_offset);
269
-		}
266
+        if ($timezone_offset !== '') {
267
+            $this->config->setUserValue($loginResult->getUID(), 'core', 'timezone', $timezone);
268
+            $this->session->set('timezone', $timezone_offset);
269
+        }
270 270
 
271
-		if ($this->twoFactorManager->isTwoFactorAuthenticated($loginResult)) {
272
-			$this->twoFactorManager->prepareTwoFactorLogin($loginResult, $remember_login);
271
+        if ($this->twoFactorManager->isTwoFactorAuthenticated($loginResult)) {
272
+            $this->twoFactorManager->prepareTwoFactorLogin($loginResult, $remember_login);
273 273
 
274
-			$providers = $this->twoFactorManager->getProviders($loginResult);
275
-			if (count($providers) === 1) {
276
-				// Single provider, hence we can redirect to that provider's challenge page directly
277
-				/* @var $provider IProvider */
278
-				$provider = array_pop($providers);
279
-				$url = 'core.TwoFactorChallenge.showChallenge';
280
-				$urlParams = [
281
-					'challengeProviderId' => $provider->getId(),
282
-				];
283
-			} else {
284
-				$url = 'core.TwoFactorChallenge.selectChallenge';
285
-				$urlParams = [];
286
-			}
274
+            $providers = $this->twoFactorManager->getProviders($loginResult);
275
+            if (count($providers) === 1) {
276
+                // Single provider, hence we can redirect to that provider's challenge page directly
277
+                /* @var $provider IProvider */
278
+                $provider = array_pop($providers);
279
+                $url = 'core.TwoFactorChallenge.showChallenge';
280
+                $urlParams = [
281
+                    'challengeProviderId' => $provider->getId(),
282
+                ];
283
+            } else {
284
+                $url = 'core.TwoFactorChallenge.selectChallenge';
285
+                $urlParams = [];
286
+            }
287 287
 
288
-			if (!is_null($redirect_url)) {
289
-				$urlParams['redirect_url'] = $redirect_url;
290
-			}
288
+            if (!is_null($redirect_url)) {
289
+                $urlParams['redirect_url'] = $redirect_url;
290
+            }
291 291
 
292
-			return new RedirectResponse($this->urlGenerator->linkToRoute($url, $urlParams));
293
-		}
292
+            return new RedirectResponse($this->urlGenerator->linkToRoute($url, $urlParams));
293
+        }
294 294
 
295
-		if ($remember_login) {
296
-			$this->userSession->createRememberMeToken($loginResult);
297
-		}
295
+        if ($remember_login) {
296
+            $this->userSession->createRememberMeToken($loginResult);
297
+        }
298 298
 
299
-		return $this->generateRedirect($redirect_url);
300
-	}
299
+        return $this->generateRedirect($redirect_url);
300
+    }
301 301
 
302
-	/**
303
-	 * @NoAdminRequired
304
-	 * @UseSession
305
-	 *
306
-	 * @license GNU AGPL version 3 or any later version
307
-	 *
308
-	 * @param string $password
309
-	 * @return DataResponse
310
-	 */
311
-	public function confirmPassword($password) {
312
-		$currentDelay = $this->throttler->getDelay($this->request->getRemoteAddress(), 'sudo');
313
-		$this->throttler->sleepDelay($this->request->getRemoteAddress(), 'sudo');
302
+    /**
303
+     * @NoAdminRequired
304
+     * @UseSession
305
+     *
306
+     * @license GNU AGPL version 3 or any later version
307
+     *
308
+     * @param string $password
309
+     * @return DataResponse
310
+     */
311
+    public function confirmPassword($password) {
312
+        $currentDelay = $this->throttler->getDelay($this->request->getRemoteAddress(), 'sudo');
313
+        $this->throttler->sleepDelay($this->request->getRemoteAddress(), 'sudo');
314 314
 
315
-		$loginName = $this->userSession->getLoginName();
316
-		$loginResult = $this->userManager->checkPassword($loginName, $password);
317
-		if ($loginResult === false) {
318
-			$this->throttler->registerAttempt('sudo', $this->request->getRemoteAddress(), ['user' => $loginName]);
319
-			if ($currentDelay === 0) {
320
-				$this->throttler->sleepDelay($this->request->getRemoteAddress(), 'sudo');
321
-			}
315
+        $loginName = $this->userSession->getLoginName();
316
+        $loginResult = $this->userManager->checkPassword($loginName, $password);
317
+        if ($loginResult === false) {
318
+            $this->throttler->registerAttempt('sudo', $this->request->getRemoteAddress(), ['user' => $loginName]);
319
+            if ($currentDelay === 0) {
320
+                $this->throttler->sleepDelay($this->request->getRemoteAddress(), 'sudo');
321
+            }
322 322
 
323
-			return new DataResponse([], Http::STATUS_FORBIDDEN);
324
-		}
323
+            return new DataResponse([], Http::STATUS_FORBIDDEN);
324
+        }
325 325
 
326
-		$confirmTimestamp = time();
327
-		$this->session->set('last-password-confirm', $confirmTimestamp);
328
-		return new DataResponse(['lastLogin' => $confirmTimestamp], Http::STATUS_OK);
329
-	}
326
+        $confirmTimestamp = time();
327
+        $this->session->set('last-password-confirm', $confirmTimestamp);
328
+        return new DataResponse(['lastLogin' => $confirmTimestamp], Http::STATUS_OK);
329
+    }
330 330
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -219,7 +219,7 @@  discard block
 block discarded – undo
219 219
 		// If the user is already logged in and the CSRF check does not pass then
220 220
 		// simply redirect the user to the correct page as required. This is the
221 221
 		// case when an user has already logged-in, in another tab.
222
-		if(!$this->request->passesCSRFCheck()) {
222
+		if (!$this->request->passesCSRFCheck()) {
223 223
 			return $this->generateRedirect($redirect_url);
224 224
 		}
225 225
 
@@ -238,12 +238,12 @@  discard block
 block discarded – undo
238 238
 				$user = $users[0]->getUID();
239 239
 				$loginResult = $this->userManager->checkPassword($user, $password);
240 240
 			} else {
241
-				$this->logger->warning('Login failed: \''. $user .'\' (Remote IP: \''. $this->request->getRemoteAddress(). '\')', ['app' => 'core']);
241
+				$this->logger->warning('Login failed: \''.$user.'\' (Remote IP: \''.$this->request->getRemoteAddress().'\')', ['app' => 'core']);
242 242
 			}
243 243
 		}
244 244
 		if ($loginResult === false) {
245 245
 			$this->throttler->registerAttempt('login', $this->request->getRemoteAddress(), ['user' => $originalUser]);
246
-			if($currentDelay === 0) {
246
+			if ($currentDelay === 0) {
247 247
 				$this->throttler->sleepDelay($this->request->getRemoteAddress(), 'login');
248 248
 			}
249 249
 			$this->session->set('loginMessages', [
@@ -256,7 +256,7 @@  discard block
 block discarded – undo
256 256
 		// TODO: remove password checks from above and let the user session handle failures
257 257
 		// requires https://github.com/owncloud/core/pull/24616
258 258
 		$this->userSession->login($user, $password);
259
-		$this->userSession->createSessionToken($this->request, $loginResult->getUID(), $user, $password, (int)$remember_login);
259
+		$this->userSession->createSessionToken($this->request, $loginResult->getUID(), $user, $password, (int) $remember_login);
260 260
 
261 261
 		// User has successfully logged in, now remove the password reset link, when it is available
262 262
 		$this->config->deleteUserValue($loginResult->getUID(), 'core', 'lostpassword');
Please login to merge, or discard this patch.