Skip to content

Commit 5535a79

Browse files
committed
fix(sharing): Move permission validation to share manager
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
1 parent 55b764b commit 5535a79

File tree

2 files changed

+37
-6
lines changed

2 files changed

+37
-6
lines changed

lib/private/Share20/Manager.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,6 @@ protected function generalCreateChecks(IShare $share, bool $isUpdate = false) {
296296
throw new \InvalidArgumentException('A share requires permissions');
297297
}
298298

299-
$isFederatedShare = $share->getNode()->getStorage()->instanceOfStorage('\OCA\Files_Sharing\External\Storage');
300299
$permissions = 0;
301300

302301
$isReshare = $share->getNode()->getOwner() && $share->getNode()->getOwner()->getUID() !== $share->getSharedBy();
@@ -305,6 +304,7 @@ protected function generalCreateChecks(IShare $share, bool $isUpdate = false) {
305304
$isReshare = $share->getShareOwner() !== $share->getSharedBy();
306305
}
307306

307+
$isFederatedShare = $share->getNode()->getStorage()->instanceOfStorage('\OCA\Files_Sharing\External\Storage');
308308
if (!$isFederatedShare && $isReshare) {
309309
$userMounts = array_filter($userFolder->getById($share->getNode()->getId()), function ($mount) {
310310
// We need to filter since there might be other mountpoints that contain the file
@@ -349,6 +349,17 @@ protected function generalCreateChecks(IShare $share, bool $isUpdate = false) {
349349
}
350350
}
351351

352+
// Permissions must be valid
353+
if ($share->getPermissions() < 0 || $share->getPermissions() > \OCP\Constants::PERMISSION_ALL) {
354+
throw new \InvalidArgumentException($this->l->t('Valid permissions are required for sharing'));
355+
}
356+
357+
// Single file shares should never have delete or create permissions
358+
if (($share->getNode() instanceof File)
359+
&& (($share->getPermissions() & (\OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_DELETE)) !== 0)) {
360+
throw new \InvalidArgumentException($this->l->t('File shares cannot have create or delete permissions'));
361+
}
362+
352363
// Check that we do not share with more permissions than we have
353364
if ($share->getPermissions() & ~$permissions) {
354365
$path = $userFolder->getRelativePath($share->getNode()->getPath());

tests/lib/Share20/ManagerTest.php

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -690,10 +690,9 @@ public function dataGeneralChecks() {
690690
$mount = $this->createMock(MoveableMount::class);
691691
$limitedPermssions->method('getMountPoint')->willReturn($mount);
692692

693-
694-
$data[] = [$this->createShare(null, IShare::TYPE_USER, $limitedPermssions, $user2, $user0, $user0, 31, null, null), 'Cannot increase permissions of path', true];
693+
// increase permissions of a re-share
695694
$data[] = [$this->createShare(null, IShare::TYPE_GROUP, $limitedPermssions, $group0, $user0, $user0, 17, null, null), 'Cannot increase permissions of path', true];
696-
$data[] = [$this->createShare(null, IShare::TYPE_LINK, $limitedPermssions, null, $user0, $user0, 3, null, null), 'Cannot increase permissions of path', true];
695+
$data[] = [$this->createShare(null, IShare::TYPE_USER, $limitedPermssions, $user2, $user0, $user0, 3, null, null), 'Cannot increase permissions of path', true];
697696

698697
$nonMoveableMountPermssions = $this->createMock(Folder::class);
699698
$nonMoveableMountPermssions->method('isShareable')->willReturn(true);
@@ -718,6 +717,20 @@ public function dataGeneralChecks() {
718717
$data[] = [$this->createShare(null, IShare::TYPE_GROUP, $rootFolder, $group0, $user0, $user0, 2, null, null), 'You cannot share your root folder', true];
719718
$data[] = [$this->createShare(null, IShare::TYPE_LINK, $rootFolder, null, $user0, $user0, 16, null, null), 'You cannot share your root folder', true];
720719

720+
$allPermssionsFiles = $this->createMock(File::class);
721+
$allPermssionsFiles->method('isShareable')->willReturn(true);
722+
$allPermssionsFiles->method('getPermissions')->willReturn(\OCP\Constants::PERMISSION_ALL);
723+
$allPermssionsFiles->method('getId')->willReturn(187);
724+
$allPermssionsFiles->method('getOwner')
725+
->willReturn($owner);
726+
$allPermssionsFiles->method('getStorage')
727+
->willReturn($storage);
728+
729+
// test invalid CREATE or DELETE permissions
730+
$data[] = [$this->createShare(null, IShare::TYPE_USER, $allPermssionsFiles, $user2, $user0, $user0, \OCP\Constants::PERMISSION_ALL, null, null), 'File shares cannot have create or delete permissions', true];
731+
$data[] = [$this->createShare(null, IShare::TYPE_GROUP, $allPermssionsFiles, $group0, $user0, $user0, \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE, null, null), 'File shares cannot have create or delete permissions', true];
732+
$data[] = [$this->createShare(null, IShare::TYPE_LINK, $allPermssionsFiles, null, $user0, $user0, \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_DELETE, null, null), 'File shares cannot have create or delete permissions', true];
733+
721734
$allPermssions = $this->createMock(Folder::class);
722735
$allPermssions->method('isShareable')->willReturn(true);
723736
$allPermssions->method('getPermissions')->willReturn(\OCP\Constants::PERMISSION_ALL);
@@ -730,6 +743,12 @@ public function dataGeneralChecks() {
730743
$data[] = [$this->createShare(null, IShare::TYPE_USER, $allPermssions, $user2, $user0, $user0, 30, null, null), 'Shares need at least read permissions', true];
731744
$data[] = [$this->createShare(null, IShare::TYPE_GROUP, $allPermssions, $group0, $user0, $user0, 2, null, null), 'Shares need at least read permissions', true];
732745

746+
// test invalid permissions
747+
$data[] = [$this->createShare(null, IShare::TYPE_USER, $allPermssions, $user2, $user0, $user0, 32, null, null), 'Valid permissions are required for sharing', true];
748+
$data[] = [$this->createShare(null, IShare::TYPE_GROUP, $allPermssions, $group0, $user0, $user0, 63, null, null), 'Valid permissions are required for sharing', true];
749+
$data[] = [$this->createShare(null, IShare::TYPE_LINK, $allPermssions, null, $user0, $user0, -1, null, null), 'Valid permissions are required for sharing', true];
750+
751+
// working shares
733752
$data[] = [$this->createShare(null, IShare::TYPE_USER, $allPermssions, $user2, $user0, $user0, 31, null, null), null, false];
734753
$data[] = [$this->createShare(null, IShare::TYPE_GROUP, $allPermssions, $group0, $user0, $user0, 3, null, null), null, false];
735754
$data[] = [$this->createShare(null, IShare::TYPE_LINK, $allPermssions, null, $user0, $user0, 17, null, null), null, false];
@@ -2185,9 +2204,10 @@ public function testCanShare($expected, $sharingEnabled, $disabledForUser) {
21852204
$this->assertEquals($expected, !$exception);
21862205
}
21872206

2188-
public function testCreateShareUser() {
2207+
public function testCreateShareUser(): void {
2208+
/** @var Manager|MockObject $manager */
21892209
$manager = $this->createManagerMock()
2190-
->setMethods(['canShare', 'generalCreateChecks', 'userCreateChecks', 'pathCreateChecks'])
2210+
->onlyMethods(['canShare', 'generalCreateChecks', 'userCreateChecks', 'pathCreateChecks'])
21912211
->getMock();
21922212

21932213
$shareOwner = $this->createMock(IUser::class);

0 commit comments

Comments
 (0)