From a710e0c9e3e059f1af9b1943445006c276a82fdb Mon Sep 17 00:00:00 2001 From: skjnldsv Date: Thu, 26 Dec 2024 13:50:01 +0100 Subject: [PATCH] fix(federatedfilesharing): get share by token fallback Signed-off-by: skjnldsv --- .../lib/OCM/CloudFederationProviderFiles.php | 8 ++- apps/files_sharing/lib/External/Manager.php | 62 +++++++++++++++++-- 2 files changed, 65 insertions(+), 5 deletions(-) diff --git a/apps/federatedfilesharing/lib/OCM/CloudFederationProviderFiles.php b/apps/federatedfilesharing/lib/OCM/CloudFederationProviderFiles.php index 8821ff9834e57..5c633c0fbbfdb 100644 --- a/apps/federatedfilesharing/lib/OCM/CloudFederationProviderFiles.php +++ b/apps/federatedfilesharing/lib/OCM/CloudFederationProviderFiles.php @@ -767,7 +767,13 @@ public function getFederationIdFromSharedSecret( try { $share = $provider->getShareByToken($sharedSecret); } catch (ShareNotFound) { - return ''; + // Maybe we're dealing with a share federated from another server + $share = $this->externalShareManager->getShareByToken($sharedSecret); + if ($share === false) { + return ''; + } + + return $share['user'] . '@' . $share['remote']; } // if uid_owner is a local account, the request comes from the recipient diff --git a/apps/files_sharing/lib/External/Manager.php b/apps/files_sharing/lib/External/Manager.php index e10b6c1c91f05..a69755edf2c28 100644 --- a/apps/files_sharing/lib/External/Manager.php +++ b/apps/files_sharing/lib/External/Manager.php @@ -177,6 +177,23 @@ private function fetchShare($id) { return $share; } + /** + * get share by token + * + * @param string $token + * @return mixed share of false + */ + private function fetchShareByToken($token) { + $getShare = $this->connection->prepare(' + SELECT `id`, `remote`, `remote_id`, `share_token`, `name`, `owner`, `user`, `mountpoint`, `accepted`, `parent`, `share_type`, `password`, `mountpoint_hash` + FROM `*PREFIX*share_external` + WHERE `share_token` = ?'); + $result = $getShare->execute([$token]); + $share = $result->fetch(); + $result->closeCursor(); + return $share; + } + private function fetchUserShare($parentId, $uid) { $getShare = $this->connection->prepare(' SELECT `id`, `remote`, `remote_id`, `share_token`, `name`, `owner`, `user`, `mountpoint`, `accepted`, `parent`, `share_type`, `password`, `mountpoint_hash` @@ -199,12 +216,48 @@ private function fetchUserShare($parentId, $uid) { */ public function getShare($id) { $share = $this->fetchShare($id); - $validShare = is_array($share) && isset($share['share_type']) && isset($share['user']); // check if the user is allowed to access it - if ($validShare && (int)$share['share_type'] === IShare::TYPE_USER && $share['user'] === $this->uid) { + if ($this->canAccessShare($share)) { return $share; - } elseif ($validShare && (int)$share['share_type'] === IShare::TYPE_GROUP) { + } + + return false; + } + + /** + * Get share by token + * + * @param string $token + * @return array|false + */ + public function getShareByToken(string $token): array|false { + $share = $this->fetchShareByToken($token); + + // We do not check if the user is allowed to access it here, + // as this is not used from a user context. + if ($share === false) { + return false; + } + + return $share; + } + + private function canAccessShare(array $share): bool { + $validShare = isset($share['share_type']) && isset($share['user']); + + if (!$validShare) { + return false; + } + + // If the share is a user share, check if the user is the recipient + if ((int)$share['share_type'] === IShare::TYPE_USER + && $share['user'] === $this->uid) { + return true; + } + + // If the share is a group share, check if the user is in the group + if ((int)$share['share_type'] === IShare::TYPE_GROUP) { $parentId = (int)$share['parent']; if ($parentId !== -1) { // we just retrieved a sub-share, switch to the parent entry for verification @@ -212,9 +265,10 @@ public function getShare($id) { } else { $groupShare = $share; } + $user = $this->userManager->get($this->uid); if ($this->groupManager->get($groupShare['user'])->inGroup($user)) { - return $share; + return true; } }