diff options
author | Robin Appelman <robin@icewind.nl> | 2022-03-28 18:45:06 +0200 |
---|---|---|
committer | Robin Appelman <robin@icewind.nl> | 2022-04-04 14:57:56 +0200 |
commit | 99ac46d8f5de241b49e33e2c4fb874270f6860cc (patch) | |
tree | 4275e6e959229c742ee369fc0a439e4312c15816 /lib | |
parent | 74c97e257132384be3d6e0978b847c9d6933928b (diff) | |
download | nextcloud-server-99ac46d8f5de241b49e33e2c4fb874270f6860cc.tar.gz nextcloud-server-99ac46d8f5de241b49e33e2c4fb874270f6860cc.zip |
allow getting mounts by providers
Signed-off-by: Robin Appelman <robin@icewind.nl>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/private/Files/Config/MountProviderCollection.php | 4 | ||||
-rw-r--r-- | lib/private/Files/Mount/Manager.php | 18 | ||||
-rw-r--r-- | lib/private/Files/SetupManager.php | 98 | ||||
-rw-r--r-- | lib/public/Files/Config/IMountProviderCollection.php | 4 |
4 files changed, 100 insertions, 24 deletions
diff --git a/lib/private/Files/Config/MountProviderCollection.php b/lib/private/Files/Config/MountProviderCollection.php index 2b0acf7d69d..334fce15d9e 100644 --- a/lib/private/Files/Config/MountProviderCollection.php +++ b/lib/private/Files/Config/MountProviderCollection.php @@ -97,10 +97,10 @@ class MountProviderCollection implements IMountProviderCollection, Emitter { return $this->getUserMountsForProviders($user, $this->providers); } - public function getUserMountsForProviderClass(IUser $user, string $mountProviderClass): array { + public function getUserMountsForProviderClasses(IUser $user, array $mountProviderClasses): array { $providers = array_filter( $this->providers, - fn (IMountProvider $mountProvider) => (get_class($mountProvider) === $mountProviderClass) + fn (IMountProvider $mountProvider) => (in_array(get_class($mountProvider), $mountProviderClasses)) ); return $this->getUserMountsForProviders($user, $providers); } diff --git a/lib/private/Files/Mount/Manager.php b/lib/private/Files/Mount/Manager.php index ecd97760f17..d0f5f3f5a52 100644 --- a/lib/private/Files/Mount/Manager.php +++ b/lib/private/Files/Mount/Manager.php @@ -204,4 +204,22 @@ class Manager implements IMountManager { public function getSetupManager(): SetupManager { return $this->setupManager; } + + /** + * Return all mounts in a path from a specific mount provider + * + * @param string $path + * @param string[] $mountProviders + * @return MountPoint[] + */ + public function getMountsByMountProvider(string $path, array $mountProviders) { + $this->getSetupManager()->setupForProvider($path, $mountProviders); + if (in_array('', $mountProviders)) { + return $this->mounts; + } else { + return array_filter($this->mounts, function ($mount) use ($mountProviders) { + return in_array($mount->getMountProvider(), $mountProviders); + }); + } + } } diff --git a/lib/private/Files/SetupManager.php b/lib/private/Files/SetupManager.php index da50983da32..ddb0bbceb81 100644 --- a/lib/private/Files/SetupManager.php +++ b/lib/private/Files/SetupManager.php @@ -40,6 +40,7 @@ use OC_Util; use OCP\Constants; use OCP\Diagnostics\IEventLogger; use OCP\EventDispatcher\IEventDispatcher; +use OCP\Files\Config\IHomeMountProvider; use OCP\Files\Config\IMountProvider; use OCP\Files\Config\IUserMountCache; use OCP\Files\Events\InvalidateMountCacheEvent; @@ -263,6 +264,11 @@ class SetupManager { return strpos($mount->getMountPoint(), $userRoot) === 0; }); $this->userMountCache->registerMounts($user, $mounts); + + $cacheDuration = $this->config->getSystemValueInt('fs_mount_cache_duration', 5 * 60); + if ($cacheDuration > 0) { + $this->cache->set($user->getUID(), true, $cacheDuration); + } } /** @@ -321,25 +327,32 @@ class SetupManager { } /** - * Set up the filesystem for the specified path + * Get the user to setup for a path or `null` if the root needs to be setup + * + * @param string $path + * @return IUser|null */ - public function setupForPath(string $path, bool $includeChildren = false): void { + private function getUserForPath(string $path) { if (substr_count($path, '/') < 2) { if ($user = $this->userSession->getUser()) { - $this->setupForUser($user); + return $user; } else { - $this->setupRoot(); + return null; } - return; } elseif (strpos($path, '/appdata_' . \OC_Util::getInstanceId()) === 0 || strpos($path, '/files_external/') === 0) { - $this->setupRoot(); - return; + return null; } else { [, $userId] = explode('/', $path); } - $user = $this->userManager->get($userId); + return $this->userManager->get($userId); + } + /** + * Set up the filesystem for the specified path + */ + public function setupForPath(string $path, bool $includeChildren = false): void { + $user = $this->getUserForPath($path); if (!$user) { $this->setupRoot(); return; @@ -349,17 +362,8 @@ class SetupManager { return; } - // we perform a "cached" setup only after having done the full setup recently - // this is also used to trigger a full setup after handling events that are likely - // to change the available mounts - $cachedSetup = $this->cache->get($user->getUID()); - if (!$cachedSetup) { + if ($this->fullSetupRequired($user)) { $this->setupForUser($user); - - $cacheDuration = $this->config->getSystemValueInt('fs_mount_cache_duration', 5 * 60); - if ($cacheDuration > 0) { - $this->cache->set($user->getUID(), true, $cacheDuration); - } return; } @@ -381,7 +385,7 @@ class SetupManager { $setupProviders[] = $cachedMount->getMountProvider(); $currentProviders[] = $cachedMount->getMountProvider(); if ($cachedMount->getMountProvider()) { - $mounts = $this->mountProviderCollection->getUserMountsForProviderClass($user, $cachedMount->getMountProvider()); + $mounts = $this->mountProviderCollection->getUserMountsForProviderClasses($user, [$cachedMount->getMountProvider()]); } else { $this->logger->debug("mount at " . $cachedMount->getMountPoint() . " has no provider set, performing full setup"); $this->setupForUser($user); @@ -396,7 +400,7 @@ class SetupManager { $setupProviders[] = $cachedMount->getMountProvider(); $currentProviders[] = $cachedMount->getMountProvider(); if ($cachedMount->getMountProvider()) { - $mounts = array_merge($mounts, $this->mountProviderCollection->getUserMountsForProviderClass($user, $cachedMount->getMountProvider())); + $mounts = array_merge($mounts, $this->mountProviderCollection->getUserMountsForProviderClasses($user, [$cachedMount->getMountProvider()])); } else { $this->logger->debug("mount at " . $cachedMount->getMountPoint() . " has no provider set, performing full setup"); $this->setupForUser($user); @@ -416,6 +420,60 @@ class SetupManager { } } + private function fullSetupRequired(IUser $user): bool { + // we perform a "cached" setup only after having done the full setup recently + // this is also used to trigger a full setup after handling events that are likely + // to change the available mounts + return !$this->cache->get($user->getUID()); + } + + /** + * @param string $path + * @param string[] $providers + */ + public function setupForProvider(string $path, array $providers): void { + $user = $this->getUserForPath($path); + if (!$user) { + $this->setupRoot(); + return; + } + + if ($this->isSetupComplete($user)) { + return; + } + + if ($this->fullSetupRequired($user)) { + $this->setupForUser($user); + return; + } + + // home providers are always used + $providers = array_filter($providers, function (string $provider) { + return !is_subclass_of($provider, IHomeMountProvider::class); + }); + + if (in_array('', $providers)) { + $this->setupForUser($user); + } + $setupProviders = $this->setupUserMountProviders[$user->getUID()] ?? []; + + $providers = array_diff($providers, $setupProviders); + if (count($providers) === 0) { + if (!$this->isSetupStarted($user)) { + $this->oneTimeUserSetup($user); + } + return; + } else { + $this->setupUserMountProviders[$user->getUID()] = array_merge($setupProviders, $providers); + $mounts = $this->mountProviderCollection->getUserMountsForProviderClasses($user, $providers); + } + + $this->userMountCache->registerMounts($user, $mounts, $providers); + $this->setupForUserWith($user, function () use ($mounts) { + array_walk($mounts, [$this->mountManager, 'addMount']); + }); + } + public function tearDown() { $this->setupUsers = []; $this->setupUsersComplete = []; diff --git a/lib/public/Files/Config/IMountProviderCollection.php b/lib/public/Files/Config/IMountProviderCollection.php index 5894d06a388..2d42246b863 100644 --- a/lib/public/Files/Config/IMountProviderCollection.php +++ b/lib/public/Files/Config/IMountProviderCollection.php @@ -42,11 +42,11 @@ interface IMountProviderCollection { * Get the configured mount points for the user from a specific mount provider * * @param \OCP\IUser $user - * @param class-string<IMountProvider> $mountProviderClass + * @param class-string<IMountProvider>[] $mountProviderClasses * @return \OCP\Files\Mount\IMountPoint[] * @since 24.0.0 */ - public function getUserMountsForProviderClass(IUser $user, string $mountProviderClass); + public function getUserMountsForProviderClasses(IUser $user, array $mountProviderClasses): array; /** * Get the configured home mount for this user |