getBackendOptions() as $option => $value) { $storage->setBackendOption($option, MountConfig::substitutePlaceholdersInConfig($value, $user->getUID())); } $objectStore = $storage->getBackendOption('objectstore'); if ($objectStore) { $objectClass = $objectStore['class']; if (!is_subclass_of($objectClass, IObjectStore::class)) { throw new \InvalidArgumentException('Invalid object store'); } $storage->setBackendOption('objectstore', new $objectClass($objectStore)); } $storage->getAuthMechanism()->manipulateStorageConfig($storage, $user); $storage->getBackend()->manipulateStorageConfig($storage, $user); } /** * Construct the storage implementation * * @param StorageConfig $storageConfig */ private function constructStorage(StorageConfig $storageConfig): IStorage { $class = $storageConfig->getBackend()->getStorageClass(); if (!is_a($class, IConstructableStorage::class, true)) { Server::get(LoggerInterface::class)->warning('Building a storage not implementing IConstructableStorage is deprecated since 31.0.0', ['class' => $class]); } $storage = new $class($storageConfig->getBackendOptions()); // auth mechanism should fire first $storage = $storageConfig->getBackend()->wrapStorage($storage); $storage = $storageConfig->getAuthMechanism()->wrapStorage($storage); return $storage; } /** * Get all mountpoints applicable for the user * * @return IMountPoint[] */ public function getMountsForUser(IUser $user, IStorageFactory $loader) { $this->userStoragesService->setUser($user); $this->userGlobalStoragesService->setUser($user); $storageConfigs = $this->userGlobalStoragesService->getAllStoragesForUser(); $storages = array_map(function (StorageConfig $storageConfig) use ($user) { try { $this->prepareStorageConfig($storageConfig, $user); return $this->constructStorage($storageConfig); } catch (\Exception $e) { // propagate exception into filesystem return new FailedStorage(['exception' => $e]); } }, $storageConfigs); Storage::getGlobalCache()->loadForStorageIds(array_map(function (IStorage $storage) { return $storage->getId(); }, $storages)); $availableStorages = array_map(function (IStorage $storage, StorageConfig $storageConfig): IStorage { try { $availability = $storage->getAvailability(); if (!$availability['available'] && !Availability::shouldRecheck($availability)) { $storage = new FailedStorage([ 'exception' => new StorageNotAvailableException('Storage with mount id ' . $storageConfig->getId() . ' is not available') ]); } } catch (\Exception $e) { // propagate exception into filesystem $storage = new FailedStorage(['exception' => $e]); } return $storage; }, $storages, $storageConfigs); $mounts = array_map(function (StorageConfig $storageConfig, IStorage $storage) use ($user, $loader) { $storage->setOwner($user->getUID()); if ($storageConfig->getType() === StorageConfig::MOUNT_TYPE_PERSONAL) { return new PersonalMount( $this->userStoragesService, $storageConfig, $storageConfig->getId(), new KnownMtime([ 'storage' => $storage, 'clock' => $this->clock, ]), '/' . $user->getUID() . '/files' . $storageConfig->getMountPoint(), null, $loader, $storageConfig->getMountOptions(), $storageConfig->getId() ); } else { return new SystemMountPoint( $storageConfig, $storage, '/' . $user->getUID() . '/files' . $storageConfig->getMountPoint(), null, $loader, $storageConfig->getMountOptions(), $storageConfig->getId() ); } }, $storageConfigs, $availableStorages); $this->userStoragesService->resetUser(); $this->userGlobalStoragesService->resetUser(); return $mounts; } }