Completed
Push — master ( f7ae47...78ca6f )
by Björn
20:51 queued 10s
created
core/Controller/LostController.php 1 patch
Indentation   +326 added lines, -326 removed lines patch added patch discarded remove patch
@@ -58,330 +58,330 @@
 block discarded – undo
58 58
  */
59 59
 class LostController extends Controller {
60 60
 
61
-	/** @var IURLGenerator */
62
-	protected $urlGenerator;
63
-	/** @var IUserManager */
64
-	protected $userManager;
65
-	/** @var Defaults */
66
-	protected $defaults;
67
-	/** @var IL10N */
68
-	protected $l10n;
69
-	/** @var string */
70
-	protected $from;
71
-	/** @var IManager */
72
-	protected $encryptionManager;
73
-	/** @var IConfig */
74
-	protected $config;
75
-	/** @var ISecureRandom */
76
-	protected $secureRandom;
77
-	/** @var IMailer */
78
-	protected $mailer;
79
-	/** @var ITimeFactory */
80
-	protected $timeFactory;
81
-	/** @var ICrypto */
82
-	protected $crypto;
83
-
84
-	/**
85
-	 * @param string $appName
86
-	 * @param IRequest $request
87
-	 * @param IURLGenerator $urlGenerator
88
-	 * @param IUserManager $userManager
89
-	 * @param Defaults $defaults
90
-	 * @param IL10N $l10n
91
-	 * @param IConfig $config
92
-	 * @param ISecureRandom $secureRandom
93
-	 * @param string $defaultMailAddress
94
-	 * @param IManager $encryptionManager
95
-	 * @param IMailer $mailer
96
-	 * @param ITimeFactory $timeFactory
97
-	 * @param ICrypto $crypto
98
-	 */
99
-	public function __construct($appName,
100
-								IRequest $request,
101
-								IURLGenerator $urlGenerator,
102
-								IUserManager $userManager,
103
-								Defaults $defaults,
104
-								IL10N $l10n,
105
-								IConfig $config,
106
-								ISecureRandom $secureRandom,
107
-								$defaultMailAddress,
108
-								IManager $encryptionManager,
109
-								IMailer $mailer,
110
-								ITimeFactory $timeFactory,
111
-								ICrypto $crypto) {
112
-		parent::__construct($appName, $request);
113
-		$this->urlGenerator = $urlGenerator;
114
-		$this->userManager = $userManager;
115
-		$this->defaults = $defaults;
116
-		$this->l10n = $l10n;
117
-		$this->secureRandom = $secureRandom;
118
-		$this->from = $defaultMailAddress;
119
-		$this->encryptionManager = $encryptionManager;
120
-		$this->config = $config;
121
-		$this->mailer = $mailer;
122
-		$this->timeFactory = $timeFactory;
123
-		$this->crypto = $crypto;
124
-	}
125
-
126
-	/**
127
-	 * Someone wants to reset their password:
128
-	 *
129
-	 * @PublicPage
130
-	 * @NoCSRFRequired
131
-	 *
132
-	 * @param string $token
133
-	 * @param string $userId
134
-	 * @return TemplateResponse
135
-	 */
136
-	public function resetform($token, $userId) {
137
-		if ($this->config->getSystemValue('lost_password_link', '') !== '') {
138
-			return new TemplateResponse('core', 'error', [
139
-					'errors' => [['error' => $this->l10n->t('Password reset is disabled')]]
140
-				],
141
-				'guest'
142
-			);
143
-		}
144
-
145
-		try {
146
-			$this->checkPasswordResetToken($token, $userId);
147
-		} catch (\Exception $e) {
148
-			return new TemplateResponse(
149
-				'core', 'error', [
150
-					"errors" => array(array("error" => $e->getMessage()))
151
-				],
152
-				'guest'
153
-			);
154
-		}
155
-
156
-		return new TemplateResponse(
157
-			'core',
158
-			'lostpassword/resetpassword',
159
-			array(
160
-				'link' => $this->urlGenerator->linkToRouteAbsolute('core.lost.setPassword', array('userId' => $userId, 'token' => $token)),
161
-			),
162
-			'guest'
163
-		);
164
-	}
165
-
166
-	/**
167
-	 * @param string $token
168
-	 * @param string $userId
169
-	 * @throws \Exception
170
-	 */
171
-	protected function checkPasswordResetToken($token, $userId) {
172
-		$user = $this->userManager->get($userId);
173
-		if($user === null || !$user->isEnabled()) {
174
-			throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid'));
175
-		}
176
-
177
-		try {
178
-			$encryptedToken = $this->config->getUserValue($userId, 'core', 'lostpassword', null);
179
-			$mailAddress = !is_null($user->getEMailAddress()) ? $user->getEMailAddress() : '';
180
-			$decryptedToken = $this->crypto->decrypt($encryptedToken, $mailAddress.$this->config->getSystemValue('secret'));
181
-		} catch (\Exception $e) {
182
-			throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid'));
183
-		}
184
-
185
-		$splittedToken = explode(':', $decryptedToken);
186
-		if(count($splittedToken) !== 2) {
187
-			throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid'));
188
-		}
189
-
190
-		if ($splittedToken[0] < ($this->timeFactory->getTime() - 60*60*12) ||
191
-			$user->getLastLogin() > $splittedToken[0]) {
192
-			throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is expired'));
193
-		}
194
-
195
-		if (!hash_equals($splittedToken[1], $token)) {
196
-			throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid'));
197
-		}
198
-	}
199
-
200
-	/**
201
-	 * @param $message
202
-	 * @param array $additional
203
-	 * @return array
204
-	 */
205
-	private function error($message, array $additional=array()) {
206
-		return array_merge(array('status' => 'error', 'msg' => $message), $additional);
207
-	}
208
-
209
-	/**
210
-	 * @param array $data
211
-	 * @return array
212
-	 */
213
-	private function success($data = []) {
214
-		return array_merge($data, ['status'=>'success']);
215
-	}
216
-
217
-	/**
218
-	 * @PublicPage
219
-	 * @BruteForceProtection(action=passwordResetEmail)
220
-	 * @AnonRateThrottle(limit=10, period=300)
221
-	 *
222
-	 * @param string $user
223
-	 * @return JSONResponse
224
-	 */
225
-	public function email($user){
226
-		if ($this->config->getSystemValue('lost_password_link', '') !== '') {
227
-			return new JSONResponse($this->error($this->l10n->t('Password reset is disabled')));
228
-		}
229
-
230
-		\OCP\Util::emitHook(
231
-			'\OCA\Files_Sharing\API\Server2Server',
232
-			'preLoginNameUsedAsUserName',
233
-			['uid' => &$user]
234
-		);
235
-
236
-		// FIXME: use HTTP error codes
237
-		try {
238
-			$this->sendEmail($user);
239
-		} catch (\Exception $e){
240
-			$response = new JSONResponse($this->error($e->getMessage()));
241
-			$response->throttle();
242
-			return $response;
243
-		}
244
-
245
-		$response = new JSONResponse($this->success());
246
-		$response->throttle();
247
-		return $response;
248
-	}
249
-
250
-	/**
251
-	 * @PublicPage
252
-	 * @param string $token
253
-	 * @param string $userId
254
-	 * @param string $password
255
-	 * @param boolean $proceed
256
-	 * @return array
257
-	 */
258
-	public function setPassword($token, $userId, $password, $proceed) {
259
-		if ($this->config->getSystemValue('lost_password_link', '') !== '') {
260
-			return $this->error($this->l10n->t('Password reset is disabled'));
261
-		}
262
-
263
-		if ($this->encryptionManager->isEnabled() && !$proceed) {
264
-			$encryptionModules = $this->encryptionManager->getEncryptionModules();
265
-			foreach ($encryptionModules as $module) {
266
-				/** @var IEncryptionModule $instance */
267
-				$instance = call_user_func($module['callback']);
268
-				// this way we can find out whether per-user keys are used or a system wide encryption key
269
-				if ($instance->needDetailedAccessList()) {
270
-					return $this->error('', array('encryption' => true));
271
-				}
272
-			}
273
-		}
274
-
275
-		try {
276
-			$this->checkPasswordResetToken($token, $userId);
277
-			$user = $this->userManager->get($userId);
278
-
279
-			\OC_Hook::emit('\OC\Core\LostPassword\Controller\LostController', 'pre_passwordReset', array('uid' => $userId, 'password' => $password));
280
-
281
-			if (!$user->setPassword($password)) {
282
-				throw new \Exception();
283
-			}
284
-
285
-			\OC_Hook::emit('\OC\Core\LostPassword\Controller\LostController', 'post_passwordReset', array('uid' => $userId, 'password' => $password));
286
-
287
-			$this->config->deleteUserValue($userId, 'core', 'lostpassword');
288
-			@\OC::$server->getUserSession()->unsetMagicInCookie();
289
-		} catch (HintException $e){
290
-			return $this->error($e->getHint());
291
-		} catch (\Exception $e){
292
-			return $this->error($e->getMessage());
293
-		}
294
-
295
-		return $this->success(['user' => $userId]);
296
-	}
297
-
298
-	/**
299
-	 * @param string $input
300
-	 * @throws \Exception
301
-	 */
302
-	protected function sendEmail($input) {
303
-		$user = $this->findUserByIdOrMail($input);
304
-		$email = $user->getEMailAddress();
305
-
306
-		if (empty($email)) {
307
-			throw new \Exception(
308
-				$this->l10n->t('Could not send reset email because there is no email address for this username. Please contact your administrator.')
309
-			);
310
-		}
311
-
312
-		// Generate the token. It is stored encrypted in the database with the
313
-		// secret being the users' email address appended with the system secret.
314
-		// This makes the token automatically invalidate once the user changes
315
-		// their email address.
316
-		$token = $this->secureRandom->generate(
317
-			21,
318
-			ISecureRandom::CHAR_DIGITS.
319
-			ISecureRandom::CHAR_LOWER.
320
-			ISecureRandom::CHAR_UPPER
321
-		);
322
-		$tokenValue = $this->timeFactory->getTime() .':'. $token;
323
-		$encryptedValue = $this->crypto->encrypt($tokenValue, $email . $this->config->getSystemValue('secret'));
324
-		$this->config->setUserValue($user->getUID(), 'core', 'lostpassword', $encryptedValue);
325
-
326
-		$link = $this->urlGenerator->linkToRouteAbsolute('core.lost.resetform', array('userId' => $user->getUID(), 'token' => $token));
327
-
328
-		$emailTemplate = $this->mailer->createEMailTemplate('core.ResetPassword', [
329
-			'link' => $link,
330
-		]);
331
-
332
-		$emailTemplate->setSubject($this->l10n->t('%s password reset', [$this->defaults->getName()]));
333
-		$emailTemplate->addHeader();
334
-		$emailTemplate->addHeading($this->l10n->t('Password reset'));
335
-
336
-		$emailTemplate->addBodyText(
337
-			htmlspecialchars($this->l10n->t('Click the following button to reset your password. If you have not requested the password reset, then ignore this email.')),
338
-			$this->l10n->t('Click the following link to reset your password. If you have not requested the password reset, then ignore this email.')
339
-		);
340
-
341
-		$emailTemplate->addBodyButton(
342
-			htmlspecialchars($this->l10n->t('Reset your password')),
343
-			$link,
344
-			false
345
-		);
346
-		$emailTemplate->addFooter();
347
-
348
-		try {
349
-			$message = $this->mailer->createMessage();
350
-			$message->setTo([$email => $user->getUID()]);
351
-			$message->setFrom([$this->from => $this->defaults->getName()]);
352
-			$message->useTemplate($emailTemplate);
353
-			$this->mailer->send($message);
354
-		} catch (\Exception $e) {
355
-			throw new \Exception($this->l10n->t(
356
-				'Couldn\'t send reset email. Please contact your administrator.'
357
-			));
358
-		}
359
-	}
360
-
361
-	/**
362
-	 * @param string $input
363
-	 * @return IUser
364
-	 * @throws \InvalidArgumentException
365
-	 */
366
-	protected function findUserByIdOrMail($input) {
367
-		$user = $this->userManager->get($input);
368
-		if ($user instanceof IUser) {
369
-			if (!$user->isEnabled()) {
370
-				throw new \InvalidArgumentException($this->l10n->t('Couldn\'t send reset email. Please make sure your username is correct.'));
371
-			}
372
-
373
-			return $user;
374
-		}
375
-		$users = $this->userManager->getByEmail($input);
376
-		if (count($users) === 1) {
377
-			$user = $users[0];
378
-			if (!$user->isEnabled()) {
379
-				throw new \InvalidArgumentException($this->l10n->t('Couldn\'t send reset email. Please make sure your username is correct.'));
380
-			}
381
-
382
-			return $user;
383
-		}
384
-
385
-		throw new \InvalidArgumentException($this->l10n->t('Couldn\'t send reset email. Please make sure your username is correct.'));
386
-	}
61
+    /** @var IURLGenerator */
62
+    protected $urlGenerator;
63
+    /** @var IUserManager */
64
+    protected $userManager;
65
+    /** @var Defaults */
66
+    protected $defaults;
67
+    /** @var IL10N */
68
+    protected $l10n;
69
+    /** @var string */
70
+    protected $from;
71
+    /** @var IManager */
72
+    protected $encryptionManager;
73
+    /** @var IConfig */
74
+    protected $config;
75
+    /** @var ISecureRandom */
76
+    protected $secureRandom;
77
+    /** @var IMailer */
78
+    protected $mailer;
79
+    /** @var ITimeFactory */
80
+    protected $timeFactory;
81
+    /** @var ICrypto */
82
+    protected $crypto;
83
+
84
+    /**
85
+     * @param string $appName
86
+     * @param IRequest $request
87
+     * @param IURLGenerator $urlGenerator
88
+     * @param IUserManager $userManager
89
+     * @param Defaults $defaults
90
+     * @param IL10N $l10n
91
+     * @param IConfig $config
92
+     * @param ISecureRandom $secureRandom
93
+     * @param string $defaultMailAddress
94
+     * @param IManager $encryptionManager
95
+     * @param IMailer $mailer
96
+     * @param ITimeFactory $timeFactory
97
+     * @param ICrypto $crypto
98
+     */
99
+    public function __construct($appName,
100
+                                IRequest $request,
101
+                                IURLGenerator $urlGenerator,
102
+                                IUserManager $userManager,
103
+                                Defaults $defaults,
104
+                                IL10N $l10n,
105
+                                IConfig $config,
106
+                                ISecureRandom $secureRandom,
107
+                                $defaultMailAddress,
108
+                                IManager $encryptionManager,
109
+                                IMailer $mailer,
110
+                                ITimeFactory $timeFactory,
111
+                                ICrypto $crypto) {
112
+        parent::__construct($appName, $request);
113
+        $this->urlGenerator = $urlGenerator;
114
+        $this->userManager = $userManager;
115
+        $this->defaults = $defaults;
116
+        $this->l10n = $l10n;
117
+        $this->secureRandom = $secureRandom;
118
+        $this->from = $defaultMailAddress;
119
+        $this->encryptionManager = $encryptionManager;
120
+        $this->config = $config;
121
+        $this->mailer = $mailer;
122
+        $this->timeFactory = $timeFactory;
123
+        $this->crypto = $crypto;
124
+    }
125
+
126
+    /**
127
+     * Someone wants to reset their password:
128
+     *
129
+     * @PublicPage
130
+     * @NoCSRFRequired
131
+     *
132
+     * @param string $token
133
+     * @param string $userId
134
+     * @return TemplateResponse
135
+     */
136
+    public function resetform($token, $userId) {
137
+        if ($this->config->getSystemValue('lost_password_link', '') !== '') {
138
+            return new TemplateResponse('core', 'error', [
139
+                    'errors' => [['error' => $this->l10n->t('Password reset is disabled')]]
140
+                ],
141
+                'guest'
142
+            );
143
+        }
144
+
145
+        try {
146
+            $this->checkPasswordResetToken($token, $userId);
147
+        } catch (\Exception $e) {
148
+            return new TemplateResponse(
149
+                'core', 'error', [
150
+                    "errors" => array(array("error" => $e->getMessage()))
151
+                ],
152
+                'guest'
153
+            );
154
+        }
155
+
156
+        return new TemplateResponse(
157
+            'core',
158
+            'lostpassword/resetpassword',
159
+            array(
160
+                'link' => $this->urlGenerator->linkToRouteAbsolute('core.lost.setPassword', array('userId' => $userId, 'token' => $token)),
161
+            ),
162
+            'guest'
163
+        );
164
+    }
165
+
166
+    /**
167
+     * @param string $token
168
+     * @param string $userId
169
+     * @throws \Exception
170
+     */
171
+    protected function checkPasswordResetToken($token, $userId) {
172
+        $user = $this->userManager->get($userId);
173
+        if($user === null || !$user->isEnabled()) {
174
+            throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid'));
175
+        }
176
+
177
+        try {
178
+            $encryptedToken = $this->config->getUserValue($userId, 'core', 'lostpassword', null);
179
+            $mailAddress = !is_null($user->getEMailAddress()) ? $user->getEMailAddress() : '';
180
+            $decryptedToken = $this->crypto->decrypt($encryptedToken, $mailAddress.$this->config->getSystemValue('secret'));
181
+        } catch (\Exception $e) {
182
+            throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid'));
183
+        }
184
+
185
+        $splittedToken = explode(':', $decryptedToken);
186
+        if(count($splittedToken) !== 2) {
187
+            throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid'));
188
+        }
189
+
190
+        if ($splittedToken[0] < ($this->timeFactory->getTime() - 60*60*12) ||
191
+            $user->getLastLogin() > $splittedToken[0]) {
192
+            throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is expired'));
193
+        }
194
+
195
+        if (!hash_equals($splittedToken[1], $token)) {
196
+            throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid'));
197
+        }
198
+    }
199
+
200
+    /**
201
+     * @param $message
202
+     * @param array $additional
203
+     * @return array
204
+     */
205
+    private function error($message, array $additional=array()) {
206
+        return array_merge(array('status' => 'error', 'msg' => $message), $additional);
207
+    }
208
+
209
+    /**
210
+     * @param array $data
211
+     * @return array
212
+     */
213
+    private function success($data = []) {
214
+        return array_merge($data, ['status'=>'success']);
215
+    }
216
+
217
+    /**
218
+     * @PublicPage
219
+     * @BruteForceProtection(action=passwordResetEmail)
220
+     * @AnonRateThrottle(limit=10, period=300)
221
+     *
222
+     * @param string $user
223
+     * @return JSONResponse
224
+     */
225
+    public function email($user){
226
+        if ($this->config->getSystemValue('lost_password_link', '') !== '') {
227
+            return new JSONResponse($this->error($this->l10n->t('Password reset is disabled')));
228
+        }
229
+
230
+        \OCP\Util::emitHook(
231
+            '\OCA\Files_Sharing\API\Server2Server',
232
+            'preLoginNameUsedAsUserName',
233
+            ['uid' => &$user]
234
+        );
235
+
236
+        // FIXME: use HTTP error codes
237
+        try {
238
+            $this->sendEmail($user);
239
+        } catch (\Exception $e){
240
+            $response = new JSONResponse($this->error($e->getMessage()));
241
+            $response->throttle();
242
+            return $response;
243
+        }
244
+
245
+        $response = new JSONResponse($this->success());
246
+        $response->throttle();
247
+        return $response;
248
+    }
249
+
250
+    /**
251
+     * @PublicPage
252
+     * @param string $token
253
+     * @param string $userId
254
+     * @param string $password
255
+     * @param boolean $proceed
256
+     * @return array
257
+     */
258
+    public function setPassword($token, $userId, $password, $proceed) {
259
+        if ($this->config->getSystemValue('lost_password_link', '') !== '') {
260
+            return $this->error($this->l10n->t('Password reset is disabled'));
261
+        }
262
+
263
+        if ($this->encryptionManager->isEnabled() && !$proceed) {
264
+            $encryptionModules = $this->encryptionManager->getEncryptionModules();
265
+            foreach ($encryptionModules as $module) {
266
+                /** @var IEncryptionModule $instance */
267
+                $instance = call_user_func($module['callback']);
268
+                // this way we can find out whether per-user keys are used or a system wide encryption key
269
+                if ($instance->needDetailedAccessList()) {
270
+                    return $this->error('', array('encryption' => true));
271
+                }
272
+            }
273
+        }
274
+
275
+        try {
276
+            $this->checkPasswordResetToken($token, $userId);
277
+            $user = $this->userManager->get($userId);
278
+
279
+            \OC_Hook::emit('\OC\Core\LostPassword\Controller\LostController', 'pre_passwordReset', array('uid' => $userId, 'password' => $password));
280
+
281
+            if (!$user->setPassword($password)) {
282
+                throw new \Exception();
283
+            }
284
+
285
+            \OC_Hook::emit('\OC\Core\LostPassword\Controller\LostController', 'post_passwordReset', array('uid' => $userId, 'password' => $password));
286
+
287
+            $this->config->deleteUserValue($userId, 'core', 'lostpassword');
288
+            @\OC::$server->getUserSession()->unsetMagicInCookie();
289
+        } catch (HintException $e){
290
+            return $this->error($e->getHint());
291
+        } catch (\Exception $e){
292
+            return $this->error($e->getMessage());
293
+        }
294
+
295
+        return $this->success(['user' => $userId]);
296
+    }
297
+
298
+    /**
299
+     * @param string $input
300
+     * @throws \Exception
301
+     */
302
+    protected function sendEmail($input) {
303
+        $user = $this->findUserByIdOrMail($input);
304
+        $email = $user->getEMailAddress();
305
+
306
+        if (empty($email)) {
307
+            throw new \Exception(
308
+                $this->l10n->t('Could not send reset email because there is no email address for this username. Please contact your administrator.')
309
+            );
310
+        }
311
+
312
+        // Generate the token. It is stored encrypted in the database with the
313
+        // secret being the users' email address appended with the system secret.
314
+        // This makes the token automatically invalidate once the user changes
315
+        // their email address.
316
+        $token = $this->secureRandom->generate(
317
+            21,
318
+            ISecureRandom::CHAR_DIGITS.
319
+            ISecureRandom::CHAR_LOWER.
320
+            ISecureRandom::CHAR_UPPER
321
+        );
322
+        $tokenValue = $this->timeFactory->getTime() .':'. $token;
323
+        $encryptedValue = $this->crypto->encrypt($tokenValue, $email . $this->config->getSystemValue('secret'));
324
+        $this->config->setUserValue($user->getUID(), 'core', 'lostpassword', $encryptedValue);
325
+
326
+        $link = $this->urlGenerator->linkToRouteAbsolute('core.lost.resetform', array('userId' => $user->getUID(), 'token' => $token));
327
+
328
+        $emailTemplate = $this->mailer->createEMailTemplate('core.ResetPassword', [
329
+            'link' => $link,
330
+        ]);
331
+
332
+        $emailTemplate->setSubject($this->l10n->t('%s password reset', [$this->defaults->getName()]));
333
+        $emailTemplate->addHeader();
334
+        $emailTemplate->addHeading($this->l10n->t('Password reset'));
335
+
336
+        $emailTemplate->addBodyText(
337
+            htmlspecialchars($this->l10n->t('Click the following button to reset your password. If you have not requested the password reset, then ignore this email.')),
338
+            $this->l10n->t('Click the following link to reset your password. If you have not requested the password reset, then ignore this email.')
339
+        );
340
+
341
+        $emailTemplate->addBodyButton(
342
+            htmlspecialchars($this->l10n->t('Reset your password')),
343
+            $link,
344
+            false
345
+        );
346
+        $emailTemplate->addFooter();
347
+
348
+        try {
349
+            $message = $this->mailer->createMessage();
350
+            $message->setTo([$email => $user->getUID()]);
351
+            $message->setFrom([$this->from => $this->defaults->getName()]);
352
+            $message->useTemplate($emailTemplate);
353
+            $this->mailer->send($message);
354
+        } catch (\Exception $e) {
355
+            throw new \Exception($this->l10n->t(
356
+                'Couldn\'t send reset email. Please contact your administrator.'
357
+            ));
358
+        }
359
+    }
360
+
361
+    /**
362
+     * @param string $input
363
+     * @return IUser
364
+     * @throws \InvalidArgumentException
365
+     */
366
+    protected function findUserByIdOrMail($input) {
367
+        $user = $this->userManager->get($input);
368
+        if ($user instanceof IUser) {
369
+            if (!$user->isEnabled()) {
370
+                throw new \InvalidArgumentException($this->l10n->t('Couldn\'t send reset email. Please make sure your username is correct.'));
371
+            }
372
+
373
+            return $user;
374
+        }
375
+        $users = $this->userManager->getByEmail($input);
376
+        if (count($users) === 1) {
377
+            $user = $users[0];
378
+            if (!$user->isEnabled()) {
379
+                throw new \InvalidArgumentException($this->l10n->t('Couldn\'t send reset email. Please make sure your username is correct.'));
380
+            }
381
+
382
+            return $user;
383
+        }
384
+
385
+        throw new \InvalidArgumentException($this->l10n->t('Couldn\'t send reset email. Please make sure your username is correct.'));
386
+    }
387 387
 }
Please login to merge, or discard this patch.