Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions apps/files_sharing/lib/Controller/Share20OcsController.php
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,10 @@ public function updateShare($id) {
$share->getNode()->unlock(ILockingProvider::LOCK_SHARED);
return new Result(null, 400, $this->l->t('Wrong or no update parameter given'));
} else {
if (($share->getPermissions() < $permissions) &&
!$this->canIncreasePermission($share)) {
return new Result(null, 404, 'Cannot increase permission of ' . $share->getTarget());
}
$permissions = (int)$permissions;
$share->setPermissions($permissions);
}
Expand Down Expand Up @@ -889,6 +893,31 @@ public function updateShare($id) {
return new Result($this->formatShare($share));
}

/**
* If the user is not the owner of the share, then lets not allow to increase
* the permission of the share.
*
* @param IShare $share
* @return bool , true if permission is allowed to increase, else false. Also false if no user session available
*/
private function canIncreasePermission(IShare $share) {
$userObj = $this->userSession->getUser();
if ($userObj === null) {
return false;
}

$shareHome = $this->rootFolder->getUserFolder($share->getSharedBy());
$nodes = $shareHome->getById($share->getNode()->getId());
foreach ($nodes as $node) {
$nodeOwner = $node->getOwner()->getUID();
if ($nodeOwner !== $userObj->getUID()) {
return false;
}
}

return true;
}

/**
* @NoCSRFRequired
* @NoAdminRequired
Expand Down
90 changes: 88 additions & 2 deletions apps/files_sharing/tests/Controller/Share20OcsControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2235,7 +2235,8 @@ public function testUpdateShareCannotIncreasePermissions() {
->setShareType(Share::SHARE_TYPE_GROUP)
->setSharedWith('group1')
->setPermissions(\OCP\Constants::PERMISSION_READ)
->setNode($folder);
->setNode($folder)
->setTarget('/folderShare');

$this->request
->method('getParam')
Expand All @@ -2254,13 +2255,89 @@ public function testUpdateShareCannotIncreasePermissions() {

$this->shareManager->expects($this->never())->method('updateShare');

$expected = new Result(null, 404, 'Cannot increase permissions');
$folderOwner = $this->createMock(IUser::class);
$folderOwner->method('getUID')
->willReturn('foo1234');
$userHomeFolder = $this->createMock(Folder::class);
$userNode = $this->createMock(Folder::class);
$userNode->method('getOwner')
->willReturn($folderOwner);
$userHomeFolder->method('getById')
->willReturn([$userNode]);
$this->rootFolder->method('getUserFolder')
->willReturn($userHomeFolder);

$expected = new Result(null, 404, 'Cannot increase permission of ' . $share->getTarget());
$result = $ocs->updateShare(42);

$this->assertEquals($expected->getMeta(), $result->getMeta());
$this->assertEquals($expected->getData(), $result->getData());
}

public function providesDataForTestingIncreasePermissionRegularShare() {
return [
['file', 16, 17],
['file', 17, 19],
['folder', 17, 19],
['folder', 19, 21],
['folder', 21, 23],
];
}

/**
* @dataProvider providesDataForTestingIncreasePermissionRegularShare
*
* @param string $nodeType
* @param int $currentPermission
* @param string $updatePermissionTo
*/
public function testRegularShareRecipientCannotIncreasePermission($nodeType, $currentPermission, $updatePermissionTo) {
$ocs = $this->mockFormatShare();

$share = \OC::$server->getShareManager()->newShare();
$share
->setId(42)
->setSharedBy($this->currentUser->getUID())
->setShareOwner('anotheruser')
->setShareType(Share::SHARE_TYPE_USER)
->setSharedWith('user1')
->setPermissions($currentPermission);

if ($nodeType === 'file') {
$file = $this->createMock(File::class);
$share->setNode($file);
$share->setTarget('/testFile');
} else {
$folder = $this->createMock(Folder::class);
$share->setNode($folder);
$share->setTarget('/testFolder');
}

$this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);

$this->request
->method('getParam')
->will($this->returnValueMap([
['permissions', null, $updatePermissionTo],
]));

$folderOwner = $this->createMock(IUser::class);
$folderOwner->method('getUID')
->willReturn('foo1234');
$userHomeFolder = $this->createMock(Folder::class);
$userNode = $this->createMock(Folder::class);
$userNode->method('getOwner')
->willReturn($folderOwner);
$userHomeFolder->method('getById')
->willReturn([$userNode]);
$this->rootFolder->method('getUserFolder')
->willReturn($userHomeFolder);

$result = $ocs->updateShare(42);
$this->assertEquals(404, $result->getStatusCode());
$this->assertEquals('Cannot increase permission of ' . $share->getTarget(), $result->getMeta()['message']);
}

/**
* @dataProvider publicUploadParamsProvider
*/
Expand Down Expand Up @@ -2363,6 +2440,15 @@ public function testUpdateShareCanIncreasePermissionsIfOwner() {
->with($share)
->willReturn($share);

$userHomeFolder = $this->createMock(Folder::class);
$userNode = $this->createMock(Folder::class);
$userNode->method('getOwner')
->willReturn($this->currentUser);
$userHomeFolder->method('getById')
->willReturn([$userNode]);
$this->rootFolder->method('getUserFolder')
->willReturn($userHomeFolder);

$expected = new Result();
$result = $ocs->updateShare(42);

Expand Down