diff options
Diffstat (limited to 'apps/files_external/lib')
-rw-r--r-- | apps/files_external/lib/AppInfo/Application.php | 73 | ||||
-rw-r--r-- | apps/files_external/lib/Command/Create.php | 2 | ||||
-rw-r--r-- | apps/files_external/lib/Command/Import.php | 2 | ||||
-rw-r--r-- | apps/files_external/lib/Controller/ApiController.php | 51 | ||||
-rw-r--r-- | apps/files_external/lib/Lib/StorageConfig.php | 12 | ||||
-rw-r--r-- | apps/files_external/lib/Listener/GroupDeletedListener.php | 45 | ||||
-rw-r--r-- | apps/files_external/lib/Listener/UserDeletedListener.php | 45 | ||||
-rw-r--r-- | apps/files_external/lib/MountConfig.php | 116 |
8 files changed, 185 insertions, 161 deletions
diff --git a/apps/files_external/lib/AppInfo/Application.php b/apps/files_external/lib/AppInfo/Application.php index 151b14fdfa9..7f6d8863350 100644 --- a/apps/files_external/lib/AppInfo/Application.php +++ b/apps/files_external/lib/AppInfo/Application.php @@ -29,8 +29,10 @@ */ namespace OCA\Files_External\AppInfo; +use OCA\Files_External\Config\ConfigAdapter; use OCA\Files_External\Config\UserPlaceholderHandler; -use OCA\Files_External\Service\DBConfigService; +use OCA\Files_External\Listener\GroupDeletedListener; +use OCA\Files_External\Listener\UserDeletedListener; use OCA\Files_External\Lib\Auth\AmazonS3\AccessKey; use OCA\Files_External\Lib\Auth\Builtin; use OCA\Files_External\Lib\Auth\NullMechanism; @@ -62,14 +64,19 @@ use OCA\Files_External\Lib\Config\IAuthMechanismProvider; use OCA\Files_External\Lib\Config\IBackendProvider; use OCA\Files_External\Service\BackendService; use OCP\AppFramework\App; -use OCP\IGroup; -use OCP\IUser; -use Symfony\Component\EventDispatcher\GenericEvent; +use OCP\AppFramework\Bootstrap\IBootContext; +use OCP\AppFramework\Bootstrap\IBootstrap; +use OCP\AppFramework\Bootstrap\IRegistrationContext; +use OCP\Files\Config\IMountProviderCollection; +use OCP\Group\Events\GroupDeletedEvent; +use OCP\User\Events\UserDeletedEvent; + +require_once __DIR__ . '/../../3rdparty/autoload.php'; /** * @package OCA\Files_External\AppInfo */ -class Application extends App implements IBackendProvider, IAuthMechanismProvider { +class Application extends App implements IBackendProvider, IAuthMechanismProvider, IBootstrap { /** * Application constructor. @@ -78,15 +85,33 @@ class Application extends App implements IBackendProvider, IAuthMechanismProvide */ public function __construct(array $urlParams = []) { parent::__construct('files_external', $urlParams); + } - $container = $this->getContainer(); + public function register(IRegistrationContext $context): void { + $context->registerEventListener(UserDeletedEvent::class, UserDeletedListener::class); + $context->registerEventListener(GroupDeletedEvent::class, GroupDeletedListener::class); + } - /** @var BackendService $backendService */ - $backendService = $container->query(BackendService::class); - $backendService->registerBackendProvider($this); - $backendService->registerAuthMechanismProvider($this); - $backendService->registerConfigHandler('user', function () use ($container) { - return $container->query(UserPlaceholderHandler::class); + public function boot(IBootContext $context): void { + $context->injectFn(function (IMountProviderCollection $mountProviderCollection, ConfigAdapter $configAdapter) { + $mountProviderCollection->registerProvider($configAdapter); + }); + \OCA\Files\App::getNavigationManager()->add(function () { + $l = \OC::$server->getL10N('files_external'); + return [ + 'id' => 'extstoragemounts', + 'appname' => 'files_external', + 'script' => 'list.php', + 'order' => 30, + 'name' => $l->t('External storage'), + ]; + }); + $context->injectFn(function (BackendService $backendService, UserPlaceholderHandler $userConfigHandler) { + $backendService->registerBackendProvider($this); + $backendService->registerAuthMechanismProvider($this); + $backendService->registerConfigHandler('user', function () use ($userConfigHandler) { + return $userConfigHandler; + }); }); // force-load auth mechanisms since some will register hooks @@ -94,30 +119,6 @@ class Application extends App implements IBackendProvider, IAuthMechanismProvide $this->getAuthMechanisms(); } - public function registerListeners() { - $dispatcher = $this->getContainer()->getServer()->getEventDispatcher(); - $dispatcher->addListener( - IUser::class . '::postDelete', - function (GenericEvent $event) { - /** @var IUser $user */ - $user = $event->getSubject(); - /** @var DBConfigService $config */ - $config = $this->getContainer()->query(DBConfigService::class); - $config->modifyMountsOnUserDelete($user->getUID()); - } - ); - $dispatcher->addListener( - IGroup::class . '::postDelete', - function (GenericEvent $event) { - /** @var IGroup $group */ - $group = $event->getSubject(); - /** @var DBConfigService $config */ - $config = $this->getContainer()->query(DBConfigService::class); - $config->modifyMountsOnGroupDelete($group->getGID()); - } - ); - } - /** * @{inheritdoc} */ diff --git a/apps/files_external/lib/Command/Create.php b/apps/files_external/lib/Command/Create.php index 3fe9e71b17a..99991b893cd 100644 --- a/apps/files_external/lib/Command/Create.php +++ b/apps/files_external/lib/Command/Create.php @@ -119,7 +119,7 @@ class Create extends Base { } protected function execute(InputInterface $input, OutputInterface $output): int { - $user = $input->getOption('user'); + $user = (string) $input->getOption('user'); $mountPoint = $input->getArgument('mount_point'); $storageIdentifier = $input->getArgument('storage_backend'); $authIdentifier = $input->getArgument('authentication_backend'); diff --git a/apps/files_external/lib/Command/Import.php b/apps/files_external/lib/Command/Import.php index 5d9a6893353..53ae0d7c5bf 100644 --- a/apps/files_external/lib/Command/Import.php +++ b/apps/files_external/lib/Command/Import.php @@ -107,7 +107,7 @@ class Import extends Base { } protected function execute(InputInterface $input, OutputInterface $output): int { - $user = $input->getOption('user'); + $user = (string) $input->getOption('user'); $path = $input->getArgument('path'); if ($path === '-') { $json = file_get_contents('php://stdin'); diff --git a/apps/files_external/lib/Controller/ApiController.php b/apps/files_external/lib/Controller/ApiController.php index d7f24b44cff..40539d0bbca 100644 --- a/apps/files_external/lib/Controller/ApiController.php +++ b/apps/files_external/lib/Controller/ApiController.php @@ -29,6 +29,9 @@ declare(strict_types=1); */ namespace OCA\Files_External\Controller; +use OCA\Files_External\Lib\StorageConfig; +use OCA\Files_External\Service\UserGlobalStoragesService; +use OCA\Files_External\Service\UserStoragesService; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\OCSController; use OCP\IRequest; @@ -38,35 +41,41 @@ class ApiController extends OCSController { /** @var IUserSession */ private $userSession; + /** @var UserGlobalStoragesService */ + private $userGlobalStoragesService; + /** @var UserStoragesService */ + private $userStoragesService; - public function __construct(string $appName, - IRequest $request, - IUserSession $userSession) { + public function __construct( + string $appName, + IRequest $request, + IUserSession $userSession, + UserGlobalStoragesService $userGlobalStorageService, + UserStoragesService $userStorageService + ) { parent::__construct($appName, $request); $this->userSession = $userSession; + $this->userGlobalStoragesService = $userGlobalStorageService; + $this->userStoragesService = $userStorageService; } /** * Formats the given mount config to a mount entry. * * @param string $mountPoint mount point name, relative to the data dir - * @param array $mountConfig mount config to format + * @param StorageConfig $mountConfig mount config to format * * @return array entry */ - private function formatMount(string $mountPoint, array $mountConfig): array { - // strip "/$user/files" from mount point - $mountPoint = explode('/', trim($mountPoint, '/'), 3); - $mountPoint = $mountPoint[2] ?? ''; - + private function formatMount(string $mountPoint, StorageConfig $mountConfig): array { // split path from mount point $path = \dirname($mountPoint); - if ($path === '.') { + if ($path === '.' || $path === '/') { $path = ''; } - $isSystemMount = !$mountConfig['personal']; + $isSystemMount = $mountConfig->getType() === StorageConfig::MOUNT_TYPE_ADMIN; $permissions = \OCP\Constants::PERMISSION_READ; // personal mounts can be deleted @@ -78,11 +87,11 @@ class ApiController extends OCSController { 'name' => basename($mountPoint), 'path' => $path, 'type' => 'dir', - 'backend' => $mountConfig['backend'], + 'backend' => $mountConfig->getBackend()->getText(), 'scope' => $isSystemMount ? 'system' : 'personal', 'permissions' => $permissions, - 'id' => $mountConfig['id'], - 'class' => $mountConfig['class'] + 'id' => $mountConfig->getId(), + 'class' => $mountConfig->getBackend()->getIdentifier(), ]; return $entry; } @@ -96,10 +105,18 @@ class ApiController extends OCSController { */ public function getUserMounts(): DataResponse { $entries = []; - $user = $this->userSession->getUser()->getUID(); + $mountPoints = []; + + foreach ($this->userGlobalStoragesService->getStorages() as $storage) { + $mountPoint = $storage->getMountPoint(); + $mountPoints[$mountPoint] = $storage; + } - $mounts = \OCA\Files_External\MountConfig::getAbsoluteMountPoints($user); - foreach ($mounts as $mountPoint => $mount) { + foreach ($this->userStoragesService->getStorages() as $storage) { + $mountPoint = $storage->getMountPoint(); + $mountPoints[$mountPoint] = $storage; + } + foreach ($mountPoints as $mountPoint => $mount) { $entries[] = $this->formatMount($mountPoint, $mount); } diff --git a/apps/files_external/lib/Lib/StorageConfig.php b/apps/files_external/lib/Lib/StorageConfig.php index ca8622ab32d..97b72005018 100644 --- a/apps/files_external/lib/Lib/StorageConfig.php +++ b/apps/files_external/lib/Lib/StorageConfig.php @@ -98,14 +98,14 @@ class StorageConfig implements \JsonSerializable { /** * List of users who have access to this storage * - * @var array + * @var string[] */ private $applicableUsers = []; /** * List of groups that have access to this storage * - * @var array + * @var string[] */ private $applicableGroups = []; @@ -272,7 +272,7 @@ class StorageConfig implements \JsonSerializable { /** * Returns the users for which to mount this storage * - * @return array applicable users + * @return string[] applicable users */ public function getApplicableUsers() { return $this->applicableUsers; @@ -281,7 +281,7 @@ class StorageConfig implements \JsonSerializable { /** * Sets the users for which to mount this storage * - * @param array|null $applicableUsers applicable users + * @param string[]|null $applicableUsers applicable users */ public function setApplicableUsers($applicableUsers) { if (is_null($applicableUsers)) { @@ -293,7 +293,7 @@ class StorageConfig implements \JsonSerializable { /** * Returns the groups for which to mount this storage * - * @return array applicable groups + * @return string[] applicable groups */ public function getApplicableGroups() { return $this->applicableGroups; @@ -302,7 +302,7 @@ class StorageConfig implements \JsonSerializable { /** * Sets the groups for which to mount this storage * - * @param array|null $applicableGroups applicable groups + * @param string[]|null $applicableGroups applicable groups */ public function setApplicableGroups($applicableGroups) { if (is_null($applicableGroups)) { diff --git a/apps/files_external/lib/Listener/GroupDeletedListener.php b/apps/files_external/lib/Listener/GroupDeletedListener.php new file mode 100644 index 00000000000..d274f35d9cf --- /dev/null +++ b/apps/files_external/lib/Listener/GroupDeletedListener.php @@ -0,0 +1,45 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2021 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\Files_External\Listener; + +use OCA\Files_External\Service\DBConfigService; +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; +use OCP\Group\Events\GroupDeletedEvent; + +class GroupDeletedListener implements IEventListener { + /** @var DBConfigService */ + private $config; + + public function __construct(DBConfigService $config) { + $this->config = $config; + } + + public function handle(Event $event): void { + if (!$event instanceof GroupDeletedEvent) { + return; + } + $this->config->modifyMountsOnGroupDelete($event->getGroup()->getGID()); + } +} diff --git a/apps/files_external/lib/Listener/UserDeletedListener.php b/apps/files_external/lib/Listener/UserDeletedListener.php new file mode 100644 index 00000000000..1417119b317 --- /dev/null +++ b/apps/files_external/lib/Listener/UserDeletedListener.php @@ -0,0 +1,45 @@ +<?php + +declare(strict_types=1); +/** + * @copyright Copyright (c) 2021 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\Files_External\Listener; + +use OCA\Files_External\Service\DBConfigService; +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; +use OCP\User\Events\UserDeletedEvent; + +class UserDeletedListener implements IEventListener { + /** @var DBConfigService */ + private $config; + + public function __construct(DBConfigService $config) { + $this->config = $config; + } + + public function handle(Event $event): void { + if (!$event instanceof UserDeletedEvent) { + return; + } + $this->config->modifyMountsOnUserDelete($event->getUser()->getUID()); + } +} diff --git a/apps/files_external/lib/MountConfig.php b/apps/files_external/lib/MountConfig.php index 0a9168bbfd7..aa3b662e224 100644 --- a/apps/files_external/lib/MountConfig.php +++ b/apps/files_external/lib/MountConfig.php @@ -39,17 +39,14 @@ */ namespace OCA\Files_External; -use OCA\Files_External\AppInfo\Application; use OCA\Files_External\Config\IConfigHandler; use OCA\Files_External\Config\UserContext; use OCA\Files_External\Lib\Backend\Backend; -use OCA\Files_External\Lib\StorageConfig; use OCA\Files_External\Service\BackendService; use OCA\Files_External\Service\GlobalStoragesService; use OCA\Files_External\Service\UserGlobalStoragesService; use OCA\Files_External\Service\UserStoragesService; use OCP\Files\StorageNotAvailableException; -use OCP\IUserManager; use phpseclib\Crypt\AES; /** @@ -66,102 +63,21 @@ class MountConfig { // whether to skip backend test (for unit tests, as this static class is not mockable) public static $skipTest = false; - /** @var Application */ - public static $app; - - /** - * Returns the mount points for the given user. - * The mount point is relative to the data directory. - * - * @param string $uid user - * @return array of mount point string as key, mountpoint config as value - * - * @deprecated 8.2.0 use UserGlobalStoragesService::getStorages() and UserStoragesService::getStorages() - */ - public static function getAbsoluteMountPoints($uid) { - $mountPoints = []; - - $userGlobalStoragesService = self::$app->getContainer()->query(UserGlobalStoragesService::class); - $userStoragesService = self::$app->getContainer()->query(UserStoragesService::class); - $user = self::$app->getContainer()->query(IUserManager::class)->get($uid); - - $userGlobalStoragesService->setUser($user); - $userStoragesService->setUser($user); - - foreach ($userGlobalStoragesService->getStorages() as $storage) { - /** @var \OCA\Files_External\Lib\StorageConfig $storage */ - $mountPoint = '/'.$uid.'/files'.$storage->getMountPoint(); - $mountEntry = self::prepareMountPointEntry($storage, false); - foreach ($mountEntry['options'] as &$option) { - $option = self::substitutePlaceholdersInConfig($option, $uid); - } - $mountPoints[$mountPoint] = $mountEntry; - } - - foreach ($userStoragesService->getStorages() as $storage) { - $mountPoint = '/'.$uid.'/files'.$storage->getMountPoint(); - $mountEntry = self::prepareMountPointEntry($storage, true); - foreach ($mountEntry['options'] as &$option) { - $option = self::substitutePlaceholdersInConfig($option, $uid); - } - $mountPoints[$mountPoint] = $mountEntry; - } - - $userGlobalStoragesService->resetUser(); - $userStoragesService->resetUser(); - - return $mountPoints; - } - - /** - * Get the system mount points - * - * @return array - * - * @deprecated 8.2.0 use GlobalStoragesService::getStorages() - */ - public static function getSystemMountPoints() { - $mountPoints = []; - $service = self::$app->getContainer()->query(GlobalStoragesService::class); - - foreach ($service->getStorages() as $storage) { - $mountPoints[] = self::prepareMountPointEntry($storage, false); - } - - return $mountPoints; - } - - /** - * Convert a StorageConfig to the legacy mountPoints array format - * There's a lot of extra information in here, to satisfy all of the legacy functions - * - * @param StorageConfig $storage - * @param bool $isPersonal - * @return array - */ - private static function prepareMountPointEntry(StorageConfig $storage, $isPersonal) { - $mountEntry = []; - - $mountEntry['mountpoint'] = substr($storage->getMountPoint(), 1); // remove leading slash - $mountEntry['class'] = $storage->getBackend()->getIdentifier(); - $mountEntry['backend'] = $storage->getBackend()->getText(); - $mountEntry['authMechanism'] = $storage->getAuthMechanism()->getIdentifier(); - $mountEntry['personal'] = $isPersonal; - $mountEntry['options'] = self::decryptPasswords($storage->getBackendOptions()); - $mountEntry['mountOptions'] = $storage->getMountOptions(); - $mountEntry['priority'] = $storage->getPriority(); - $mountEntry['applicable'] = [ - 'groups' => $storage->getApplicableGroups(), - 'users' => $storage->getApplicableUsers(), - ]; - // if mountpoint is applicable to all users the old API expects ['all'] - if (empty($mountEntry['applicable']['groups']) && empty($mountEntry['applicable']['users'])) { - $mountEntry['applicable']['users'] = ['all']; - } - - $mountEntry['id'] = $storage->getId(); - - return $mountEntry; + /** @var UserGlobalStoragesService */ + private $userGlobalStorageService; + /** @var UserStoragesService */ + private $userStorageService; + /** @var GlobalStoragesService */ + private $globalStorageService; + + public function __construct( + UserGlobalStoragesService $userGlobalStorageService, + UserStoragesService $userStorageService, + GlobalStoragesService $globalStorageService + ) { + $this->userGlobalStorageService = $userGlobalStorageService; + $this->userStorageService = $userStorageService; + $this->globalStorageService = $globalStorageService; } /** @@ -173,7 +89,7 @@ class MountConfig { */ public static function substitutePlaceholdersInConfig($input, string $userId = null) { /** @var BackendService $backendService */ - $backendService = self::$app->getContainer()->query(BackendService::class); + $backendService = \OC::$server->get(BackendService::class); /** @var IConfigHandler[] $handlers */ $handlers = $backendService->getConfigHandlers(); foreach ($handlers as $handler) { |