Skip to content

Commit

Permalink
fix(federatedfilesharing): get share by token fallback
Browse files Browse the repository at this point in the history
Signed-off-by: skjnldsv <[email protected]>
  • Loading branch information
skjnldsv committed Dec 28, 2024
1 parent 895a939 commit bc0ad5e
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
62 changes: 58 additions & 4 deletions apps/files_sharing/lib/External/Manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand All @@ -199,22 +216,59 @@ 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
$groupShare = $this->fetchShare($parentId);
} else {
$groupShare = $share;
}

$user = $this->userManager->get($this->uid);
if ($this->groupManager->get($groupShare['user'])->inGroup($user)) {
return $share;
return true;
}
}

Expand Down

0 comments on commit bc0ad5e

Please sign in to comment.