fix(sharing): Inherit correct share atrributes 4 federated storage

When creating public shares from federated storage, getById() can return
an empty array if the storage isn't in the mount cache (e.g., unscanned
federated shares). This causes the inheritance check loop to skip entirely,
leaving restrictive defaults that incorrectly hide the download button.

Add fallback to use the node already set on the share object during
creation when getById() returns empty.

Signed-off-by: nfebe <fenn25.fn@gmail.com>
This commit is contained in:
nfebe 2025-11-17 19:41:32 +01:00
parent d843e03a34
commit e7d7014c30
2 changed files with 42 additions and 1 deletions

View file

@ -2098,10 +2098,22 @@ class ShareAPIController extends OCSController {
$canDownload = false;
$hideDownload = true;
$userExplicitlySetHideDownload = $share->getHideDownload(); // Capture user's explicit choice
$userExplicitlySetHideDownload = $share->getHideDownload();
$userFolder = $this->rootFolder->getUserFolder($share->getSharedBy());
$nodes = $userFolder->getById($share->getNodeId());
// Fallback: getById fails for federated storage when mount cache is incomplete.
// Use node already set on share during creation.
if (empty($nodes)) {
try {
$node = $share->getNode();
$nodes = [$node];
} catch (\Exception $e) {
return;
}
}
foreach ($nodes as $node) {
// Owner always can download it - so allow it, but respect their explicit choice about hiding downloads
if ($node->getOwner()?->getUID() === $share->getSharedBy()) {

View file

@ -5648,4 +5648,33 @@ class ShareAPIControllerTest extends TestCase {
$this->invokePrivate($ocs, 'checkInheritedAttributes', [$share]);
}
public function testFederatedStorageFallbackWhenGetByIdEmpty(): void {
$ocs = $this->mockFormatShare();
$share = $this->createMock(IShare::class);
$node = $this->createMock(File::class);
$userFolder = $this->createMock(Folder::class);
$owner = $this->createMock(IUser::class);
$storage = $this->createMock(\OCA\Files_Sharing\External\Storage::class);
$share->method('getSharedBy')->willReturn('sharedByUser');
$share->method('getNodeId')->willReturn(42);
$share->method('getHideDownload')->willReturn(false);
$share->method('getNode')->willReturn($node);
$node->method('getOwner')->willReturn($owner);
$owner->method('getUID')->willReturn('differentOwner');
$node->method('getStorage')->willReturn($storage);
$storage->method('instanceOfStorage')->willReturnMap([
[SharedStorage::class, false],
[\OCA\Files_Sharing\External\Storage::class, true]
]);
$userFolder->method('getById')->with(42)->willReturn([]);
$this->rootFolder->method('getUserFolder')->with('sharedByUser')->willReturn($userFolder);
$share->expects($this->once())->method('setHideDownload')->with(false);
$this->invokePrivate($ocs, 'checkInheritedAttributes', [$share]);
}
}