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',
|
||||
function (IAppContainer $c) {
|
||||
$server = $c->getServer();
|
||||
|
|
|
@ -30,6 +30,11 @@ namespace OCA\Encryption\AppInfo;
|
|||
'url' => '/ajax/adminRecovery',
|
||||
'verb' => 'POST'
|
||||
],
|
||||
[
|
||||
'name' => 'Settings#updatePrivateKeyPassword',
|
||||
'url' => '/ajax/updatePrivateKeyPassword',
|
||||
'verb' => 'POST'
|
||||
],
|
||||
[
|
||||
'name' => 'Recovery#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