diff options
Diffstat (limited to 'lib/private')
-rw-r--r-- | lib/private/Authentication/Listeners/UserDeletedFilesCleanupListener.php | 73 | ||||
-rw-r--r-- | lib/private/Comments/Manager.php | 5 | ||||
-rw-r--r-- | lib/private/Files/Storage/Common.php | 2 | ||||
-rw-r--r-- | lib/private/Route/Router.php | 26 | ||||
-rw-r--r-- | lib/private/User/User.php | 13 | ||||
-rw-r--r-- | lib/private/legacy/OC_App.php | 4 | ||||
-rw-r--r-- | lib/private/legacy/OC_Util.php | 2 |
7 files changed, 91 insertions, 34 deletions
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/Comments/Manager.php b/lib/private/Comments/Manager.php index beaab9535ac..93b5ed4cc42 100644 --- a/lib/private/Comments/Manager.php +++ b/lib/private/Comments/Manager.php @@ -30,7 +30,6 @@ namespace OC\Comments; use Doctrine\DBAL\Exception\DriverException; use Doctrine\DBAL\Exception\InvalidFieldNameException; -use OCA\Comments\AppInfo\Application; use OCP\AppFramework\Utility\ITimeFactory; use OCP\Comments\CommentsEvent; use OCP\Comments\IComment; @@ -1309,7 +1308,7 @@ class Manager implements ICommentsManager { * @since 21.0.0 */ public function load(): void { - $this->initialStateService->provideInitialState(Application::APP_ID, 'max-message-length', IComment::MAX_MESSAGE_LENGTH); - Util::addScript(Application::APP_ID, 'comments-app'); + $this->initialStateService->provideInitialState('comments', 'max-message-length', IComment::MAX_MESSAGE_LENGTH); + Util::addScript('comments', 'comments-app'); } } 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/Route/Router.php b/lib/private/Route/Router.php index 2ed8a1991e7..ac9508b3069 100644 --- a/lib/private/Route/Router.php +++ b/lib/private/Route/Router.php @@ -234,32 +234,29 @@ class Router implements IRouter { * @throws \Exception * @return array */ - public function findMatchingRoute(string $url): array { - if (substr($url, 0, 6) === '/apps/') { + public function findMatchingRoute(string $url, bool $loadAll = false): array { + if (strpos($url, '/apps/') === 0) { // empty string / 'apps' / $app / rest of the route [, , $app,] = explode('/', $url, 4); $app = \OC_App::cleanAppId($app); \OC::$REQUESTEDAPP = $app; $this->loadRoutes($app); - } elseif (substr($url, 0, 13) === '/ocsapp/apps/') { + } elseif (strpos($url, '/ocsapp/apps/') === 0) { // empty string / 'ocsapp' / 'apps' / $app / rest of the route [, , , $app,] = explode('/', $url, 5); $app = \OC_App::cleanAppId($app); \OC::$REQUESTEDAPP = $app; $this->loadRoutes($app); - } elseif (substr($url, 0, 10) === '/settings/') { + } elseif (strpos($url, '/settings/') === 0) { $this->loadRoutes('settings'); - } elseif (substr($url, 0, 6) === '/core/') { - \OC::$REQUESTEDAPP = $url; - if (!\OC::$server->getConfig()->getSystemValueBool('maintenance') && !Util::needUpgrade()) { - \OC_App::loadApps(); - } - $this->loadRoutes('core'); - } else { - $this->loadRoutes(); } + \OC::$REQUESTEDAPP = $url; + if (!\OC::$server->getConfig()->getSystemValueBool('maintenance') && !Util::needUpgrade()) { + \OC_App::loadApps(); + } + $this->loadRoutes('core'); $matcher = new UrlMatcher($this->root, $this->context); try { @@ -272,6 +269,11 @@ class Router implements IRouter { try { $parameters = $matcher->match($url . '/'); } catch (ResourceNotFoundException $newException) { + // Attempt to fallback to load all routes if none of the above route patterns matches and the route is not in core + if (!$loadAll) { + $this->loadRoutes(); + return $this->findMatchingRoute($url, true); + } // If we still didn't match a route, we throw the original exception throw $e; } 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); diff --git a/lib/private/legacy/OC_App.php b/lib/private/legacy/OC_App.php index ed85253b649..bca0a3dd08e 100644 --- a/lib/private/legacy/OC_App.php +++ b/lib/private/legacy/OC_App.php @@ -460,10 +460,6 @@ class OC_App { * @return string|false */ public static function getInstallPath() { - if (\OC::$server->getSystemConfig()->getValue('appstoreenabled', true) == false) { - return false; - } - foreach (OC::$APPSROOTS as $dir) { if (isset($dir['writable']) && $dir['writable'] === true) { return $dir['path']; diff --git a/lib/private/legacy/OC_Util.php b/lib/private/legacy/OC_Util.php index c9e19221f95..05ecd61b3a8 100644 --- a/lib/private/legacy/OC_Util.php +++ b/lib/private/legacy/OC_Util.php @@ -768,7 +768,7 @@ class OC_Util { $errors[] = [ 'error' => $l->t('Cannot write into "apps" directory'), 'hint' => $l->t('This can usually be fixed by giving the webserver write access to the apps directory' - . ' or disabling the appstore in the config file.') + . ' or disabling the App Store in the config file.') ]; } } |