Downloading shared files works

This commit is contained in:
brantje 2016-10-05 16:58:19 +02:00
parent 75dd4cfe34
commit e6aef00193
No known key found for this signature in database
GPG key ID: 5FF1D117F918687F
12 changed files with 139 additions and 21 deletions

View file

@ -62,6 +62,7 @@ return [
['name' => 'share#unshareCredential', 'url' => '/api/v2/sharing/credential/{item_guid}', 'verb' => 'DELETE'], ['name' => 'share#unshareCredential', 'url' => '/api/v2/sharing/credential/{item_guid}', 'verb' => 'DELETE'],
['name' => 'share#getRevisions', 'url' => '/api/v2/sharing/credential/{item_guid}/revisions', 'verb' => 'GET'], ['name' => 'share#getRevisions', 'url' => '/api/v2/sharing/credential/{item_guid}/revisions', 'verb' => 'GET'],
['name' => 'share#getItemAcl', 'url' => '/api/v2/sharing/credential/{item_guid}/acl', 'verb' => 'GET'], ['name' => 'share#getItemAcl', 'url' => '/api/v2/sharing/credential/{item_guid}/acl', 'verb' => 'GET'],
['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#updateSharedCredentialACL', 'url' => '/api/v2/sharing/credential/{item_guid}/acl', 'verb' => 'PATCH'],
//Internal API //Internal API

View file

@ -56,20 +56,20 @@ class FileController extends ApiController {
return $this->fileService->deleteFile($file_id, $this->userId); return $this->fileService->deleteFile($file_id, $this->userId);
} }
public function updateFile($file_id, $data, $filename, $mimetype, $size){ public function updateFile($file_id, $file_data, $filename, $mimetype, $size){
try{ try{
$file = $this->fileService->getFile($file_id, $this->userId); $file = $this->fileService->getFile($file_id, $this->userId);
} catch (DoesNotExistException $doesNotExistException){ } catch (DoesNotExistException $doesNotExistException){
} }
if($file){ if($file){
if($data) { if($file_data) {
$file->setFileData($data); $file->setFileData($file_data);
} }
if($filename) { if($filename) {
$file->setFilename($filename); $file->setFilename($filename);
} }
if($filename || $data){ if($filename || $file_data){
$this->fileService->updateFile($file); $this->fileService->updateFile($file);
} }
} }

View file

@ -16,6 +16,7 @@ use OCA\Passman\Db\ShareRequest;
use OCA\Passman\Db\SharingACL; use OCA\Passman\Db\SharingACL;
use OCA\Passman\Db\Vault; use OCA\Passman\Db\Vault;
use OCA\Passman\Service\CredentialService; use OCA\Passman\Service\CredentialService;
use OCA\Passman\Service\FileService;
use OCA\Passman\Service\NotificationService; use OCA\Passman\Service\NotificationService;
use OCA\Passman\Service\ShareService; use OCA\Passman\Service\ShareService;
use OCP\AppFramework\Db\DoesNotExistException; use OCP\AppFramework\Db\DoesNotExistException;
@ -23,6 +24,8 @@ use OCP\AppFramework\Http\NotFoundResponse;
use OCP\IRequest; use OCP\IRequest;
use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\ApiController; use OCP\AppFramework\ApiController;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;
use OCP\IGroup; use OCP\IGroup;
use OCP\IGroupManager; use OCP\IGroupManager;
@ -43,6 +46,7 @@ class ShareController extends ApiController {
private $shareService; private $shareService;
private $credentialService; private $credentialService;
private $notificationService; private $notificationService;
private $fileService;
private $limit = 50; private $limit = 50;
private $offset = 0; private $offset = 0;
@ -56,7 +60,8 @@ class ShareController extends ApiController {
VaultService $vaultService, VaultService $vaultService,
ShareService $shareService, ShareService $shareService,
CredentialService $credentialService, CredentialService $credentialService,
NotificationService $notificationService NotificationService $notificationService,
FileService $fileService
) { ) {
parent::__construct($AppName, $request); parent::__construct($AppName, $request);
@ -68,6 +73,7 @@ class ShareController extends ApiController {
$this->shareService = $shareService; $this->shareService = $shareService;
$this->credentialService = $credentialService; $this->credentialService = $credentialService;
$this->notificationService = $notificationService; $this->notificationService = $notificationService;
$this->fileService = $fileService;
} }
/** /**
@ -385,6 +391,11 @@ class ShareController extends ApiController {
} }
} }
/**
* @param $item_guid
* @return JSONResponse
* @NoAdminRequired
*/
public function getItemAcl($item_guid) { public function getItemAcl($item_guid) {
$acl = $this->shareService->getCredentialAclList($item_guid); $acl = $this->shareService->getCredentialAclList($item_guid);
$pending = $this->shareService->getCredentialPendingAclList($item_guid); $pending = $this->shareService->getCredentialPendingAclList($item_guid);
@ -404,6 +415,33 @@ class ShareController extends ApiController {
} }
} }
/**
* @param $credential_guid
* @param $file_guid
* @NoAdminRequired
*/
public function getFile($item_guid, $file_guid){
try {
$credential = $this->credentialService->getCredentialByGUID($item_guid);
} catch (DoesNotExistException $e){
return new JSONResponse(array());
}
$acl = $this->shareService->getACL($this->userId->getUID(), $credential->getGuid());
if (!$acl->hasPermission(SharingACL::FILES)){
return new NotFoundResponse();
} else {
return $this->fileService->getFileByGuid($file_guid);
}
}
/**
* @param $item_guid
* @param $user_id
* @param $permission
* @return JSONResponse
* @NoAdminRequired
*/
public function updateSharedCredentialACL($item_guid, $user_id, $permission) { public function updateSharedCredentialACL($item_guid, $user_id, $permission) {
try { try {
$credential = $this->credentialService->getCredentialByGUID($item_guid); $credential = $this->credentialService->getCredentialByGUID($item_guid);

View file

@ -316,17 +316,43 @@ angular.module('passmanApp')
}); });
$scope.downloadFile = function (file) { $scope.downloadFile = function (credential, file) {
FileService.getFile(file).then(function (result) { console.log(credential, file);
var file_data = EncryptService.decryptString(result.file_data); var callback = function(result){
var key = null;
if(!result.hasOwnProperty('file_data')){
NotificationService.showNotification('Error downloading file, you probably don\'t have enough permissions', 5000);
return;
}
if(!credential.hasOwnProperty('acl') && credential.hasOwnProperty('shared_key')){
key = EncryptService.decryptString(angular.copy(credential.shared_key));
}
if(credential.hasOwnProperty('acl')){
key = EncryptService.decryptString(angular.copy(credential.acl.shared_key));
}
var file_data = EncryptService.decryptString(result.file_data, key);
var uriContent = FileService.dataURItoBlob(file_data, file.mimetype), a = document.createElement("a"); var uriContent = FileService.dataURItoBlob(file_data, file.mimetype), a = document.createElement("a");
a.style = "display: none"; a.style = "display: none";
a.id= 'downloadLink';
a.href = uriContent; a.href = uriContent;
a.download = escapeHTML(file.filename); a.download = escapeHTML(file.filename);
document.body.appendChild(a); jQuery('.detailsView').append(a);
a.click(); a.click();
window.URL.revokeObjectURL(uriContent); window.URL.revokeObjectURL(uriContent);
}); jQuery('#downloadLink').remove();
setTimeout(function(){
$scope.selectedCredential = credential;
}, 200)
};
if(!credential.hasOwnProperty('acl')){
FileService.getFile(file).then(callback);
} else {
ShareService.downloadSharedFile(credential, file).then(callback);
}
}; };
}]); }]);

