mirror of
https://github.com/nextcloud/server.git
synced 2026-04-22 23:03:00 -04:00
fix set recovery key and implement change password
This commit is contained in:
parent
a98b7dbf6f
commit
4b4aeaa5b2
6 changed files with 108 additions and 30 deletions
|
|
@ -33,6 +33,11 @@ namespace OCA\Encryption\AppInfo;
|
|||
'name' => 'Recovery#userRecovery',
|
||||
'url' => '/ajax/userRecovery',
|
||||
'verb' => 'POST'
|
||||
],
|
||||
[
|
||||
'name' => 'Recovery#changeRecoveryPassword',
|
||||
'url' => '/ajax/changeRecoveryPassword',
|
||||
'verb' => 'POST'
|
||||
]
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ use OCP\IConfig;
|
|||
use OCP\IL10N;
|
||||
use OCP\IRequest;
|
||||
use OCP\JSON;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use OCP\AppFramework\Http\DataResponse;
|
||||
|
||||
class RecoveryController extends Controller {
|
||||
/**
|
||||
|
|
@ -62,32 +62,60 @@ class RecoveryController extends Controller {
|
|||
// Check if both passwords are the same
|
||||
if (empty($recoveryPassword)) {
|
||||
$errorMessage = $this->l->t('Missing recovery key password');
|
||||
return new JsonResponse(['data' => ['message' => $errorMessage]], 500);
|
||||
return new DataResponse(['data' => ['message' => $errorMessage]], 500);
|
||||
}
|
||||
|
||||
if (empty($confirmPassword)) {
|
||||
$errorMessage = $this->l->t('Please repeat the recovery key password');
|
||||
return new JsonResponse(['data' => ['message' => $errorMessage]], 500);
|
||||
return new DataResponse(['data' => ['message' => $errorMessage]], 500);
|
||||
}
|
||||
|
||||
if ($recoveryPassword !== $confirmPassword) {
|
||||
$errorMessage = $this->l->t('Repeated recovery key password does not match the provided recovery key password');
|
||||
return new JsonResponse(['data' => ['message' => $errorMessage]], 500);
|
||||
return new DataResponse(['data' => ['message' => $errorMessage]], 500);
|
||||
}
|
||||
|
||||
// Enable recoveryAdmin
|
||||
$recoveryKeyId = $this->config->getAppValue('encryption', 'recoveryKeyId');
|
||||
|
||||
if (isset($adminEnableRecovery) && $adminEnableRecovery === '1') {
|
||||
if ($this->recovery->enableAdminRecovery($recoveryKeyId, $recoveryPassword)) {
|
||||
return new JsonResponse(['data' => array('message' => $this->l->t('Recovery key successfully enabled'))]);
|
||||
if ($this->recovery->enableAdminRecovery($recoveryPassword)) {
|
||||
return new DataResponse(['status' =>'success', 'data' => array('message' => $this->l->t('Recovery key successfully enabled'))]);
|
||||
}
|
||||
return new JsonResponse(['data' => array('message' => $this->l->t('Could not enable recovery key. Please check your recovery key password!'))]);
|
||||
return new DataResponse(['data' => array('message' => $this->l->t('Could not enable recovery key. Please check your recovery key password!'))]);
|
||||
} elseif (isset($adminEnableRecovery) && $adminEnableRecovery === '0') {
|
||||
if ($this->recovery->disableAdminRecovery($recoveryKeyId, $recoveryPassword)) {
|
||||
return new JsonResponse(['data' => array('message' => $this->l->t('Recovery key successfully disabled'))]);
|
||||
if ($this->recovery->disableAdminRecovery($recoveryPassword)) {
|
||||
return new DataResponse(['data' => array('message' => $this->l->t('Recovery key successfully disabled'))]);
|
||||
}
|
||||
return new JsonResponse(['data' => array('message' => $this->l->t('Could not disable recovery key. Please check your recovery key password!'))]);
|
||||
return new DataResponse(['data' => array('message' => $this->l->t('Could not disable recovery key. Please check your recovery key password!'))]);
|
||||
}
|
||||
}
|
||||
|
||||
public function changeRecoveryPassword($newPassword, $oldPassword, $confirmPassword) {
|
||||
//check if both passwords are the same
|
||||
if (empty($oldPassword)) {
|
||||
$errorMessage = $this->l->t('Please provide the old recovery password');
|
||||
return new DataResponse(array('data' => array('message' => $errorMessage)));
|
||||
}
|
||||
|
||||
if (empty($newPassword)) {
|
||||
$errorMessage = $this->l->t('Please provide a new recovery password');
|
||||
return new DataResponse (array('data' => array('message' => $errorMessage)));
|
||||
}
|
||||
|
||||
if (empty($confirmPassword)) {
|
||||
$errorMessage = $this->l->t('Please repeat the new recovery password');
|
||||
return new DataResponse(array('data' => array('message' => $errorMessage)));
|
||||
}
|
||||
|
||||
if ($newPassword !== $confirmPassword) {
|
||||
$errorMessage = $this->l->t('Repeated recovery key password does not match the provided recovery key password');
|
||||
return new DataResponse(array('data' => array('message' => $errorMessage)));
|
||||
}
|
||||
|
||||
$result = $this->recovery->changeRecoveryKeyPassword($newPassword, $oldPassword);
|
||||
|
||||
if ($result) {
|
||||
return new DataResponse(array('status' => 'success' ,'data' => array('message' => $this->l->t('Password successfully changed.'))));
|
||||
} else {
|
||||
return new DataResponse(array('data' => array('message' => $this->l->t('Could not change the password. Maybe the old password was not correct.'))));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ $(document).ready(function(){
|
|||
var confirmNewPassword = $('#repeatedNewEncryptionRecoveryPassword').val();
|
||||
OC.msg.startSaving('#encryptionChangeRecoveryKey .msg');
|
||||
$.post(
|
||||
OC.filePath( 'encryption', 'ajax', 'changeRecoveryPassword.php' )
|
||||
OC.generateUrl('/apps/encryption/ajax/changeRecoveryPassword')
|
||||
, { oldPassword: oldRecoveryPassword, newPassword: newRecoveryPassword, confirmPassword: confirmNewPassword }
|
||||
, function( data ) {
|
||||
OC.msg.finishedSaving('#encryptionChangeRecoveryKey .msg', data);
|
||||
|
|
|
|||
|
|
@ -23,6 +23,6 @@
|
|||
namespace OCA\Encryption\Exceptions;
|
||||
|
||||
|
||||
class PrivateKeyMissingException extends GenericEncryptionException{
|
||||
class PrivateKeyMissingException extends \Exception{
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,6 +108,14 @@ class KeyManager {
|
|||
$this->config = $config;
|
||||
$this->recoveryKeyId = $this->config->getAppValue('encryption',
|
||||
'recoveryKeyId');
|
||||
if (empty($this->recoveryKeyId)) {
|
||||
$this->recoveryKeyId = 'recoveryKey_' . substr(md5(time()), 0, 8);
|
||||
$this->config->setAppValue('encryption',
|
||||
'recoveryKeyId',
|
||||
$this->recoveryKeyId);
|
||||
}
|
||||
|
||||
|
||||
$this->publicShareKeyId = $this->config->getAppValue('encryption',
|
||||
'publicShareKeyId');
|
||||
$this->log = $log;
|
||||
|
|
@ -171,7 +179,7 @@ class KeyManager {
|
|||
* @return bool
|
||||
*/
|
||||
public function checkRecoveryPassword($password) {
|
||||
$recoveryKey = $this->keyStorage->getSystemUserKey($this->recoveryKeyId);
|
||||
$recoveryKey = $this->keyStorage->getSystemUserKey($this->recoveryKeyId . '.privateKey');
|
||||
$decryptedRecoveryKey = $this->crypt->decryptPrivateKey($recoveryKey,
|
||||
$password);
|
||||
|
||||
|
|
@ -202,6 +210,26 @@ class KeyManager {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $uid
|
||||
* @param string $password
|
||||
* @param array $keyPair
|
||||
* @return bool
|
||||
*/
|
||||
public function setRecoveryKey($password, $keyPair) {
|
||||
// Save Public Key
|
||||
$this->keyStorage->setSystemUserKey($this->getRecoveryKeyId(). '.publicKey', $keyPair['publicKey']);
|
||||
|
||||
$encryptedKey = $this->crypt->symmetricEncryptFileContent($keyPair['privateKey'],
|
||||
$password);
|
||||
|
||||
if ($encryptedKey) {
|
||||
$this->setSystemPrivateKey($this->getRecoveryKeyId(), $encryptedKey);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $userId
|
||||
* @param $key
|
||||
|
|
@ -428,9 +456,19 @@ class KeyManager {
|
|||
}
|
||||
|
||||
/**
|
||||
* @param string $keyId
|
||||
* @return string returns openssl key
|
||||
*/
|
||||
public function getSystemPrivateKey() {
|
||||
return $this->keyStorage->getSystemUserKey($this->privateKeyId);
|
||||
public function getSystemPrivateKey($keyId) {
|
||||
return $this->keyStorage->getSystemUserKey($keyId . '.' . $this->privateKeyId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $keyId
|
||||
* @param string $key
|
||||
* @return string returns openssl key
|
||||
*/
|
||||
public function setSystemPrivateKey($keyId, $key) {
|
||||
return $this->keyStorage->setSystemUserKey($keyId . '.' . $this->privateKeyId, $key);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -88,24 +88,14 @@ class Recovery {
|
|||
* @param $password
|
||||
* @return bool
|
||||
*/
|
||||
public function enableAdminRecovery($recoveryKeyId, $password) {
|
||||
public function enableAdminRecovery($password) {
|
||||
$appConfig = $this->config;
|
||||
|
||||
if ($recoveryKeyId === null) {
|
||||
$recoveryKeyId = $this->random->getLowStrengthGenerator();
|
||||
$appConfig->setAppValue('encryption',
|
||||
'recoveryKeyId',
|
||||
$recoveryKeyId);
|
||||
}
|
||||
|
||||
$keyManager = $this->keyManager;
|
||||
|
||||
if (!$keyManager->recoveryKeyExists()) {
|
||||
$keyPair = $this->crypt->createKeyPair();
|
||||
|
||||
return $this->keyManager->storeKeyPair($this->user->getUID(),
|
||||
$password,
|
||||
$keyPair);
|
||||
$this->keyManager->setRecoveryKey($password, $keyPair);
|
||||
}
|
||||
|
||||
if ($keyManager->checkRecoveryPassword($password)) {
|
||||
|
|
@ -116,6 +106,23 @@ class Recovery {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* change recovery key id
|
||||
*
|
||||
* @param string $newPassword
|
||||
* @param string $oldPassword
|
||||
*/
|
||||
public function changeRecoveryKeyPassword($newPassword, $oldPassword) {
|
||||
$recoveryKey = $this->keyManager->getSystemPrivateKey($this->keyManager->getRecoveryKeyId());
|
||||
$decryptedRecoveryKey = $this->crypt->decryptPrivateKey($recoveryKey, $oldPassword);
|
||||
$encryptedRecoveryKey = $this->crypt->symmetricEncryptFileContent($decryptedRecoveryKey, $newPassword);
|
||||
if ($encryptedRecoveryKey) {
|
||||
$this->keyManager->setSystemPrivateKey($this->keyManager->getRecoveryKeyId(), $encryptedRecoveryKey);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $recoveryPassword
|
||||
* @return bool
|
||||
|
|
|
|||
Loading…
Reference in a new issue