From 1423912a67c1c98e09991957519feea9f5dfd64f Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Mon, 10 May 2021 17:34:10 +0200 Subject: [PATCH] better cleanup of filecache when deleting an external storage this way it can delete the cache entries even with per-user credentials Signed-off-by: Robin Appelman --- .../lib/Service/StoragesService.php | 39 +----------------- lib/private/Files/Cache/Storage.php | 40 +++++++++++++++++++ 2 files changed, 41 insertions(+), 38 deletions(-) diff --git a/apps/files_external/lib/Service/StoragesService.php b/apps/files_external/lib/Service/StoragesService.php index 63f0c5d52c5ab..334b1c5041a55 100644 --- a/apps/files_external/lib/Service/StoragesService.php +++ b/apps/files_external/lib/Service/StoragesService.php @@ -479,44 +479,7 @@ public function removeStorage($id) { $this->triggerHooks($deletedStorage, Filesystem::signal_delete_mount); // delete oc_storages entries and oc_filecache - try { - $rustyStorageId = $this->getRustyStorageIdFromConfig($deletedStorage); - \OC\Files\Cache\Storage::remove($rustyStorageId); - } catch (\Exception $e) { - // can happen either for invalid configs where the storage could not - // be instantiated or whenever $user vars where used, in which case - // the storage id could not be computed - \OC::$server->getLogger()->logException($e, [ - 'level' => ILogger::ERROR, - 'app' => 'files_external', - ]); - } - } - - /** - * Returns the rusty storage id from oc_storages from the given storage config. - * - * @param StorageConfig $storageConfig - * @return string rusty storage id - */ - private function getRustyStorageIdFromConfig(StorageConfig $storageConfig) { - // if any of the storage options contains $user, it is not possible - // to compute the possible storage id as we don't know which users - // mounted it already (and we certainly don't want to iterate over ALL users) - foreach ($storageConfig->getBackendOptions() as $value) { - if (strpos($value, '$user') !== false) { - throw new \Exception('Cannot compute storage id for deletion due to $user vars in the configuration'); - } - } - - // note: similar to ConfigAdapter->prepateStorageConfig() - $storageConfig->getAuthMechanism()->manipulateStorageConfig($storageConfig); - $storageConfig->getBackend()->manipulateStorageConfig($storageConfig); - - $class = $storageConfig->getBackend()->getStorageClass(); - $storageImpl = new $class($storageConfig->getBackendOptions()); - - return $storageImpl->getId(); + \OC\Files\Cache\Storage::cleanByMountId($id); } /** diff --git a/lib/private/Files/Cache/Storage.php b/lib/private/Files/Cache/Storage.php index 173091f53b059..0ce9032414444 100644 --- a/lib/private/Files/Cache/Storage.php +++ b/lib/private/Files/Cache/Storage.php @@ -29,6 +29,7 @@ namespace OC\Files\Cache; +use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\Files\Storage\IStorage; use Psr\Log\LoggerInterface; @@ -219,4 +220,43 @@ public static function remove($storageId) { $query->execute(); } } + + /** + * remove the entry for the storage by the mount id + * + * @param int $mountId + */ + public static function cleanByMountId(int $mountId) { + $db = \OC::$server->getDatabaseConnection(); + + try { + $db->beginTransaction(); + + $query = $db->getQueryBuilder(); + $query->select('storage_id') + ->from('mounts') + ->where($query->expr()->eq('mount_id', $query->createNamedParameter($mountId, IQueryBuilder::PARAM_INT))); + $storageIds = $query->executeQuery()->fetchAll(\PDO::FETCH_COLUMN); + + $query = $db->getQueryBuilder(); + $query->delete('filecache') + ->where($query->expr()->in('storage', $query->createNamedParameter($storageIds, IQueryBuilder::PARAM_INT_ARRAY))); + $query->executeStatement(); + + $query = $db->getQueryBuilder(); + $query->delete('storages') + ->where($query->expr()->eq('id', $query->createNamedParameter($storageIds, IQueryBuilder::PARAM_INT_ARRAY))); + $query->executeStatement(); + + $query = $db->getQueryBuilder(); + $query->delete('mounts') + ->where($query->expr()->eq('mount_id', $query->createNamedParameter($mountId, IQueryBuilder::PARAM_INT))); + $query->executeStatement(); + + $db->commit(); + } catch (\Exception $e) { + $db->rollBack(); + throw $e; + } + } }