Fix shares read permissions

A user with reshare permissions on a file is now able to get any share
of that file (just like the owner).

Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
This commit is contained in:
John Molakvoæ (skjnldsv) 2019-08-16 15:09:15 +02:00
parent b1069b29fa
commit ff895abac0
No known key found for this signature in database
GPG Key ID: 60C25B8C072916CF
6 changed files with 122 additions and 14 deletions

View File

@ -305,13 +305,13 @@ class ShareAPIController extends OCSController {
throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
}
if ($this->canAccessShare($share)) {
try {
try {
if ($this->canAccessShare($share)) {
$share = $this->formatShare($share);
return new DataResponse([$share]);
} catch (NotFoundException $e) {
//Fall trough
}
} catch (NotFoundException $e) {
// Fall trough
}
throw new OCSNotFoundException($this->l->t('Wrong share ID, share doesn\'t exist'));
@ -983,6 +983,13 @@ class ShareAPIController extends OCSController {
}
/**
* Does the user have read permission on the share
*
* @param \OCP\Share\IShare $share the share to check
* @param boolean $checkGroups check groups as well?
* @return boolean
* @throws NotFoundException
*
* @suppress PhanUndeclaredClassMethod
*/
protected function canAccessShare(\OCP\Share\IShare $share, bool $checkGroups = true): bool {
@ -997,12 +1004,21 @@ class ShareAPIController extends OCSController {
return true;
}
// If the share is shared with you (or a group you are a member of)
// If the share is shared with you, you can access it!
if ($share->getShareType() === Share::SHARE_TYPE_USER
&& $share->getSharedWith() === $this->currentUser) {
return true;
}
// Have reshare rights on the shared file/folder ?
// Does the currentUser have access to the shared file?
$userFolder = $this->rootFolder->getUserFolder($this->currentUser);
$files = $userFolder->getById($share->getNodeId());
if (!empty($files) && $this->shareProviderResharingRights($this->currentUser, $share, $files[0])) {
return true;
}
// If in the recipient group, you can see the share
if ($checkGroups && $share->getShareType() === Share::SHARE_TYPE_GROUP) {
$sharedWith = $this->groupManager->get($share->getSharedWith());
$user = $this->userManager->get($this->currentUser);

View File

@ -375,6 +375,15 @@ class ShareAPIControllerTest extends TestCase {
->method('lock')
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
$this->rootFolder->method('getUserFolder')
->with($this->currentUser)
->willReturn($userFolder);
$userFolder->method('getById')
->with($share->getNodeId())
->willReturn([$share->getNode()]);
$this->shareManager->expects($this->once())
->method('deleteFromSelf')
->with($share, $this->currentUser);
@ -427,6 +436,15 @@ class ShareAPIControllerTest extends TestCase {
->method('lock')
->with(\OCP\Lock\ILockingProvider::LOCK_SHARED);
$userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
$this->rootFolder->method('getUserFolder')
->with($this->currentUser)
->willReturn($userFolder);
$userFolder->method('getById')
->with($share->getNodeId())
->willReturn([$share->getNode()]);
$this->shareManager->expects($this->never())
->method('deleteFromSelf');
@ -758,6 +776,11 @@ class ShareAPIControllerTest extends TestCase {
->with('ocinternal:42', 'currentUser')
->willReturn($share);
$userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
$this->rootFolder->method('getUserFolder')
->with($this->currentUser)
->willReturn($userFolder);
$this->ocs->getShare(42);
}
@ -775,6 +798,27 @@ class ShareAPIControllerTest extends TestCase {
$share->method('getSharedWith')->willReturn($this->currentUser);
$this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
$file = $this->getMockBuilder(File::class)->getMock();
$userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
$this->rootFolder->method('getUserFolder')
->with($this->currentUser)
->willReturn($userFolder);
$userFolder->method('getById')
->with($share->getNodeId())
->willReturn([$file]);
$file->method('getPermissions')
->will($this->onConsecutiveCalls(\OCP\Constants::PERMISSION_SHARE, \OCP\Constants::PERMISSION_READ));
// getPermissions -> share
$share = $this->getMockBuilder(IShare::class)->getMock();
$share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_USER);
$share->method('getSharedWith')->willReturn($this->getMockBuilder(IUser::class)->getMock());
$this->assertTrue($this->invokePrivate($this->ocs, 'canAccessShare', [$share]));
// getPermissions -> read
$share = $this->getMockBuilder(IShare::class)->getMock();
$share->method('getShareType')->willReturn(\OCP\Share::SHARE_TYPE_USER);
$share->method('getSharedWith')->willReturn($this->getMockBuilder(IUser::class)->getMock());
@ -852,6 +896,15 @@ class ShareAPIControllerTest extends TestCase {
* @param bool canAccessShareByHelper
*/
public function testCanAccessRoomShare(bool $expected, \OCP\Share\IShare $share, bool $helperAvailable, bool $canAccessShareByHelper) {
$userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
$this->rootFolder->method('getUserFolder')
->with($this->currentUser)
->willReturn($userFolder);
$userFolder->method('getById')
->with($share->getNodeId())
->willReturn([$share->getNode()]);
if (!$helperAvailable) {
$this->appManager->method('isEnabledForUser')
->with('spreed')
@ -1727,6 +1780,15 @@ class ShareAPIControllerTest extends TestCase {
$this->shareManager->method('getShareById')->with('ocinternal:42')->willReturn($share);
$userFolder = $this->getMockBuilder('OCP\Files\Folder')->getMock();
$this->rootFolder->method('getUserFolder')
->with($this->currentUser)
->willReturn($userFolder);
$userFolder->method('getById')
->with($share->getNodeId())
->willReturn([$share->getNode()]);
$this->ocs->updateShare(42);
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -321,6 +321,36 @@ Feature: sharing
Then the OCS status code should be "404"
And the HTTP status code should be "200"
Scenario: Get a share with a user with resharing rights
Given user "user0" exists
And user "user1" exists
And user "user2" exists
And file "textfile0.txt" of user "user0" is shared with user "user1"
And file "textfile0.txt" of user "user0" is shared with user "user2"
And As an "user1"
When Getting info of last share
Then the OCS status code should be "100"
And the HTTP status code should be "200"
And Share fields of last share match with
| id | A_NUMBER |
| item_type | file |
| item_source | A_NUMBER |
| share_type | 0 |
| share_with | user2 |
| file_source | A_NUMBER |
| file_target | /textfile0.txt |
| path | /textfile0 (2).txt |
| permissions | 19 |
| stime | A_NUMBER |
| storage | A_NUMBER |
| mail_send | 0 |
| uid_owner | user0 |
| storage_id | shared::/textfile0 (2).txt |
| file_parent | A_NUMBER |
| share_with_displayname | user2 |
| displayname_owner | user0 |
| mimetype | text/plain |
Scenario: Share of folder and sub-folder to same user - core#20645
Given As an "admin"
And user "user0" exists
@ -427,8 +457,8 @@ Feature: sharing
And file "textfile0.txt" of user "user0" is shared with user "user2"
And As an "user1"
When Deleting last share
Then the OCS status code should be "404"
And the HTTP status code should be "200"
Then the OCS status code should be "403"
And the HTTP status code should be "401"
Scenario: Keep usergroup shares (#22143)
Given As an "admin"

View File

@ -398,8 +398,8 @@ Feature: sharing
When As an "user1"
And Updating last share with
| permissions | 19 |
Then the OCS status code should be "404"
And the HTTP status code should be "200"
Then the OCS status code should be "403"
And the HTTP status code should be "401"
Scenario: do not allow to increase link share permissions on reshare
Given As an "admin"