Completed
Push — stable13 ( 329c21...e3a2b9 )
by Roeland
84:33
created
core/Controller/LostController.php 2 patches
Spacing   +10 added lines, -10 removed lines patch added patch discarded remove patch
@@ -170,7 +170,7 @@  discard block
 block discarded – undo
170 170
 	 */
171 171
 	protected function checkPasswordResetToken($token, $userId) {
172 172
 		$user = $this->userManager->get($userId);
173
-		if($user === null || !$user->isEnabled()) {
173
+		if ($user === null || !$user->isEnabled()) {
174 174
 			throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid'));
175 175
 		}
176 176
 
@@ -183,11 +183,11 @@  discard block
 block discarded – undo
183 183
 		}
184 184
 
185 185
 		$splittedToken = explode(':', $decryptedToken);
186
-		if(count($splittedToken) !== 2) {
186
+		if (count($splittedToken) !== 2) {
187 187
 			throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid'));
188 188
 		}
189 189
 
190
-		if ($splittedToken[0] < ($this->timeFactory->getTime() - 60*60*24*7) ||
190
+		if ($splittedToken[0] < ($this->timeFactory->getTime() - 60 * 60 * 24 * 7) ||
191 191
 			$user->getLastLogin() > $splittedToken[0]) {
192 192
 			throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is expired'));
193 193
 		}
@@ -202,7 +202,7 @@  discard block
 block discarded – undo
202 202
 	 * @param array $additional
203 203
 	 * @return array
204 204
 	 */
205
-	private function error($message, array $additional=array()) {
205
+	private function error($message, array $additional = array()) {
206 206
 		return array_merge(array('status' => 'error', 'msg' => $message), $additional);
207 207
 	}
208 208
 
@@ -222,7 +222,7 @@  discard block
 block discarded – undo
222 222
 	 * @param string $user
223 223
 	 * @return JSONResponse
224 224
 	 */
225
-	public function email($user){
225
+	public function email($user) {
226 226
 		if ($this->config->getSystemValue('lost_password_link', '') !== '') {
227 227
 			return new JSONResponse($this->error($this->l10n->t('Password reset is disabled')));
228 228
 		}
@@ -236,7 +236,7 @@  discard block
 block discarded – undo
236 236
 		// FIXME: use HTTP error codes
237 237
 		try {
238 238
 			$this->sendEmail($user);
239
-		} catch (\Exception $e){
239
+		} catch (\Exception $e) {
240 240
 			$response = new JSONResponse($this->error($e->getMessage()));
241 241
 			$response->throttle();
242 242
 			return $response;
@@ -286,9 +286,9 @@  discard block
 block discarded – undo
286 286
 
287 287
 			$this->config->deleteUserValue($userId, 'core', 'lostpassword');
288 288
 			@\OC::$server->getUserSession()->unsetMagicInCookie();
289
-		} catch (HintException $e){
289
+		} catch (HintException $e) {
290 290
 			return $this->error($e->getHint());
291
-		} catch (\Exception $e){
291
+		} catch (\Exception $e) {
292 292
 			return $this->error($e->getMessage());
293 293
 		}
294 294
 
@@ -319,8 +319,8 @@  discard block
 block discarded – undo
319 319
 			ISecureRandom::CHAR_LOWER.
320 320
 			ISecureRandom::CHAR_UPPER
321 321
 		);
322
-		$tokenValue = $this->timeFactory->getTime() .':'. $token;
323
-		$encryptedValue = $this->crypto->encrypt($tokenValue, $email . $this->config->getSystemValue('secret'));
322
+		$tokenValue = $this->timeFactory->getTime().':'.$token;
323
+		$encryptedValue = $this->crypto->encrypt($tokenValue, $email.$this->config->getSystemValue('secret'));
324 324
 		$this->config->setUserValue($user->getUID(), 'core', 'lostpassword', $encryptedValue);
325 325
 
326 326
 		$link = $this->urlGenerator->linkToRouteAbsolute('core.lost.resetform', array('userId' => $user->getUID(), 'token' => $token));
Please login to merge, or discard this patch.
Indentation   +325 added lines, -325 removed lines patch added patch discarded remove patch
@@ -58,329 +58,329 @@
 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*24*7) ||
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
-	 * @return array
211
-	 */
212
-	private function success() {
213
-		return array('status'=>'success');
214
-	}
215
-
216
-	/**
217
-	 * @PublicPage
218
-	 * @BruteForceProtection(action=passwordResetEmail)
219
-	 * @AnonRateThrottle(limit=10, period=300)
220
-	 *
221
-	 * @param string $user
222
-	 * @return JSONResponse
223
-	 */
224
-	public function email($user){
225
-		if ($this->config->getSystemValue('lost_password_link', '') !== '') {
226
-			return new JSONResponse($this->error($this->l10n->t('Password reset is disabled')));
227
-		}
228
-
229
-		\OCP\Util::emitHook(
230
-			'\OCA\Files_Sharing\API\Server2Server',
231
-			'preLoginNameUsedAsUserName',
232
-			['uid' => &$user]
233
-		);
234
-
235
-		// FIXME: use HTTP error codes
236
-		try {
237
-			$this->sendEmail($user);
238
-		} catch (\Exception $e){
239
-			$response = new JSONResponse($this->error($e->getMessage()));
240
-			$response->throttle();
241
-			return $response;
242
-		}
243
-
244
-		$response = new JSONResponse($this->success());
245
-		$response->throttle();
246
-		return $response;
247
-	}
248
-
249
-	/**
250
-	 * @PublicPage
251
-	 * @param string $token
252
-	 * @param string $userId
253
-	 * @param string $password
254
-	 * @param boolean $proceed
255
-	 * @return array
256
-	 */
257
-	public function setPassword($token, $userId, $password, $proceed) {
258
-		if ($this->config->getSystemValue('lost_password_link', '') !== '') {
259
-			return $this->error($this->l10n->t('Password reset is disabled'));
260
-		}
261
-
262
-		if ($this->encryptionManager->isEnabled() && !$proceed) {
263
-			$encryptionModules = $this->encryptionManager->getEncryptionModules();
264
-			foreach ($encryptionModules as $module) {
265
-				/** @var IEncryptionModule $instance */
266
-				$instance = call_user_func($module['callback']);
267
-				// this way we can find out whether per-user keys are used or a system wide encryption key
268
-				if ($instance->needDetailedAccessList()) {
269
-					return $this->error('', array('encryption' => true));
270
-				}
271
-			}
272
-		}
273
-
274
-		try {
275
-			$this->checkPasswordResetToken($token, $userId);
276
-			$user = $this->userManager->get($userId);
277
-
278
-			\OC_Hook::emit('\OC\Core\LostPassword\Controller\LostController', 'pre_passwordReset', array('uid' => $userId, 'password' => $password));
279
-
280
-			if (!$user->setPassword($password)) {
281
-				throw new \Exception();
282
-			}
283
-
284
-			\OC_Hook::emit('\OC\Core\LostPassword\Controller\LostController', 'post_passwordReset', array('uid' => $userId, 'password' => $password));
285
-
286
-			$this->config->deleteUserValue($userId, 'core', 'lostpassword');
287
-			@\OC::$server->getUserSession()->unsetMagicInCookie();
288
-		} catch (HintException $e){
289
-			return $this->error($e->getHint());
290
-		} catch (\Exception $e){
291
-			return $this->error($e->getMessage());
292
-		}
293
-
294
-		return $this->success();
295
-	}
296
-
297
-	/**
298
-	 * @param string $input
299
-	 * @throws \Exception
300
-	 */
301
-	protected function sendEmail($input) {
302
-		$user = $this->findUserByIdOrMail($input);
303
-		$email = $user->getEMailAddress();
304
-
305
-		if (empty($email)) {
306
-			throw new \Exception(
307
-				$this->l10n->t('Could not send reset email because there is no email address for this username. Please contact your administrator.')
308
-			);
309
-		}
310
-
311
-		// Generate the token. It is stored encrypted in the database with the
312
-		// secret being the users' email address appended with the system secret.
313
-		// This makes the token automatically invalidate once the user changes
314
-		// their email address.
315
-		$token = $this->secureRandom->generate(
316
-			21,
317
-			ISecureRandom::CHAR_DIGITS.
318
-			ISecureRandom::CHAR_LOWER.
319
-			ISecureRandom::CHAR_UPPER
320
-		);
321
-		$tokenValue = $this->timeFactory->getTime() .':'. $token;
322
-		$encryptedValue = $this->crypto->encrypt($tokenValue, $email . $this->config->getSystemValue('secret'));
323
-		$this->config->setUserValue($user->getUID(), 'core', 'lostpassword', $encryptedValue);
324
-
325
-		$link = $this->urlGenerator->linkToRouteAbsolute('core.lost.resetform', array('userId' => $user->getUID(), 'token' => $token));
326
-
327
-		$emailTemplate = $this->mailer->createEMailTemplate('core.ResetPassword', [
328
-			'link' => $link,
329
-		]);
330
-
331
-		$emailTemplate->setSubject($this->l10n->t('%s password reset', [$this->defaults->getName()]));
332
-		$emailTemplate->addHeader();
333
-		$emailTemplate->addHeading($this->l10n->t('Password reset'));
334
-
335
-		$emailTemplate->addBodyText(
336
-			$this->l10n->t('Click the following button to reset your password. If you have not requested the password reset, then ignore this email.'),
337
-			$this->l10n->t('Click the following link to reset your password. If you have not requested the password reset, then ignore this email.')
338
-		);
339
-
340
-		$emailTemplate->addBodyButton(
341
-			$this->l10n->t('Reset your password'),
342
-			$link,
343
-			false
344
-		);
345
-		$emailTemplate->addFooter();
346
-
347
-		try {
348
-			$message = $this->mailer->createMessage();
349
-			$message->setTo([$email => $user->getUID()]);
350
-			$message->setFrom([$this->from => $this->defaults->getName()]);
351
-			$message->useTemplate($emailTemplate);
352
-			$this->mailer->send($message);
353
-		} catch (\Exception $e) {
354
-			throw new \Exception($this->l10n->t(
355
-				'Couldn\'t send reset email. Please contact your administrator.'
356
-			));
357
-		}
358
-	}
359
-
360
-	/**
361
-	 * @param string $input
362
-	 * @return IUser
363
-	 * @throws \InvalidArgumentException
364
-	 */
365
-	protected function findUserByIdOrMail($input) {
366
-		$user = $this->userManager->get($input);
367
-		if ($user instanceof IUser) {
368
-			if (!$user->isEnabled()) {
369
-				throw new \InvalidArgumentException($this->l10n->t('Couldn\'t send reset email. Please make sure your username is correct.'));
370
-			}
371
-
372
-			return $user;
373
-		}
374
-		$users = $this->userManager->getByEmail($input);
375
-		if (count($users) === 1) {
376
-			$user = $users[0];
377
-			if (!$user->isEnabled()) {
378
-				throw new \InvalidArgumentException($this->l10n->t('Couldn\'t send reset email. Please make sure your username is correct.'));
379
-			}
380
-
381
-			return $user;
382
-		}
383
-
384
-		throw new \InvalidArgumentException($this->l10n->t('Couldn\'t send reset email. Please make sure your username is correct.'));
385
-	}
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*24*7) ||
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
+     * @return array
211
+     */
212
+    private function success() {
213
+        return array('status'=>'success');
214
+    }
215
+
216
+    /**
217
+     * @PublicPage
218
+     * @BruteForceProtection(action=passwordResetEmail)
219
+     * @AnonRateThrottle(limit=10, period=300)
220
+     *
221
+     * @param string $user
222
+     * @return JSONResponse
223
+     */
224
+    public function email($user){
225
+        if ($this->config->getSystemValue('lost_password_link', '') !== '') {
226
+            return new JSONResponse($this->error($this->l10n->t('Password reset is disabled')));
227
+        }
228
+
229
+        \OCP\Util::emitHook(
230
+            '\OCA\Files_Sharing\API\Server2Server',
231
+            'preLoginNameUsedAsUserName',
232
+            ['uid' => &$user]
233
+        );
234
+
235
+        // FIXME: use HTTP error codes
236
+        try {
237
+            $this->sendEmail($user);
238
+        } catch (\Exception $e){
239
+            $response = new JSONResponse($this->error($e->getMessage()));
240
+            $response->throttle();
241
+            return $response;
242
+        }
243
+
244
+        $response = new JSONResponse($this->success());
245
+        $response->throttle();
246
+        return $response;
247
+    }
248
+
249
+    /**
250
+     * @PublicPage
251
+     * @param string $token
252
+     * @param string $userId
253
+     * @param string $password
254
+     * @param boolean $proceed
255
+     * @return array
256
+     */
257
+    public function setPassword($token, $userId, $password, $proceed) {
258
+        if ($this->config->getSystemValue('lost_password_link', '') !== '') {
259
+            return $this->error($this->l10n->t('Password reset is disabled'));
260
+        }
261
+
262
+        if ($this->encryptionManager->isEnabled() && !$proceed) {
263
+            $encryptionModules = $this->encryptionManager->getEncryptionModules();
264
+            foreach ($encryptionModules as $module) {
265
+                /** @var IEncryptionModule $instance */
266
+                $instance = call_user_func($module['callback']);
267
+                // this way we can find out whether per-user keys are used or a system wide encryption key
268
+                if ($instance->needDetailedAccessList()) {
269
+                    return $this->error('', array('encryption' => true));
270
+                }
271
+            }
272
+        }
273
+
274
+        try {
275
+            $this->checkPasswordResetToken($token, $userId);
276
+            $user = $this->userManager->get($userId);
277
+
278
+            \OC_Hook::emit('\OC\Core\LostPassword\Controller\LostController', 'pre_passwordReset', array('uid' => $userId, 'password' => $password));
279
+
280
+            if (!$user->setPassword($password)) {
281
+                throw new \Exception();
282
+            }
283
+
284
+            \OC_Hook::emit('\OC\Core\LostPassword\Controller\LostController', 'post_passwordReset', array('uid' => $userId, 'password' => $password));
285
+
286
+            $this->config->deleteUserValue($userId, 'core', 'lostpassword');
287
+            @\OC::$server->getUserSession()->unsetMagicInCookie();
288
+        } catch (HintException $e){
289
+            return $this->error($e->getHint());
290
+        } catch (\Exception $e){
291
+            return $this->error($e->getMessage());
292
+        }
293
+
294
+        return $this->success();
295
+    }
296
+
297
+    /**
298
+     * @param string $input
299
+     * @throws \Exception
300
+     */
301
+    protected function sendEmail($input) {
302
+        $user = $this->findUserByIdOrMail($input);
303
+        $email = $user->getEMailAddress();
304
+
305
+        if (empty($email)) {
306
+            throw new \Exception(
307
+                $this->l10n->t('Could not send reset email because there is no email address for this username. Please contact your administrator.')
308
+            );
309
+        }
310
+
311
+        // Generate the token. It is stored encrypted in the database with the
312
+        // secret being the users' email address appended with the system secret.
313
+        // This makes the token automatically invalidate once the user changes
314
+        // their email address.
315
+        $token = $this->secureRandom->generate(
316
+            21,
317
+            ISecureRandom::CHAR_DIGITS.
318
+            ISecureRandom::CHAR_LOWER.
319
+            ISecureRandom::CHAR_UPPER
320
+        );
321
+        $tokenValue = $this->timeFactory->getTime() .':'. $token;
322
+        $encryptedValue = $this->crypto->encrypt($tokenValue, $email . $this->config->getSystemValue('secret'));
323
+        $this->config->setUserValue($user->getUID(), 'core', 'lostpassword', $encryptedValue);
324
+
325
+        $link = $this->urlGenerator->linkToRouteAbsolute('core.lost.resetform', array('userId' => $user->getUID(), 'token' => $token));
326
+
327
+        $emailTemplate = $this->mailer->createEMailTemplate('core.ResetPassword', [
328
+            'link' => $link,
329
+        ]);
330
+
331
+        $emailTemplate->setSubject($this->l10n->t('%s password reset', [$this->defaults->getName()]));
332
+        $emailTemplate->addHeader();
333
+        $emailTemplate->addHeading($this->l10n->t('Password reset'));
334
+
335
+        $emailTemplate->addBodyText(
336
+            $this->l10n->t('Click the following button to reset your password. If you have not requested the password reset, then ignore this email.'),
337
+            $this->l10n->t('Click the following link to reset your password. If you have not requested the password reset, then ignore this email.')
338
+        );
339
+
340
+        $emailTemplate->addBodyButton(
341
+            $this->l10n->t('Reset your password'),
342
+            $link,
343
+            false
344
+        );
345
+        $emailTemplate->addFooter();
346
+
347
+        try {
348
+            $message = $this->mailer->createMessage();
349
+            $message->setTo([$email => $user->getUID()]);
350
+            $message->setFrom([$this->from => $this->defaults->getName()]);
351
+            $message->useTemplate($emailTemplate);
352
+            $this->mailer->send($message);
353
+        } catch (\Exception $e) {
354
+            throw new \Exception($this->l10n->t(
355
+                'Couldn\'t send reset email. Please contact your administrator.'
356
+            ));
357
+        }
358
+    }
359
+
360
+    /**
361
+     * @param string $input
362
+     * @return IUser
363
+     * @throws \InvalidArgumentException
364
+     */
365
+    protected function findUserByIdOrMail($input) {
366
+        $user = $this->userManager->get($input);
367
+        if ($user instanceof IUser) {
368
+            if (!$user->isEnabled()) {
369
+                throw new \InvalidArgumentException($this->l10n->t('Couldn\'t send reset email. Please make sure your username is correct.'));
370
+            }
371
+
372
+            return $user;
373
+        }
374
+        $users = $this->userManager->getByEmail($input);
375
+        if (count($users) === 1) {
376
+            $user = $users[0];
377
+            if (!$user->isEnabled()) {
378
+                throw new \InvalidArgumentException($this->l10n->t('Couldn\'t send reset email. Please make sure your username is correct.'));
379
+            }
380
+
381
+            return $user;
382
+        }
383
+
384
+        throw new \InvalidArgumentException($this->l10n->t('Couldn\'t send reset email. Please make sure your username is correct.'));
385
+    }
386 386
 }
Please login to merge, or discard this patch.