[BUGFIX] Handle access restrictions on recycler search 05/57105/2
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:14:50 +0000 (20:14 +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/57105
Reviewed-by: Frans Saris <franssaris@gmail.com>
Tested-by: Frans Saris <franssaris@gmail.com>
typo3/sysext/core/Classes/Resource/ResourceStorage.php

index 6271af9..ee140f0 100644 (file)
@@ -1722,14 +1722,20 @@ class ResourceStorage implements ResourceStorageInterface
         $deleted = true;
 
         if ($this->driver->fileExists($fileObject->getIdentifier())) {
         $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;
             }
             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);
             }
             if (!$result) {
                 throw new Exception\FileOperationErrorException('Deleting the file "' . $fileObject->getIdentifier() . '\' failed.', 1329831691);
             }
@@ -1834,12 +1840,18 @@ class ResourceStorage implements ResourceStorageInterface
             } else {
                 $tempPath = $file->getForLocalProcessing();
                 $newIdentifier = $this->driver->addFile($tempPath, $targetFolder->getIdentifier(), $sanitizedTargetFileName);
             } 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 {
                 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]);
                 }
                 if ($file instanceof File) {
                     $file->updateProperties(['storage' => $this->getUid(), 'identifier' => $newIdentifier]);
                 }
@@ -3053,12 +3065,9 @@ class ResourceStorage implements ResourceStorageInterface
         }
 
         $recyclerFolder = null;
         }
 
         $recyclerFolder = null;
-        $rootFolder = $this->getRootLevelFolder(false);
-        $folder = null;
+        $folder = $file->getParentFolder();
 
         do {
 
         do {
-            $folder = $folder !== null ? $folder->getParentFolder() : $file->getParentFolder();
-
             if ($folder->getRole() === FolderInterface::ROLE_RECYCLER) {
                 break;
             }
             if ($folder->getRole() === FolderInterface::ROLE_RECYCLER) {
                 break;
             }
@@ -3069,7 +3078,11 @@ class ResourceStorage implements ResourceStorageInterface
                     break;
                 }
             }
                     break;
                 }
             }
-        } while ($recyclerFolder === null && $folder->getCombinedIdentifier() !== $rootFolder->getCombinedIdentifier());
+
+            $parentFolder = $folder->getParentFolder();
+            $isFolderLoop = $folder->getIdentifier() === $parentFolder->getIdentifier();
+            $folder = $parentFolder;
+        } while ($recyclerFolder === null && !$isFolderLoop);
 
         return $recyclerFolder;
     }
 
         return $recyclerFolder;
     }