зеркало из https://github.com/nextcloud/passman.git
implement re-encryption of the acl shared_key when changing vault password
This commit is contained in:
Родитель
6660985f88
Коммит
776ffe6ea1
|
@ -58,6 +58,7 @@ return [
|
|||
['name' => 'share#getPendingRequests', 'url' => '/api/v2/sharing/pending', 'verb' => 'GET'],
|
||||
['name' => 'share#deleteShareRequest', 'url' => '/api/v2/sharing/decline/{share_request_id}', 'verb' => 'DELETE'],
|
||||
['name' => 'share#getVaultItems', 'url' => '/api/v2/sharing/vault/{vault_guid}/get', 'verb' => 'GET'],
|
||||
['name' => 'share#getVaultAclEntries', 'url' => '/api/v2/sharing/vault/{vault_guid}/acl', 'verb' => 'GET'],
|
||||
['name' => 'share#createPublicShare', 'url' => '/api/v2/sharing/public', 'verb' => 'POST'],
|
||||
['name' => 'share#getPublicCredentialData', 'url' => '/api/v2/sharing/credential/{credential_guid}/public', 'verb' => 'GET'],
|
||||
['name' => 'share#unshareCredential', 'url' => '/api/v2/sharing/credential/{item_guid}', 'verb' => 'DELETE'],
|
||||
|
@ -67,6 +68,7 @@ return [
|
|||
['name' => 'share#uploadFile', 'url' => '/api/v2/sharing/credential/{item_guid}/file', 'verb' => 'POST'],
|
||||
['name' => 'share#getFile', 'url' => '/api/v2/sharing/credential/{item_guid}/file/{file_guid}', 'verb' => 'GET'],
|
||||
['name' => 'share#updateSharedCredentialACL', 'url' => '/api/v2/sharing/credential/{item_guid}/acl', 'verb' => 'PATCH'],
|
||||
['name' => 'share#updateSharedCredentialACLSharedKey', 'url' => '/api/v2/sharing/credential/{item_guid}/acl/shared_key', 'verb' => 'PATCH'],
|
||||
['name' => 'internal#getAppVersion', 'url' => '/api/v2/version', 'verb' => 'GET'],
|
||||
|
||||
//Settings
|
||||
|
|
|
@ -368,6 +368,20 @@ class ShareController extends ApiController {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains the list of acl entries for credentials shared with this vault
|
||||
*
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function getVaultAclEntries($vault_guid) {
|
||||
try {
|
||||
return new JSONResponse($this->shareService->getVaultAclList($this->userId->getUID(), $vault_guid));
|
||||
} catch (\Exception $ex) {
|
||||
return new NotFoundResponse();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $share_request_id
|
||||
* @return JSONResponse
|
||||
|
@ -557,4 +571,18 @@ class ShareController extends ApiController {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $item_guid
|
||||
* @param $shared_key
|
||||
* @return JSONResponse
|
||||
* @NoAdminRequired
|
||||
* @NoCSRFRequired
|
||||
*/
|
||||
public function updateSharedCredentialACLSharedKey($item_guid, $shared_key) {
|
||||
/** @var SharingACL $acl */
|
||||
$acl = $this->shareService->getACL($this->userId->getUID(), $item_guid);
|
||||
$acl->setSharedKey($shared_key);
|
||||
return new JSONResponse($this->shareService->updateCredentialACL($acl)->jsonSerialize());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -78,13 +78,12 @@
|
|||
}
|
||||
_credential.tags_raw = _credential.tags;
|
||||
} catch (e) {
|
||||
|
||||
NotificationService.showNotification($translate.instant('error.decrypt'), 5000);
|
||||
console.error(e);
|
||||
//$rootScope.$broadcast('logout');
|
||||
//SettingsService.setSetting('defaultVaultPass', null);
|
||||
//.setSetting('defaultVault', null);
|
||||
//$location.path('/')
|
||||
|
||||
}
|
||||
_credentials[i] = _credential;
|
||||
}
|
||||
|
|
|
@ -250,8 +250,10 @@
|
|||
vault.private_sharing_key = EncryptService.decryptString(angular.copy(vault.private_sharing_key), oldVaultPass);
|
||||
vault.private_sharing_key = EncryptService.encryptString(vault.private_sharing_key, newVaultPass);
|
||||
VaultService.updateSharingKeys(vault).then(function () {
|
||||
$rootScope.$broadcast('logout');
|
||||
NotificationService.showNotification($translate.instant('login.new.pass'), 5000);
|
||||
VaultService.reEncryptACLSharingKeys(vault, oldVaultPass, newVaultPass, EncryptService).then(function () {
|
||||
$rootScope.$broadcast('logout');
|
||||
NotificationService.showNotification($translate.instant('login.new.pass'), 5000);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -259,11 +261,12 @@
|
|||
if (_selected_credentials[index].shared_key) {
|
||||
// only re-encrypt the shared key, if the credential is shared and not encrypted with the vault key like default credentials
|
||||
CredentialService.getCredential(_selected_credentials[index].guid).then((function (credential) {
|
||||
let decrypted_shared_key = EncryptService.decryptString(angular.copy(credential.shared_key), oldVaultPass);
|
||||
credential.set_share_key = true;
|
||||
credential.skip_revision = true;
|
||||
credential.shared_key = EncryptService.encryptString(decrypted_shared_key, newVaultPass);
|
||||
CredentialService.updateCredential(credential, true).then(next_credential_callback);
|
||||
const decrypted_shared_key = EncryptService.decryptString(angular.copy(credential.shared_key), oldVaultPass);
|
||||
let _credential = angular.copy(credential);
|
||||
_credential.set_share_key = true;
|
||||
_credential.skip_revision = true;
|
||||
_credential.shared_key = EncryptService.encryptString(decrypted_shared_key, newVaultPass);
|
||||
CredentialService.updateCredential(_credential, true).then(next_credential_callback);
|
||||
}));
|
||||
} else {
|
||||
CredentialService.reencryptCredential(_selected_credentials[index].guid, oldVaultPass, newVaultPass).progress(function (data) {
|
||||
|
|
|
@ -141,13 +141,13 @@
|
|||
}
|
||||
} catch (e) {
|
||||
console.error('Error decrypting credential:', credential);
|
||||
console.error('Error decrypting credential field:', field);
|
||||
throw e;
|
||||
}
|
||||
try {
|
||||
credential[field] = JSON.parse(field_decrypted_value);
|
||||
} catch (e) {
|
||||
console.warn('Field' + field + ' in ' + credential.label + ' could not be parsed! Value:' + fieldValue);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -122,6 +122,30 @@
|
|||
}
|
||||
});
|
||||
},
|
||||
reEncryptACLSharingKeys: function (vault, oldVaultPass, newVaultPass, EncryptService) {
|
||||
const queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/vault/' + vault.guid + '/acl');
|
||||
return $http.get(queryUrl).then(function (response) {
|
||||
if (response.data) {
|
||||
const updateACLSharingKey = function (index) {
|
||||
let acl = response.data[index];
|
||||
const decrypted_shared_key = EncryptService.decryptString(angular.copy(acl.shared_key), oldVaultPass);
|
||||
acl.shared_key = EncryptService.encryptString(decrypted_shared_key, newVaultPass);
|
||||
|
||||
const patchUrl = OC.generateUrl('apps/passman/api/v2/sharing/credential/' + acl.item_guid + '/acl/shared_key');
|
||||
$http.patch(patchUrl, {
|
||||
shared_key: acl.shared_key
|
||||
}).then(function () {
|
||||
if (index < response.data.length - 1) {
|
||||
return updateACLSharingKey(index + 1);
|
||||
}
|
||||
});
|
||||
};
|
||||
if (response.data[0]) {
|
||||
return updateACLSharingKey(0);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
deleteVault: function (vault, file_ids) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/vaults/' + vault.guid);
|
||||
var deleteFilesUrl = OC.generateUrl('apps/passman/api/v2/files/delete');
|
||||
|
|
|
@ -273,6 +273,17 @@ class ShareService {
|
|||
return $this->sharingACL->getCredentialAclList($item_guid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the access control list by vault guid
|
||||
*
|
||||
* @param string $user_id
|
||||
* @param string $vault_guid
|
||||
* @return Entity[]
|
||||
*/
|
||||
public function getVaultAclList(string $user_id, string $vault_guid) {
|
||||
return $this->sharingACL->getVaultEntries($user_id, $vault_guid);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $item_guid
|
||||
* @return Entity[]
|
||||
|
|
Загрузка…
Ссылка в новой задаче