summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVincent Petry <pvince81@owncloud.com>2016-05-25 11:08:46 +0200
committerVincent Petry <pvince81@owncloud.com>2016-05-25 11:08:46 +0200
commit25e6026fa6f4c696fce13642ab57ff9c4f2f00d6 (patch)
tree82d36a95c5467cb6f26b260925da133f2e6ca272
parentb5f455f5ac31ea3a35b8adc70ae82d8e4d31920f (diff)
parentd06598081471896dde67a15bb02cae49d1548480 (diff)
downloadnextcloud-server-25e6026fa6f4c696fce13642ab57ff9c4f2f00d6.tar.gz
nextcloud-server-25e6026fa6f4c696fce13642ab57ff9c4f2f00d6.zip
Merge pull request #24735 from juliushaertl/passwordreset-invalid
Show error messages if a password reset link is invalid or expired
-rw-r--r--core/Controller/LostController.php50
-rw-r--r--tests/Core/Controller/LostControllerTest.php107
2 files changed, 139 insertions, 18 deletions
diff --git a/core/Controller/LostController.php b/core/Controller/LostController.php
index 0e0932b288b..61e29495608 100644
--- a/core/Controller/LostController.php
+++ b/core/Controller/LostController.php
@@ -121,6 +121,17 @@ class LostController extends Controller {
* @return TemplateResponse
*/
public function resetform($token, $userId) {
+ try {
+ $this->checkPasswordResetToken($token, $userId);
+ } catch (\Exception $e) {
+ return new TemplateResponse(
+ 'core', 'error', [
+ "errors" => array(array("error" => $e->getMessage()))
+ ],
+ 'guest'
+ );
+ }
+
return new TemplateResponse(
'core',
'lostpassword/resetpassword',
@@ -132,6 +143,29 @@ class LostController extends Controller {
}
/**
+ * @param string $userId
+ * @param string $userId
+ * @throws \Exception
+ */
+ private function checkPasswordResetToken($token, $userId) {
+ $user = $this->userManager->get($userId);
+
+ $splittedToken = explode(':', $this->config->getUserValue($userId, 'owncloud', 'lostpassword', null));
+ if(count($splittedToken) !== 2) {
+ throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid'));
+ }
+
+ if ($splittedToken[0] < ($this->timeFactory->getTime() - 60*60*12) ||
+ $user->getLastLogin() > $splittedToken[0]) {
+ throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is expired'));
+ }
+
+ if (!StringUtils::equals($splittedToken[1], $token)) {
+ throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid'));
+ }
+ }
+
+ /**
* @param $message
* @param array $additional
* @return array
@@ -178,22 +212,9 @@ class LostController extends Controller {
}
try {
+ $this->checkPasswordResetToken($token, $userId);
$user = $this->userManager->get($userId);
- $splittedToken = explode(':', $this->config->getUserValue($userId, 'owncloud', 'lostpassword', null));
- if(count($splittedToken) !== 2) {
- throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid'));
- }
-
- if ($splittedToken[0] < ($this->timeFactory->getTime() - 60*60*12) ||
- $user->getLastLogin() > $splittedToken[0]) {
- throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is expired'));
- }
-
- if (!StringUtils::equals($splittedToken[1], $token)) {
- throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid'));
- }
-
if (!$user->setPassword($password)) {
throw new \Exception();
}
@@ -202,7 +223,6 @@ class LostController extends Controller {
$this->config->deleteUserValue($userId, 'owncloud', 'lostpassword');
@\OC_User::unsetMagicInCookie();
-
} catch (\Exception $e){
return $this->error($e->getMessage());
}
diff --git a/tests/Core/Controller/LostControllerTest.php b/tests/Core/Controller/LostControllerTest.php
index ca63c3404eb..492a04bcfde 100644
--- a/tests/Core/Controller/LostControllerTest.php
+++ b/tests/Core/Controller/LostControllerTest.php
@@ -114,14 +114,115 @@ class LostControllerTest extends \PHPUnit_Framework_TestCase {
);
}
- public function testResetFormUnsuccessful() {
+ public function testResetFormInvalidToken() {
$userId = 'admin';
$token = 'MySecretToken';
+ $response = $this->lostController->resetform($token, $userId);
+ $expectedResponse = new TemplateResponse('core',
+ 'error',
+ [
+ 'errors' => [
+ ['error' => 'Couldn\'t reset password because the token is invalid'],
+ ]
+ ],
+ 'guest');
+ $this->assertEquals($expectedResponse, $response);
+ }
+
+ public function testResetFormInvalidTokenMatch() {
+ $this->config
+ ->expects($this->once())
+ ->method('getUserValue')
+ ->with('ValidTokenUser', 'owncloud', 'lostpassword', null)
+ ->will($this->returnValue('12345:TheOnlyAndOnlyOneTokenToResetThePassword'));
+ $user = $this->getMockBuilder('\OCP\IUser')
+ ->disableOriginalConstructor()->getMock();
+ $user
+ ->expects($this->once())
+ ->method('getLastLogin')
+ ->will($this->returnValue(12344));
+ $this->userManager
+ ->expects($this->once())
+ ->method('get')
+ ->with('ValidTokenUser')
+ ->will($this->returnValue($user));
+ $userId = 'ValidTokenUser';
+ $token = '12345:MySecretToken';
+ $response = $this->lostController->resetform($token, $userId);
+ $expectedResponse = new TemplateResponse('core',
+ 'error',
+ [
+ 'errors' => [
+ ['error' => 'Couldn\'t reset password because the token is invalid'],
+ ]
+ ],
+ 'guest');
+ $this->assertEquals($expectedResponse, $response);
+ }
+
+
+ public function testResetFormExpiredToken() {
+ $userId = 'ValidTokenUser';
+ $token = '12345:TheOnlyAndOnlyOneTokenToResetThePassword';
+ $user = $this->getMockBuilder('\OCP\IUser')
+ ->disableOriginalConstructor()->getMock();
+ $this->userManager
+ ->expects($this->once())
+ ->method('get')
+ ->with('ValidTokenUser')
+ ->will($this->returnValue($user));
+ $this->timeFactory
+ ->expects($this->once())
+ ->method('getTime')
+ ->will($this->returnValue(12345*60*60*12));
+ $userId = 'ValidTokenUser';
+ $token = 'TheOnlyAndOnlyOneTokenToResetThePassword';
+ $this->config
+ ->expects($this->once())
+ ->method('getUserValue')
+ ->with('ValidTokenUser', 'owncloud', 'lostpassword', null)
+ ->will($this->returnValue('12345:TheOnlyAndOnlyOneTokenToResetThePassword'));
+ $response = $this->lostController->resetform($token, $userId);
+ $expectedResponse = new TemplateResponse('core',
+ 'error',
+ [
+ 'errors' => [
+ ['error' => 'Couldn\'t reset password because the token is expired'],
+ ]
+ ],
+ 'guest');
+ $this->assertEquals($expectedResponse, $response);
+ }
+ public function testResetFormValidToken() {
+ $userId = 'ValidTokenUser';
+ $token = '12345:TheOnlyAndOnlyOneTokenToResetThePassword';
+ $user = $this->getMockBuilder('\OCP\IUser')
+ ->disableOriginalConstructor()->getMock();
+ $user
+ ->expects($this->once())
+ ->method('getLastLogin')
+ ->will($this->returnValue(12344));
+ $this->userManager
+ ->expects($this->once())
+ ->method('get')
+ ->with('ValidTokenUser')
+ ->will($this->returnValue($user));
+ $this->timeFactory
+ ->expects($this->once())
+ ->method('getTime')
+ ->will($this->returnValue(12348));
+ $userId = 'ValidTokenUser';
+ $token = 'TheOnlyAndOnlyOneTokenToResetThePassword';
+ $this->config
+ ->expects($this->once())
+ ->method('getUserValue')
+ ->with('ValidTokenUser', 'owncloud', 'lostpassword', null)
+ ->will($this->returnValue('12345:TheOnlyAndOnlyOneTokenToResetThePassword'));
$this->urlGenerator
->expects($this->once())
->method('linkToRouteAbsolute')
- ->with('core.lost.setPassword', array('userId' => 'admin', 'token' => 'MySecretToken'))
+ ->with('core.lost.setPassword', array('userId' => 'ValidTokenUser', 'token' => 'TheOnlyAndOnlyOneTokenToResetThePassword'))
->will($this->returnValue('https://ownCloud.com/index.php/lostpassword/'));
$response = $this->lostController->resetform($token, $userId);
@@ -329,7 +430,7 @@ class LostControllerTest extends \PHPUnit_Framework_TestCase {
->with('NewPassword')
->will($this->returnValue(true));
$this->userManager
- ->expects($this->once())
+ ->expects($this->exactly(2))
->method('get')
->with('ValidTokenUser')
->will($this->returnValue($user));