diff options
author | John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> | 2019-08-26 13:11:09 +0200 |
---|---|---|
committer | John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> | 2019-10-04 19:25:11 +0200 |
commit | b1069b29fa7eacdaed8160e600f5a98b32e6784b (patch) | |
tree | 27b5cf9cc8da469a6478616c2ff41376bba34b16 /apps/files_sharing/lib/Controller | |
parent | f02cff1304f5a8d4ff4f2f42add72fdfa688dedf (diff) | |
download | nextcloud-server-b1069b29fa7eacdaed8160e600f5a98b32e6784b.tar.gz nextcloud-server-b1069b29fa7eacdaed8160e600f5a98b32e6784b.zip |
Add checks for whether a user with access to a share can delete it
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
Diffstat (limited to 'apps/files_sharing/lib/Controller')
-rw-r--r-- | apps/files_sharing/lib/Controller/ShareAPIController.php | 98 |
1 files changed, 89 insertions, 9 deletions
diff --git a/apps/files_sharing/lib/Controller/ShareAPIController.php b/apps/files_sharing/lib/Controller/ShareAPIController.php index f7b297909b5..986f8cea1d8 100644 --- a/apps/files_sharing/lib/Controller/ShareAPIController.php +++ b/apps/files_sharing/lib/Controller/ShareAPIController.php @@ -336,21 +336,24 @@ class ShareAPIController extends OCSController { try { $this->lock($share->getNode()); } catch (LockedException $e) { - throw new OCSNotFoundException($this->l->t('could not delete share')); + throw new OCSNotFoundException($this->l->t('Could not delete share')); } if (!$this->canAccessShare($share)) { - throw new OCSNotFoundException($this->l->t('Could not delete share')); + throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist')); } - if (( - $share->getShareType() === Share::SHARE_TYPE_GROUP - || $share->getShareType() === Share::SHARE_TYPE_ROOM - ) - && $share->getShareOwner() !== $this->currentUser - && $share->getSharedBy() !== $this->currentUser) { + // if it's a group share or a room share + // we don't delete the share, but only the + // mount point. Allowing it to be restored + // from the deleted shares + if ($this->canDeleteShareFromSelf($share)) { $this->shareManager->deleteFromSelf($share, $this->currentUser); } else { + if (!$this->canDeleteShare($share)) { + throw new OCSForbiddenException($this->l->t('Could not delete share')); + } + $this->shareManager->deleteShare($share); } @@ -500,7 +503,6 @@ class ShareAPIController extends OCSController { } } - if ($sendPasswordByTalk === 'true') { if (!$this->appManager->isEnabledForUser('spreed')) { throw new OCSForbiddenException($this->l->t('Sharing %s sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled', [$path->getPath()])); @@ -1053,6 +1055,83 @@ class ShareAPIController extends OCSController { } /** + * Does the user have delete permission on the share + * + * @param \OCP\Share\IShare $share the share to check + * @return boolean + */ + protected function canDeleteShare(\OCP\Share\IShare $share): bool { + // A file with permissions 0 can't be accessed by us. So Don't show it + if ($share->getPermissions() === 0) { + return false; + } + + // if the user is the recipient, i can unshare + // the share with self + if ($share->getShareType() === Share::SHARE_TYPE_USER && + $share->getSharedWith() === $this->currentUser + ) { + return true; + } + + // The owner of the file and the creator of the share + // can always delete the share + if ($share->getShareOwner() === $this->currentUser || + $share->getSharedBy() === $this->currentUser + ) { + return true; + } + + return false; + } + + /** + * Does the user have delete permission on the share + * This differs from the canDeleteShare function as it only + * remove the share for the current user. It does NOT + * completely delete the share but only the mount point. + * It can then be restored from the deleted shares section. + * + * @param \OCP\Share\IShare $share the share to check + * @return boolean + * + * @suppress PhanUndeclaredClassMethod + */ + protected function canDeleteShareFromSelf(\OCP\Share\IShare $share): bool { + if ($share->getShareType() !== Share::SHARE_TYPE_GROUP && + $share->getShareType() !== Share::SHARE_TYPE_ROOM + ) { + return false; + } + + if ($share->getShareOwner() === $this->currentUser || + $share->getSharedBy() === $this->currentUser + ) { + // Delete the whole share, not just for self + return false; + } + + // If in the recipient group, you can delete the share from self + if ($share->getShareType() === Share::SHARE_TYPE_GROUP) { + $sharedWith = $this->groupManager->get($share->getSharedWith()); + $user = $this->userManager->get($this->currentUser); + if ($user !== null && $sharedWith !== null && $sharedWith->inGroup($user)) { + return true; + } + } + + if ($share->getShareType() === Share::SHARE_TYPE_ROOM) { + try { + return $this->getRoomShareHelper()->canAccessShare($share, $this->currentUser); + } catch (QueryException $e) { + return false; + } + } + + return false; + } + + /** * Make sure that the passed date is valid ISO 8601 * So YYYY-MM-DD * If not throw an exception @@ -1228,4 +1307,5 @@ class ShareAPIController extends OCSController { return false; } + } |