feat(files_sharing): Allow users with share permission to manage shares on IShareOwnerlessMount

Signed-off-by: provokateurin <kate@provokateurin.de>
This commit is contained in:
provokateurin 2024-10-15 11:08:21 +02:00
parent b658ab7a86
commit beea8854ca
No known key found for this signature in database
2 changed files with 137 additions and 0 deletions

View file

@ -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;
}

View file

@ -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();