[BUGFIX] Handle access restrictions on recycler search 52/57052/9
authorNicole Cordes <typo3@cordes.co>
Fri, 25 May 2018 12:05:16 +0000 (14:05 +0200)
committerFrans Saris <franssaris@gmail.com>
Thu, 31 May 2018 18:12:18 +0000 (20:12 +0200)
Fetching a parent folder may throws an error if the user hasn't
access to the parent. This exception needs to be caught and the
search for an existing recycler folder needs to be stopped
immediately.

Furthermore the patch removes the comparison with the root level
folder but checks the parent folder doesn't equal the folder itself.

Another loop is fixed by calling moveFile on the correct
ResourceStorge and not the current one.

Resolves: #85079
Related: #81836
Releases: master, 8.7
Change-Id: I51f5e20d7fa7da9b350ac0ca60cab05866a4d337
Reviewed-on: https://review.typo3.org/57052
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Tested-by: Markus Klein <markus.klein@typo3.org>
Reviewed-by: Frans Saris <franssaris@gmail.com>
Tested-by: Frans Saris <franssaris@gmail.com>
typo3/sysext/core/Classes/Resource/ResourceStorage.php

index 0d34b94..56c8cb3 100644 (file)
@@ -1697,14 +1697,20 @@ class ResourceStorage implements ResourceStorageInterface
         $deleted = true;
 
         if ($this->driver->fileExists($fileObject->getIdentifier())) {
-            $recyclerFolder = $this->getNearestRecyclerFolder($fileObject);
+            // Disable permission check to find nearest recycler and move file without errors
+            $currentPermissions = $this->evaluatePermissions;
+            $this->evaluatePermissions = false;
 
+            $recyclerFolder = $this->getNearestRecyclerFolder($fileObject);
             if ($recyclerFolder === null) {
                 $result = $this->driver->deleteFile($fileObject->getIdentifier());
             } else {
                 $result = $this->moveFile($fileObject, $recyclerFolder);
                 $deleted = false;
             }
+
+            $this->evaluatePermissions = $currentPermissions;
+
             if (!$result) {
                 throw new Exception\FileOperationErrorException('Deleting the file "' . $fileObject->getIdentifier() . '\' failed.', 1329831691);
             }
@@ -1809,12 +1815,18 @@ class ResourceStorage implements ResourceStorageInterface
             } else {
                 $tempPath = $file->getForLocalProcessing();
                 $newIdentifier = $this->driver->addFile($tempPath, $targetFolder->getIdentifier(), $sanitizedTargetFileName);
-                $recyclerFolder = $this->getNearestRecyclerFolder($file);
+
+                // Disable permission check to find nearest recycler and move file without errors
+                $currentPermissions = $sourceStorage->evaluatePermissions;
+                $sourceStorage->evaluatePermissions = false;
+
+                $recyclerFolder = $sourceStorage->getNearestRecyclerFolder($file);
                 if ($recyclerFolder === null) {
                     $sourceStorage->driver->deleteFile($file->getIdentifier());
                 } else {
-                    $this->moveFile($file, $recyclerFolder);
+                    $sourceStorage->moveFile($file, $recyclerFolder);
                 }
+                $sourceStorage->evaluatePermissions = $currentPermissions;
                 if ($file instanceof File) {
                     $file->updateProperties(['storage' => $this->getUid(), 'identifier' => $newIdentifier]);
                 }
@@ -3028,12 +3040,9 @@ class ResourceStorage implements ResourceStorageInterface
         }
 
         $recyclerFolder = null;
-        $rootFolder = $this->getRootLevelFolder(false);
-        $folder = null;
+        $folder = $file->getParentFolder();
 
         do {
-            $folder = $folder !== null ? $folder->getParentFolder() : $file->getParentFolder();
-
             if ($folder->getRole() === FolderInterface::ROLE_RECYCLER) {
                 break;
             }
@@ -3044,7 +3053,11 @@ class ResourceStorage implements ResourceStorageInterface
                     break;
                 }
             }
-        } while ($recyclerFolder === null && $folder->getCombinedIdentifier() !== $rootFolder->getCombinedIdentifier());
+
+            $parentFolder = $folder->getParentFolder();
+            $isFolderLoop = $folder->getIdentifier() === $parentFolder->getIdentifier();
+            $folder = $parentFolder;
+        } while ($recyclerFolder === null && !$isFolderLoop);
 
         return $recyclerFolder;
     }