let user update the private key password in case the login password was changed from outside
This commit is contained in:
parent
ac133e9faa
commit
d0a6fb1f2c
|
@ -167,6 +167,20 @@ class Application extends \OCP\AppFramework\App {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$container->registerService('SettingsController', function (IAppContainer $c) {
|
||||||
|
$server = $c->getServer();
|
||||||
|
return new \OCA\Encryption\Controller\SettingsController(
|
||||||
|
$c->getAppName(),
|
||||||
|
$server->getRequest(),
|
||||||
|
$server->getL10N($c->getAppName()),
|
||||||
|
$server->getUserManager(),
|
||||||
|
$server->getUserSession(),
|
||||||
|
$c->query('KeyManager'),
|
||||||
|
$c->query('Crypt'),
|
||||||
|
$c->query('Session')
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
$container->registerService('UserSetup',
|
$container->registerService('UserSetup',
|
||||||
function (IAppContainer $c) {
|
function (IAppContainer $c) {
|
||||||
$server = $c->getServer();
|
$server = $c->getServer();
|
||||||
|
|
|
@ -30,6 +30,11 @@ namespace OCA\Encryption\AppInfo;
|
||||||
'url' => '/ajax/adminRecovery',
|
'url' => '/ajax/adminRecovery',
|
||||||
'verb' => 'POST'
|
'verb' => 'POST'
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'name' => 'Settings#updatePrivateKeyPassword',
|
||||||
|
'url' => '/ajax/updatePrivateKeyPassword',
|
||||||
|
'verb' => 'POST'
|
||||||
|
],
|
||||||
[
|
[
|
||||||
'name' => 'Recovery#changeRecoveryPassword',
|
'name' => 'Recovery#changeRecoveryPassword',
|
||||||
'url' => '/ajax/changeRecoveryPassword',
|
'url' => '/ajax/changeRecoveryPassword',
|
||||||
|
|
|
@ -0,0 +1,144 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Björn Schießle <schiessle@owncloud.com>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
namespace OCA\Encryption\Controller;
|
||||||
|
|
||||||
|
|
||||||
|
use OCA\Encryption\Crypto\Crypt;
|
||||||
|
use OCA\Encryption\KeyManager;
|
||||||
|
use OCA\Encryption\Session;
|
||||||
|
use OCP\AppFramework\Controller;
|
||||||
|
use OCP\AppFramework\Http\DataResponse;
|
||||||
|
use OCP\IL10N;
|
||||||
|
use OCP\IRequest;
|
||||||
|
use OCP\IUserManager;
|
||||||
|
use OCP\IUserSession;
|
||||||
|
|
||||||
|
class SettingsController extends Controller {
|
||||||
|
|
||||||
|
/** @var IL10N */
|
||||||
|
private $l;
|
||||||
|
|
||||||
|
/** @var IUserManager */
|
||||||
|
private $userManager;
|
||||||
|
|
||||||
|
/** @var IUserSession */
|
||||||
|
private $userSession;
|
||||||
|
|
||||||
|
/** @var KeyManager */
|
||||||
|
private $keyManager;
|
||||||
|
|
||||||
|
/** @var Crypt */
|
||||||
|
private $crypt;
|
||||||
|
|
||||||
|
/** @var Session */
|
||||||
|
private $session;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $AppName
|
||||||
|
* @param IRequest $request
|
||||||
|
* @param IL10N $l10n
|
||||||
|
* @param IUserManager $userManager
|
||||||
|
* @param IUserSession $userSession
|
||||||
|
* @param KeyManager $keyManager
|
||||||
|
* @param Crypt $crypt
|
||||||
|
* @param Session $session
|
||||||
|
*/
|
||||||
|
public function __construct($AppName,
|
||||||
|
IRequest $request,
|
||||||
|
IL10N $l10n,
|
||||||
|
IUserManager $userManager,
|
||||||
|
IUserSession $userSession,
|
||||||
|
KeyManager $keyManager,
|
||||||
|
Crypt $crypt,
|
||||||
|
Session $session) {
|
||||||
|
parent::__construct($AppName, $request);
|
||||||
|
$this->l = $l10n;
|
||||||
|
$this->userSession = $userSession;
|
||||||
|
$this->userManager = $userManager;
|
||||||
|
$this->keyManager = $keyManager;
|
||||||
|
$this->crypt = $crypt;
|
||||||
|
$this->session = $session;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @NoAdminRequired
|
||||||
|
* @UseSession
|
||||||
|
*
|
||||||
|
* @param string $oldPassword
|
||||||
|
* @param string $newPassword
|
||||||
|
* @return DataResponse
|
||||||
|
*/
|
||||||
|
public function updatePrivateKeyPassword($oldPassword, $newPassword) {
|
||||||
|
$result = false;
|
||||||
|
$uid = $this->userSession->getUser()->getUID();
|
||||||
|
$errorMessage = $this->l->t('Could not update the private key password.');
|
||||||
|
|
||||||
|
//check if password is correct
|
||||||
|
$passwordCorrect = $this->userManager->checkPassword($uid, $newPassword);
|
||||||
|
|
||||||
|
if ($passwordCorrect !== false) {
|
||||||
|
$encryptedKey = $this->keyManager->getPrivateKey($uid);
|
||||||
|
$decryptedKey = $this->crypt->decryptPrivateKey($encryptedKey, $oldPassword);
|
||||||
|
|
||||||
|
if ($decryptedKey) {
|
||||||
|
$encryptedKey = $this->crypt->symmetricEncryptFileContent($decryptedKey, $newPassword);
|
||||||
|
$header = $this->crypt->generateHeader();
|
||||||
|
if ($encryptedKey) {
|
||||||
|
$this->keyManager->setPrivateKey($uid, $header . $encryptedKey);
|
||||||
|
$this->session->setPrivateKey($decryptedKey);
|
||||||
|
$result = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$result = false;
|
||||||
|
$errorMessage = $this->l->t(
|
||||||
|
'The old password was not correct, please try again.');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$result = false;
|
||||||
|
$errorMessage = $this->l->t(
|
||||||
|
'The current log-in password was not correct, please try again.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($result === true) {
|
||||||
|
$this->session->setStatus(Session::INIT_SUCCESSFUL);
|
||||||
|
return new DataResponse(
|
||||||
|
array(
|
||||||
|
'status' => 'success',
|
||||||
|
'data' => array(
|
||||||
|
'message' => (string) $this->l->t('Private key password successfully updated.'))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return new DataResponse(
|
||||||
|
array(
|
||||||
|
'data' => array
|
||||||
|
('message' => (string) $errorMessage)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,221 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @author Björn Schießle <schiessle@owncloud.com>
|
||||||
|
*
|
||||||
|
* @copyright Copyright (c) 2015, ownCloud, Inc.
|
||||||
|
* @license AGPL-3.0
|
||||||
|
*
|
||||||
|
* This code is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License, version 3,
|
||||||
|
* as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
namespace OCA\Encryption\Tests\Controller;
|
||||||
|
|
||||||
|
|
||||||
|
use OCA\Encryption\Controller\SettingsController;
|
||||||
|
use OCA\Encryption\Session;
|
||||||
|
use Test\TestCase;
|
||||||
|
|
||||||
|
class SettingsControllerTest extends TestCase {
|
||||||
|
|
||||||
|
/** @var SettingsController */
|
||||||
|
private $controller;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject */
|
||||||
|
private $requestMock;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject */
|
||||||
|
private $l10nMock;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject */
|
||||||
|
private $userManagerMock;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject */
|
||||||
|
private $userSessionMock;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject */
|
||||||
|
private $keyManagerMock;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject */
|
||||||
|
private $cryptMock;
|
||||||
|
|
||||||
|
/** @var \PHPUnit_Framework_MockObject_MockObject */
|
||||||
|
private $sessionMock;
|
||||||
|
|
||||||
|
public function setUp() {
|
||||||
|
|
||||||
|
parent::setUp();
|
||||||
|
|
||||||
|
$this->requestMock = $this->getMock('OCP\IRequest');
|
||||||
|
|
||||||
|
$this->l10nMock = $this->getMockBuilder('OCP\IL10N')
|
||||||
|
->disableOriginalConstructor()->getMock();
|
||||||
|
|
||||||
|
$this->l10nMock->expects($this->any())
|
||||||
|
->method('t')
|
||||||
|
->will($this->returnCallback(function($message) {
|
||||||
|
return $message; }));
|
||||||
|
|
||||||
|
$this->userManagerMock = $this->getMockBuilder('OCP\IUserManager')
|
||||||
|
->disableOriginalConstructor()->getMock();
|
||||||
|
|
||||||
|
$this->keyManagerMock = $this->getMockBuilder('OCA\Encryption\KeyManager')
|
||||||
|
->disableOriginalConstructor()->getMock();
|
||||||
|
|
||||||
|
$this->cryptMock = $this->getMockBuilder('OCA\Encryption\Crypto\Crypt')
|
||||||
|
->disableOriginalConstructor()->getMock();
|
||||||
|
|
||||||
|
$this->userSessionMock = $this->getMockBuilder('OCP\IUserSession')
|
||||||
|
->disableOriginalConstructor()
|
||||||
|
->setMethods([
|
||||||
|
'isLoggedIn',
|
||||||
|
'getUID',
|
||||||
|
'login',
|
||||||
|
'logout',
|
||||||
|
'setUser',
|
||||||
|
'getUser',
|
||||||
|
'canChangePassword'
|
||||||
|
])
|
||||||
|
->getMock();
|
||||||
|
|
||||||
|
$this->userSessionMock->expects($this->any())
|
||||||
|
->method('getUID')
|
||||||
|
->willReturn('testUser');
|
||||||
|
|
||||||
|
$this->userSessionMock->expects($this->any())
|
||||||
|
->method($this->anything())
|
||||||
|
->will($this->returnSelf());
|
||||||
|
|
||||||
|
$this->sessionMock = $this->getMockBuilder('OCA\Encryption\Session')
|
||||||
|
->disableOriginalConstructor()->getMock();
|
||||||
|
|
||||||
|
$this->controller = new SettingsController(
|
||||||
|
'encryption',
|
||||||
|
$this->requestMock,
|
||||||
|
$this->l10nMock,
|
||||||
|
$this->userManagerMock,
|
||||||
|
$this->userSessionMock,
|
||||||
|
$this->keyManagerMock,
|
||||||
|
$this->cryptMock,
|
||||||
|
$this->sessionMock
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test updatePrivateKeyPassword() if wrong new password was entered
|
||||||
|
*/
|
||||||
|
public function testUpdatePrivateKeyPasswordWrongNewPassword() {
|
||||||
|
|
||||||
|
$oldPassword = 'old';
|
||||||
|
$newPassword = 'new';
|
||||||
|
|
||||||
|
$this->userManagerMock
|
||||||
|
->expects($this->once())
|
||||||
|
->method('checkPassword')
|
||||||
|
->willReturn(false);
|
||||||
|
|
||||||
|
$result = $this->controller->updatePrivateKeyPassword($oldPassword, $newPassword);
|
||||||
|
|
||||||
|
$data = $result->getData();
|
||||||
|
|
||||||
|
$this->assertSame('The current log-in password was not correct, please try again.',
|
||||||
|
$data['data']['message']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test updatePrivateKeyPassword() if wrong old password was entered
|
||||||
|
*/
|
||||||
|
public function testUpdatePrivateKeyPasswordWrongOldPassword() {
|
||||||
|
|
||||||
|
$oldPassword = 'old';
|
||||||
|
$newPassword = 'new';
|
||||||
|
|
||||||
|
$this->userManagerMock
|
||||||
|
->expects($this->once())
|
||||||
|
->method('checkPassword')
|
||||||
|
->willReturn(true);
|
||||||
|
|
||||||
|
$this->cryptMock
|
||||||
|
->expects($this->once())
|
||||||
|
->method('decryptPrivateKey')
|
||||||
|
->willReturn(false);
|
||||||
|
|
||||||
|
$result = $this->controller->updatePrivateKeyPassword($oldPassword, $newPassword);
|
||||||
|
|
||||||
|
$data = $result->getData();
|
||||||
|
|
||||||
|
$this->assertSame('The old password was not correct, please try again.',
|
||||||
|
$data['data']['message']);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* test updatePrivateKeyPassword() with the correct old and new password
|
||||||
|
*/
|
||||||
|
public function testUpdatePrivateKeyPassword() {
|
||||||
|
|
||||||
|
$oldPassword = 'old';
|
||||||
|
$newPassword = 'new';
|
||||||
|
|
||||||
|
$this->userSessionMock
|
||||||
|
->expects($this->once())
|
||||||
|
->method('getUID')
|
||||||
|
->willReturn('testUser');
|
||||||
|
|
||||||
|
$this->userManagerMock
|
||||||
|
->expects($this->once())
|
||||||
|
->method('checkPassword')
|
||||||
|
->willReturn(true);
|
||||||
|
|
||||||
|
$this->cryptMock
|
||||||
|
->expects($this->once())
|
||||||
|
->method('decryptPrivateKey')
|
||||||
|
->willReturn('decryptedKey');
|
||||||
|
|
||||||
|
$this->cryptMock
|
||||||
|
->expects($this->once())
|
||||||
|
->method('symmetricEncryptFileContent')
|
||||||
|
->willReturn('encryptedKey');
|
||||||
|
|
||||||
|
$this->cryptMock
|
||||||
|
->expects($this->once())
|
||||||
|
->method('generateHeader')
|
||||||
|
->willReturn('header.');
|
||||||
|
|
||||||
|
// methods which must be called after successful changing the key password
|
||||||
|
$this->keyManagerMock
|
||||||
|
->expects($this->once())
|
||||||
|
->method('setPrivateKey')
|
||||||
|
->with($this->equalTo('testUser'), $this->equalTo('header.encryptedKey'));
|
||||||
|
|
||||||
|
$this->sessionMock
|
||||||
|
->expects($this->once())
|
||||||
|
->method('setPrivateKey')
|
||||||
|
->with($this->equalTo('decryptedKey'));
|
||||||
|
|
||||||
|
$this->sessionMock
|
||||||
|
->expects($this->once())
|
||||||
|
->method('setStatus')
|
||||||
|
->with($this->equalTo(Session::INIT_SUCCESSFUL));
|
||||||
|
|
||||||
|
$result = $this->controller->updatePrivateKeyPassword($oldPassword, $newPassword);
|
||||||
|
|
||||||
|
$data = $result->getData();
|
||||||
|
|
||||||
|
$this->assertSame('success', $data['status']);
|
||||||
|
|
||||||
|
$this->assertSame('Private key password successfully updated.',
|
||||||
|
$data['data']['message']);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue