diff --git a/apps/files_encryption/hooks/hooks.php b/apps/files_encryption/hooks/hooks.php
index 3a0a37c0a591..eadd2b64b80c 100644
--- a/apps/files_encryption/hooks/hooks.php
+++ b/apps/files_encryption/hooks/hooks.php
@@ -263,6 +263,19 @@ public static function setPassphrase($params) {
}
}
+ /**
+ * after password reset we create a new key pair for the user
+ *
+ * @param array $params
+ */
+ public static function postPasswordReset($params) {
+ $uid = $params['uid'];
+ $password = $params['password'];
+
+ $util = new Util(new \OC\Files\View(), $uid);
+ $util->replaceUserKeys($password);
+ }
+
/*
* check if files can be encrypted to every user.
*/
diff --git a/apps/files_encryption/lib/helper.php b/apps/files_encryption/lib/helper.php
index 53c380ab2b38..7a50ade82f39 100644
--- a/apps/files_encryption/lib/helper.php
+++ b/apps/files_encryption/lib/helper.php
@@ -70,6 +70,7 @@ public static function registerFilesystemHooks() {
\OCP\Util::connectHook('OC_Filesystem', 'delete', 'OCA\Encryption\Hooks', 'preDelete');
\OCP\Util::connectHook('OC_Filesystem', 'post_umount', 'OCA\Encryption\Hooks', 'postUmount');
\OCP\Util::connectHook('OC_Filesystem', 'umount', 'OCA\Encryption\Hooks', 'preUmount');
+ \OCP\Util::connectHook('\OC\Core\LostPassword\Controller\LostController', 'post_passwordReset', 'OCA\Encryption\Hooks', 'postPasswordReset');
}
/**
diff --git a/apps/files_encryption/lib/util.php b/apps/files_encryption/lib/util.php
index c8697ae7c80e..d12b003b2276 100644
--- a/apps/files_encryption/lib/util.php
+++ b/apps/files_encryption/lib/util.php
@@ -124,6 +124,18 @@ public function userKeysExists() {
}
}
+ /**
+ * create a new public/private key pair for the user
+ *
+ * @param string $password password for the private key
+ */
+ public function replaceUserKeys($password) {
+ $this->backupAllKeys('password_reset');
+ $this->view->unlink($this->publicKeyPath);
+ $this->view->unlink($this->privateKeyPath);
+ $this->setupServerSide($password);
+ }
+
/**
* Sets up user folders and keys for serverside encryption
*
diff --git a/core/application.php b/core/application.php
index 338018477583..c36ab559c272 100644
--- a/core/application.php
+++ b/core/application.php
@@ -10,13 +10,22 @@
namespace OC\Core;
+use OC\AppFramework\Utility\SimpleContainer;
use \OCP\AppFramework\App;
use OC\Core\LostPassword\Controller\LostController;
use OC\Core\User\UserController;
+use \OCP\Util;
+/**
+ * Class Application
+ *
+ * @package OC\Core
+ */
class Application extends App {
-
+ /**
+ * @param array $urlParams
+ */
public function __construct(array $urlParams=array()){
parent::__construct('core', $urlParams);
@@ -25,29 +34,56 @@ public function __construct(array $urlParams=array()){
/**
* Controllers
*/
- $container->registerService('LostController', function($c) {
+ $container->registerService('LostController', function(SimpleContainer $c) {
return new LostController(
$c->query('AppName'),
$c->query('Request'),
- $c->query('ServerContainer')->getURLGenerator(),
- $c->query('ServerContainer')->getUserManager(),
- new \OC_Defaults(),
- $c->query('ServerContainer')->getL10N('core'),
- $c->query('ServerContainer')->getConfig(),
- $c->query('ServerContainer')->getUserSession(),
- \OCP\Util::getDefaultEmailAddress('lostpassword-noreply'),
- \OC_App::isEnabled('files_encryption')
+ $c->query('URLGenerator'),
+ $c->query('UserManager'),
+ $c->query('Defaults'),
+ $c->query('L10N'),
+ $c->query('Config'),
+ $c->query('SecureRandom'),
+ $c->query('DefaultEmailAddress'),
+ $c->query('IsEncryptionEnabled')
);
});
- $container->registerService('UserController', function($c) {
+ $container->registerService('UserController', function(SimpleContainer $c) {
return new UserController(
$c->query('AppName'),
$c->query('Request'),
- $c->query('ServerContainer')->getUserManager(),
- new \OC_Defaults()
+ $c->query('UserManager'),
+ $c->query('Defaults')
);
});
- }
+ /**
+ * Core class wrappers
+ */
+ $container->registerService('IsEncryptionEnabled', function() {
+ return \OC_App::isEnabled('files_encryption');
+ });
+ $container->registerService('URLGenerator', function(SimpleContainer $c) {
+ return $c->query('ServerContainer')->getURLGenerator();
+ });
+ $container->registerService('UserManager', function(SimpleContainer $c) {
+ return $c->query('ServerContainer')->getUserManager();
+ });
+ $container->registerService('Config', function(SimpleContainer $c) {
+ return $c->query('ServerContainer')->getConfig();
+ });
+ $container->registerService('L10N', function(SimpleContainer $c) {
+ return $c->query('ServerContainer')->getL10N('core');
+ });
+ $container->registerService('SecureRandom', function(SimpleContainer $c) {
+ return $c->query('ServerContainer')->getSecureRandom();
+ });
+ $container->registerService('Defaults', function() {
+ return new \OC_Defaults;
+ });
+ $container->registerService('DefaultEmailAddress', function() {
+ return Util::getDefaultEmailAddress('lostpassword-noreply');
+ });
+ }
}
diff --git a/core/css/styles.css b/core/css/styles.css
index c45588cece66..2859399b59e8 100644
--- a/core/css/styles.css
+++ b/core/css/styles.css
@@ -353,6 +353,12 @@ input[type="submit"].enabled {
filter: alpha(opacity=60);
opacity: .6;
}
+/* overrides another !important statement that sets this to unreadable black */
+#body-login form .warning input[type="checkbox"]:hover+label,
+#body-login form .warning input[type="checkbox"]:focus+label,
+#body-login form .warning input[type="checkbox"]+label {
+ color: #fff !important;
+}
#body-login .update h2 {
font-size: 20px;
diff --git a/core/js/lostpassword.js b/core/js/lostpassword.js
index ad221cb30fc6..35173fd3d33f 100644
--- a/core/js/lostpassword.js
+++ b/core/js/lostpassword.js
@@ -8,19 +8,12 @@ OC.Lostpassword = {
+ ('
')
+ '
'
- + ''
- + t('core', 'Reset password')
- + '',
+ + '
',
resetErrorMsg : t('core', 'Password can not be changed. Please contact your administrator.'),
init : function() {
- if ($('#lost-password-encryption').length){
- $('#lost-password-encryption').click(OC.Lostpassword.sendLink);
- } else {
- $('#lost-password').click(OC.Lostpassword.sendLink);
- }
+ $('#lost-password').click(OC.Lostpassword.sendLink);
$('#reset-password #submit').click(OC.Lostpassword.resetPassword);
},
@@ -32,8 +25,7 @@ OC.Lostpassword = {
$.post(
OC.generateUrl('/lostpassword/email'),
{
- user : $('#user').val(),
- proceed: $('#encrypted-continue').attr('checked') ? 'Yes' : 'No'
+ user : $('#user').val()
},
OC.Lostpassword.sendLinkDone
);
@@ -84,11 +76,16 @@ OC.Lostpassword = {
$.post(
$('#password').parents('form').attr('action'),
{
- password : $('#password').val()
+ password : $('#password').val(),
+ proceed: $('#encrypted-continue').attr('checked') ? 'true' : 'false'
},
OC.Lostpassword.resetDone
);
}
+ if($('#encrypted-continue').attr('checked')) {
+ $('#reset-password #submit').hide();
+ $('#reset-password #float-spinner').removeClass('hidden');
+ }
},
resetDone : function(result){
@@ -126,7 +123,7 @@ OC.Lostpassword = {
getResetStatusNode : function (){
if (!$('#lost-password').length){
- $('
').insertAfter($('#submit'));
+ $('').insertBefore($('#reset-password fieldset'));
} else {
$('#lost-password').replaceWith($(''));
}
diff --git a/core/lostpassword/controller/lostcontroller.php b/core/lostpassword/controller/lostcontroller.php
index e4d51fde077b..aee4001ed370 100644
--- a/core/lostpassword/controller/lostcontroller.php
+++ b/core/lostpassword/controller/lostcontroller.php
@@ -9,68 +9,73 @@
namespace OC\Core\LostPassword\Controller;
use \OCP\AppFramework\Controller;
-use \OCP\AppFramework\Http\JSONResponse;
use \OCP\AppFramework\Http\TemplateResponse;
use \OCP\IURLGenerator;
use \OCP\IRequest;
use \OCP\IL10N;
use \OCP\IConfig;
-use \OCP\IUserSession;
-use \OC\Core\LostPassword\EncryptedDataException;
+use OCP\IUserManager;
+use OCP\Security\ISecureRandom;
+use \OC_Defaults;
+use OCP\Security\StringUtils;
+/**
+ * Class LostController
+ *
+ * Successfully changing a password will emit the post_passwordReset hook.
+ *
+ * @package OC\Core\LostPassword\Controller
+ */
class LostController extends Controller {
- /**
- * @var \OCP\IURLGenerator
- */
+ /** @var IURLGenerator */
protected $urlGenerator;
-
- /**
- * @var \OCP\IUserManager
- */
+ /** @var IUserManager */
protected $userManager;
-
- /**
- * @var \OC_Defaults
- */
+ /** @var OC_Defaults */
protected $defaults;
-
- /**
- * @var IL10N
- */
+ /** @var IL10N */
protected $l10n;
+ /** @var string */
protected $from;
+ /** @var bool */
protected $isDataEncrypted;
-
- /**
- * @var IConfig
- */
+ /** @var IConfig */
protected $config;
+ /** @var ISecureRandom */
+ protected $secureRandom;
/**
- * @var IUserSession
+ * @param string $appName
+ * @param IRequest $request
+ * @param IURLGenerator $urlGenerator
+ * @param IUserManager $userManager
+ * @param OC_Defaults $defaults
+ * @param IL10N $l10n
+ * @param IConfig $config
+ * @param ISecureRandom $secureRandom
+ * @param string $from
+ * @param string $isDataEncrypted
*/
- protected $userSession;
-
public function __construct($appName,
- IRequest $request,
- IURLGenerator $urlGenerator,
- $userManager,
- $defaults,
- IL10N $l10n,
- IConfig $config,
- IUserSession $userSession,
- $from,
- $isDataEncrypted) {
+ IRequest $request,
+ IURLGenerator $urlGenerator,
+ IUserManager $userManager,
+ OC_Defaults $defaults,
+ IL10N $l10n,
+ IConfig $config,
+ ISecureRandom $secureRandom,
+ $from,
+ $isDataEncrypted) {
parent::__construct($appName, $request);
$this->urlGenerator = $urlGenerator;
$this->userManager = $userManager;
$this->defaults = $defaults;
$this->l10n = $l10n;
+ $this->secureRandom = $secureRandom;
$this->from = $from;
$this->isDataEncrypted = $isDataEncrypted;
$this->config = $config;
- $this->userSession = $userSession;
}
/**
@@ -81,23 +86,31 @@ public function __construct($appName,
*
* @param string $token
* @param string $userId
+ * @return TemplateResponse
*/
public function resetform($token, $userId) {
return new TemplateResponse(
'core/lostpassword',
'resetpassword',
array(
- 'isEncrypted' => $this->isDataEncrypted,
- 'link' => $this->getLink('core.lost.setPassword', $userId, $token),
+ 'link' => $this->urlGenerator->linkToRouteAbsolute('core.lost.setPassword', array('userId' => $userId, 'token' => $token)),
),
'guest'
);
}
+ /**
+ * @param $message
+ * @param array $additional
+ * @return array
+ */
private function error($message, array $additional=array()) {
return array_merge(array('status' => 'error', 'msg' => $message), $additional);
}
+ /**
+ * @return array
+ */
private function success() {
return array('status'=>'success');
}
@@ -106,14 +119,12 @@ private function success() {
* @PublicPage
*
* @param string $user
- * @param bool $proceed
+ * @return array
*/
- public function email($user, $proceed){
+ public function email($user){
// FIXME: use HTTP error codes
try {
- $this->sendEmail($user, $proceed);
- } catch (EncryptedDataException $e){
- return $this->error('', array('encryption' => '1'));
+ $this->sendEmail($user);
} catch (\Exception $e){
return $this->error($e->getMessage());
}
@@ -121,15 +132,23 @@ public function email($user, $proceed){
return $this->success();
}
-
/**
* @PublicPage
+ * @param string $token
+ * @param string $userId
+ * @param string $password
+ * @param boolean $proceed
+ * @return array
*/
- public function setPassword($token, $userId, $password) {
+ public function setPassword($token, $userId, $password, $proceed) {
+ if ($this->isDataEncrypted && !$proceed){
+ return $this->error('', array('encryption' => true));
+ }
+
try {
$user = $this->userManager->get($userId);
- if (!$this->checkToken($userId, $token)) {
+ if (!StringUtils::equals($this->config->getUserValue($userId, 'owncloud', 'lostpassword'), $token)) {
throw new \Exception($this->l10n->t('Couldn\'t reset password because the token is invalid'));
}
@@ -137,9 +156,10 @@ public function setPassword($token, $userId, $password) {
throw new \Exception();
}
- // FIXME: should be added to the all config at some point
- \OC_Preferences::deleteKey($userId, 'owncloud', 'lostpassword');
- $this->userSession->unsetMagicInCookie();
+ \OC_Hook::emit('\OC\Core\LostPassword\Controller\LostController', 'post_passwordReset', array('uid' => $userId, 'password' => $password));
+
+ $this->config->deleteUserValue($userId, 'owncloud', 'lostpassword');
+ @\OC_User::unsetMagicInCookie();
} catch (\Exception $e){
return $this->error($e->getMessage());
@@ -148,36 +168,32 @@ public function setPassword($token, $userId, $password) {
return $this->success();
}
-
- protected function sendEmail($user, $proceed) {
- if ($this->isDataEncrypted && !$proceed){
- throw new EncryptedDataException();
- }
-
+ /**
+ * @param string $user
+ * @throws \Exception
+ */
+ protected function sendEmail($user) {
if (!$this->userManager->userExists($user)) {
- throw new \Exception(
- $this->l10n->t('Couldn\'t send reset email. Please make sure '.
- 'your username is correct.'));
+ throw new \Exception($this->l10n->t('Couldn\'t send reset email. Please make sure your username is correct.'));
}
- $token = hash('sha256', \OC_Util::generateRandomBytes(30));
-
- // Hash the token again to prevent timing attacks
- $this->config->setUserValue(
- $user, 'owncloud', 'lostpassword', hash('sha256', $token)
- );
-
$email = $this->config->getUserValue($user, 'settings', 'email');
if (empty($email)) {
throw new \Exception(
$this->l10n->t('Couldn\'t send reset email because there is no '.
- 'email address for this username. Please ' .
- 'contact your administrator.')
+ 'email address for this username. Please ' .
+ 'contact your administrator.')
);
}
- $link = $this->getLink('core.lost.resetform', $user, $token);
+ $token = $this->secureRandom->getMediumStrengthGenerator()->generate(21,
+ ISecureRandom::CHAR_DIGITS.
+ ISecureRandom::CHAR_LOWER.
+ ISecureRandom::CHAR_UPPER);
+ $this->config->setUserValue($user, 'owncloud', 'lostpassword', $token);
+
+ $link = $this->urlGenerator->linkToRouteAbsolute('core.lost.resetform', array('userId' => $user, 'token' => $token));
$tmpl = new \OC_Template('core/lostpassword', 'email');
$tmpl->assign('link', $link, false);
@@ -200,23 +216,4 @@ protected function sendEmail($user, $proceed) {
}
}
-
- protected function getLink($route, $user, $token){
- $parameters = array(
- 'token' => $token,
- 'userId' => $user
- );
- $link = $this->urlGenerator->linkToRoute($route, $parameters);
-
- return $this->urlGenerator->getAbsoluteUrl($link);
- }
-
-
- protected function checkToken($user, $token) {
- return $this->config->getUserValue(
- $user, 'owncloud', 'lostpassword'
- ) === hash('sha256', $token);
- }
-
-
}
diff --git a/core/lostpassword/css/resetpassword.css b/core/lostpassword/css/resetpassword.css
index 012af672d97c..29a7e8755379 100644
--- a/core/lostpassword/css/resetpassword.css
+++ b/core/lostpassword/css/resetpassword.css
@@ -2,6 +2,10 @@
position: relative;
}
+.text-center {
+ text-align: center;
+}
+
#password-icon {
top: 20px;
}
diff --git a/core/lostpassword/encrypteddataexception.php b/core/lostpassword/encrypteddataexception.php
deleted file mode 100644
index 99d19445b6c7..000000000000
--- a/core/lostpassword/encrypteddataexception.php
+++ /dev/null
@@ -1,14 +0,0 @@
-
-
diff --git a/core/lostpassword/templates/resetpassword.php b/core/lostpassword/templates/resetpassword.php
index 118fe7871166..498c692f12e7 100644
--- a/core/lostpassword/templates/resetpassword.php
+++ b/core/lostpassword/templates/resetpassword.php
@@ -1,4 +1,10 @@
-
+
+
-
diff --git a/tests/core/lostpassword/controller/lostcontrollertest.php b/tests/core/lostpassword/controller/lostcontrollertest.php
new file mode 100644
index 000000000000..5da9e5ce48d5
--- /dev/null
+++ b/tests/core/lostpassword/controller/lostcontrollertest.php
@@ -0,0 +1,195 @@
+
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Core\LostPassword\Controller;
+use OC\Core\Application;
+use OCP\AppFramework\Http\TemplateResponse;
+
+/**
+ * Class LostControllerTest
+ *
+ * @package OC\Core\LostPassword\Controller
+ */
+class LostControllerTest extends \PHPUnit_Framework_TestCase {
+
+ private $container;
+ /** @var LostController */
+ private $lostController;
+
+ protected function setUp() {
+ $app = new Application();
+ $this->container = $app->getContainer();
+ $this->container['AppName'] = 'core';
+ $this->container['Config'] = $this->getMockBuilder('\OCP\IConfig')
+ ->disableOriginalConstructor()->getMock();
+ $this->container['L10N'] = $this->getMockBuilder('\OCP\IL10N')
+ ->disableOriginalConstructor()->getMock();
+ $this->container['Defaults'] = $this->getMockBuilder('\OC_Defaults')
+ ->disableOriginalConstructor()->getMock();
+ $this->container['UserManager'] = $this->getMockBuilder('\OCP\IUserManager')
+ ->disableOriginalConstructor()->getMock();
+ $this->container['Config'] = $this->getMockBuilder('\OCP\IConfig')
+ ->disableOriginalConstructor()->getMock();
+ $this->container['URLGenerator'] = $this->getMockBuilder('\OCP\IURLGenerator')
+ ->disableOriginalConstructor()->getMock();
+ $this->container['SecureRandom'] = $this->getMockBuilder('\OCP\Security\ISecureRandom')
+ ->disableOriginalConstructor()->getMock();
+ $this->container['IsEncryptionEnabled'] = true;
+ $this->lostController = $this->container['LostController'];
+ }
+
+ public function testResetFormUnsuccessful() {
+ $userId = 'admin';
+ $token = 'MySecretToken';
+
+ $this->container['URLGenerator']
+ ->expects($this->once())
+ ->method('linkToRouteAbsolute')
+ ->with('core.lost.setPassword', array('userId' => 'admin', 'token' => 'MySecretToken'))
+ ->will($this->returnValue('https://ownCloud.com/index.php/lostpassword/'));
+
+ $response = $this->lostController->resetform($token, $userId);
+ $expectedResponse = new TemplateResponse('core/lostpassword',
+ 'resetpassword',
+ array(
+ 'link' => 'https://ownCloud.com/index.php/lostpassword/',
+ ),
+ 'guest');
+ $this->assertEquals($expectedResponse, $response);
+ }
+
+ public function testEmailUnsucessful() {
+ $existingUser = 'ExistingUser';
+ $nonExistingUser = 'NonExistingUser';
+ $this->container['UserManager']
+ ->expects($this->any())
+ ->method('userExists')
+ ->will($this->returnValueMap(array(
+ array(true, $existingUser),
+ array(false, $nonExistingUser)
+ )));
+ $this->container['L10N']
+ ->expects($this->any())
+ ->method('t')
+ ->will(
+ $this->returnValueMap(
+ array(
+ array('Couldn\'t send reset email. Please make sure your username is correct.', array(),
+ 'Couldn\'t send reset email. Please make sure your username is correct.'),
+
+ )
+ ));
+
+ // With a non existing user
+ $response = $this->lostController->email($nonExistingUser);
+ $expectedResponse = array('status' => 'error', 'msg' => 'Couldn\'t send reset email. Please make sure your username is correct.');
+ $this->assertSame($expectedResponse, $response);
+
+ // With no mail address
+ $this->container['Config']
+ ->expects($this->any())
+ ->method('getUserValue')
+ ->with($existingUser, 'settings', 'email')
+ ->will($this->returnValue(null));
+ $response = $this->lostController->email($existingUser);
+ $expectedResponse = array('status' => 'error', 'msg' => 'Couldn\'t send reset email. Please make sure your username is correct.');
+ $this->assertSame($expectedResponse, $response);
+ }
+
+ public function testEmailSuccessful() {
+ $randomToken = $this->container['SecureRandom'];
+ $this->container['SecureRandom']
+ ->expects($this->once())
+ ->method('generate')
+ ->with('21')
+ ->will($this->returnValue('ThisIsMaybeANotSoSecretToken!'));
+ $this->container['UserManager']
+ ->expects($this->once())
+ ->method('userExists')
+ ->with('ExistingUser')
+ ->will($this->returnValue(true));
+ $this->container['Config']
+ ->expects($this->once())
+ ->method('getUserValue')
+ ->with('ExistingUser', 'settings', 'email')
+ ->will($this->returnValue('test@example.com'));
+ $this->container['SecureRandom']
+ ->expects($this->once())
+ ->method('getMediumStrengthGenerator')
+ ->will($this->returnValue($randomToken));
+ $this->container['Config']
+ ->expects($this->once())
+ ->method('setUserValue')
+ ->with('ExistingUser', 'owncloud', 'lostpassword', 'ThisIsMaybeANotSoSecretToken!');
+ $this->container['URLGenerator']
+ ->expects($this->once())
+ ->method('linkToRouteAbsolute')
+ ->with('core.lost.resetform', array('userId' => 'ExistingUser', 'token' => 'ThisIsMaybeANotSoSecretToken!'))
+ ->will($this->returnValue('https://ownCloud.com/index.php/lostpassword/'));
+
+ $response = $this->lostController->email('ExistingUser');
+ $expectedResponse = array('status' => 'success');
+ $this->assertSame($expectedResponse, $response);
+ }
+
+ public function testSetPasswordUnsuccessful() {
+ $this->container['L10N']
+ ->expects($this->any())
+ ->method('t')
+ ->will(
+ $this->returnValueMap(
+ array(
+ array('Couldn\'t reset password because the token is invalid', array(),
+ 'Couldn\'t reset password because the token is invalid'),
+ )
+ ));
+ $this->container['Config']
+ ->expects($this->once())
+ ->method('getUserValue')
+ ->with('InvalidTokenUser', 'owncloud', 'lostpassword')
+ ->will($this->returnValue('TheOnlyAndOnlyOneTokenToResetThePassword'));
+
+ // With an invalid token
+ $userName = 'InvalidTokenUser';
+ $response = $this->lostController->setPassword('wrongToken', $userName, 'NewPassword', true);
+ $expectedResponse = array('status' => 'error', 'msg' => 'Couldn\'t reset password because the token is invalid');
+ $this->assertSame($expectedResponse, $response);
+
+ // With a valid token and no proceed
+ $response = $this->lostController->setPassword('TheOnlyAndOnlyOneTokenToResetThePassword!', $userName, 'NewPassword', false);
+ $expectedResponse = array('status' => 'error', 'msg' => '', 'encryption' => true);
+ $this->assertSame($expectedResponse, $response);
+ }
+
+ public function testSetPasswordSuccessful() {
+ $this->container['Config']
+ ->expects($this->once())
+ ->method('getUserValue')
+ ->with('ValidTokenUser', 'owncloud', 'lostpassword')
+ ->will($this->returnValue('TheOnlyAndOnlyOneTokenToResetThePassword'));
+ $user = $this->getMockBuilder('\OCP\IUser')
+ ->disableOriginalConstructor()->getMock();
+ $user->expects($this->once())
+ ->method('setPassword')
+ ->with('NewPassword')
+ ->will($this->returnValue(true));
+ $this->container['UserManager']
+ ->expects($this->once())
+ ->method('get')
+ ->with('ValidTokenUser')
+ ->will($this->returnValue($user));
+ $this->container['Config']
+ ->expects($this->once())
+ ->method('deleteUserValue')
+ ->with('ValidTokenUser', 'owncloud', 'lostpassword');
+
+ $response = $this->lostController->setPassword('TheOnlyAndOnlyOneTokenToResetThePassword', 'ValidTokenUser', 'NewPassword', true);
+ $expectedResponse = array('status' => 'success');
+ $this->assertSame($expectedResponse, $response);
+ }
+}
diff --git a/tests/phpunit-autotest.xml b/tests/phpunit-autotest.xml
index 3805bb1ac795..282f5477c303 100644
--- a/tests/phpunit-autotest.xml
+++ b/tests/phpunit-autotest.xml
@@ -9,6 +9,7 @@
lib/
settings/
+ core/
apps.php
diff --git a/tests/phpunit.xml.dist b/tests/phpunit.xml.dist
index 21c63ea0469a..95abe4739655 100644
--- a/tests/phpunit.xml.dist
+++ b/tests/phpunit.xml.dist
@@ -2,6 +2,8 @@
lib/
+ settings/
+ core/
apps.php
diff --git a/tests/settings/controller/mailsettingscontrollertest.php b/tests/settings/controller/mailsettingscontrollertest.php
index 6d3485d28e49..789b6ce8fb03 100644
--- a/tests/settings/controller/mailsettingscontrollertest.php
+++ b/tests/settings/controller/mailsettingscontrollertest.php
@@ -14,7 +14,7 @@
/**
* @package OC\Settings\Controller
*/
-class MailSettingscontrollerTest extends \PHPUnit_Framework_TestCase {
+class MailSettingsControllerTest extends \PHPUnit_Framework_TestCase {
private $container;