diff --git a/.gitignore b/.gitignore
index 643b389b6..fd6636480 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@ node_modules/
build
vendor
js/
+.idea/
diff --git a/lib/ACL/RuleManager.php b/lib/ACL/RuleManager.php
index 2d35f5bfb..db619392c 100644
--- a/lib/ACL/RuleManager.php
+++ b/lib/ACL/RuleManager.php
@@ -21,23 +21,31 @@
namespace OCA\GroupFolders\ACL;
+use OCA\GroupFolders\ACL\UserMapping\IEntityMappingManager;
use OCA\GroupFolders\ACL\UserMapping\IUserMapping;
-use OCA\GroupFolders\ACL\UserMapping\IUserMappingManager;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\IDBConnection;
use OCP\IUser;
class RuleManager {
private $connection;
- private $userMappingManager;
- public function __construct(IDBConnection $connection, IUserMappingManager $userMappingManager) {
+ /**
+ * @var IEntityMappingManager
+ */
+ private $entityMappingManager;
+
+
+ public function __construct(
+ IDBConnection $connection,
+ IEntityMappingManager $entityMappingManager
+ ) {
$this->connection = $connection;
- $this->userMappingManager = $userMappingManager;
+ $this->entityMappingManager = $entityMappingManager;
}
private function createRule(array $data): ?Rule {
- $mapping = $this->userMappingManager->mappingFromId($data['mapping_type'], $data['mapping_id']);
+ $mapping = $this->entityMappingManager->mappingFromId($data['mapping_id']);
if ($mapping) {
return new Rule(
$mapping,
@@ -56,7 +64,7 @@ private function createRule(array $data): ?Rule {
* @return (Rule[])[] [$fileId => Rule[]]
*/
public function getRulesForFilesById(IUser $user, array $fileIds): array {
- $userMappings = $this->userMappingManager->getMappingsForUser($user);
+ $userMappings = $this->entityMappingManager->getMappingsForUser($user);
$query = $this->connection->getQueryBuilder();
$query->select(['fileid', 'mapping_type', 'mapping_id', 'mask', 'permissions'])
@@ -242,7 +250,7 @@ public function getAllRulesForPrefix(int $storageId, string $prefix): array {
* @return array (Rule[])[] [$path => Rule[]]
*/
public function getRulesForPrefix(IUser $user, int $storageId, string $prefix): array {
- $userMappings = $this->userMappingManager->getMappingsForUser($user);
+ $userMappings = $this->entityMappingManager->getMappingsForUser($user);
$query = $this->connection->getQueryBuilder();
$query->select(['f.fileid', 'mapping_type', 'mapping_id', 'mask', 'a.permissions', 'path'])
diff --git a/lib/ACL/UserMapping/EntityMappingManager.php b/lib/ACL/UserMapping/EntityMappingManager.php
new file mode 100644
index 000000000..5d121871b
--- /dev/null
+++ b/lib/ACL/UserMapping/EntityMappingManager.php
@@ -0,0 +1,136 @@
+
+ *
+ * @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 .
+ *
+ */
+
+namespace OCA\GroupFolders\ACL\UserMapping;
+
+use OCA\Circles\Exceptions\CircleNotFoundException;
+use OCA\Circles\Exceptions\FederatedItemException;
+use OCA\Circles\Exceptions\FederatedUserException;
+use OCA\Circles\Exceptions\FederatedUserNotFoundException;
+use OCA\Circles\Exceptions\InvalidIdException;
+use OCA\Circles\Exceptions\MemberNotFoundException;
+use OCA\Circles\Exceptions\OwnerNotFoundException;
+use OCA\Circles\Exceptions\RemoteInstanceException;
+use OCA\Circles\Exceptions\RemoteNotFoundException;
+use OCA\Circles\Exceptions\RemoteResourceNotFoundException;
+use OCA\Circles\Exceptions\RequestBuilderException;
+use OCA\Circles\Exceptions\SingleCircleNotFoundException;
+use OCA\Circles\Exceptions\UnknownRemoteException;
+use OCA\Circles\Exceptions\UserTypeNotFoundException;
+use OCA\Circles\Model\Member;
+use OCA\Circles\Model\Probes\CircleProbe;
+use OCP\Circles\ICirclesManager;
+use OCP\IUser;
+
+
+/**
+ * Class EntityMappingManager
+ *
+ * @package OCA\GroupFolders\ACL\UserMapping
+ */
+class EntityMappingManager implements IEntityMappingManager {
+
+ /** @var ICirclesManager */
+ private $circlesManager;
+
+
+ /**
+ * EntityMappingManager constructor.
+ *
+ * @param ICirclesManager $circlesManager
+ */
+ public function __construct(ICirclesManager $circlesManager) {
+ $this->circlesManager = $circlesManager;
+ }
+
+
+ /**
+ * @param IUser $user
+ * @param bool $userAssignable
+ *
+ * @return array
+ * @throws CircleNotFoundException
+ * @throws FederatedItemException
+ * @throws FederatedUserException
+ * @throws FederatedUserNotFoundException
+ * @throws InvalidIdException
+ * @throws MemberNotFoundException
+ * @throws OwnerNotFoundException
+ * @throws RemoteInstanceException
+ * @throws RemoteNotFoundException
+ * @throws RemoteResourceNotFoundException
+ * @throws RequestBuilderException
+ * @throws SingleCircleNotFoundException
+ * @throws UnknownRemoteException
+ * @throws UserTypeNotFoundException
+ */
+ public function getMappingsForUser(IUser $user, bool $userAssignable = true): array {
+ $federatedUser = $this->circlesManager->getFederatedUser($user->getUID(), Member::TYPE_USER);
+
+ $mappings = [];
+ foreach ($federatedUser->getMemberships() as $membership) {
+ // TODO: lighten by providing details within getMemberships();
+ $probe = new CircleProbe();
+ $probe->includeSystemCircles();
+ $probe->includeSingleCircles();
+ $circle = $this->circlesManager->getCircle($membership->getCircleId(), $probe);
+
+ $mappings[] =
+ new UserMapping(
+ 'entity',
+ $membership->getCircleId(),
+ $circle->getDisplayName()
+ );
+ }
+
+ return $mappings;
+ }
+
+
+ /**
+ * @param string $id
+ *
+ * @return IUserMapping|null
+ * @throws CircleNotFoundException
+ * @throws FederatedItemException
+ * @throws FederatedUserException
+ * @throws FederatedUserNotFoundException
+ * @throws InvalidIdException
+ * @throws MemberNotFoundException
+ * @throws OwnerNotFoundException
+ * @throws RemoteInstanceException
+ * @throws RemoteNotFoundException
+ * @throws RemoteResourceNotFoundException
+ * @throws RequestBuilderException
+ * @throws SingleCircleNotFoundException
+ * @throws UnknownRemoteException
+ * @throws UserTypeNotFoundException
+ */
+ public function mappingFromId(string $id): ?IUserMapping {
+ $federatedUser = $this->circlesManager->getFederatedUser($id);
+
+ return new UserMapping('entity', $id, $federatedUser->getDisplayName());
+ }
+
+}
diff --git a/lib/ACL/UserMapping/IEntityMappingManager.php b/lib/ACL/UserMapping/IEntityMappingManager.php
new file mode 100644
index 000000000..4a5b282c1
--- /dev/null
+++ b/lib/ACL/UserMapping/IEntityMappingManager.php
@@ -0,0 +1,48 @@
+
+ *
+ * @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 .
+ *
+ */
+
+namespace OCA\GroupFolders\ACL\UserMapping;
+
+use OCP\IUser;
+
+
+/**
+ * Interface IEntityMappingManager
+ *
+ * @package OCA\GroupFolders\ACL\UserMapping
+ */
+interface IEntityMappingManager {
+ /**
+ * @param IUser $user
+ * @param bool $userAssignable whether to include mappings that are assignable by non admin users
+ * @return IUserMapping[]
+ */
+ public function getMappingsForUser(IUser $user, bool $userAssignable = true): array;
+
+ /**
+ * @param string $id
+ * @return IUserMapping|null
+ */
+ public function mappingFromId(string $id): ?IUserMapping;
+}
diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php
index 42c8a2ec9..09fd75e8f 100644
--- a/lib/AppInfo/Application.php
+++ b/lib/AppInfo/Application.php
@@ -25,6 +25,8 @@
use OCA\Files_Sharing\Event\BeforeTemplateRenderedEvent;
use OCA\GroupFolders\ACL\ACLManagerFactory;
use OCA\GroupFolders\ACL\RuleManager;
+use OCA\GroupFolders\ACL\UserMapping\EntityMappingManager;
+use OCA\GroupFolders\ACL\UserMapping\IEntityMappingManager;
use OCA\GroupFolders\ACL\UserMapping\IUserMappingManager;
use OCA\GroupFolders\ACL\UserMapping\UserMappingManager;
use OCA\GroupFolders\CacheListener;
@@ -127,7 +129,7 @@ public function register(IRegistrationContext $context): void {
);
});
- $context->registerServiceAlias(IUserMappingManager::class, UserMappingManager::class);
+ $context->registerServiceAlias(IEntityMappingManager::class, EntityMappingManager::class);
}
public function boot(IBootContext $context): void {
diff --git a/lib/Command/Group.php b/lib/Command/Group.php
index 8c6208507..04e041483 100644
--- a/lib/Command/Group.php
+++ b/lib/Command/Group.php
@@ -22,7 +22,10 @@
namespace OCA\GroupFolders\Command;
use OC\Core\Command\Base;
+use OCA\Circles\CirclesManager;
+use OCA\Circles\Model\Probes\CircleProbe;
use OCA\GroupFolders\Folder\FolderManager;
+use OCP\Circles\ICirclesManager;
use OCP\Constants;
use OCP\Files\IRootFolder;
use OCP\IGroupManager;
@@ -44,11 +47,20 @@ class Group extends Base {
private $rootFolder;
private $groupManager;
- public function __construct(FolderManager $folderManager, IRootFolder $rootFolder, IGroupManager $groupManager) {
+ /** @var ICirclesManager */
+ private $circlesManager;
+
+ public function __construct(
+ FolderManager $folderManager,
+ IRootFolder $rootFolder,
+ IGroupManager $groupManager,
+ ICirclesManager $circlesManager
+ ) {
parent::__construct();
$this->folderManager = $folderManager;
$this->rootFolder = $rootFolder;
$this->groupManager = $groupManager;
+ $this->circlesManager = $circlesManager;
}
protected function configure() {
@@ -68,25 +80,32 @@ protected function execute(InputInterface $input, OutputInterface $output) {
$folder = $this->folderManager->getFolder($folderId, $this->rootFolder->getMountPoint()->getNumericStorageId());
if ($folder) {
$groupString = $input->getArgument('group');
- $group = $this->groupManager->get($groupString);
+
+ // confirmation that $groupString is a valid CircleId
+ $this->circlesManager->startSuperSession();
+
+ $probe = new CircleProbe();
+ $probe->includeSystemCircles();
+ $this->circlesManager->getCircle($groupString);
+
+// $group = $this->groupManager->get($groupString);
if ($input->getOption('delete')) {
$this->folderManager->removeApplicableGroup($folderId, $groupString);
return 0;
- } elseif ($group) {
- $permissionsString = $input->getArgument('permissions');
- $permissions = $this->getNewPermissions($permissionsString);
- if ($permissions) {
- if (!isset($folder['groups'][$groupString])) {
- $this->folderManager->addApplicableGroup($folderId, $groupString);
- }
- $this->folderManager->setGroupPermissions($folderId, $groupString, $permissions);
- return 0;
- } else {
- $output->writeln('Unable to parse permissions input: ' . implode(' ', $permissionsString) . '');
- return -1;
+ }
+
+ $permissionsString = $input->getArgument('permissions');
+ $permissions = $this->getNewPermissions($permissionsString);
+ if ($permissions) {
+ if (!isset($folder['groups'][$groupString])) {
+ $this->folderManager->addApplicableGroup($folderId, $groupString);
}
+ $this->folderManager->setGroupPermissions($folderId, $groupString, $permissions);
+
+ return 0;
} else {
- $output->writeln('group not found: ' . $groupString . '');
+ $output->writeln('Unable to parse permissions input: ' . implode(' ', $permissionsString) . '');
+
return -1;
}
} else {
diff --git a/lib/Command/ListCommand.php b/lib/Command/ListCommand.php
index 1f1c66059..2f70021d4 100644
--- a/lib/Command/ListCommand.php
+++ b/lib/Command/ListCommand.php
@@ -23,6 +23,7 @@
use OC\Core\Command\Base;
use OCA\GroupFolders\Folder\FolderManager;
+use OCP\Circles\ICirclesManager;
use OCP\Constants;
use OCP\Files\IRootFolder;
use Symfony\Component\Console\Helper\Table;
@@ -38,11 +39,13 @@ class ListCommand extends Base {
];
private $folderManager;
+ private $circlesManager;
private $rootFolder;
- public function __construct(FolderManager $folderManager, IRootFolder $rootFolder) {
+ public function __construct(FolderManager $folderManager, ICirclesManager $circlesManager, IRootFolder $rootFolder) {
parent::__construct();
$this->folderManager = $folderManager;
+ $this->circlesManager = $circlesManager;
$this->rootFolder = $rootFolder;
}
@@ -54,6 +57,7 @@ protected function configure() {
}
protected function execute(InputInterface $input, OutputInterface $output) {
+ $this->circlesManager->startSuperSession();
$folders = $this->folderManager->getAllFoldersWithSize($this->rootFolder->getMountPoint()->getNumericStorageId());
usort($folders, function ($a, $b) {
return $a['id'] - $b['id'];
@@ -73,12 +77,13 @@ protected function execute(InputInterface $input, OutputInterface $output) {
$this->writeArrayInOutputFormat($input, $output, $folders);
} else {
$table = new Table($output);
- $table->setHeaders(['Folder Id', 'Name', 'Groups', 'Quota', 'Size', 'Advanced Permissions', 'Manage advanced permissions']);
+ $table->setHeaders(['Folder Id', 'Name', 'Groups', 'Display Name', 'Quota', 'Size', 'Advanced Permissions', 'Manage advanced permissions']);
$table->setRows(array_map(function ($folder) {
$folder['size'] = \OCP\Util::humanFileSize($folder['size']);
$folder['quota'] = ($folder['quota'] > 0) ? \OCP\Util::humanFileSize($folder['quota']) : 'Unlimited';
$groupStrings = array_map(function (string $groupId, int $permissions) {
- return $groupId . ': ' . $this->permissionsToString($permissions);
+ $circle = $this->circlesManager->getCircle($groupId);
+ return $circle->getDisplayName(). ' (' . $groupId . ') : ' . $this->permissionsToString($permissions);
}, array_keys($folder['groups']), array_values($folder['groups']));
$folder['groups'] = implode("\n", $groupStrings);
$folder['acl'] = $folder['acl'] ? 'Enabled' : 'Disabled';
@@ -86,6 +91,7 @@ protected function execute(InputInterface $input, OutputInterface $output) {
return $manage['id'] . ' (' . $manage['type'] . ')';
}, $folder['manage']);
$folder['manage'] = implode("\n", $manageStrings);
+
return $folder;
}, $folders));
$table->render();
diff --git a/lib/Controller/FolderController.php b/lib/Controller/FolderController.php
index cb220bf07..42b8cff32 100644
--- a/lib/Controller/FolderController.php
+++ b/lib/Controller/FolderController.php
@@ -26,11 +26,14 @@
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCSController;
use OCP\Files\IRootFolder;
+use OCP\IGroupManager;
use OCP\IRequest;
class FolderController extends OCSController {
/** @var FolderManager */
private $manager;
+ /** @var IGroupManager */
+ private $groupManager;
/** @var MountProvider */
private $mountProvider;
/** @var IRootFolder */
@@ -42,12 +45,14 @@ public function __construct(
$AppName,
IRequest $request,
FolderManager $manager,
+ IGroupManager $groupManager,
MountProvider $mountProvider,
IRootFolder $rootFolder,
$userId
) {
parent::__construct($AppName, $request);
$this->manager = $manager;
+ $this->groupManager = $groupManager;
$this->mountProvider = $mountProvider;
$this->rootFolder = $rootFolder;
$this->userId = $userId;
@@ -209,22 +214,25 @@ private function folderDataForXML($data) {
/**
* @NoAdminRequired
- * @param $id
+ *
+ * @param int $id
* @param $fileId
+ * @param string $source
* @param string $search
+ *
* @return DataResponse
*/
- public function aclMappingSearch($id, $fileId, $search = ''): DataResponse {
- $users = [];
- $groups = [];
-
+ public function aclMappingSearch(int $id, $fileId, string $source = '', string $search = ''): DataResponse {
+ $entities = [];
if ($this->manager->canManageACL($id, $this->userId) === true) {
- $groups = $this->manager->searchGroups($id, $search);
- $users = $this->manager->searchUsers($id, $search);
+ $entities = $this->manager->searchEntities(
+ $id,
+ $search,
+ ($this->groupManager->isAdmin($this->userId) && $source === 'settings')
+ );
}
return new DataResponse([
- 'users' => $users,
- 'groups' => $groups,
+ 'entities' => $entities
]);
}
}
diff --git a/lib/Folder/FolderManager.php b/lib/Folder/FolderManager.php
index d4a17511d..51cd7a701 100644
--- a/lib/Folder/FolderManager.php
+++ b/lib/Folder/FolderManager.php
@@ -22,8 +22,25 @@
namespace OCA\GroupFolders\Folder;
use OC\Files\Cache\Cache;
+use OCA\Circles\Exceptions\CircleNotFoundException;
+use OCA\Circles\Exceptions\FederatedItemException;
+use OCA\Circles\Exceptions\FederatedUserException;
+use OCA\Circles\Exceptions\FederatedUserNotFoundException;
+use OCA\Circles\Exceptions\InitiatorNotFoundException;
+use OCA\Circles\Exceptions\InvalidIdException;
+use OCA\Circles\Exceptions\MemberNotFoundException;
+use OCA\Circles\Exceptions\OwnerNotFoundException;
+use OCA\Circles\Exceptions\RemoteInstanceException;
+use OCA\Circles\Exceptions\RemoteNotFoundException;
+use OCA\Circles\Exceptions\RemoteResourceNotFoundException;
+use OCA\Circles\Exceptions\RequestBuilderException;
+use OCA\Circles\Exceptions\SingleCircleNotFoundException;
+use OCA\Circles\Exceptions\UnknownRemoteException;
+use OCA\Circles\Exceptions\UserTypeNotFoundException;
use OCA\GroupFolders\Mount\GroupFolderStorage;
+use OCP\Circles\ICirclesManager;
use OCP\Constants;
+use OCP\DB\Exception;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\IMimeTypeLoader;
use OCP\IDBConnection;
@@ -37,10 +54,18 @@ class FolderManager {
/** @var IGroupManager */
private $groupManager;
+ /** @var ICirclesManager */
+ private $circlesManager;
+
/** @var IMimeTypeLoader */
private $mimeTypeLoader;
- public function __construct(IDBConnection $connection, IGroupManager $groupManager = null, IMimeTypeLoader $mimeTypeLoader = null) {
+ public function __construct(
+ IDBConnection $connection,
+ IGroupManager $groupManager = null,
+ ICirclesManager $circlesManager,
+ IMimeTypeLoader $mimeTypeLoader = null
+ ) {
$this->connection = $connection;
// files_fulltextsearch compatibility
@@ -51,6 +76,7 @@ public function __construct(IDBConnection $connection, IGroupManager $groupManag
$mimeTypeLoader = \OC::$server->getMimeTypeLoader();
}
$this->groupManager = $groupManager;
+ $this->circlesManager = $circlesManager;
$this->mimeTypeLoader = $mimeTypeLoader;
}
@@ -65,7 +91,7 @@ public function getAllFolders(): array {
$query = $this->connection->getQueryBuilder();
$query->select('folder_id', 'mount_point', 'quota', 'acl')
- ->from('group_folders', 'f');
+ ->from('group_folders', 'f');
$rows = $query->execute()->fetchAll();
@@ -99,7 +125,7 @@ private function getGroupfolderRootId(int $rootStorageId): int {
private function joinQueryWithFileCache(IQueryBuilder $query, int $rootStorageId): IQueryBuilder {
return $query->leftJoin('f', 'filecache', 'c', $query->expr()->andX(
// concat with empty string to work around missing cast to string
- $query->expr()->eq('name', $query->func()->concat('f.folder_id', $query->expr()->literal(""))),
+ $query->expr()->eq('c.name', $query->func()->concat('f.folder_id', $query->expr()->literal(""))),
$query->expr()->eq('parent', $query->createNamedParameter($this->getGroupfolderRootId($rootStorageId)))
));
}
@@ -115,7 +141,7 @@ public function getAllFoldersWithSize($rootStorageId): array {
$query = $this->connection->getQueryBuilder();
$query->select('folder_id', 'mount_point', 'quota', 'size', 'acl')
- ->from('group_folders', 'f');
+ ->from('group_folders', 'f');
$this->joinQueryWithFileCache($query, $rootStorageId);
$rows = $query->execute()->fetchAll();
@@ -146,19 +172,33 @@ public function getAllFoldersWithSize($rootStorageId): array {
* @psalm-return array>
*/
private function getAllFolderMappings(): array {
- $query = $this->connection->getQueryBuilder();
- $query->select('*')
- ->from('group_folders_manage');
+ $queryHelper = $this->circlesManager->getQueryHelper();
+ $query = $queryHelper->getQueryBuilder();
+
+ $query->select('folder_id', 'mapping_type', 'mapping_id')
+ ->from('group_folders_manage', 'm');
+
+ $queryHelper->addCircleDetails('m', 'mapping_id');
+
$rows = $query->execute()->fetchAll();
$folderMap = [];
foreach ($rows as $row) {
$id = (int)$row['folder_id'];
+ $circle = $queryHelper->extractCircle($row);
+ $data = [
+ 'folder_id' => $row['folder_id'],
+ 'mapping_type' => $row['mapping_type'],
+ 'mapping_id' => $row['mapping_id'],
+ 'displayName' => $circle->getDisplayName(),
+ 'definition' => $this->circlesManager->getDefinition($circle)
+ ];
+
if (!isset($folderMap[$id])) {
- $folderMap[$id] = [$row];
+ $folderMap[$id] = [$data];
} else {
- $folderMap[$id][] = $row;
+ $folderMap[$id][] = $data;
}
}
@@ -166,19 +206,30 @@ private function getAllFolderMappings(): array {
}
private function getManageAcl($mappings): array {
- return array_filter(array_map(function ($entry) {
- if ($entry['mapping_type'] === 'user') {
- $user = \OC::$server->getUserManager()->get($entry['mapping_id']);
- if ($user === null) {
- return null;
- }
- return [
- 'type' => 'user',
- 'id' => $user->getUID(),
- 'displayname' => $user->getDisplayName()
- ];
- }
- $group = \OC::$server->getGroupManager()->get($entry['mapping_id']);
+ return array_filter(
+ array_map(
+ function ($entry) {
+ if ($entry['mapping_type'] === 'entity') {
+ return [
+ 'type' => $entry['definition'],
+ 'id' => $entry['mapping_id'],
+ 'displayname' => $entry['displayName']
+ ];
+ }
+
+ if ($entry['mapping_type'] === 'user') {
+ $user = \OC::$server->getUserManager()->get($entry['mapping_id']);
+ if ($user === null) {
+ return null;
+ }
+
+ return [
+ 'type' => 'user',
+ 'id' => $user->getUID(),
+ 'displayname' => $user->getDisplayName()
+ ];
+ }
+ $group = \OC::$server->getGroupManager()->get($entry['mapping_id']);
if ($group === null) {
return [];
}
@@ -237,7 +288,7 @@ private function getAllApplicable(bool $permissionOnly = true): array {
$query = $this->connection->getQueryBuilder();
$query->select('folder_id', 'group_id', 'permissions')
- ->from('group_folders_groups');
+ ->from('group_folders_groups');
$rows = $query->execute()->fetchAll();
@@ -253,81 +304,147 @@ private function getAllApplicable(bool $permissionOnly = true): array {
return $applicableMap;
}
- private function getGroups($id): array {
+
+ /**
+ * @param int $id
+ * @param bool $asAdmin
+ *
+ * @return array
+ * @throws InitiatorNotFoundException
+ * @throws RequestBuilderException
+ * @throws FederatedItemException
+ * @throws FederatedUserException
+ * @throws FederatedUserNotFoundException
+ * @throws InvalidIdException
+ * @throws RemoteInstanceException
+ * @throws RemoteNotFoundException
+ * @throws RemoteResourceNotFoundException
+ * @throws SingleCircleNotFoundException
+ * @throws UnknownRemoteException
+ */
+ private function getEntities(int $id, bool $asAdmin = false): array {
+ if ($asAdmin) {
+ $this->circlesManager->startSuperSession();
+ } else {
+ $this->circlesManager->startSession();
+ }
+
$groups = $this->getAllApplicable()[$id] ?? [];
- $groups = array_map(function ($gid) {
- return $this->groupManager->get($gid);
- }, array_keys($groups));
- return array_map(function ($group) {
- return [
- 'gid' => $group->getGID(),
- 'displayname' => $group->getDisplayName()
+ $entities = [];
+ foreach (array_keys($groups) as $gid) {
+ try {
+ $circle = $this->circlesManager->getCircle($gid);
+ } catch (CircleNotFoundException $e) {
+ continue;
+ }
+
+ $entities[$circle->getSingleId()] = [
+ 'singleId' => $circle->getSingleId(),
+ 'displayName' => $circle->getDisplayName(),
+ 'definition' => $this->circlesManager->getDefinition($circle)
];
- }, array_filter($groups));
+ foreach ($circle->getInheritedMembers(false) as $member) {
+ if ($member->hasBasedOn()) {
+ $basedOn = $member->getBasedOn();
+ $entities[$basedOn->getSingleId()] = [
+ 'singleId' => $basedOn->getSingleId(),
+ 'displayName' => $basedOn->getDisplayName(),
+ 'definition' => $this->circlesManager->getDefinition($basedOn)
+ ];
+ } else {
+ $entities[$member->getSingleId()] = [
+ 'singleId' => $member->getSingleId(),
+ 'displayName' => $member->getDisplayName(),
+ 'definition' => $this->circlesManager->getDefinition($member)
+ ];
+ }
+ }
+ }
+
+ return array_values($entities);
}
+
+ /**
+ * @param $folderId
+ * @param $userId
+ *
+ * @return bool
+ * @throws CircleNotFoundException
+ * @throws Exception
+ * @throws FederatedItemException
+ * @throws FederatedUserException
+ * @throws FederatedUserNotFoundException
+ * @throws InvalidIdException
+ * @throws RemoteInstanceException
+ * @throws RemoteNotFoundException
+ * @throws RemoteResourceNotFoundException
+ * @throws RequestBuilderException
+ * @throws SingleCircleNotFoundException
+ * @throws UnknownRemoteException
+ * @throws MemberNotFoundException
+ * @throws OwnerNotFoundException
+ * @throws UserTypeNotFoundException
+ */
public function canManageACL($folderId, $userId): bool {
if ($this->groupManager->isAdmin($userId)) {
return true;
}
- $query = $this->connection->getQueryBuilder();
- $query->select('*')
- ->from('group_folders_manage')
- ->where($query->expr()->eq('folder_id', $query->createNamedParameter($folderId)))
- ->andWhere($query->expr()->eq('mapping_type', $query->createNamedParameter('user')))
- ->andWhere($query->expr()->eq('mapping_id', $query->createNamedParameter($userId)));
- if ($query->execute()->rowCount() === 1) {
- return true;
- }
+ $this->circlesManager->startUserSession($userId);
+ $queryHelper = $this->circlesManager->getQueryHelper();
+ $query = $queryHelper->getQueryBuilder();
- $query = $this->connection->getQueryBuilder();
- $query->select('*')
- ->from('group_folders_manage')
- ->where($query->expr()->eq('folder_id', $query->createNamedParameter($folderId)))
- ->andWhere($query->expr()->eq('mapping_type', $query->createNamedParameter('group')));
- $groups = $query->execute()->fetchAll();
- foreach ($groups as $manageRule) {
- if ($this->groupManager->isInGroup($userId, $manageRule['mapping_id'])) {
- return true;
- }
- }
- return false;
+ $query->select('folder_id', 'mapping_type', 'mapping_id')
+ ->from('group_folders_manage', 'm')
+ ->where($query->expr()->eq('folder_id', $query->createNamedParameter($folderId)))
+ ->andWhere($query->expr()->eq('mapping_type', $query->createNamedParameter('entity')));
+
+ $queryHelper->limitToSession('m', 'mapping_id');
+
+ return ($query->execute()->rowCount() > 0);
}
- public function searchGroups($id, $search = ''): array {
- $groups = $this->getGroups($id);
+ public function searchEntities($id, $search = '', bool $asAdmin = false): array {
+ $groups = $this->getEntities($id, $asAdmin);
if ($search === '') {
return $groups;
}
- return array_filter($groups, function ($group) use ($search) {
- return (stripos($group['gid'], $search) !== false) || (stripos($group['displayname'], $search) !== false);
- });
- }
- public function searchUsers($id, $search = '', $limit = 10, $offset = 0): array {
- $groups = $this->getGroups($id);
- $users = [];
- foreach ($groups as $groupArray) {
- $group = $this->groupManager->get($groupArray['gid']);
- if ($group) {
- $foundUsers = $this->groupManager->displayNamesInGroup($group->getGID(), $search, $limit, $offset);
- foreach ($foundUsers as $uid => $displayName) {
- if (!isset($users[$uid])) {
- $users[$uid] = [
- 'uid' => $uid,
- 'displayname' => $displayName
- ];
- }
+ return array_values(
+ array_filter(
+ $groups,
+ function ($group) use ($search) {
+ return (stripos($group['displayName'], $search) !== false);
}
- }
- }
- return array_values($users);
+ )
+ );
}
+// public function searchUsers($id, $search = '', $limit = 10, $offset = 0): array {
+// $groups = $this->getEntities($id);
+// $users = [];
+// foreach ($groups as $groupArray) {
+// $group = $this->groupManager->get($groupArray['gid']);
+// if ($group) {
+// $foundUsers = $this->groupManager->displayNamesInGroup($group->getGID(), $search, $limit, $offset);
+// foreach ($foundUsers as $uid => $displayName) {
+// if (!isset($users[$uid])) {
+// $users[$uid] = [
+// 'uid' => $uid,
+// 'displayname' => $displayName
+// ];
+// }
+// }
+// }
+// }
+// return array_values($users);
+// }
+
/**
* @param string $groupId
* @param int $rootStorageId
+ *
* @return array[]
*/
public function getFoldersForGroup($groupId, $rootStorageId = 0) {
@@ -351,16 +468,16 @@ public function getFoldersForGroup($groupId, $rootStorageId = 0) {
'encrypted',
'parent'
)
- ->selectAlias('a.permissions', 'group_permissions')
- ->selectAlias('c.permissions', 'permissions')
- ->from('group_folders', 'f')
- ->innerJoin(
- 'f',
- 'group_folders_groups',
- 'a',
- $query->expr()->eq('f.folder_id', 'a.folder_id')
- )
- ->where($query->expr()->eq('a.group_id', $query->createNamedParameter($groupId)));
+ ->selectAlias('a.permissions', 'group_permissions')
+ ->selectAlias('c.permissions', 'permissions')
+ ->from('group_folders', 'f')
+ ->innerJoin(
+ 'f',
+ 'group_folders_groups',
+ 'a',
+ $query->expr()->eq('f.folder_id', 'a.folder_id')
+ )
+ ->where($query->expr()->eq('a.group_id', $query->createNamedParameter($groupId)));
$this->joinQueryWithFileCache($query, $rootStorageId);
$result = $query->execute()->fetchAll();
@@ -402,12 +519,12 @@ public function getFoldersForGroups(array $groupIds, $rootStorageId = 0): array
'encrypted',
'parent'
)
- ->selectAlias('a.permissions', 'group_permissions')
- ->selectAlias('c.permissions', 'permissions')
- ->from('group_folders', 'f')
- ->innerJoin(
- 'f',
- 'group_folders_groups',
+ ->selectAlias('a.permissions', 'group_permissions')
+ ->selectAlias('c.permissions', 'permissions')
+ ->from('group_folders', 'f')
+ ->innerJoin(
+ 'f',
+ 'group_folders_groups',
'a',
$query->expr()->eq('f.folder_id', 'a.folder_id')
)
@@ -427,6 +544,67 @@ public function getFoldersForGroups(array $groupIds, $rootStorageId = 0): array
}, $result);
}
+
+ /**
+ * @param string[] $groupId
+ * @param int $rootStorageId
+ * @return array[]
+ */
+ public function getFolders($rootStorageId = 0): array {
+ if (!$this->circlesManager->isSessionInitiated()) {
+ $this->circlesManager->startSession();
+ }
+
+ $queryHelper = $this->circlesManager->getQueryHelper();
+ $query = $queryHelper->getQueryBuilder();
+
+ $query->select(
+ 'f.folder_id',
+ 'mount_point',
+ 'quota',
+ 'acl',
+ 'fileid',
+ 'storage',
+ 'path',
+ 'c.name',
+ 'mimetype',
+ 'mimepart',
+ 'size',
+ 'mtime',
+ 'storage_mtime',
+ 'etag',
+ 'encrypted',
+ 'parent'
+ )
+ ->selectAlias('a.permissions', 'group_permissions')
+ ->selectAlias('c.permissions', 'permissions')
+ ->from('group_folders', 'f')
+ ->innerJoin(
+ 'f',
+ 'group_folders_groups',
+ 'a',
+ $query->expr()->eq('f.folder_id', 'a.folder_id')
+ );
+
+// ->where($query->expr()->in('a.group_id', $query->createNamedParameter($groupIds, IQueryBuilder::PARAM_STR_ARRAY)));
+ $queryHelper->limitToSession('a', 'group_id', false);
+
+ $this->joinQueryWithFileCache($query, $rootStorageId);
+
+ $result = $query->execute()->fetchAll();
+ return array_map(function ($folder) {
+ return [
+ 'folder_id' => (int)$folder['folder_id'],
+ 'mount_point' => $folder['mount_point'],
+ 'permissions' => (int)$folder['group_permissions'],
+ 'quota' => (int)$folder['quota'],
+ 'acl' => (bool)$folder['acl'],
+ 'rootCacheEntry' => (isset($folder['fileid'])) ? Cache::cacheEntryFromData($folder, $this->mimeTypeLoader) : null
+ ];
+ }, $result);
+ }
+
+
public function createFolder($mountPoint) {
$query = $this->connection->getQueryBuilder();
@@ -481,6 +659,7 @@ public function setGroupPermissions($folderId, $groupId, $permissions): void {
}
public function setManageACL($folderId, $type, $id, $manageAcl): void {
+ $type = 'entity';
$query = $this->connection->getQueryBuilder();
if ($manageAcl === true) {
$query->insert('group_folders_manage')
@@ -492,8 +671,8 @@ public function setManageACL($folderId, $type, $id, $manageAcl): void {
} else {
$query->delete('group_folders_manage')
->where($query->expr()->eq('folder_id', $query->createNamedParameter($folderId)))
- ->andWhere($query->expr()->eq('mapping_type', $query->createNamedParameter($type)))
- ->andWhere($query->expr()->eq('mapping_id', $query->createNamedParameter($id)));
+ ->andWhere($query->expr()->eq('mapping_type', $query->createNamedParameter($type)))
+ ->andWhere($query->expr()->eq('mapping_id', $query->createNamedParameter($id)));
}
$query->execute();
}
@@ -510,8 +689,8 @@ public function setFolderQuota($folderId, $quota): void {
$query = $this->connection->getQueryBuilder();
$query->update('group_folders')
- ->set('quota', $query->createNamedParameter($quota))
- ->where($query->expr()->eq('folder_id', $query->createNamedParameter($folderId)));
+ ->set('quota', $query->createNamedParameter($quota))
+ ->where($query->expr()->eq('folder_id', $query->createNamedParameter($folderId)));
$query->execute();
}
@@ -528,7 +707,7 @@ public function deleteGroup($groupId): void {
$query = $this->connection->getQueryBuilder();
$query->delete('group_folders_groups')
- ->where($query->expr()->eq('group_id', $query->createNamedParameter($groupId)));
+ ->where($query->expr()->eq('group_id', $query->createNamedParameter($groupId)));
$query->execute();
}
@@ -536,14 +715,14 @@ public function setFolderACL($folderId, bool $acl): void {
$query = $this->connection->getQueryBuilder();
$query->update('group_folders')
- ->set('acl', $query->createNamedParameter((int)$acl, IQueryBuilder::PARAM_INT))
- ->where($query->expr()->eq('folder_id', $query->createNamedParameter($folderId)));
+ ->set('acl', $query->createNamedParameter((int)$acl, IQueryBuilder::PARAM_INT))
+ ->where($query->expr()->eq('folder_id', $query->createNamedParameter($folderId)));
$query->execute();
if ($acl === false) {
$query = $this->connection->getQueryBuilder();
$query->delete('group_folders_manage')
- ->where($query->expr()->eq('folder_id', $query->createNamedParameter($folderId)));
+ ->where($query->expr()->eq('folder_id', $query->createNamedParameter($folderId)));
$query->execute();
}
}
@@ -551,11 +730,27 @@ public function setFolderACL($folderId, bool $acl): void {
/**
* @param IUser $user
* @param int $rootStorageId
+ *
* @return array[]
+ * @throws CircleNotFoundException
+ * @throws Exception
+ * @throws FederatedItemException
+ * @throws FederatedUserException
+ * @throws FederatedUserNotFoundException
+ * @throws InvalidIdException
+ * @throws RemoteInstanceException
+ * @throws RemoteNotFoundException
+ * @throws RemoteResourceNotFoundException
+ * @throws RequestBuilderException
+ * @throws SingleCircleNotFoundException
+ * @throws UnknownRemoteException
*/
- public function getFoldersForUser(IUser $user, $rootStorageId = 0) {
- $groups = $this->groupManager->getUserGroupIds($user);
- $folders = $this->getFoldersForGroups($groups, $rootStorageId);
+ public function getFoldersForUser(IUser $user, int $rootStorageId = 0): array {
+// $groups = $this->groupManager->getUserGroupIds($user);
+// $folders = $this->getFoldersForGroups($groups, $rootStorageId);
+
+ $this->circlesManager->startUserSession($user->getUID());
+ $folders = $this->getFolders();
$mergedFolders = [];
foreach ($folders as $folder) {
diff --git a/src/components/SharingSidebarView.vue b/src/components/SharingSidebarView.vue
index c02b0d872..3506de425 100644
--- a/src/components/SharingSidebarView.vue
+++ b/src/components/SharingSidebarView.vue
@@ -236,11 +236,7 @@ export default {
})
},
getFullDisplayName(displayName, type) {
- if (type === 'group') {
- return t('groupfolders', '{displayName} (Group)', { displayName })
- }
-
- return displayName
+ return displayName + ' (' + type + ')'
},
searchMappings(query) {
if (searchRequestCancelSource) {
@@ -248,27 +244,21 @@ export default {
}
searchRequestCancelSource = axios.CancelToken.source()
this.isSearching = true
+
axios.get(generateUrl(`apps/groupfolders/folders/${this.groupFolderId}/search`) + '?format=json&search=' + query, {
cancelToken: searchRequestCancelSource.token,
}).then((result) => {
this.isSearching = false
- const groups = Object.values(result.data.ocs.data.groups).map((group) => {
+ const entities = Object.values(result.data.ocs.data.entities).map((entity) => {
return {
- unique: 'group:' + group.gid,
- type: 'group',
- id: group.gid,
- displayname: group.displayname,
+ unique: entity.singleId,
+ id: entity.singleId,
+ displayname: entity.displayName,
+ type: entity.definition
}
})
- const users = Object.values(result.data.ocs.data.users).map((user) => {
- return {
- unique: 'user:' + user.uid,
- type: 'user',
- id: user.uid,
- displayname: user.displayname,
- }
- })
- this.options = [...groups, ...users].filter((entry) => {
+
+ this.options = entities.filter((entry) => {
// filter out existing acl rules
return !this.list.find((existingAcl) => entry.unique === existingAcl.getUniqueMappingIdentifier())
})
diff --git a/src/settings/Api.ts b/src/settings/Api.ts
index a2ac02510..176a873ac 100644
--- a/src/settings/Api.ts
+++ b/src/settings/Api.ts
@@ -7,6 +7,13 @@ export interface Group {
displayname: string;
}
+export interface Entity {
+ singleId: string;
+ displayName: string;
+ definition: string;
+ type: string;
+}
+
export interface OCSUser {
uid: string;
displayname: string;
@@ -46,7 +53,15 @@ export class Api {
listGroups(): Thenable {
const version = parseInt(OC.config.version, 10);
- if (version >= 14) {
+ if (version >= 22) {
+ return $.getJSON(OC.linkToOCS('cloud', 1) + 'admin/entities/details?filter=-single')
+ .then((data: OCSResult<{ entities: Entity[]; }>) => data.ocs.data.entities.map(entity => {
+ return {
+ id: entity.singleId,
+ displayname: entity.displayName + ' (' + entity.definition + ')'
+ };
+ }));
+ } else if (version >= 14) {
return $.getJSON(OC.linkToOCS('cloud', 1) + 'groups/details')
.then((data: OCSResult<{ groups: Group[]; }>) => data.ocs.data.groups);
} else {
@@ -118,24 +133,19 @@ export class Api {
});
}
- aclMappingSearch(folderId: number, search: string): Thenable<{groups: OCSGroup[], users: OCSUser[]}> {
- return $.getJSON(this.getUrl(`folders/${folderId}/search?format=json&search=${search}`))
- .then((data: OCSResult<{ groups: OCSGroup[]; users: OCSUser[]; }>) => {
+ aclMappingSearch(folderId: number, search: string): Thenable<{groups: OCSGroup[], users: OCSUser[], entities: Entity[]}> {
+ return $.getJSON(this.getUrl(`folders/${folderId}/search?format=json&source=settings&search=${search}`))
+ .then((data: OCSResult<{ entities: Entity[]; groups: OCSGroup; users: OCSUser; }>) => {
return {
- groups: Object.values(data.ocs.data.groups).map((item) => {
+ entities: Object.values(data.ocs.data.entities).map((item) => {
return {
- type: 'group',
- id: item.gid,
- displayname: item.displayname
+ type: item.definition,
+ id: item.singleId,
+ displayname: item.displayName
}
}),
- users: Object.values(data.ocs.data.users).map((item) => {
- return {
- type: 'user',
- id: item.uid,
- displayname: item.displayname
- }
- })
+ groups: [],
+ users: []
}
});
}
diff --git a/src/settings/App.tsx b/src/settings/App.tsx
index e6743fc84..a28dc9278 100644
--- a/src/settings/App.tsx
+++ b/src/settings/App.tsx
@@ -1,7 +1,7 @@
import * as React from 'react';
import {ChangeEvent, Component, FormEvent} from 'react';
-import {Api, Folder, Group, ManageRuleProps, OCSGroup, OCSUser} from './Api';
+import {Api, Entity, Folder, Group, ManageRuleProps, OCSGroup, OCSUser} from './Api';
import {FolderGroups} from './FolderGroups';
import {QuotaSelect} from './QuotaSelect';
import './App.scss';
@@ -320,7 +320,7 @@ export class App extends Component<{}, AppState> implements OC.Plugin void;
- onSearch: (name: string) => Thenable<{ groups: OCSGroup[]; users: OCSUser[]; }>;
+ onSearch: (name: string) => Thenable<{ groups: OCSGroup[]; users: OCSUser[]; entities: Entity[]; }>;
};
@@ -329,13 +329,14 @@ function ManageAclSelect({onChange, onSearch, folder}: ManageAclSelectProps) {
const handleSearch = (inputValue: string) => {
return new Promise(resolve => {
onSearch(inputValue).then((result) => {
- resolve([...result.groups, ...result.users])
+ resolve([...result.groups, ...result.users, ...result.entities])
})
})
}
const typeLabel = (item) => {
- return item.type === 'user' ? 'User' : 'Group'
+ // return item.type === 'user' ? 'User' : 'Group'
+ return item.type
}
return