Add getAccessList to ShareManager

Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
This commit is contained in:
Roeland Jago Douma 2016-09-09 12:53:17 +02:00
parent 5505faa3d7
commit d84df15590
No known key found for this signature in database
GPG key ID: F941078878347C0C
2 changed files with 144 additions and 6 deletions

View file

@ -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];
}
/**

View file

@ -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 {