Skip to content

Commit 303eed2

Browse files
Merge pull request #62218 from nextcloud/backport/61905/stable34
[stable34] fix(files_sharing): preserve unmasked permissions as scan_permissions
2 parents 2735918 + c394016 commit 303eed2

2 files changed

Lines changed: 52 additions & 0 deletions

File tree

apps/files_sharing/lib/Cache.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,9 @@ protected function formatCacheEntry($entry, $path = null) {
145145

146146
try {
147147
if (isset($entry['permissions'])) {
148+
// keep the unmasked permissions so a future scan or cross-storage
149+
// copy doesn't persist the share-masked permissions in the cache
150+
$entry['scan_permissions'] ??= $entry['permissions'];
148151
$entry['permissions'] &= $this->share->getPermissions();
149152
} else {
150153
$entry['permissions'] = $this->storage->getPermissions($entry['path']);

apps/files_sharing/tests/CacheTest.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,55 @@ public function testSearchShareJailedStorage(): void {
558558
$this->assertCount(1, $results);
559559
}
560560

561+
public function testSingleFileShareKeepsUnmaskedPermissionsAsScanPermissions(): void {
562+
$sourceEntry = $this->ownerCache->get('files/container/shared single file.txt');
563+
564+
/** @var SharedStorage $sharedStorage */
565+
[$sharedStorage] = $this->user2View->resolvePath('shared single file.txt');
566+
$entry = $sharedStorage->getCache()->get('');
567+
568+
$mask = Constants::PERMISSION_ALL & ~(Constants::PERMISSION_CREATE | Constants::PERMISSION_DELETE);
569+
$this->assertEquals($sourceEntry->getPermissions() & $mask, $entry->getPermissions());
570+
$this->assertEquals($sourceEntry->getPermissions(), $entry['scan_permissions']);
571+
}
572+
573+
public function testFolderShareKeepsUnmaskedPermissionsAsScanPermissions(): void {
574+
self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
575+
576+
$rootFolder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER1);
577+
$node = $rootFolder->get('container');
578+
$share = $this->shareManager->newShare();
579+
$share->setNode($node)
580+
->setShareType(IShare::TYPE_USER)
581+
->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
582+
->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
583+
->setPermissions(Constants::PERMISSION_READ | Constants::PERMISSION_SHARE);
584+
$share = $this->shareManager->createShare($share);
585+
$share->setStatus(IShare::STATUS_ACCEPTED);
586+
$this->shareManager->updateShare($share);
587+
Server::get(ISetupManager::class)->tearDown();
588+
589+
self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
590+
591+
/** @var SharedStorage $sharedStorage */
592+
[$sharedStorage] = $this->user2View->resolvePath('container');
593+
$sharedCache = $sharedStorage->getCache();
594+
$mask = Constants::PERMISSION_READ | Constants::PERMISSION_SHARE;
595+
596+
$entry = $sharedCache->get('shareddir/bar.txt');
597+
$sourceEntry = $this->ownerCache->get('files/container/shareddir/bar.txt');
598+
$this->assertEquals($sourceEntry->getPermissions() & $mask, $entry->getPermissions());
599+
$this->assertEquals($sourceEntry->getPermissions(), $entry['scan_permissions']);
600+
601+
$children = $sharedCache->getFolderContents('shareddir');
602+
$this->assertNotEmpty($children);
603+
foreach ($children as $child) {
604+
$sourceChild = $this->ownerCache->get('files/container/shareddir/' . $child->getName());
605+
$this->assertEquals($sourceChild->getPermissions() & $mask, $child->getPermissions());
606+
$this->assertEquals($sourceChild->getPermissions(), $child['scan_permissions']);
607+
}
608+
}
609+
561610
public function testWatcherRootChange(): void {
562611
$sourceStorage = new Temporary();
563612
$sourceStorage->mkdir('shared');

0 commit comments

Comments
 (0)