/** * Read the external storages config * * @return StorageConfig[] map of storage id to storage config */ public function getAllStorages() { $mountPoints = $this->readLegacyConfig(); /** * Here is the how the horribly messy mount point array looks like * from the mount.json file: * * $storageOptions = $mountPoints[$mountType][$applicable][$mountPath] * * - $mountType is either "user" or "group" * - $applicable is the name of a user or group (or the current user for personal mounts) * - $mountPath is the mount point path (where the storage must be mounted) * - $storageOptions is a map of storage options: * - "priority": storage priority * - "backend": backend identifier * - "class": LEGACY backend class name * - "options": backend-specific options * - "authMechanism": authentication mechanism identifier * - "mountOptions": mount-specific options (ex: disable previews, scanner, etc) */ // group by storage id /** @var StorageConfig[] $storages */ $storages = []; // for storages without id (legacy), group by config hash for // later processing $storagesWithConfigHash = []; foreach ($mountPoints as $mountType => $applicables) { foreach ($applicables as $applicable => $mountPaths) { foreach ($mountPaths as $rootMountPath => $storageOptions) { $currentStorage = null; /** * Flag whether the config that was read already has an id. * If not, it will use a config hash instead and generate * a proper id later * * @var boolean */ $hasId = false; // the root mount point is in the format "/$user/files/the/mount/point" // we remove the "/$user/files" prefix $parts = explode('/', ltrim($rootMountPath, '/'), 3); if (count($parts) < 3) { // something went wrong, skip \OCP\Util::writeLog('files_external', 'Could not parse mount point "' . $rootMountPath . '"', \OCP\Util::ERROR); continue; } $relativeMountPath = rtrim($parts[2], '/'); // note: we cannot do this after the loop because the decrypted config // options might be needed for the config hash $storageOptions['options'] = \OC_Mount_Config::decryptPasswords($storageOptions['options']); if (!isset($storageOptions['backend'])) { $storageOptions['backend'] = $storageOptions['class']; // legacy compat } if (!isset($storageOptions['authMechanism'])) { $storageOptions['authMechanism'] = null; // ensure config hash works } if (isset($storageOptions['id'])) { $configId = (int) $storageOptions['id']; if (isset($storages[$configId])) { $currentStorage = $storages[$configId]; } $hasId = true; } else { // missing id in legacy config, need to generate // but at this point we don't know the max-id, so use // first group it by config hash $storageOptions['mountpoint'] = $rootMountPath; $configId = \OC_Mount_Config::makeConfigHash($storageOptions); if (isset($storagesWithConfigHash[$configId])) { $currentStorage = $storagesWithConfigHash[$configId]; } } if (is_null($currentStorage)) { // create new $currentStorage = new StorageConfig($configId); $currentStorage->setMountPoint($relativeMountPath); } try { $this->populateStorageConfigWithLegacyOptions($currentStorage, $mountType, $applicable, $storageOptions); if ($hasId) { $storages[$configId] = $currentStorage; } else { $storagesWithConfigHash[$configId] = $currentStorage; } } catch (\UnexpectedValueException $e) { // don't die if a storage backend doesn't exist \OCP\Util::writeLog('files_external', 'Could not load storage: "' . $e->getMessage() . '"', \OCP\Util::ERROR); } } } } // convert parameter values foreach ($storages as $storage) { $storage->getBackend()->validateStorageDefinition($storage); $storage->getAuthMechanism()->validateStorageDefinition($storage); } return $storages; }
/** * Read the external storages config * * @return array map of storage id to storage config */ protected function readConfig() { $mountPoints = $this->readLegacyConfig(); /** * Here is the how the horribly messy mount point array looks like * from the mount.json file: * * $storageOptions = $mountPoints[$mountType][$applicable][$mountPath] * * - $mountType is either "user" or "group" * - $applicable is the name of a user or group (or the current user for personal mounts) * - $mountPath is the mount point path (where the storage must be mounted) * - $storageOptions is a map of storage options: * - "priority": storage priority * - "backend": backend class name * - "options": backend-specific options * - "mountOptions": mount-specific options (ex: disable previews, scanner, etc) */ // group by storage id $storages = []; // for storages without id (legacy), group by config hash for // later processing $storagesWithConfigHash = []; foreach ($mountPoints as $mountType => $applicables) { foreach ($applicables as $applicable => $mountPaths) { foreach ($mountPaths as $rootMountPath => $storageOptions) { $currentStorage = null; /** * Flag whether the config that was read already has an id. * If not, it will use a config hash instead and generate * a proper id later * * @var boolean */ $hasId = false; // the root mount point is in the format "/$user/files/the/mount/point" // we remove the "/$user/files" prefix $parts = explode('/', trim($rootMountPath, '/'), 3); if (count($parts) < 3) { // something went wrong, skip \OCP\Util::writeLog('files_external', 'Could not parse mount point "' . $rootMountPath . '"', \OCP\Util::ERROR); continue; } $relativeMountPath = $parts[2]; // note: we cannot do this after the loop because the decrypted config // options might be needed for the config hash $storageOptions['options'] = \OC_Mount_Config::decryptPasswords($storageOptions['options']); if (isset($storageOptions['id'])) { $configId = (int) $storageOptions['id']; if (isset($storages[$configId])) { $currentStorage = $storages[$configId]; } $hasId = true; } else { // missing id in legacy config, need to generate // but at this point we don't know the max-id, so use // first group it by config hash $storageOptions['mountpoint'] = $rootMountPath; $configId = \OC_Mount_Config::makeConfigHash($storageOptions); if (isset($storagesWithConfigHash[$configId])) { $currentStorage = $storagesWithConfigHash[$configId]; } } if (is_null($currentStorage)) { // create new $currentStorage = new StorageConfig($configId); $currentStorage->setMountPoint($relativeMountPath); } $this->populateStorageConfigWithLegacyOptions($currentStorage, $mountType, $applicable, $storageOptions); if ($hasId) { $storages[$configId] = $currentStorage; } else { $storagesWithConfigHash[$configId] = $currentStorage; } } } } // process storages with config hash, they must get a real id if (!empty($storagesWithConfigHash)) { $nextId = $this->generateNextId($storages); foreach ($storagesWithConfigHash as $storage) { $storage->setId($nextId); $storages[$nextId] = $storage; $nextId++; } // re-save the config with the generated ids $this->writeConfig($storages); } return $storages; }