Skip to content

Commit e3e7322

Browse files
susnuxbackportbot[bot]
authored andcommitted
fix(sharing): Ensure download restrictions are not dropped
When a user receives a share with share-permissions but also with download restrictions (hide download or the modern download permission attribute), then re-shares of that share must always also include those restrictions. Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de> [skip ci]
1 parent 7448885 commit e3e7322

3 files changed

Lines changed: 168 additions & 68 deletions

File tree

apps/files_sharing/lib/Controller/ShareAPIController.php

Lines changed: 31 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,7 @@ public function createShare(
792792
}
793793

794794
$share->setShareType($shareType);
795+
$this->checkInheritedAttributes($share);
795796

796797
if ($note !== '') {
797798
$share->setNote($note);
@@ -1272,7 +1273,6 @@ public function updateShare(
12721273
if ($attributes !== null) {
12731274
$share = $this->setShareAttributes($share, $attributes);
12741275
}
1275-
$this->checkInheritedAttributes($share);
12761276

12771277
/**
12781278
* expiration date, password and publicUpload only make sense for link shares
@@ -1351,6 +1351,7 @@ public function updateShare(
13511351
}
13521352

13531353
try {
1354+
$this->checkInheritedAttributes($share);
13541355
$share = $this->shareManager->updateShare($share);
13551356
} catch (HintException $e) {
13561357
$code = $e->getCode() === 0 ? 403 : $e->getCode();
@@ -2055,20 +2056,18 @@ private function checkInheritedAttributes(IShare $share): void {
20552056
if (!$share->getSharedBy()) {
20562057
return; // Probably in a test
20572058
}
2059+
2060+
$canDownload = false;
2061+
$hideDownload = true;
2062+
20582063
$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
2059-
$node = $userFolder->getFirstNodeById($share->getNodeId());
2060-
if (!$node) {
2061-
return;
2062-
}
2063-
if ($node->getStorage()->instanceOfStorage(SharedStorage::class)) {
2064-
$storage = $node->getStorage();
2065-
if ($storage instanceof Wrapper) {
2066-
$storage = $storage->getInstanceOfStorage(SharedStorage::class);
2067-
if ($storage === null) {
2068-
throw new \RuntimeException('Should not happen, instanceOfStorage but getInstanceOfStorage return null');
2069-
}
2070-
} else {
2071-
throw new \RuntimeException('Should not happen, instanceOfStorage but not a wrapper');
2064+
$nodes = $userFolder->getById($share->getNodeId());
2065+
foreach ($nodes as $node) {
2066+
// Owner always can download it - so allow it and break
2067+
if ($node->getOwner()?->getUID() === $share->getSharedBy()) {
2068+
$canDownload = true;
2069+
$hideDownload = false;
2070+
break;
20722071
}
20732072
/** @var \OCA\Files_Sharing\SharedStorage $storage */
20742073
$inheritedAttributes = $storage->getShare()->getAttributes();
@@ -2079,6 +2078,24 @@ private function checkInheritedAttributes(IShare $share): void {
20792078
$attributes->setAttribute('permissions', 'download', false);
20802079
$share->setAttributes($attributes);
20812080
}
2081+
2082+
/** @var SharedStorage $storage */
2083+
$originalShare = $storage->getShare();
2084+
$inheritedAttributes = $originalShare->getAttributes();
2085+
// hide if hidden and also the current share enforces hide (can only be false if one share is false or user is owner)
2086+
$hideDownload = $hideDownload && $originalShare->getHideDownload();
2087+
// allow download if already allowed by previous share or when the current share allows downloading
2088+
$canDownload = $canDownload || $inheritedAttributes === null || $inheritedAttributes->getAttribute('permissions', 'download') !== false;
2089+
}
2090+
}
2091+
2092+
if ($hideDownload || !$canDownload) {
2093+
$share->setHideDownload(true);
2094+
2095+
if (!$canDownload) {
2096+
$attributes = $share->getAttributes() ?? $share->newAttributes();
2097+
$attributes->setAttribute('permissions', 'download', false);
2098+
$share->setAttributes($attributes);
20822099
}
20832100
}
20842101

0 commit comments

Comments
 (0)