aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorprovokateurin <kate@provokateurin.de>2024-10-15 11:08:21 +0200
committerprovokateurin <kate@provokateurin.de>2024-11-25 10:27:31 +0100
commitbeea8854cac3544792fc13514b5b194b875b44e6 (patch)
tree25ee303914094f43272377560235183ded17695c
parentb658ab7a86eb2df5d1af8d1ed9d466d33f6c44f0 (diff)
downloadnextcloud-server-beea8854cac3544792fc13514b5b194b875b44e6.tar.gz
nextcloud-server-beea8854cac3544792fc13514b5b194b875b44e6.zip
feat(files_sharing): Allow users with share permission to manage shares on IShareOwnerlessMount
Signed-off-by: provokateurin <kate@provokateurin.de>
-rw-r--r--apps/files_sharing/lib/Controller/ShareAPIController.php13
-rw-r--r--apps/files_sharing/tests/Controller/ShareAPIControllerTest.php124
2 files changed, 137 insertions, 0 deletions
diff --git a/apps/files_sharing/lib/Controller/ShareAPIController.php b/apps/files_sharing/lib/Controller/ShareAPIController.php
index 2ef4cb77726..ff20a0acf3c 100644
--- a/apps/files_sharing/lib/Controller/ShareAPIController.php
+++ b/apps/files_sharing/lib/Controller/ShareAPIController.php
@@ -35,6 +35,7 @@ use OCP\Files\File;
use OCP\Files\Folder;
use OCP\Files\InvalidPathException;
use OCP\Files\IRootFolder;
+use OCP\Files\Mount\IShareOwnerlessMount;
use OCP\Files\Node;
use OCP\Files\NotFoundException;
use OCP\HintException;
@@ -1541,6 +1542,12 @@ class ShareAPIController extends OCSController {
return true;
}
+ $userFolder = $this->rootFolder->getUserFolder($this->userId);
+ $file = $userFolder->getFirstNodeById($share->getNodeId());
+ if ($file?->getMountPoint() instanceof IShareOwnerlessMount && $this->shareProviderResharingRights($this->userId, $share, $file)) {
+ return true;
+ }
+
//! we do NOT support some kind of `admin` in groups.
//! You cannot edit shares shared to a group you're
//! a member of if you're not the share owner or the file owner!
@@ -1576,6 +1583,12 @@ class ShareAPIController extends OCSController {
return true;
}
+ $userFolder = $this->rootFolder->getUserFolder($this->userId);
+ $file = $userFolder->getFirstNodeById($share->getNodeId());
+ if ($file?->getMountPoint() instanceof IShareOwnerlessMount && $this->shareProviderResharingRights($this->userId, $share, $file)) {
+ return true;
+ }
+
return false;
}
diff --git a/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php b/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php
index 768bebe0271..abb98826ab5 100644
--- a/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php
+++ b/apps/files_sharing/tests/Controller/ShareAPIControllerTest.php
@@ -18,6 +18,7 @@ use OCP\Files\File;
use OCP\Files\Folder;
use OCP\Files\IRootFolder;
use OCP\Files\Mount\IMountPoint;
+use OCP\Files\Mount\IShareOwnerlessMount;
use OCP\Files\NotFoundException;
use OCP\Files\Storage\IStorage;
use OCP\IConfig;
@@ -232,10 +233,20 @@ class ShareAPIControllerTest extends TestCase {
$this->expectExceptionMessage('Could not delete share');
$node = $this->getMockBuilder(File::class)->getMock();
+ $node->method('getId')->willReturn(1);
$share = $this->newShare();
$share->setNode($node);
+ $userFolder = $this->getMockBuilder(Folder::class)->getMock();
+ $this->rootFolder->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $userFolder->method('getFirstNodeById')
+ ->with($share->getNodeId())
+ ->willReturn($node);
+
$this->shareManager
->expects($this->once())
->method('getShareById')
@@ -476,6 +487,62 @@ class ShareAPIControllerTest extends TestCase {
$this->ocs->deleteShare(42);
}
+ public function testDeleteShareOwnerless(): void {
+ $ocs = $this->mockFormatShare();
+
+ $mount = $this->createMock(IShareOwnerlessMount::class);
+
+ $file = $this->createMock(File::class);
+ $file
+ ->expects($this->exactly(2))
+ ->method('getPermissions')
+ ->willReturn(Constants::PERMISSION_SHARE);
+ $file
+ ->expects($this->once())
+ ->method('getMountPoint')
+ ->willReturn($mount);
+
+ $userFolder = $this->createMock(Folder::class);
+ $userFolder
+ ->expects($this->exactly(2))
+ ->method('getFirstNodeById')
+ ->with(2)
+ ->willReturn($file);
+
+ $this->rootFolder
+ ->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $share = $this->createMock(IShare::class);
+ $share
+ ->expects($this->once())
+ ->method('getNode')
+ ->willReturn($file);
+ $share
+ ->expects($this->exactly(2))
+ ->method('getNodeId')
+ ->willReturn(2);
+ $share
+ ->expects($this->exactly(2))
+ ->method('getPermissions')
+ ->willReturn(Constants::PERMISSION_SHARE);
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('getShareById')
+ ->with('ocinternal:1', $this->currentUser)
+ ->willReturn($share);
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('deleteShare')
+ ->with($share);
+
+ $result = $ocs->deleteShare(1);
+ $this->assertInstanceOf(DataResponse::class, $result);
+ }
+
/*
* FIXME: Enable once we have a federated Share Provider
@@ -3748,6 +3815,63 @@ class ShareAPIControllerTest extends TestCase {
$this->assertInstanceOf(DataResponse::class, $result);
}
+ public function testUpdateShareOwnerless(): void {
+ $ocs = $this->mockFormatShare();
+
+ $mount = $this->createMock(IShareOwnerlessMount::class);
+
+ $file = $this->createMock(File::class);
+ $file
+ ->expects($this->exactly(2))
+ ->method('getPermissions')
+ ->willReturn(Constants::PERMISSION_SHARE);
+ $file
+ ->expects($this->once())
+ ->method('getMountPoint')
+ ->willReturn($mount);
+
+ $userFolder = $this->createMock(Folder::class);
+ $userFolder
+ ->expects($this->exactly(2))
+ ->method('getFirstNodeById')
+ ->with(2)
+ ->willReturn($file);
+
+ $this->rootFolder
+ ->method('getUserFolder')
+ ->with($this->currentUser)
+ ->willReturn($userFolder);
+
+ $share = $this->createMock(IShare::class);
+ $share
+ ->expects($this->once())
+ ->method('getNode')
+ ->willReturn($file);
+ $share
+ ->expects($this->exactly(2))
+ ->method('getNodeId')
+ ->willReturn(2);
+ $share
+ ->expects($this->exactly(2))
+ ->method('getPermissions')
+ ->willReturn(Constants::PERMISSION_SHARE);
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('getShareById')
+ ->with('ocinternal:1', $this->currentUser)
+ ->willReturn($share);
+
+ $this->shareManager
+ ->expects($this->once())
+ ->method('updateShare')
+ ->with($share)
+ ->willReturn($share);
+
+ $result = $ocs->updateShare(1, Constants::PERMISSION_ALL);
+ $this->assertInstanceOf(DataResponse::class, $result);
+ }
+
public function dataFormatShare() {
$file = $this->getMockBuilder(File::class)->getMock();
$folder = $this->getMockBuilder(Folder::class)->getMock();