View file

@ -10,7 +10,7 @@
*/ */
angular.module('passmanApp') angular.module('passmanApp')
.controller('ShareCtrl', ['$scope', 'VaultService', 'CredentialService', 'SettingsService', '$location', '$routeParams', 'ShareService', 'NotificationService', 'SharingACL','EncryptService', 'FileService', .controller('ShareCtrl', ['$scope', 'VaultService', 'CredentialService', 'SettingsService', '$location', '$routeParams', 'ShareService', 'NotificationService', 'SharingACL','EncryptService', 'FileService',
function ($scope, VaultService, CredentialService, SettingsService, $location, $routeParams, ShareService, NotificationService, SharingACL, EncryptService) { function ($scope, VaultService, CredentialService, SettingsService, $location, $routeParams, ShareService, NotificationService, SharingACL, EncryptService, FileService) {
$scope.active_vault = VaultService.getActiveVault(); $scope.active_vault = VaultService.getActiveVault();
$scope.tabs = [{ $scope.tabs = [{
@ -183,7 +183,18 @@ angular.module('passmanApp')
_credential.shared_key = null; _credential.shared_key = null;
CredentialService.updateCredential(_credential).then(function () { CredentialService.updateCredential(_credential).then(function () {
NotificationService.showNotification('Credential unshared', 4000) NotificationService.showNotification('Credential unshared', 4000)
}) });
for(var f = 0; f < $scope.storedCredential.files.length; f++){
var _file = $scope.storedCredential.files[f];
FileService.getFile(_file).then(function (fileData) {
console.log(fileData);
//Decrypt with old key
fileData.filename = EncryptService.decryptString(fileData.filename);
fileData.file_data = EncryptService.decryptString(fileData.file_data);
FileService.updateFile(fileData, $scope.active_vault.vaultKey);
})
}
}; };
/** /**
@ -251,7 +262,6 @@ angular.module('passmanApp')
for (var i = 0; i < list.length; i++) { for (var i = 0; i < list.length; i++) {
var iterator = i; var iterator = i;
var target_user = list[i]; var target_user = list[i];
console.log(target_user)
if(target_user.hasOwnProperty('created')){ if(target_user.hasOwnProperty('created')){
console.log('Updating permissions') console.log('Updating permissions')
@ -273,7 +283,6 @@ angular.module('passmanApp')
CredentialService.updateCredential(encryptedSharedCredential, true).then(function(sharedCredential){ CredentialService.updateCredential(encryptedSharedCredential, true).then(function(sharedCredential){
$scope.storedCredential = ShareService.decryptSharedCredential(sharedCredential, key); $scope.storedCredential = ShareService.decryptSharedCredential(sharedCredential, key);
}); });
console.log($scope.storedCredential);
//@TODO Update files with new key (async) //@TODO Update files with new key (async)
// Files are stored in $scope.storedCredential.files // Files are stored in $scope.storedCredential.files
@ -281,6 +290,17 @@ angular.module('passmanApp')
// Then decrypt the data obtained with var EncryptService.decryptString(result.file_data); // Then decrypt the data obtained with var EncryptService.decryptString(result.file_data);
// To update a file you can use the FileService.updateFile // To update a file you can use the FileService.updateFile
for(var f = 0; f < $scope.storedCredential.files.length; f++){
var _file = $scope.storedCredential.files[f];
FileService.getFile(_file).then(function (fileData) {
//Decrypt with old key
fileData.filename = EncryptService.decryptString(fileData.filename);
fileData.file_data = EncryptService.decryptString(fileData.file_data);
FileService.updateFile(fileData, key);
})
}
//@TODO Update revisions with new key (async) //@TODO Update revisions with new key (async)
// With CredentialService.getRevisions we can get the revisions. // With CredentialService.getRevisions we can get the revisions.
// Then we can update them using CredentialService.updateRevision // Then we can update them using CredentialService.updateRevision

View file

@ -60,8 +60,8 @@ angular.module('passmanApp')
var queryUrl = OC.generateUrl('apps/passman/api/v2/file/'+ file.file_id); var queryUrl = OC.generateUrl('apps/passman/api/v2/file/'+ file.file_id);
var _file = angular.copy(file); var _file = angular.copy(file);
_file.filename = EncryptService.encryptString(_file.filename, key); _file.filename = EncryptService.encryptString(_file.filename, key);
var data = EncryptService.encryptString(angular.copy(file.data), key); var data = EncryptService.encryptString(angular.copy(file.file_data), key);
_file.data = data; _file.file_data = data;
return $http.patch(queryUrl, _file).then(function (response) { return $http.patch(queryUrl, _file).then(function (response) {
if (response.data) { if (response.data) {
return response.data; return response.data;

View file

@ -129,6 +129,14 @@ angular.module('passmanApp')
} }
}); });
}, },
downloadSharedFile: function (credential, file) {
var queryUrl = OC.generateUrl('apps/passman/api/v2/sharing/credential/'+ credential.guid +'/file/'+ file.guid);
return $http.get(queryUrl).then(function (response) {
if (response.data) {
return response.data;
}
});
},
encryptSharedCredential: function (credential, sharedKey) { encryptSharedCredential: function (credential, sharedKey) {
var _credential = angular.copy(credential); var _credential = angular.copy(credential);
_credential.shared_key = EncryptService.encryptString(sharedKey); _credential.shared_key = EncryptService.encryptString(sharedKey);

File diff suppressed because one or more lines are too long

View file

@ -20,6 +20,7 @@ use OCA\Passman\Service\ActivityService;
use OCA\Passman\Service\CronService; use OCA\Passman\Service\CronService;
use OCA\Passman\Service\CredentialService; use OCA\Passman\Service\CredentialService;
use OCA\Passman\Service\ShareService; use OCA\Passman\Service\ShareService;
use OCA\Passman\Service\FileService;
use OCA\Passman\Service\VaultService; use OCA\Passman\Service\VaultService;
use OCA\Passman\Utility\Utils; use OCA\Passman\Utility\Utils;
use OCA\Passman\Service\NotificationService; use OCA\Passman\Service\NotificationService;
@ -56,7 +57,8 @@ class Application extends App {
$c->query('VaultService'), $c->query('VaultService'),
$c->query('ShareService'), $c->query('ShareService'),
$c->query('CredentialService'), $c->query('CredentialService'),
$c->query('NotificationService') $c->query('NotificationService'),
$c->query('FileService')
); );
}); });
@ -91,6 +93,7 @@ class Application extends App {
$container->registerAlias('NotificationService', NotificationService::class); $container->registerAlias('NotificationService', NotificationService::class);
$container->registerAlias('ActivityService', ActivityService::class); $container->registerAlias('ActivityService', ActivityService::class);
$container->registerAlias('VaultService', VaultService::class); $container->registerAlias('VaultService', VaultService::class);
$container->registerAlias('FileService', FileService::class);
$container->registerAlias('ShareService', ShareService::class); $container->registerAlias('ShareService', ShareService::class);
$container->registerAlias('Utils', Utils::class); $container->registerAlias('Utils', Utils::class);
} }

View file

@ -38,7 +38,24 @@ class FileMapper extends Mapper {
$sql .= ' and `user_id` = ? '; $sql .= ' and `user_id` = ? ';
array_push($params, $user_id); array_push($params, $user_id);
} }
return $this->findEntities($sql, $params); return $this->findEntity($sql, $params);
}
/**
* @param $file_id
* @param null $user_id
* @return File
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
*/
public function getFileByGuid($file_guid, $user_id = null) {
$sql = 'SELECT * FROM `*PREFIX*passman_files` ' .
'WHERE `guid` = ?';
$params = [$file_guid];
if ($user_id !== null) {
$sql .= ' and `user_id` = ? ';
array_push($params, $user_id);
}
return $this->findEntity($sql, $params);
} }
public function create($file_raw, $userId) { public function create($file_raw, $userId) {

View file

@ -29,6 +29,10 @@ class FileService {
return $this->fileMapper->getFile($fileId, $userId); return $this->fileMapper->getFile($fileId, $userId);
} }
public function getFileByGuid($file_guid, $userId = null) {
return $this->fileMapper->getFileByGuid($file_guid, $userId);
}
public function createFile($file, $userId) { public function createFile($file, $userId) {
return $this->fileMapper->create($file, $userId); return $this->fileMapper->create($file, $userId);
} }

View file

@ -58,7 +58,7 @@
</div> </div>
</div> </div>
{{filtered_credentials}} {{filtered_credentials}}
<div off-click="closeSelected()"> <div off-click="closeSelected()" off-click-filter="'#downloadLink'">
<div class="loaderContainer" ng-if="show_spinner"> <div class="loaderContainer" ng-if="show_spinner">
<div class="loader" use-theme type="'border-bottom-color'"></div> <div class="loader" use-theme type="'border-bottom-color'"></div>
@ -164,7 +164,7 @@
</td> </td>
<td> <td>
<div ng-repeat="file in selectedCredential.files" <div ng-repeat="file in selectedCredential.files"
class="link" ng-click="downloadFile(file)"> class="link" ng-click="downloadFile(selectedCredential, file)">
{{file.filename}} ({{file.size | bytes}}) {{file.filename}} ({{file.size | bytes}})
</div> </div>
</td> </td>
@ -248,6 +248,7 @@
</button> </button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div class="share_popup" style="display: none"> <div class="share_popup" style="display: none">