diff --git a/appinfo/database.xml b/appinfo/database.xml index 2eb7d643..0db5f287 100644 --- a/appinfo/database.xml +++ b/appinfo/database.xml @@ -433,12 +433,6 @@ false 64 - - group_id - text - false - 64 - created integer @@ -496,6 +490,12 @@ true 64 + + target_user_id + text + false + 64 + target_vault_id integer diff --git a/appinfo/info.xml b/appinfo/info.xml index dc7f939e..dcf2ed83 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -5,7 +5,7 @@ A password manager for Nextcloud AGPL Sander Brand - 1.0.2.15 + 1.0.2.17 Passman other https://github.com/nextcloud/passman/ diff --git a/appinfo/routes.php b/appinfo/routes.php index ae6dda5c..aeae4c00 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -50,6 +50,8 @@ return [ ['name' => 'share#search', 'url' => '/api/v2/sharing/search', 'verb' => 'POST'], ['name' => 'share#getVaultsByUser', 'url' => '/api/v2/sharing/vaults/{user_id}', 'verb' => 'GET'], ['name' => 'share#applyIntermediateShare', 'url' => '/api/v2/sharing/share', 'verb' => 'POST'], + ['name' => 'share#savePendingRequest', 'url' => '/api/v2/sharing/save' 'verb' => 'POST'], + ['name' => 'share#getPendingRequests', 'url' => '/api/v2/sharing/pending', 'verb' => 'POST'], //Internal API diff --git a/controller/sharecontroller.php b/controller/sharecontroller.php index f1d2cc1a..8ffdc6f4 100644 --- a/controller/sharecontroller.php +++ b/controller/sharecontroller.php @@ -113,4 +113,12 @@ class ShareController extends ApiController { $link, $this->userId, Activity::TYPE_ITEM_ACTION); } + public function savePendingRequest($item_guid, $target_vault_guid, $final_shared_key) { + $this->shareService->applyShare($item_guid, $target_vault_guid, $final_shared_key); + } + + public function getPendingRequests() { + return new JSONResponse($this->shareService->getUserPendingRequests()); + } + } \ No newline at end of file diff --git a/lib/Db/ShareRequest.php b/lib/Db/ShareRequest.php index a60d5852..ff8376c1 100644 --- a/lib/Db/ShareRequest.php +++ b/lib/Db/ShareRequest.php @@ -9,6 +9,7 @@ namespace OCA\Passman\Db; +use OCA\Passman\Utility\PermissionEntity; use OCP\AppFramework\Db\Entity; /** @@ -18,6 +19,8 @@ use OCP\AppFramework\Db\Entity; * @method integer getItemId() * @method void setItemGuid(string $value) * @method string getItemGuid() + * @method void setTargetUserId(string $value) + * @method string getTargetUserId() * @method void setTargetVaultId(integer $value) * @method integer getTargetVaultId() * @method void setTargetVaultGuid(integer $value) @@ -30,14 +33,12 @@ use OCP\AppFramework\Db\Entity; * @method integer getCreated() */ -class ShareRequest extends Entity implements \JsonSerializable { - CONST READ = 0b00000001; - CONST WRITE = 0b00000010; - CONST OWNER = 0b10000000; +class ShareRequest extends PermissionEntity implements \JsonSerializable { protected $itemId, $itemGuid, + $targetUserId, $targetVaultId, $targetVaultGuid, $sharedKey, @@ -51,37 +52,6 @@ class ShareRequest extends Entity implements \JsonSerializable { $this->addType('permissions', 'integer'); } - /** - * Checks wether a user matches one or more permissions at once - * @param $permission - * @return bool - */ - public function hasPermission($permission) { - $tmp = $this->getPermissions(); - $tmp = $tmp & $permission; - return $tmp == $permission; - } - - /** - * Adds the given permission or permissions set to the user current permissions - * @param $permission - */ - public function addPermission($permission) { - $tmp = $this->getPermissions(); - $tmp = $tmp | $permission; - $this->setPermissions($tmp); - } - - /** - * Takes the given permission or permissions out from the user - * @param $permission - */ - public function removePermission($permission) { - $tmp = $this->getPermissions(); - $tmp = $tmp & !$permission; - $this->setPermissions($tmp); - } - /** * Specify data which should be serialized to JSON * @link http://php.net/manual/en/jsonserializable.jsonserialize.php @@ -95,6 +65,10 @@ class ShareRequest extends Entity implements \JsonSerializable { 'req_id' => $this->getId(), 'item_id' => $this->getItemId(), 'item_guid' => $this->getItemGuid(), + 'target_user_id' => $this->getTargetUserId(), + 'target_vault_id' => $this->getTargetVaultId(), + 'target_vault_guid' => $this->getTargetVaultGuid(), + 'item_guid' => $this->getItemGuid(), 'shared_key' => $this->getSharedKey(), 'permissions' => $this->getPermissions(), 'created' => $this->getCreated(), diff --git a/lib/Db/ShareRequestMapper.php b/lib/Db/ShareRequestMapper.php index 9c7a9612..607ae76b 100644 --- a/lib/Db/ShareRequestMapper.php +++ b/lib/Db/ShareRequestMapper.php @@ -24,4 +24,32 @@ class ShareRequestMapper extends Mapper { public function createRequest(ShareRequest $request){ return $this->insert($request); } + + /** + * Obtains a request by the given item and vault GUID pair + * @param $item_guid + * @param $target_vault_guid + * @return ShareRequest + */ + public function getRequestByGuid($item_guid, $target_vault_guid){ + $q = "SELECT * FROM *PREFIX*" . self::TABLE_NAME . " WHERE item_guid = ? AND target_vault_guid = ?"; + return $this->findEntity($q, [$item_guid, $target_vault_guid]); + } + + public function cleanItemRequestsForUser($item_id, $target_user_id){ + $req = new ShareRequest(); + $req->setItemId($item_id); + $req->setTargetUserId($target_user_id); + return $this->delete($req); + } + + /** + * Obtains all pending share requests for the given user ID + * @param $user_id + * @return ShareRequest[] + */ + public function getUserPendingRequests($user_id){ + $q = "SELECT * FROM *PREFIX*{{self::TABLE_NAME }} WHERE user_id = ?"; + return $this->findEntities($q, [$user_id]); + } } \ No newline at end of file diff --git a/lib/Db/SharingACL.php b/lib/Db/SharingACL.php index 7c2244b1..d6f37db4 100644 --- a/lib/Db/SharingACL.php +++ b/lib/Db/SharingACL.php @@ -7,6 +7,7 @@ namespace OCA\Passman\Db; +use OCA\Passman\Utility\PermissionEntity; use OCP\AppFramework\Db\Entity; /** @@ -18,19 +19,35 @@ use OCP\AppFramework\Db\Entity; * @method string getItemGuid() * @method void setUserId(string $value) * @method string getUserid() - * @method void setGroupId(string $value) - * @method string getGroupId() * @method void setCreated(integer $value) * @method integer getCreated() * @method void setExpire(integer $value) * @method integer getExpire() * @method void setPermissions(integer $value) * @method integer getPermissions() + * @method void setVaultId(integer $value) + * @method integer getVaultId() + * @method void setVaultGuid(string $vault) + * @method string getVaultGuid() + * @method void setSharedKey(string $value) + * @method string getSharedKey() */ -class SharingACL extends Entity implements \JsonSerializable +class SharingACL extends PermissionEntity implements \JsonSerializable { + protected + $itemId, + $itemGuid, + $userId, + $created, + $expire, + $permissions, + $vaultId, + $vaultGuid, + $sharedKey; + + public function __construct() { // add types in constructor $this->addType('itemId', 'integer'); diff --git a/lib/Db/SharingACLMapper.php b/lib/Db/SharingACLMapper.php index b1df9dc4..c022d89f 100644 --- a/lib/Db/SharingACLMapper.php +++ b/lib/Db/SharingACLMapper.php @@ -14,8 +14,7 @@ use OCP\IDBConnection; use OCP\IUser; use OCA\Passman\Utility\Utils; -class SharingACLMapper extends Mapper -{ +class SharingACLMapper extends Mapper { const TABLE_NAME = '`*PREFIX*passman_sharing_acl`'; public function __construct(IDBConnection $db, Utils $utils) { @@ -34,4 +33,8 @@ class SharingACLMapper extends Mapper return $this->findEntities($sql, [$userId, $item_guid]); } + + public function createACLEntry(SharingACL $acl){ + return $this->insert($acl); + } } \ No newline at end of file diff --git a/lib/Service/ShareService.php b/lib/Service/ShareService.php index ddefaad5..0683c1a1 100644 --- a/lib/Service/ShareService.php +++ b/lib/Service/ShareService.php @@ -11,6 +11,7 @@ namespace OCA\Passman\Service; use OCA\Passman\Db\ShareRequest; use OCA\Passman\Db\ShareRequestMapper; +use OCA\Passman\Db\SharingACL; use OCA\Passman\Db\SharingACLMapper; class ShareService { @@ -24,12 +25,11 @@ class ShareService { /** * Creates requests for all the items on the request array of objects. - * This array objects must follow this spec: - * { - * vault_id: The id of the target vault - * guid: The guid of the target vault - * key: The shared key cyphered with the target vault RSA public key - * } + * This array must follow this spec: + * user_id: The target user id + * vault_id: The id of the target vault + * guid: The guid of the target vault + * key: The shared key cyphered with the target vault RSA public key * @param $target_item_id string The shared item ID * @param $target_item_guid string The shared item GUID * @param $request_array array @@ -43,6 +43,7 @@ class ShareService { $t = new ShareRequest(); $t->setItemId($target_item_id); $t->setItemGuid($target_item_guid); + $t->setTargetUserId($req['user_id']); $t->setTargetVaultId($req['vault_id']); $t->setTargetVaultGuid($req['guid']); $t->setSharedKey($req['key']); @@ -52,4 +53,38 @@ class ShareService { } return $requests; } + + /** + * Applies the given share, defaults to no expire + * @param $item_guid + * @param $target_vault_guid + * @param $final_shared_key + */ + public function applyShare($item_guid, $target_vault_guid, $final_shared_key){ + $request = $this->shareRequest->getRequestByGuid($item_guid, $target_vault_guid); + $permissions = $request->getPermissions(); + + $acl = new SharingACL(); + $acl->setItemId($request->getItemId()); + $acl->setItemGuid($request->getItemGuid()); + $acl->setUserId($request->getTargetUserId()); + $acl->setCreated($request->getCreated()); + $acl->setExpire(0); + $acl->setPermissions($permissions); + $acl->setVaultId($request->getTargetVaultId()); + $acl->getVaultGuid($request->getTargetVaultGuid()); + $acl->setSharedKey($final_shared_key); + + $this->sharingACL->createACLEntry($acl); + $this->shareRequest->cleanItemRequestsForUser($request->getItemId(), $request->getTargetUserId()); + } + + /** + * Obtains pending requests for the given user ID + * @param $user_id + * @return \OCA\Passman\Db\ShareRequest[] + */ + public function getUserPendingRequests($user_id){ + return $this->shareRequest->getUserPendingRequests($user_id); + } } \ No newline at end of file diff --git a/lib/Utility/PermissionEntity.php b/lib/Utility/PermissionEntity.php new file mode 100644 index 00000000..8d4c778a --- /dev/null +++ b/lib/Utility/PermissionEntity.php @@ -0,0 +1,49 @@ +getPermissions(); + $tmp = $tmp & $permission; + return $tmp == $permission; + } + + /** + * Adds the given permission or permissions set to the user current permissions + * @param $permission + */ + public function addPermission($permission) { + $tmp = $this->getPermissions(); + $tmp = $tmp | $permission; + $this->setPermissions($tmp); + } + + /** + * Takes the given permission or permissions out from the user + * @param $permission + */ + public function removePermission($permission) { + $tmp = $this->getPermissions(); + $tmp = $tmp & !$permission; + $this->setPermissions($tmp); + } +} \ No newline at end of file