Browse Source

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>
tags/v18.0.0beta1
John Molakvoæ (skjnldsv) 4 years ago
parent
commit
ff895abac0
No account linked to committer's email address

+ 21
- 5
apps/files_sharing/lib/Controller/ShareAPIController.php 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);

+ 62
- 0
apps/files_sharing/tests/Controller/ShareAPIControllerTest.php 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);
}


+ 4
- 4
apps/oauth2/js/oauth2.js
File diff suppressed because it is too large
View File


+ 1
- 1
apps/oauth2/js/oauth2.js.map
File diff suppressed because it is too large
View File


+ 32
- 2
build/integration/sharing_features/sharing-v1-part2.feature 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"

+ 2
- 2
build/integration/sharing_features/sharing-v1-part3.feature 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"

Loading…
Cancel
Save