From 769778340bd498de537568e6a7b787e0eb0c4ff5 Mon Sep 17 00:00:00 2001 From: Carl Schwan Date: Mon, 10 Oct 2022 11:42:30 +0200 Subject: Refactor DelegationService Use a consistent way to define api only users using delegation service with a custom class name. Signed-off-by: Carl Schwan --- lib/AppInfo/Application.php | 2 - lib/AuthorizedAdminSettingMiddleware.php | 24 +++------ lib/Controller/FolderController.php | 6 +-- lib/Service/DelegationService.php | 84 +++++++++++++++++++------------- lib/Service/FoldersFilter.php | 26 +++++----- 5 files changed, 72 insertions(+), 70 deletions(-) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 4804d5b3..04f855c9 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -63,8 +63,6 @@ use OCP\IUserSession; use Psr\Log\LoggerInterface; class Application extends App implements IBootstrap { - public const CLASS_NAME_ADMIN_DELEGATION = 'OCA\GroupFolders\Settings\Admin'; - public function __construct(array $urlParams = []) { parent::__construct('groupfolders', $urlParams); } diff --git a/lib/AuthorizedAdminSettingMiddleware.php b/lib/AuthorizedAdminSettingMiddleware.php index c8f08e35..512e72a7 100644 --- a/lib/AuthorizedAdminSettingMiddleware.php +++ b/lib/AuthorizedAdminSettingMiddleware.php @@ -24,6 +24,7 @@ namespace OCA\GroupFolders; use Exception; use OC\AppFramework\Utility\ControllerMethodReflector; use OC\Settings\AuthorizedGroupMapper; +use OCA\GroupFolders\Service\DelegationService; use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\Response; use OCP\AppFramework\Http\TemplateResponse; @@ -42,6 +43,7 @@ class AuthorizedAdminSettingMiddleware extends Middleware { private IUserSession $userSession; private LoggerInterface $logger; private bool $isAdminUser; + private DelegationService $delegatedService; public function __construct( AuthorizedGroupMapper $groupAuthorizationMapper, @@ -51,7 +53,8 @@ class AuthorizedAdminSettingMiddleware extends Middleware { IUserSession $userSession, LoggerInterface $logger, ?string $userId, - IGroupManager $groupManager + IGroupManager $groupManager, + DelegationService $delegatedService ) { $this->reflector = $reflector; $this->logger = $logger; @@ -60,6 +63,7 @@ class AuthorizedAdminSettingMiddleware extends Middleware { $this->groupAuthorizationMapper = $groupAuthorizationMapper; $this->userSession = $userSession; $this->isAdminUser = $userId !== null && $groupManager->isAdmin($userId); + $this->delegatedService = $delegatedService; } /** @@ -72,23 +76,7 @@ class AuthorizedAdminSettingMiddleware extends Middleware { */ public function beforeController($controller, $methodName) { if ($this->reflector->hasAnnotation('RequireGroupFolderAdmin')) { - if ($this->isAdminUser) { - return; - } - - $settingClasses = [ - \OCA\GroupFolders\Settings\Admin::class, - \OCA\GroupFolders\Controller\DelegationController::class, - ]; - $authorizedClasses = $this->groupAuthorizationMapper->findAllClassesForUser($this->userSession->getUser()); - foreach ($settingClasses as $settingClass) { - $authorized = in_array($settingClass, $authorizedClasses, true); - if ($authorized) { - break; - } - } - - if (!$authorized) { + if (!$this->delegatedService->hasApiAccess()) { throw new Exception('Logged in user must be an admin, a sub admin or gotten special right to access this setting'); } } diff --git a/lib/Controller/FolderController.php b/lib/Controller/FolderController.php index c8e14107..d7dd6598 100644 --- a/lib/Controller/FolderController.php +++ b/lib/Controller/FolderController.php @@ -70,11 +70,11 @@ class FolderController extends OCSController { */ public function getFolders(): DataResponse { $folders = $this->manager->getAllFoldersWithSize($this->getRootFolderStorageId()); - if ($this->delegationService->isAdminNextcloud() || $this->delegationService->isAdmin()) { + if ($this->delegationService->isAdminNextcloud() || $this->delegationService->isDelegatedAdmin()) { return new DataResponse($folders); } - if ($this->delegationService->isSubAdmin()) { - $folders = $this->foldersFilter->getForSubAdmin($folders); + if ($this->delegationService->hasOnlyApiAccess()) { + $folders = $this->foldersFilter->getForApiUser($folders); } return new DataResponse($folders); } diff --git a/lib/Service/DelegationService.php b/lib/Service/DelegationService.php index 4bb79936..5a58841e 100644 --- a/lib/Service/DelegationService.php +++ b/lib/Service/DelegationService.php @@ -21,28 +21,44 @@ namespace OCA\GroupFolders\Service; -use OCA\GroupFolders\AppInfo\Application; +use OC\Settings\AuthorizedGroupMapper; +use OCA\GroupFolders\Controller\DelegationController; +use OCA\GroupFolders\Settings\Admin; use OCA\Settings\Service\AuthorizedGroupService; use OCP\IConfig; use OCP\IGroupManager; use OCP\IUserSession; class DelegationService { + /** + * Has access to the entire groupfolders + */ + private const CLASS_NAME_ADMIN_DELEGATION = Admin::class; + + /** + * Has access only to the groupfolders in which the user has advanced + * permissions. + */ + private const CLASS_API_ACCESS = DelegationController::class; + private AuthorizedGroupService $authorizedGroupService; private IConfig $config; private IGroupManager $groupManager; private IUserSession $userSession; + private AuthorizedGroupMapper $groupAuthorizationMapper; public function __construct( AuthorizedGroupService $authorizedGroupService, IConfig $config, IGroupManager $groupManager, - IUserSession $userSession + IUserSession $userSession, + AuthorizedGroupMapper $groupAuthorizationMapper ) { $this->authorizedGroupService = $authorizedGroupService; $this->config = $config; $this->groupManager = $groupManager; $this->userSession = $userSession; + $this->groupAuthorizationMapper = $groupAuthorizationMapper; } /** @@ -53,48 +69,46 @@ class DelegationService { } /** - * Return true if user is a member of a group that - * has been granted admin rights on groupfolders - * - * @return bool + * @return bool true if the user is a delegated admin */ - public function isAdmin(): bool { - $authorizedGroups = $this->authorizedGroupService->findExistingGroupsForClass(Application::CLASS_NAME_ADMIN_DELEGATION); - - $userGroups = $this->groupManager->getUserGroups($this->userSession->getUser()); - - $groups = array_map(function ($group) { - return $group->getGroupId(); - }, $authorizedGroups); - - foreach ($userGroups as $userGroup) { - if (in_array($userGroup->getGID(), $groups)) { - return true; - } - } - return false; + public function isDelegatedAdmin(): bool { + $authorized = false; + return $this->getAccessLevel([ + self::CLASS_NAME_ADMIN_DELEGATION, + ]); } /** - * Return true if user is an admin. - * @return bool + * @return bool true if the user has api access */ - public function isSubAdmin(): bool { - $allowedGroups = json_decode($this->config->getAppValue('groupfolders', 'delegated-sub-admins', '[]')); - $userGroups = $this->groupManager->getUserGroups($this->userSession->getUser()); - foreach ($userGroups as $userGroup) { - if (in_array($userGroup->getGID(), $allowedGroups)) { - return true; - } + public function hasApiAccess(): bool { + if ($this->isAdminNextcloud()) { + return true; } - return false; + return $this->getAccessLevel([ + self::CLASS_API_ACCESS, + self::CLASS_NAME_ADMIN_DELEGATION, + ]); } /** - * Return true if user is admin or subadmin. - * @return bool + * @return bool true if the user has api access */ - public function isAdminOrSubAdmin(): bool { - return $this->isAdmin() || $this->isSubAdmin(); + public function hasOnlyApiAccess(): bool { + return $this->getAccessLevel([ + self::CLASS_API_ACCESS, + ]); + } + + private function getAccessLevel(array $settingClasses) { + $authorized = false; + $authorizedClasses = $this->groupAuthorizationMapper->findAllClassesForUser($this->userSession->getUser()); + foreach ($settingClasses as $settingClass) { + $authorized = in_array($settingClass, $authorizedClasses, true); + if ($authorized) { + break; + } + } + return $authorized; } } diff --git a/lib/Service/FoldersFilter.php b/lib/Service/FoldersFilter.php index 7f08a3b7..3c7acf41 100644 --- a/lib/Service/FoldersFilter.php +++ b/lib/Service/FoldersFilter.php @@ -34,21 +34,23 @@ class FoldersFilter { } /** - * @param array $folders - * @return array $folders for subadmin only + * @param array $folders List of all folders + * @return array $folders List of folders that the api user can access */ - public function getForSubAdmin($folders): array { + public function getForApiUser(array $folders): array { $user = $this->userSession->getUser(); - $folders = array_filter($folders, function ($folder) use ($user) { - if (!empty($folder['manage'])) { - foreach ($folder['manage'] as $manager) { - if ($manager['type'] === 'group') { - if ($this->groupManager->isInGroup($user->getUid(), $manager['id'])) { - return $folder; - } - } elseif ($manager['id'] === $user->getUid()) { - return $folder; + $folders = array_filter($folders, function ($folder) use ($user): bool { + if (empty($folder['manage'])) { + return false; + } + + foreach ($folder['manage'] as $manager) { + if ($manager['type'] === 'group') { + if ($this->groupManager->isInGroup($user->getUid(), $manager['id'])) { + return true; } + } elseif ($manager['id'] === $user->getUid()) { + return true; } } }); -- cgit v1.2.3