Skip to content

Commit eb9600a

Browse files
committed
take permissions from multiple paths into account for share permissions
Signed-off-by: Robin Appelman <robin@icewind.nl>
1 parent fbf1334 commit eb9600a

File tree

2 files changed

+64
-11
lines changed

2 files changed

+64
-11
lines changed

apps/files_sharing/lib/Controller/ShareAPIController.php

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -469,12 +469,21 @@ public function createShare(
469469

470470
$userFolder = $this->rootFolder->getUserFolder($this->currentUser);
471471
try {
472-
$path = $userFolder->get($path);
472+
/** @var \OC\Files\Node\Node $node */
473+
$node = $userFolder->get($path);
473474
} catch (NotFoundException $e) {
474475
throw new OCSNotFoundException($this->l->t('Wrong path, file/folder does not exist'));
475476
}
476477

477-
$share->setNode($path);
478+
// a user can have access to a file through different paths, with differing permissions
479+
// combine all permissions to determine if the user can share this file
480+
$nodes = $userFolder->getById($node->getId());
481+
foreach ($nodes as $nodeById) {
482+
/** @var \OC\Files\Node\Node $nodeById */
483+
$node->getFileInfo()['permissions'] |= $nodeById->getFileInfo()['permissions'];
484+
}
485+
486+
$share->setNode($node);
478487

479488
try {
480489
$this->lock($share->getNode());
@@ -489,7 +498,7 @@ public function createShare(
489498
// Shares always require read permissions
490499
$permissions |= Constants::PERMISSION_READ;
491500

492-
if ($path instanceof \OCP\Files\File) {
501+
if ($node instanceof \OCP\Files\File) {
493502
// Single file shares should never have delete or create permissions
494503
$permissions &= ~Constants::PERMISSION_DELETE;
495504
$permissions &= ~Constants::PERMISSION_CREATE;
@@ -500,8 +509,8 @@ public function createShare(
500509
* We check the permissions via webdav. But the permissions of the mount point
501510
* do not equal the share permissions. Here we fix that for federated mounts.
502511
*/
503-
if ($path->getStorage()->instanceOfStorage(Storage::class)) {
504-
$permissions &= ~($permissions & ~$path->getPermissions());
512+
if ($node->getStorage()->instanceOfStorage(Storage::class)) {
513+
$permissions &= ~($permissions & ~$node->getPermissions());
505514
}
506515

507516
if ($shareType === IShare::TYPE_USER) {
@@ -537,7 +546,7 @@ public function createShare(
537546
}
538547

539548
// Public upload can only be set for folders
540-
if ($path instanceof \OCP\Files\File) {
549+
if ($node instanceof \OCP\Files\File) {
541550
throw new OCSNotFoundException($this->l->t('Public upload is only possible for publicly shared folders'));
542551
}
543552

@@ -573,7 +582,7 @@ public function createShare(
573582

574583
if ($sendPasswordByTalk === 'true') {
575584
if (!$this->appManager->isEnabledForUser('spreed')) {
576-
throw new OCSForbiddenException($this->l->t('Sharing %s sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled', [$path->getPath()]));
585+
throw new OCSForbiddenException($this->l->t('Sharing %s sending the password by Nextcloud Talk failed because Nextcloud Talk is not enabled', [$node->getPath()]));
577586
}
578587

579588
$share->setSendPasswordByTalk(true);
@@ -590,7 +599,7 @@ public function createShare(
590599
}
591600
} elseif ($shareType === IShare::TYPE_REMOTE) {
592601
if (!$this->shareManager->outgoingServer2ServerSharesAllowed()) {
593-
throw new OCSForbiddenException($this->l->t('Sharing %1$s failed because the back end does not allow shares from type %2$s', [$path->getPath(), $shareType]));
602+
throw new OCSForbiddenException($this->l->t('Sharing %1$s failed because the back end does not allow shares from type %2$s', [$node->getPath(), $shareType]));
594603
}
595604

596605
if ($shareWith === null) {
@@ -609,7 +618,7 @@ public function createShare(
609618
}
610619
} elseif ($shareType === IShare::TYPE_REMOTE_GROUP) {
611620
if (!$this->shareManager->outgoingServer2ServerGroupSharesAllowed()) {
612-
throw new OCSForbiddenException($this->l->t('Sharing %1$s failed because the back end does not allow shares from type %2$s', [$path->getPath(), $shareType]));
621+
throw new OCSForbiddenException($this->l->t('Sharing %1$s failed because the back end does not allow shares from type %2$s', [$node->getPath(), $shareType]));
613622
}
614623

615624
if ($shareWith === null) {
@@ -643,13 +652,13 @@ public function createShare(
643652
try {
644653
$this->getRoomShareHelper()->createShare($share, $shareWith, $permissions, $expireDate);
645654
} catch (QueryException $e) {
646-
throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not support room shares', [$path->getPath()]));
655+
throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not support room shares', [$node->getPath()]));
647656
}
648657
} elseif ($shareType === IShare::TYPE_DECK) {
649658
try {
650659
$this->getDeckShareHelper()->createShare($share, $shareWith, $permissions, $expireDate);
651660
} catch (QueryException $e) {
652-
throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not support room shares', [$path->getPath()]));
661+
throw new OCSForbiddenException($this->l->t('Sharing %s failed because the back end does not support room shares', [$node->getPath()]));
653662
}
654663
} else {
655664
throw new OCSBadRequestException($this->l->t('Unknown share type'));

apps/files_sharing/tests/Controller/ShareAPIControllerTest.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1619,6 +1619,8 @@ public function testCreateShareInvalidPermissions() {
16191619
->method('get')
16201620
->with('valid-path')
16211621
->willReturn($path);
1622+
$userFolder->method('getById')
1623+
->willReturn([]);
16221624

16231625
$path->expects($this->once())
16241626
->method('lock')
@@ -1651,6 +1653,8 @@ public function testCreateShareUserNoShareWith() {
16511653
->method('get')
16521654
->with('valid-path')
16531655
->willReturn($path);
1656+
$userFolder->method('getById')
1657+
->willReturn([]);
16541658

16551659
$path->expects($this->once())
16561660
->method('lock')
@@ -1683,6 +1687,8 @@ public function testCreateShareUserNoValidShareWith() {
16831687
->method('get')
16841688
->with('valid-path')
16851689
->willReturn($path);
1690+
$userFolder->method('getById')
1691+
->willReturn([]);
16861692
$path->expects($this->once())
16871693
->method('lock')
16881694
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
@@ -1733,6 +1739,8 @@ public function testCreateShareUser() {
17331739
->method('get')
17341740
->with('valid-path')
17351741
->willReturn($path);
1742+
$userFolder->method('getById')
1743+
->willReturn([]);
17361744

17371745
$this->userManager->method('userExists')->with('validUser')->willReturn(true);
17381746

@@ -1787,6 +1795,8 @@ public function testCreateShareGroupNoValidShareWith() {
17871795
->method('get')
17881796
->with('valid-path')
17891797
->willReturn($path);
1798+
$userFolder->method('getById')
1799+
->willReturn([]);
17901800

17911801
$path->expects($this->once())
17921802
->method('lock')
@@ -1844,6 +1854,8 @@ public function testCreateShareGroup() {
18441854
->method('get')
18451855
->with('valid-path')
18461856
->willReturn($path);
1857+
$userFolder->method('getById')
1858+
->willReturn([]);
18471859

18481860
$this->groupManager->method('groupExists')->with('validGroup')->willReturn(true);
18491861

@@ -1896,6 +1908,8 @@ public function testCreateShareGroupNotAllowed() {
18961908
->method('get')
18971909
->with('valid-path')
18981910
->willReturn($path);
1911+
$userFolder->method('getById')
1912+
->willReturn([]);
18991913

19001914
$this->groupManager->method('groupExists')->with('validGroup')->willReturn(true);
19011915

@@ -1926,6 +1940,8 @@ public function testCreateShareLinkNoLinksAllowed() {
19261940
$path->method('getStorage')->willReturn($storage);
19271941
$this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
19281942
$this->rootFolder->method('get')->with('valid-path')->willReturn($path);
1943+
$this->rootFolder->method('getById')
1944+
->willReturn([]);
19291945

19301946
$this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
19311947

@@ -1945,6 +1961,8 @@ public function testCreateShareLinkNoPublicUpload() {
19451961
$path->method('getStorage')->willReturn($storage);
19461962
$this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
19471963
$this->rootFolder->method('get')->with('valid-path')->willReturn($path);
1964+
$this->rootFolder->method('getById')
1965+
->willReturn([]);
19481966

19491967
$this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
19501968
$this->shareManager->method('shareApiAllowLinks')->willReturn(true);
@@ -1965,6 +1983,8 @@ public function testCreateShareLinkPublicUploadFile() {
19651983
$path->method('getStorage')->willReturn($storage);
19661984
$this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
19671985
$this->rootFolder->method('get')->with('valid-path')->willReturn($path);
1986+
$this->rootFolder->method('getById')
1987+
->willReturn([]);
19681988

19691989
$this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
19701990
$this->shareManager->method('shareApiAllowLinks')->willReturn(true);
@@ -1984,6 +2004,8 @@ public function testCreateShareLinkPublicUploadFolder() {
19842004
$path->method('getStorage')->willReturn($storage);
19852005
$this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
19862006
$this->rootFolder->method('get')->with('valid-path')->willReturn($path);
2007+
$this->rootFolder->method('getById')
2008+
->willReturn([]);
19872009

19882010
$this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
19892011
$this->shareManager->method('shareApiAllowLinks')->willReturn(true);
@@ -2018,6 +2040,8 @@ public function testCreateShareLinkPassword() {
20182040
$path->method('getStorage')->willReturn($storage);
20192041
$this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
20202042
$this->rootFolder->method('get')->with('valid-path')->willReturn($path);
2043+
$this->rootFolder->method('getById')
2044+
->willReturn([]);
20212045

20222046
$this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
20232047
$this->shareManager->method('shareApiAllowLinks')->willReturn(true);
@@ -2052,6 +2076,8 @@ public function testCreateShareLinkSendPasswordByTalk() {
20522076
$path->method('getStorage')->willReturn($storage);
20532077
$this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
20542078
$this->rootFolder->method('get')->with('valid-path')->willReturn($path);
2079+
$this->rootFolder->method('getById')
2080+
->willReturn([]);
20552081

20562082
$this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
20572083
$this->shareManager->method('shareApiAllowLinks')->willReturn(true);
@@ -2094,6 +2120,8 @@ public function testCreateShareLinkSendPasswordByTalkWithTalkDisabled() {
20942120
$path->method('getPath')->willReturn('valid-path');
20952121
$this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
20962122
$this->rootFolder->method('get')->with('valid-path')->willReturn($path);
2123+
$this->rootFolder->method('getById')
2124+
->willReturn([]);
20972125

20982126
$this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
20992127
$this->shareManager->method('shareApiAllowLinks')->willReturn(true);
@@ -2127,6 +2155,8 @@ public function testCreateShareValidExpireDate() {
21272155
$path->method('getStorage')->willReturn($storage);
21282156
$this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
21292157
$this->rootFolder->method('get')->with('valid-path')->willReturn($path);
2158+
$this->rootFolder->method('getById')
2159+
->willReturn([]);
21302160

21312161
$this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
21322162
$this->shareManager->method('shareApiAllowLinks')->willReturn(true);
@@ -2168,6 +2198,8 @@ public function testCreateShareInvalidExpireDate() {
21682198
$path->method('getStorage')->willReturn($storage);
21692199
$this->rootFolder->method('getUserFolder')->with($this->currentUser)->willReturnSelf();
21702200
$this->rootFolder->method('get')->with('valid-path')->willReturn($path);
2201+
$this->rootFolder->method('getById')
2202+
->willReturn([]);
21712203

21722204
$this->shareManager->method('newShare')->willReturn(\OC::$server->getShareManager()->newShare());
21732205
$this->shareManager->method('shareApiAllowLinks')->willReturn(true);
@@ -2216,6 +2248,8 @@ public function testCreateShareRemote() {
22162248
->method('get')
22172249
->with('valid-path')
22182250
->willReturn($path);
2251+
$userFolder->method('getById')
2252+
->willReturn([]);
22192253

22202254
$this->userManager->method('userExists')->with('validUser')->willReturn(true);
22212255

@@ -2286,6 +2320,8 @@ public function testCreateShareRemoteGroup() {
22862320
->method('get')
22872321
->with('valid-path')
22882322
->willReturn($path);
2323+
$userFolder->method('getById')
2324+
->willReturn([]);
22892325

22902326
$this->userManager->method('userExists')->with('validUser')->willReturn(true);
22912327

@@ -2338,6 +2374,8 @@ public function testCreateShareRoom() {
23382374
->method('get')
23392375
->with('valid-path')
23402376
->willReturn($path);
2377+
$userFolder->method('getById')
2378+
->willReturn([]);
23412379

23422380
$path->expects($this->once())
23432381
->method('lock')
@@ -2421,6 +2459,8 @@ public function testCreateShareRoomHelperNotAvailable() {
24212459
->method('get')
24222460
->with('valid-path')
24232461
->willReturn($path);
2462+
$userFolder->method('getById')
2463+
->willReturn([]);
24242464

24252465
$path->expects($this->once())
24262466
->method('lock')
@@ -2461,6 +2501,8 @@ public function testCreateShareRoomHelperThrowException() {
24612501
->method('get')
24622502
->with('valid-path')
24632503
->willReturn($path);
2504+
$userFolder->method('getById')
2505+
->willReturn([]);
24642506

24652507
$path->expects($this->once())
24662508
->method('lock')
@@ -2541,6 +2583,8 @@ public function testCreateReshareOfFederatedMountNoDeletePermissions() {
25412583
->method('get')
25422584
->with('valid-path')
25432585
->willReturn($path);
2586+
$userFolder->method('getById')
2587+
->willReturn([]);
25442588

25452589
$this->userManager->method('userExists')->with('validUser')->willReturn(true);
25462590

0 commit comments

Comments
 (0)