mirror of
https://github.com/nextcloud/passman.git
synced 2026-01-04 06:37:12 +08:00
File upload / delete works
This commit is contained in:
parent
110d888dbd
commit
6caf31a992
16 changed files with 276 additions and 39 deletions
|
|
@ -262,10 +262,10 @@
|
|||
<length>64</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>item_id</name>
|
||||
<name>mimetype</name>
|
||||
<type>text</type>
|
||||
<length>255</length>
|
||||
<notnull>true</notnull>
|
||||
<length>64</length>
|
||||
</field>
|
||||
<field>
|
||||
<name>filename</name>
|
||||
|
|
@ -294,12 +294,6 @@
|
|||
<name>id</name>
|
||||
</field>
|
||||
</index>
|
||||
<index>
|
||||
<name>passman_file_item_id_index</name>
|
||||
<field>
|
||||
<name>item_id</name>
|
||||
</field>
|
||||
</index>
|
||||
<index>
|
||||
<name>passman_file_user_id_index</name>
|
||||
<field>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
<description>A password manager for Nextcloud</description>
|
||||
<licence>AGPL</licence>
|
||||
<author>Sander Brand</author>
|
||||
<version>1.0.2.2</version>
|
||||
<version>1.0.2.3</version>
|
||||
<namespace>Passman</namespace>
|
||||
<category>other</category>
|
||||
<website>https://github.com/nextcloud/passman/</website>
|
||||
|
|
|
|||
|
|
@ -39,8 +39,8 @@ return [
|
|||
['name' => 'credential#deleteRevision', 'url' => '/api/v2/credentials/{credential_id}/revision/{revision_id}', 'verb' => 'DELETE'],
|
||||
|
||||
//File stuff
|
||||
['name' => 'credential#uploadFile', 'url' => '/api/v2/credentials/{credential_id}/file', 'verb' => 'POST'],
|
||||
['name' => 'credential#deleteFile', 'url' => '/api/v2/credentials/{credential_id}/file/{file_id}', 'verb' => 'DELETE'],
|
||||
['name' => 'file#uploadFile', 'url' => '/api/v2/file', 'verb' => 'POST'],
|
||||
['name' => 'file#deleteFile', 'url' => '/api/v2/file/{file_id}', 'verb' => 'DELETE'],
|
||||
|
||||
]
|
||||
];
|
||||
|
|
@ -99,18 +99,4 @@ class CredentialController extends ApiController {
|
|||
public function deleteRevision($credential_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
*/
|
||||
public function uploadFile($credential_id) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
*/
|
||||
public function deleteFile($credential_id) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
51
controller/filecontroller.php
Normal file
51
controller/filecontroller.php
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
<?php
|
||||
/**
|
||||
* Nextcloud - passman
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Sander Brand <brantje@gmail.com>
|
||||
* @copyright Sander Brand 2016
|
||||
*/
|
||||
|
||||
namespace OCA\Passman\Controller;
|
||||
|
||||
use OCP\IRequest;
|
||||
use OCP\AppFramework\Http\JSONResponse;
|
||||
use OCP\AppFramework\ApiController;
|
||||
use OCA\Passman\Service\FileService;
|
||||
|
||||
class FileController extends ApiController {
|
||||
private $userId;
|
||||
private $fileService;
|
||||
public function __construct($AppName,
|
||||
IRequest $request,
|
||||
$UserId,
|
||||
FileService $fileService){
|
||||
parent::__construct($AppName, $request);
|
||||
$this->userId = $UserId;
|
||||
$this->fileService = $fileService;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
*/
|
||||
public function uploadFile($data, $filename, $mimetype, $size) {
|
||||
$file = array(
|
||||
'filename' => $filename,
|
||||
'size' => $size,
|
||||
'mimetype' => $mimetype,
|
||||
'file_data' => $data
|
||||
);
|
||||
return $this->fileService->createFile($file, $this->userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
*/
|
||||
public function deleteFile($file_id) {
|
||||
return $this->fileService->deleteFile($file_id, $this->userId);
|
||||
}
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@ use OCP\AppFramework\ApiController;
|
|||
use OCA\Passman\Service\VaultService;
|
||||
use OCA\Passman\Service\CredentialService;
|
||||
|
||||
|
||||
class VaultController extends ApiController {
|
||||
private $userId;
|
||||
private $vaultService;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
* Controller of the passmanApp
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.controller('CredentialEditCtrl', ['$scope', 'VaultService', 'CredentialService', 'SettingsService', '$location', '$routeParams', function ($scope, VaultService, CredentialService, SettingsService, $location, $routeParams) {
|
||||
.controller('CredentialEditCtrl', ['$scope', 'VaultService', 'CredentialService', 'SettingsService', '$location', '$routeParams', 'FileService', function ($scope, VaultService, CredentialService, SettingsService, $location, $routeParams, FileService) {
|
||||
$scope.active_vault = VaultService.getActiveVault();
|
||||
|
||||
|
||||
|
|
@ -119,7 +119,7 @@ angular.module('passmanApp')
|
|||
$scope.deleteCustomField = function(field){
|
||||
var idx = $scope.storedCredential.custom_fields.indexOf(field);
|
||||
$scope.storedCredential.custom_fields.splice(idx, 1);
|
||||
}
|
||||
};
|
||||
|
||||
$scope.new_file = {
|
||||
name: '',
|
||||
|
|
@ -128,19 +128,24 @@ angular.module('passmanApp')
|
|||
|
||||
$scope.deleteFile = function(file){
|
||||
var idx = $scope.storedCredential.files.indexOf(file);
|
||||
$scope.storedCredential.files.splice(idx, 1);
|
||||
FileService.deleteFile(file).then(function () {
|
||||
$scope.storedCredential.files.splice(idx, 1);
|
||||
});
|
||||
//@TODO Delete file
|
||||
};
|
||||
|
||||
$scope.fileLoaded = function (file) {
|
||||
var _file = {
|
||||
created: new Date(),
|
||||
filename: file.name,
|
||||
size: file.size,
|
||||
mimetype: file.type
|
||||
mimetype: file.type,
|
||||
data: file.data
|
||||
};
|
||||
//@TODO upload file.data
|
||||
$scope.storedCredential.files.push(_file)
|
||||
FileService.uploadFile(_file).then(function (result) {
|
||||
delete result.file_data;
|
||||
$scope.storedCredential.files.push(result);
|
||||
});
|
||||
|
||||
|
||||
$scope.$apply()
|
||||
};
|
||||
|
|
|
|||
38
js/app/services/fileservice.js
Normal file
38
js/app/services/fileservice.js
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @name passmanApp.CredentialService
|
||||
* @description
|
||||
* # CredentialService
|
||||
* Service in the passmanApp.
|
||||
*/
|
||||
angular.module('passmanApp')
|
||||
.service('FileService', ['$http', 'EncryptService', function ($http, EncryptService) {
|
||||
return {
|
||||
uploadFile: function (file) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/file');
|
||||
var _file = angular.copy(file);
|
||||
var data = EncryptService.encryptString(angular.copy(file.data));
|
||||
_file.data = data;
|
||||
return $http.post(queryUrl, _file).then(function (response) {
|
||||
if(response.data){
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
deleteFile: function (file) {
|
||||
var queryUrl = OC.generateUrl('apps/passman/api/v2/file/'+ file.file_id);
|
||||
var _file = angular.copy(file);
|
||||
return $http.delete(queryUrl, _file).then(function (response) {
|
||||
if(response.data){
|
||||
return response.data;
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
});
|
||||
},
|
||||
}
|
||||
}]);
|
||||
|
|
@ -23,7 +23,7 @@ angular.module('views/partials/forms/edit_credential/custom_fields.html', []).ru
|
|||
angular.module('views/partials/forms/edit_credential/files.html', []).run(['$templateCache', function($templateCache) {
|
||||
'use strict';
|
||||
$templateCache.put('views/partials/forms/edit_credential/files.html',
|
||||
'<div class="row file_tab"><div class="col-xs-12 col-md-6"><input type="file" file-select success="fileLoaded" error="fileLoadError" progress="fileSelectProgress"> <span ng-if="fileprogress.file_percent > 0"><div progress-bar="fileprogress.file_percent"></div></span></div></div><div class="row files" ng-if="storedCredential.files.length > 0"><div class="col-xs-12 table"><table><thead use-theme><tr><th class="field_label">Filename</th><th class="field_value">Upload date</th><th class="field_secret">Type</th><th class="field_actions">Actions</th></tr></thead><tr ng-repeat="file in storedCredential.files"><td><a href="#" editable-text="file.filename">{{ file.filename || "empty" }}</a></td><td>{{file.created}}</td><td>{{file.mimetype}}</td><td class="field_actions"><i class="fa fa-trash" ng-click="deleteFile(file)"></i></td></tr></table></div></div>');
|
||||
'<div class="row file_tab"><div class="col-xs-12 col-md-6"><input type="file" file-select success="fileLoaded" error="fileLoadError" progress="fileSelectProgress"> <span ng-if="fileprogress.file_percent > 0"><div progress-bar="fileprogress.file_percent"></div></span></div></div><div class="row files" ng-if="storedCredential.files.length > 0"><div class="col-xs-12 table"><table><thead use-theme><tr><th class="field_label">Filename</th><th class="field_value">Upload date</th><th class="field_secret">Size</th><th class="field_actions">Actions</th></tr></thead><tr ng-repeat="file in storedCredential.files"><td><a href="#" editable-text="file.filename">{{ file.filename || "empty" }}</a></td><td>{{file.created}}</td><td>{{file.size}}</td><td class="field_actions"><i class="fa fa-trash" ng-click="deleteFile(file)"></i></td></tr></table></div></div>');
|
||||
}]);
|
||||
|
||||
angular.module('views/partials/forms/edit_credential/otp.html', []).run(['$templateCache', function($templateCache) {
|
||||
|
|
|
|||
|
|
@ -97,7 +97,7 @@ class Credential extends Entity implements \JsonSerializable{
|
|||
|
||||
|
||||
/**
|
||||
* Turns entitie attributes into an array
|
||||
* Turns entity attributes into an array
|
||||
*/
|
||||
public function jsonSerialize() {
|
||||
return [
|
||||
|
|
|
|||
66
lib/Db/File.php
Normal file
66
lib/Db/File.php
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
/**
|
||||
* Nextcloud - passman
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Sander Brand <brantje@gmail.com>
|
||||
* @copyright Sander Brand 2016
|
||||
*/
|
||||
|
||||
namespace OCA\Passman\Db;
|
||||
use \OCP\AppFramework\Db\Entity;
|
||||
|
||||
/**
|
||||
* @method integer getId()
|
||||
* @method void setId(integer $value)
|
||||
* @method void setGuid(string $value)
|
||||
* @method string getGuid()
|
||||
* @method void setUserId(string $value)
|
||||
* @method string getUserid()
|
||||
* @method void setMimetype(string $value)
|
||||
* @method string getMimetype()
|
||||
* @method void setFilename(string $value)
|
||||
* @method string getFilename()
|
||||
* @method void setSize(integer $value)
|
||||
* @method integer getSize()
|
||||
* @method void setCreated(integer $value)
|
||||
* @method integer getCreated()
|
||||
* @method void setFileData(string $value)
|
||||
* @method string getFileData()
|
||||
*/
|
||||
|
||||
|
||||
class File extends Entity implements \JsonSerializable{
|
||||
|
||||
use EntityJSONSerializer;
|
||||
|
||||
protected $guid;
|
||||
protected $userId;
|
||||
protected $mimetype;
|
||||
protected $filename;
|
||||
protected $size;
|
||||
protected $created;
|
||||
protected $fileData;
|
||||
|
||||
public function __construct() {
|
||||
// add types in constructor
|
||||
$this->addType('created', 'integer');
|
||||
$this->addType('size', 'integer');
|
||||
}
|
||||
/**
|
||||
* Turns entity attributes into an array
|
||||
*/
|
||||
public function jsonSerialize() {
|
||||
return [
|
||||
'file_id' => $this->getId(),
|
||||
'filename' => $this->getFilename(),
|
||||
'guid' => $this->getGuid(),
|
||||
'size' => $this->getSize(),
|
||||
'file_data' => $this->getFileData(),
|
||||
'created' => $this->getCreated(),
|
||||
'mimetype' => $this->getMimetype(),
|
||||
];
|
||||
}
|
||||
}
|
||||
55
lib/Db/FileMapper.php
Normal file
55
lib/Db/FileMapper.php
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
<?php
|
||||
/**
|
||||
* Nextcloud - passman
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Sander Brand <brantje@gmail.com>
|
||||
* @copyright Sander Brand 2016
|
||||
*/
|
||||
namespace OCA\Passman\Db;
|
||||
|
||||
use OCA\Passman\Utility\Utils;
|
||||
use OCP\IDBConnection;
|
||||
use OCP\AppFramework\Db\Mapper;
|
||||
|
||||
class FileMapper extends Mapper {
|
||||
private $utils;
|
||||
public function __construct(IDBConnection $db, Utils $utils) {
|
||||
parent::__construct($db, 'passman_files');
|
||||
$this->utils = $utils;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @throws \OCP\AppFramework\Db\DoesNotExistException if not found
|
||||
* @throws \OCP\AppFramework\Db\MultipleObjectsReturnedException if more than one result
|
||||
*/
|
||||
public function getFile($itemId, $fileId) {
|
||||
$sql = 'SELECT * FROM `*PREFIX*passman_files` ' .
|
||||
'WHERE `id` = ? and `item_id` = ? ';
|
||||
return $this->findEntities($sql, [$fileId, $itemId]);
|
||||
}
|
||||
|
||||
public function create($file_raw, $userId){
|
||||
$file = new File();
|
||||
$file->setGuid($this->utils->GUID());
|
||||
$file->setUserId($userId);
|
||||
$file->setFilename($file_raw['filename']);
|
||||
$file->setSize($file_raw['size']);
|
||||
$file->setCreated($this->utils->getTime());
|
||||
$file->setFileData($file_raw['file_data']);
|
||||
$file->setMimetype($file_raw['mimetype']);
|
||||
|
||||
|
||||
return $this->insert($file);
|
||||
}
|
||||
|
||||
public function deleteFile($file_id, $userId) {
|
||||
$file = new File();
|
||||
$file->setId($file_id);
|
||||
$file->setUserId($userId);
|
||||
$this->delete($file); // TODO: Change the autogenerated stub
|
||||
}
|
||||
}
|
||||
|
|
@ -23,8 +23,8 @@ use \OCP\AppFramework\Db\Entity;
|
|||
* @method string getUserid()
|
||||
* @method void setCreated(integer $value)
|
||||
* @method integer getCreated()
|
||||
* @method void setlastAccess(integer $value)
|
||||
* @method integer getlastAccess()
|
||||
* @method void setLastAccess(integer $value)
|
||||
* @method integer getLastAccess()
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ class Vault extends Entity implements \JsonSerializable{
|
|||
$this->addType('lastAccess', 'integer');
|
||||
}
|
||||
/**
|
||||
* Turns entitie attributes into an array
|
||||
* Turns entity attributes into an array
|
||||
*/
|
||||
public function jsonSerialize() {
|
||||
return [
|
||||
|
|
|
|||
40
lib/Service/FileService.php
Normal file
40
lib/Service/FileService.php
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
<?php
|
||||
/**
|
||||
* Nextcloud - passman
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Sander Brand <brantje@gmail.com>
|
||||
* @copyright Sander Brand 2016
|
||||
*/
|
||||
|
||||
namespace OCA\Passman\Service;
|
||||
|
||||
use OCP\IConfig;
|
||||
use OCP\AppFramework\Db\DoesNotExistException;
|
||||
|
||||
use OCA\Passman\Db\FileMapper;
|
||||
|
||||
|
||||
class FileService {
|
||||
|
||||
private $fileMapper;
|
||||
|
||||
public function __construct(FileMapper $fileMapper) {
|
||||
$this->fileMapper = $fileMapper;
|
||||
}
|
||||
|
||||
public function getFile($userId, $fileId) {
|
||||
return $this->fileMapper->getFile($userId, $fileId);
|
||||
}
|
||||
|
||||
public function createFile($file, $userId) {
|
||||
return $this->fileMapper->create($file, $userId);
|
||||
}
|
||||
|
||||
public function deleteFile($file_id, $userId) {
|
||||
return $this->fileMapper->deleteFile($file_id, $userId);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -34,6 +34,7 @@ script('passman', 'app/services/cacheservice');
|
|||
script('passman', 'app/services/vaultservice');
|
||||
script('passman', 'app/services/credentialservice');
|
||||
script('passman', 'app/services/settingsservice');
|
||||
script('passman', 'app/services/fileservice');
|
||||
script('passman', 'app/services/encryptservice');
|
||||
script('passman', 'app/directives/passwordgen');
|
||||
script('passman', 'app/directives/fileselect');
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
<tr>
|
||||
<th class="field_label">Filename</th>
|
||||
<th class="field_value">Upload date</th>
|
||||
<th class="field_secret">Type</th>
|
||||
<th class="field_secret">Size</th>
|
||||
<th class="field_actions">Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
<td>
|
||||
{{file.created}}
|
||||
</td>
|
||||
<td>{{file.mimetype}}</td>
|
||||
<td>{{file.size}}</td>
|
||||
<td class="field_actions">
|
||||
<i class="fa fa-trash" ng-click="deleteFile(file)"></i>
|
||||
</td>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue