Skip to content

Commit

Permalink
merge permissions when a user has access to a folder trough multiple …
Browse files Browse the repository at this point in the history
…groups

Fixes #72, #69

Signed-off-by: Robin Appelman <robin@icewind.nl>
  • Loading branch information
icewind1991 committed Nov 8, 2017
1 parent 66bef73 commit 7d83788
Show file tree
Hide file tree
Showing 4 changed files with 181 additions and 3 deletions.
12 changes: 10 additions & 2 deletions lib/Folder/FolderManager.php
Expand Up @@ -86,7 +86,7 @@ private function getAllApplicable() {

/**
* @param string $groupId
* @return array [$mountPoint => $permissions]
* @return array[]
*/
public function getFoldersForGroup($groupId) {
$query = $this->connection->getQueryBuilder();
Expand All @@ -101,7 +101,15 @@ public function getFoldersForGroup($groupId) {
)
->where($query->expr()->eq('a.group_id', $query->createNamedParameter($groupId)));

return $query->execute()->fetchAll();
$result = $query->execute()->fetchAll();
return array_map(function ($folder) {
return [
'folder_id' => (int)$folder['folder_id'],
'mount_point' => $folder['mount_point'],
'permissions' => (int)$folder['permissions'],
'quota' => (int)$folder['quota'],
];
}, $result);
}

public function createFolder($mountPoint) {
Expand Down
18 changes: 17 additions & 1 deletion lib/Mount/MountProvider.php
Expand Up @@ -57,12 +57,28 @@ public function __construct(IGroupManager $groupProvider, FolderManager $folderM
$this->rootProvider = $rootProvider;
}

public function getMountsForUser(IUser $user, IStorageFactory $loader) {
public function getFoldersForUser(IUser $user) {
$groups = $this->groupProvider->getUserGroupIds($user);
$folders = array_reduce($groups, function ($folders, $groupId) {
return array_merge($folders, $this->folderManager->getFoldersForGroup($groupId));
}, []);

$mergedFolders = [];
foreach ($folders as $folder) {
$id = $folder['folder_id'];
if (isset($mergedFolders[$id])) {
$mergedFolders[$id]['permissions'] |= $folder['permissions'];
} else {
$mergedFolders[$id] = $folder;
}
}

return array_values($mergedFolders);
}

public function getMountsForUser(IUser $user, IStorageFactory $loader) {
$folders = $this->getFoldersForUser($user);

return array_map(function ($folder) use ($user, $loader) {
return $this->getMount($folder['folder_id'], '/' . $user->getUID() . '/files/' . $folder['mount_point'], $folder['permissions'], $folder['quota'], $loader);
}, $folders);
Expand Down
13 changes: 13 additions & 0 deletions tests/Folder/FolderManagerTest.php
Expand Up @@ -147,4 +147,17 @@ public function testRenameFolder() {
['mount_point' => 'other', 'groups' => []],
]);
}

public function testGetFoldersForGroup() {
$folderId1 = $this->manager->createFolder('foo');
$this->manager->addApplicableGroup($folderId1, 'g1');
$this->manager->addApplicableGroup($folderId1, 'g2');
$this->manager->setGroupPermissions($folderId1, 'g1', 2);

$folders = $this->manager->getFoldersForGroup('g1');
$this->assertCount(1, $folders);
$folder = $folders[0];
$this->assertEquals('foo', $folder['mount_point']);
$this->assertEquals(2, $folder['permissions']);
}
}
141 changes: 141 additions & 0 deletions tests/Mount/MountProviderTest.php
@@ -0,0 +1,141 @@
<?php
/**
* @copyright Copyright (c) 2017 Robin Appelman <robin@icewind.nl>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

namespace OCA\GroupFolders\Tests\Mount;

use OC\User\User;
use OCA\GroupFolders\Folder\FolderManager;
use OCA\GroupFolders\Mount\MountProvider;
use OCP\Files\Folder;
use OCP\Files\Storage\IStorageFactory;
use OCP\IGroupManager;
use OCP\IUser;
use Test\TestCase;
use Test\Traits\UserTrait;

class MountProviderTest extends TestCase {
/** @var IGroupManager|\PHPUnit_Framework_MockObject_MockObject */
private $groupManager;
/** @var FolderManager|\PHPUnit_Framework_MockObject_MockObject */
private $folderManager;
/** @var Folder|\PHPUnit_Framework_MockObject_MockObject */
private $rootFolder;
/** @var IStorageFactory|\PHPUnit_Framework_MockObject_MockObject */
private $loader;
/** @var MountProvider */
private $mountProvider;

protected function setUp() {
parent::setUp();

$this->groupManager = $this->createMock(IGroupManager::class);
$this->folderManager = $this->createMock(FolderManager::class);
$this->rootFolder = $this->createMock(Folder::class);
$this->loader = $this->createMock(IStorageFactory::class);

$this->rootFolder->expects($this->any())
->method('get')
->willReturn($this->rootFolder);

$this->mountProvider = new MountProvider($this->groupManager, $this->folderManager, function () {
return $this->rootFolder;
});
}

/**
* @param string[] $groups
* @return \PHPUnit_Framework_MockObject_MockObject|IUser
*/
protected function getUser($groups = []) {
$user = $this->createMock(IUser::class);
$this->groupManager->expects($this->any())
->method('getUserGroupIds')
->willReturn($groups);

return $user;
}

public function testGetFoldersForUserEmpty() {
$folders = $this->mountProvider->getFoldersForUser($this->getUser());
$this->assertEquals([], $folders);
}

public function testGetFoldersForUserSimple() {
$folder = [
[
'folder_id' => 1,
'mount_point' => 'foo',
'permissions' => 31,
'quota' => -3
]
];

$this->folderManager->expects($this->once())
->method('getFoldersForGroup')
->willReturn($folder);

$folders = $this->mountProvider->getFoldersForUser($this->getUser(['g1']));
$this->assertEquals($folder, $folders);
}

public function testGetFoldersForUserMerge() {
$folder1 = [
[
'folder_id' => 1,
'mount_point' => 'foo',
'permissions' => 3,
'quota' => 1000
]
];
$folder2 = [
[
'folder_id' => 1,
'mount_point' => 'foo',
'permissions' => 8,
'quota' => 1000
]
];

$this->folderManager->expects($this->any())
->method('getFoldersForGroup')
->willReturnCallback(function ($group) use ($folder1, $folder2) {
switch ($group) {
case 'g1':
return $folder1;
case 'g2':
return $folder2;
default:
return [];
}
});

$folders = $this->mountProvider->getFoldersForUser($this->getUser(['g1', 'g2', 'g3']));
$this->assertEquals([
[
'folder_id' => 1,
'mount_point' => 'foo',
'permissions' => 11,
'quota' => 1000
]
], $folders);
}
}

0 comments on commit 7d83788

Please sign in to comment.