diff options
author | Roeland Jago Douma <roeland@famdouma.nl> | 2016-09-09 12:53:17 +0200 |
---|---|---|
committer | Roeland Jago Douma <roeland@famdouma.nl> | 2017-04-13 12:58:48 +0200 |
commit | d84df155900bfdb58a8826802cde5a096065a078 (patch) | |
tree | 32271ae27883407fd0123902b779ad8125d100a4 | |
parent | 5505faa3d7b6f5a95f18fe5027355d700d69f396 (diff) | |
download | nextcloud-server-d84df155900bfdb58a8826802cde5a096065a078.tar.gz nextcloud-server-d84df155900bfdb58a8826802cde5a096065a078.zip |
Add getAccessList to ShareManager
Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
-rw-r--r-- | lib/private/Share20/Manager.php | 67 | ||||
-rw-r--r-- | tests/lib/Share20/ManagerTest.php | 83 |
2 files changed, 144 insertions, 6 deletions
diff --git a/lib/private/Share20/Manager.php b/lib/private/Share20/Manager.php index 292b07d28d5..127eef423ed 100644 --- a/lib/private/Share20/Manager.php +++ b/lib/private/Share20/Manager.php @@ -48,6 +48,7 @@ use OCP\Share\Exceptions\GenericShareException; use OCP\Share\Exceptions\ShareNotFound; use OCP\Share\IManager; use OCP\Share\IProviderFactory; +use OCP\Share\IShare; use Symfony\Component\EventDispatcher\EventDispatcher; use Symfony\Component\EventDispatcher\GenericEvent; use OCP\Share\IShareProvider; @@ -1176,7 +1177,7 @@ class Manager implements IManager { /** * Get access list to a path. This means - * all the users and groups that can access a given path. + * all the users that can access a given path. * * Consider: * -root @@ -1185,20 +1186,76 @@ class Manager implements IManager { * |-fileA * * fileA is shared with user1 - * folder2 is shared with group2 + * folder2 is shared with group2 (user4 is a member of group2) * folder1 is shared with user2 * * Then the access list will to '/folder1/folder2/fileA' is: * [ - * 'users' => ['user1', 'user2'], - * 'groups' => ['group2'] + * users => ['user1', 'user2', 'user4'], + * public => bool + * remote => bool * ] * - * This is required for encryption + * This is required for encryption/activities * * @param \OCP\Files\Node $path + * @return array */ public function getAccessList(\OCP\Files\Node $path) { + $owner = $path->getOwner()->getUID(); + + //Get node for the owner + $userFolder = $this->rootFolder->getUserFolder($owner); + $path = $userFolder->getById($path->getId())[0]; + + $providers = $this->factory->getAllProviders(); + + /** @var IShare[] $shares */ + $shares = []; + + // Collect all the shares + while ($path !== $userFolder) { + foreach ($providers as $provider) { + $shares = array_merge($shares, $provider->getSharesByPath($path)); + } + $path = $path->getParent(); + } + + $users = []; + $public = false; + $remote = false; + foreach ($shares as $share) { + if ($share->getShareType() === \OCP\Share::SHARE_TYPE_USER) { + $uid = $share->getSharedWith(); + + // Skip if user does not exist + if (!$this->userManager->userExists($uid)) { + continue; + } + + $users[$uid] = null; + } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_GROUP) { + $group = $this->groupManager->get($share->getSharedWith()); + + // If group does not exist skip + if ($group === null) { + continue; + } + + $groupUsers = $group->getUsers(); + foreach ($groupUsers as $groupUser) { + $users[$groupUser->getUID()] = null; + } + } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_LINK) { + $public = true; + } else if ($share->getShareType() === \OCP\Share::SHARE_TYPE_REMOTE) { + $remote = true; + } + } + + $users = array_keys($users); + + return ['users' => $users, 'public' => $public, 'remote' => $remote]; } /** diff --git a/tests/lib/Share20/ManagerTest.php b/tests/lib/Share20/ManagerTest.php index 5436b188350..20ba62fa225 100644 --- a/tests/lib/Share20/ManagerTest.php +++ b/tests/lib/Share20/ManagerTest.php @@ -2639,7 +2639,6 @@ class ManagerTest extends \Test\TestCase { $this->manager->moveShare($share, 'recipient'); } - /** * @dataProvider dataTestShareProviderExists */ @@ -2737,6 +2736,88 @@ class ManagerTest extends \Test\TestCase { $this->assertSame($expects, $result); } + + public function testGetAccessList() { + $owner = $this->createMock(IUser::class); + $owner->expects($this->once()) + ->method('getUID') + ->willReturn('owner'); + + $node = $this->createMock(Node::class); + $node->expects($this->once()) + ->method('getOwner') + ->willReturn($owner); + $node->expects($this->once()) + ->method('getId') + ->willReturn(42); + + $userFolder = $this->createMock(Folder::class); + $file = $this->createMock(File::class); + $folder = $this->createMock(Folder::class); + + $file->method('getParent') + ->willReturn($folder); + $folder->method('getParent') + ->willReturn($userFolder); + $userFolder->method('getById') + ->with($this->equalTo(42)) + ->willReturn([$file]); + + $userShare = $this->createMock(IShare::class); + $userShare->method('getShareType') + ->willReturn(\OCP\Share::SHARE_TYPE_USER); + $userShare->method('getSharedWith') + ->willReturn('user1'); + $groupShare = $this->createMock(IShare::class); + $groupShare->method('getShareType') + ->willReturn(\OCP\Share::SHARE_TYPE_GROUP); + $groupShare->method('getSharedWith') + ->willReturn('group1'); + $publicShare = $this->createMock(IShare::class); + $publicShare->method('getShareType') + ->willReturn(\OCP\Share::SHARE_TYPE_LINK); + $remoteShare = $this->createMock(IShare::class); + $remoteShare->method('getShareType') + ->willReturn(\OCP\Share::SHARE_TYPE_REMOTE); + + $this->userManager->method('userExists') + ->with($this->equalTo('user1')) + ->willReturn(true); + + $user2 = $this->createMock(IUser::class); + $user2->method('getUID') + ->willReturn('user2'); + $group1 = $this->createMock(IGroup::class); + $this->groupManager->method('get') + ->with($this->equalTo('group1')) + ->willReturn($group1); + $group1->method('getUsers') + ->willReturn([$user2]); + + $this->defaultProvider->expects($this->any()) + ->method('getSharesByPath') + ->will($this->returnCallback(function(Node $path) use ($file, $folder, $userShare, $groupShare, $publicShare, $remoteShare) { + if ($path === $file) { + return [$userShare, $publicShare]; + } else if ($path === $folder) { + return [$groupShare, $remoteShare]; + } else { + return []; + } + })); + + $this->rootFolder->method('getUserFolder') + ->with($this->equalTo('owner')) + ->willReturn($userFolder); + + $expected = [ + 'users' => ['user1', 'user2'], + 'public' => true, + 'remote' => true, + ]; + + $this->assertEquals($expected, $this->manager->getAccessList($node)); + } } class DummyFactory implements IProviderFactory { |