diff options
author | Bjoern Schiessle <bjoern@schiessle.org> | 2018-06-13 14:19:59 +0200 |
---|---|---|
committer | Bjoern Schiessle <bjoern@schiessle.org> | 2018-07-11 10:11:44 +0200 |
commit | b23032e4c569f7ba54197171cbb02ed8119b6811 (patch) | |
tree | 882cc64ab6398f33962428d79aa270055a20f6e0 /apps/files_sharing/lib | |
parent | c8631d607ef827f0eb29312faf7b2b808e1a8e7d (diff) | |
download | nextcloud-server-b23032e4c569f7ba54197171cbb02ed8119b6811.tar.gz nextcloud-server-b23032e4c569f7ba54197171cbb02ed8119b6811.zip |
implement federated group shares
Signed-off-by: Bjoern Schiessle <bjoern@schiessle.org>
Diffstat (limited to 'apps/files_sharing/lib')
-rw-r--r-- | apps/files_sharing/lib/Controller/ShareAPIController.php | 93 | ||||
-rw-r--r-- | apps/files_sharing/lib/External/Manager.php | 31 |
2 files changed, 76 insertions, 48 deletions
diff --git a/apps/files_sharing/lib/Controller/ShareAPIController.php b/apps/files_sharing/lib/Controller/ShareAPIController.php index 67ff9eae6d3..59b763ecf81 100644 --- a/apps/files_sharing/lib/Controller/ShareAPIController.php +++ b/apps/files_sharing/lib/Controller/ShareAPIController.php @@ -48,6 +48,7 @@ use OCP\IRequest; use OCP\IURLGenerator; use OCP\Files\IRootFolder; use OCP\Lock\LockedException; +use OCP\Share; use OCP\Share\IManager; use OCP\Share\Exceptions\ShareNotFound; use OCP\Share\Exceptions\GenericShareException; @@ -181,15 +182,15 @@ class ShareAPIController extends OCSController { $result['expiration'] = $expiration->format('Y-m-d 00:00:00'); } - if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) { + if ($share->getShareType() === Share::SHARE_TYPE_USER) { $sharedWith = $this->userManager->get($share->getSharedWith()); $result['share_with'] = $share->getSharedWith(); $result['share_with_displayname'] = $sharedWith !== null ? $sharedWith->getDisplayName() : $share->getSharedWith(); - } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) { + } else if ($share->getShareType() === Share::SHARE_TYPE_GROUP) { $group = $this->groupManager->get($share->getSharedWith()); $result['share_with'] = $share->getSharedWith(); $result['share_with_displayname'] = $group !== null ? $group->getDisplayName() : $share->getSharedWith(); - } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) { + } else if ($share->getShareType() === Share::SHARE_TYPE_LINK) { $result['share_with'] = $share->getPassword(); $result['share_with_displayname'] = $share->getPassword(); @@ -197,16 +198,16 @@ class ShareAPIController extends OCSController { $result['token'] = $share->getToken(); $result['url'] = $this->urlGenerator->linkToRouteAbsolute('files_sharing.sharecontroller.showShare', ['token' => $share->getToken()]); - } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_REMOTE) { + } else if ($share->getShareType() === Share::SHARE_TYPE_REMOTE || $share->getShareType() || Share::SHARE_TYPE_REMOTE_GROUP) { $result['share_with'] = $share->getSharedWith(); $result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'CLOUD'); $result['token'] = $share->getToken(); - } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) { + } else if ($share->getShareType() === Share::SHARE_TYPE_EMAIL) { $result['share_with'] = $share->getSharedWith(); $result['password'] = $share->getPassword(); $result['share_with_displayname'] = $this->getDisplayNameFromAddressBook($share->getSharedWith(), 'EMAIL'); $result['token'] = $share->getToken(); - } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_CIRCLE) { + } else if ($share->getShareType() === Share::SHARE_TYPE_CIRCLE) { // getSharedWith() returns either "name (type, owner)" or // "name (type, owner) [id]", depending on the Circles app version. $hasCircleId = (substr($share->getSharedWith(), -1) === ']'); @@ -301,7 +302,7 @@ class ShareAPIController extends OCSController { throw new OCSNotFoundException($this->l->t('Could not delete share')); } - if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP && + if ($share->getShareType() === Share::SHARE_TYPE_GROUP && $share->getShareOwner() !== $this->currentUser && $share->getSharedBy() !== $this->currentUser) { $this->shareManager->deleteFromSelf($share, $this->currentUser); @@ -388,14 +389,14 @@ class ShareAPIController extends OCSController { $permissions &= ~($permissions & ~$path->getPermissions()); } - if ($shareType === \OCP\Share::SHARE_TYPE_USER) { + if ($shareType === Share::SHARE_TYPE_USER) { // Valid user is required to share if ($shareWith === null || !$this->userManager->userExists($shareWith)) { throw new OCSNotFoundException($this->l->t('Please specify a valid user')); } $share->setSharedWith($shareWith); $share->setPermissions($permissions); - } else if ($shareType === \OCP\Share::SHARE_TYPE_GROUP) { + } else if ($shareType === Share::SHARE_TYPE_GROUP) { if (!$this->shareManager->allowGroupSharing()) { throw new OCSNotFoundException($this->l->t('Group sharing is disabled by the administrator')); } @@ -406,7 +407,7 @@ class ShareAPIController extends OCSController { } $share->setSharedWith($shareWith); $share->setPermissions($permissions); - } else if ($shareType === \OCP\Share::SHARE_TYPE_LINK) { + } else if ($shareType === Share::SHARE_TYPE_LINK) { //Can we even share links? if (!$this->shareManager->shareApiAllowLinks()) { throw new OCSNotFoundException($this->l->t('Public link sharing is disabled by the administrator')); @@ -416,7 +417,7 @@ class ShareAPIController extends OCSController { * For now we only allow 1 link share. * Return the existing link share if this is a duplicate */ - $existingShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_LINK, $path, false, 1, 0); + $existingShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_LINK, $path, false, 1, 0); if (!empty($existingShares)) { return new DataResponse($this->formatShare($existingShares[0])); } @@ -457,21 +458,28 @@ class ShareAPIController extends OCSController { } } - } else if ($shareType === \OCP\Share::SHARE_TYPE_REMOTE) { + } else if ($shareType === Share::SHARE_TYPE_REMOTE) { if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) { throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not allow shares from type %s', [$path->getPath(), $shareType])); } $share->setSharedWith($shareWith); $share->setPermissions($permissions); - } else if ($shareType === \OCP\Share::SHARE_TYPE_EMAIL) { + } else if ($shareType === Share::SHARE_TYPE_REMOTE_GROUP) { + if (!$this->shareManager->outgoingServer2ServerGroupSharesAllowed()) { + throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not allow shares from type %s', [$path->getPath(), $shareType])); + } + + $share->setSharedWith($shareWith); + $share->setPermissions($permissions); + } else if ($shareType === Share::SHARE_TYPE_EMAIL) { if ($share->getNodeType() === 'file') { $share->setPermissions(Constants::PERMISSION_READ); } else { $share->setPermissions($permissions); } $share->setSharedWith($shareWith); - } else if ($shareType === \OCP\Share::SHARE_TYPE_CIRCLE) { + } else if ($shareType === Share::SHARE_TYPE_CIRCLE) { if (!\OC::$server->getAppManager()->isEnabledForUser('circles') || !class_exists('\OCA\Circles\ShareByCircleProvider')) { throw new OCSNotFoundException($this->l->t('You cannot share to a Circle if the app is not enabled')); } @@ -512,9 +520,9 @@ class ShareAPIController extends OCSController { */ private function getSharedWithMe($node = null, bool $includeTags): DataResponse { - $userShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $node, -1, 0); - $groupShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $node, -1, 0); - $circleShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_CIRCLE, $node, -1, 0); + $userShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_USER, $node, -1, 0); + $groupShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_GROUP, $node, -1, 0); + $circleShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_CIRCLE, $node, -1, 0); $shares = array_merge($userShares, $groupShares, $circleShares); @@ -554,14 +562,14 @@ class ShareAPIController extends OCSController { /** @var \OCP\Share\IShare[] $shares */ $shares = []; foreach ($nodes as $node) { - $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $node, false, -1, 0)); - $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $node, false, -1, 0)); - $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_LINK, $node, false, -1, 0)); - if($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) { - $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_EMAIL, $node, false, -1, 0)); + $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_USER, $node, false, -1, 0)); + $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_GROUP, $node, false, -1, 0)); + $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_LINK, $node, false, -1, 0)); + if($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) { + $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_EMAIL, $node, false, -1, 0)); } if ($this->shareManager->outgoingServer2ServerSharesAllowed()) { - $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_REMOTE, $node, false, -1, 0)); + $shares = array_merge($shares, $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_REMOTE, $node, false, -1, 0)); } } @@ -635,16 +643,16 @@ class ShareAPIController extends OCSController { } // Get all shares - $userShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $path, $reshares, -1, 0); - $groupShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $path, $reshares, -1, 0); - $linkShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_LINK, $path, $reshares, -1, 0); - if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) { - $mailShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_EMAIL, $path, $reshares, -1, 0); + $userShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_USER, $path, $reshares, -1, 0); + $groupShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_GROUP, $path, $reshares, -1, 0); + $linkShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_LINK, $path, $reshares, -1, 0); + if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) { + $mailShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_EMAIL, $path, $reshares, -1, 0); } else { $mailShares = []; } - if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_CIRCLE)) { - $circleShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_CIRCLE, $path, $reshares, -1, 0); + if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_CIRCLE)) { + $circleShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_CIRCLE, $path, $reshares, -1, 0); } else { $circleShares = []; } @@ -652,7 +660,12 @@ class ShareAPIController extends OCSController { $shares = array_merge($userShares, $groupShares, $linkShares, $mailShares, $circleShares); if ($this->shareManager->outgoingServer2ServerSharesAllowed()) { - $federatedShares = $this->shareManager->getSharesBy($this->currentUser, \OCP\Share::SHARE_TYPE_REMOTE, $path, $reshares, -1, 0); + $federatedShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_REMOTE, $path, $reshares, -1, 0); + $shares = array_merge($shares, $federatedShares); + } + + if ($this->shareManager->outgoingServer2ServerGroupSharesAllowed()) { + $federatedShares = $this->shareManager->getSharesBy($this->currentUser, Share::SHARE_TYPE_REMOTE_GROUP, $path, $reshares, -1, 0); $shares = array_merge($shares, $federatedShares); } @@ -711,7 +724,7 @@ class ShareAPIController extends OCSController { /* * expirationdate, password and publicUpload only make sense for link shares */ - if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) { + if ($share->getShareType() === Share::SHARE_TYPE_LINK) { $newPermissions = null; if ($publicUpload === 'true') { @@ -783,7 +796,7 @@ class ShareAPIController extends OCSController { $share->setPermissions($permissions); } - if ($share->getShareType() === \OCP\Share::SHARE_TYPE_EMAIL) { + if ($share->getShareType() === Share::SHARE_TYPE_EMAIL) { if ($password === '') { $share->setPassword(null); } else if ($password !== null) { @@ -806,8 +819,8 @@ class ShareAPIController extends OCSController { if ($permissions !== null && $share->getShareOwner() !== $this->currentUser) { /* Check if this is an incomming share */ - $incomingShares = $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_USER, $share->getNode(), -1, 0); - $incomingShares = array_merge($incomingShares, $this->shareManager->getSharedWith($this->currentUser, \OCP\Share::SHARE_TYPE_GROUP, $share->getNode(), -1, 0)); + $incomingShares = $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_USER, $share->getNode(), -1, 0); + $incomingShares = array_merge($incomingShares, $this->shareManager->getSharedWith($this->currentUser, Share::SHARE_TYPE_GROUP, $share->getNode(), -1, 0)); /** @var \OCP\Share\IShare[] $incomingShares */ if (!empty($incomingShares)) { @@ -846,13 +859,13 @@ class ShareAPIController extends OCSController { } // If the share is shared with you (or a group you are a member of) - if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER && + if ($share->getShareType() === Share::SHARE_TYPE_USER && $share->getSharedWith() === $this->currentUser ) { return true; } - if ($checkGroups && $share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) { + if ($checkGroups && $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)) { @@ -860,7 +873,7 @@ class ShareAPIController extends OCSController { } } - if ($share->getShareType() === \OCP\Share::SHARE_TYPE_CIRCLE) { + if ($share->getShareType() === Share::SHARE_TYPE_CIRCLE) { // TODO: have a sanity check like above? return true; } @@ -915,7 +928,7 @@ class ShareAPIController extends OCSController { try { - if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_CIRCLE)) { + if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_CIRCLE)) { $share = $this->shareManager->getShareById('ocCircleShare:' . $id, $this->currentUser); return $share; } @@ -924,7 +937,7 @@ class ShareAPIController extends OCSController { } try { - if ($this->shareManager->shareProviderExists(\OCP\Share::SHARE_TYPE_EMAIL)) { + if ($this->shareManager->shareProviderExists(Share::SHARE_TYPE_EMAIL)) { $share = $this->shareManager->getShareById('ocMailShare:' . $id, $this->currentUser); return $share; } diff --git a/apps/files_sharing/lib/External/Manager.php b/apps/files_sharing/lib/External/Manager.php index 02783560afe..4875e7e26ce 100644 --- a/apps/files_sharing/lib/External/Manager.php +++ b/apps/files_sharing/lib/External/Manager.php @@ -126,12 +126,15 @@ class Manager { * @param string $password * @param string $name * @param string $owner + * @param int $shareType * @param boolean $accepted * @param string $user * @param int $remoteId + * @param int $parent * @return Mount|null + * @throws \Doctrine\DBAL\DBALException */ - public function addShare($remote, $token, $password, $name, $owner, $accepted=false, $user = null, $remoteId = -1) { + public function addShare($remote, $token, $password, $name, $owner, $shareType, $accepted=false, $user = null, $remoteId = -1, $parent = -1) { $user = $user ? $user : $this->uid; $accepted = $accepted ? 1 : 0; @@ -156,6 +159,7 @@ class Manager { 'mountpoint_hash' => $hash, 'accepted' => $accepted, 'remote_id' => $remoteId, + 'share_type' => $shareType, ]; $i = 1; @@ -174,10 +178,10 @@ class Manager { $query = $this->connection->prepare(' INSERT INTO `*PREFIX*share_external` - (`remote`, `share_token`, `password`, `name`, `owner`, `user`, `mountpoint`, `mountpoint_hash`, `accepted`, `remote_id`) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) + (`remote`, `share_token`, `password`, `name`, `owner`, `user`, `mountpoint`, `mountpoint_hash`, `accepted`, `remote_id`, `parent`, `share_type`) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) '); - $query->execute(array($remote, $token, $password, $name, $owner, $user, $mountPoint, $hash, $accepted, $remoteId)); + $query->execute(array($remote, $token, $password, $name, $owner, $user, $mountPoint, $hash, $accepted, $remoteId, $parent, $shareType)); $options = array( 'remote' => $remote, @@ -223,13 +227,17 @@ class Manager { $mountPoint = Filesystem::normalizePath($mountPoint); $hash = md5($mountPoint); - $acceptShare = $this->connection->prepare(' + if($share['share_type'] === \OCP\Share::SHARE_TYPE_USER) { + $acceptShare = $this->connection->prepare(' UPDATE `*PREFIX*share_external` SET `accepted` = ?, `mountpoint` = ?, `mountpoint_hash` = ? WHERE `id` = ? AND `user` = ?'); - $updated = $acceptShare->execute(array(1, $mountPoint, $hash, $id, $this->uid)); + $updated = $acceptShare->execute(array(1, $mountPoint, $hash, $id, $this->uid)); + } else { + // TODO group share, add additional row for the user who accepted it + } if ($updated === true) { $this->sendFeedbackToRemote($share['remote'], $share['share_token'], $share['remote_id'], 'accept'); \OC_Hook::emit(Share::class, 'federated_share_added', ['server' => $share['remote']]); @@ -537,10 +545,17 @@ class Manager { * @return array list of open server-to-server shares */ private function getShares($accepted) { + $user = $this->userManager->get($this->uid); + $groups = $this->groupManager->getUserGroups($user); + $userGroups = []; + foreach ($groups as $group) { + $userGroups[] = $group->getGID(); + } + $query = 'SELECT `id`, `remote`, `remote_id`, `share_token`, `name`, `owner`, `user`, `mountpoint`, `accepted` FROM `*PREFIX*share_external` - WHERE `user` = ?'; - $parameters = [$this->uid]; + WHERE `user` = ? OR `user` IN (?)'; + $parameters = [$this->uid, implode(',',$userGroups)]; if (!is_null($accepted)) { $query .= ' AND `accepted` = ?'; $parameters[] = (int) $accepted; |