Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/server.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorRobin Appelman <robin@icewind.nl>2021-04-27 16:43:34 +0300
committerRobin Appelman <robin@icewind.nl>2021-04-27 21:29:51 +0300
commited2d02d5f1000c76776c6e8dbe24fa787ffe6d0d (patch)
treeea8a4030a698abd0bfe7c797976d474972332345 /lib
parent9de6efd14e4fd8bbf3c9cacde7524b205ca7e93e (diff)
better cleanup of user files on user deletion
Signed-off-by: Robin Appelman <robin@icewind.nl>
Diffstat (limited to 'lib')
-rw-r--r--lib/composer/composer/autoload_classmap.php1
-rw-r--r--lib/composer/composer/autoload_static.php1
-rw-r--r--lib/private/Authentication/Listeners/UserDeletedFilesCleanupListener.php73
-rw-r--r--lib/private/Files/Storage/Common.php2
-rw-r--r--lib/private/User/User.php13
5 files changed, 76 insertions, 14 deletions
diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php
index 3033c0f69e5..88d7a165dcc 100644
--- a/lib/composer/composer/autoload_classmap.php
+++ b/lib/composer/composer/autoload_classmap.php
@@ -685,6 +685,7 @@ return array(
'OC\\Authentication\\Listeners\\RemoteWipeActivityListener' => $baseDir . '/lib/private/Authentication/Listeners/RemoteWipeActivityListener.php',
'OC\\Authentication\\Listeners\\RemoteWipeEmailListener' => $baseDir . '/lib/private/Authentication/Listeners/RemoteWipeEmailListener.php',
'OC\\Authentication\\Listeners\\RemoteWipeNotificationsListener' => $baseDir . '/lib/private/Authentication/Listeners/RemoteWipeNotificationsListener.php',
+ 'OC\\Authentication\\Listeners\\UserDeletedFilesCleanupListener' => $baseDir . '/lib/private/Authentication/Listeners/UserDeletedFilesCleanupListener.php',
'OC\\Authentication\\Listeners\\UserDeletedStoreCleanupListener' => $baseDir . '/lib/private/Authentication/Listeners/UserDeletedStoreCleanupListener.php',
'OC\\Authentication\\Listeners\\UserDeletedTokenCleanupListener' => $baseDir . '/lib/private/Authentication/Listeners/UserDeletedTokenCleanupListener.php',
'OC\\Authentication\\Listeners\\UserLoggedInListener' => $baseDir . '/lib/private/Authentication/Listeners/UserLoggedInListener.php',
diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php
index dafae4aa46e..2abb4e8f333 100644
--- a/lib/composer/composer/autoload_static.php
+++ b/lib/composer/composer/autoload_static.php
@@ -714,6 +714,7 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c
'OC\\Authentication\\Listeners\\RemoteWipeActivityListener' => __DIR__ . '/../../..' . '/lib/private/Authentication/Listeners/RemoteWipeActivityListener.php',
'OC\\Authentication\\Listeners\\RemoteWipeEmailListener' => __DIR__ . '/../../..' . '/lib/private/Authentication/Listeners/RemoteWipeEmailListener.php',
'OC\\Authentication\\Listeners\\RemoteWipeNotificationsListener' => __DIR__ . '/../../..' . '/lib/private/Authentication/Listeners/RemoteWipeNotificationsListener.php',
+ 'OC\\Authentication\\Listeners\\UserDeletedFilesCleanupListener' => __DIR__ . '/../../..' . '/lib/private/Authentication/Listeners/UserDeletedFilesCleanupListener.php',
'OC\\Authentication\\Listeners\\UserDeletedStoreCleanupListener' => __DIR__ . '/../../..' . '/lib/private/Authentication/Listeners/UserDeletedStoreCleanupListener.php',
'OC\\Authentication\\Listeners\\UserDeletedTokenCleanupListener' => __DIR__ . '/../../..' . '/lib/private/Authentication/Listeners/UserDeletedTokenCleanupListener.php',
'OC\\Authentication\\Listeners\\UserLoggedInListener' => __DIR__ . '/../../..' . '/lib/private/Authentication/Listeners/UserLoggedInListener.php',
diff --git a/lib/private/Authentication/Listeners/UserDeletedFilesCleanupListener.php b/lib/private/Authentication/Listeners/UserDeletedFilesCleanupListener.php
new file mode 100644
index 00000000000..fba813e0a24
--- /dev/null
+++ b/lib/private/Authentication/Listeners/UserDeletedFilesCleanupListener.php
@@ -0,0 +1,73 @@
+<?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 OC\Authentication\Listeners;
+
+use OC\Files\Cache\Cache;
+use OCP\EventDispatcher\Event;
+use OCP\EventDispatcher\IEventListener;
+use OCP\Files\Config\IMountProviderCollection;
+use OCP\Files\Storage\IStorage;
+use OCP\User\Events\BeforeUserDeletedEvent;
+use OCP\User\Events\UserDeletedEvent;
+
+class UserDeletedFilesCleanupListener implements IEventListener {
+ /** @var array<string,IStorage> */
+ private $homeStorageCache = [];
+
+ /** @var IMountProviderCollection */
+ private $mountProviderCollection;
+
+ public function __construct(IMountProviderCollection $mountProviderCollection) {
+ $this->mountProviderCollection = $mountProviderCollection;
+ }
+
+ public function handle(Event $event): void {
+ // since we can't reliably get the user home storage after the user is deleted
+ // but the user deletion might get canceled during the before event
+ // we only cache the user home storage during the before event and then do the
+ // action deletion during the after event
+
+ if ($event instanceof BeforeUserDeletedEvent) {
+ $userHome = $this->mountProviderCollection->getHomeMountForUser($event->getUser());
+ $storage = $userHome->getStorage();
+ if (!$storage) {
+ throw new \Exception("User has no home storage");
+ }
+ $this->homeStorageCache[$event->getUser()->getUID()] = $storage;
+ }
+ if ($event instanceof UserDeletedEvent) {
+ if (!isset($this->homeStorageCache[$event->getUser()->getUID()])) {
+ throw new \Exception("UserDeletedEvent fired without matching BeforeUserDeletedEvent");
+ }
+ $storage = $this->homeStorageCache[$event->getUser()->getUID()];
+ $cache = $storage->getCache();
+ if ($cache instanceof Cache) {
+ $cache->clear();
+ } else {
+ throw new \Exception("Home storage has invalid cache");
+ }
+ $storage->rmdir('');
+ }
+ }
+}
diff --git a/lib/private/Files/Storage/Common.php b/lib/private/Files/Storage/Common.php
index aa2aeee403b..21baea1b78f 100644
--- a/lib/private/Files/Storage/Common.php
+++ b/lib/private/Files/Storage/Common.php
@@ -153,7 +153,7 @@ abstract class Common implements Storage, ILockingStorage, IWriteStreamStorage {
public function isDeletable($path) {
if ($path === '' || $path === '/') {
- return false;
+ return $this->isUpdatable($path);
}
$parent = dirname($path);
return $this->isUpdatable($parent) && $this->isUpdatable($path);
diff --git a/lib/private/User/User.php b/lib/private/User/User.php
index 5bc42a469d7..771cb431cbd 100644
--- a/lib/private/User/User.php
+++ b/lib/private/User/User.php
@@ -38,7 +38,6 @@ namespace OC\User;
use OC\Accounts\AccountManager;
use OC\Avatar\AvatarManager;
-use OC\Files\Cache\Storage;
use OC\Hooks\Emitter;
use OC_Helper;
use OCP\EventDispatcher\IEventDispatcher;
@@ -221,8 +220,6 @@ class User implements IUser {
$this->emitter->emit('\OC\User', 'preDelete', [$this]);
}
$this->dispatcher->dispatchTyped(new BeforeUserDeletedEvent($this));
- // get the home now because it won't return it after user deletion
- $homePath = $this->getHome();
$result = $this->backend->deleteUser($this->uid);
if ($result) {
@@ -241,16 +238,6 @@ class User implements IUser {
// Delete the user's keys in preferences
\OC::$server->getConfig()->deleteAllUserValues($this->uid);
- // Delete user files in /data/
- if ($homePath !== false) {
- // FIXME: this operates directly on FS, should use View instead...
- // also this is not testable/mockable...
- \OC_Helper::rmdirr($homePath);
- }
-
- // Delete the users entry in the storage table
- Storage::remove('home::' . $this->uid);
-
\OC::$server->getCommentsManager()->deleteReferencesOfActor('users', $this->uid);
\OC::$server->getCommentsManager()->deleteReadMarksFromUser($this);