[BUGFIX] Check access to folder in FileListController 08/39108/9
authorNicole Cordes <typo3@cordes.co>
Thu, 30 Apr 2015 16:12:27 +0000 (18:12 +0200)
committerNicole Cordes <typo3@cordes.co>
Thu, 18 Jun 2015 08:18:42 +0000 (10:18 +0200)
Currently if a folder isn't accessible for the user, the root folder
is taken as fallback solution. But this folder might be inaccessible as
well. This patch adds an access check for the returned folder and
turns thrown errors into flash messages.

Releases: master, 6.2
Resolves: #66693
Resolves: #56641
Change-Id: I310df8061edc790dde1034a27136365b4253ac7f
Reviewed-on: http://review.typo3.org/39108
Reviewed-by: Helmut Hummel <helmut.hummel@typo3.org>
Tested-by: Helmut Hummel <helmut.hummel@typo3.org>
Reviewed-by: Benjamin Mack <benni@typo3.org>
Tested-by: Benjamin Mack <benni@typo3.org>
typo3/sysext/core/Classes/Resource/Folder.php
typo3/sysext/core/Classes/Resource/ResourceStorage.php
typo3/sysext/filelist/Classes/Controller/FileListController.php
typo3/sysext/filelist/Classes/FileList.php
typo3/sysext/lang/locallang_mod_file_list.xlf

index df25aed..e864e66 100644 (file)
@@ -221,6 +221,7 @@ class Folder implements FolderInterface {
         * @param array $filterMethods
         * @param bool $recursive
         * @return int
+        * @throws Exception\InsufficientFolderAccessPermissionsException
         */
        public function getFileCount(array $filterMethods = array(), $recursive = FALSE) {
                return $this->storage->countFilesInFolder($this, TRUE, $recursive);
index efd19bb..092e0b8 100644 (file)
@@ -697,10 +697,17 @@ class ResourceStorage implements ResourceStorageInterface {
         */
        protected function assureFolderReadPermission(Folder $folder = NULL) {
                if (!$this->checkFolderActionPermission('read', $folder)) {
-                       throw new Exception\InsufficientFolderAccessPermissionsException(
-                               'You are not allowed to access the given folder: "' . $folder->getName() . '"',
-                               1375955684
-                       );
+                       if ($folder === NULL) {
+                               throw new Exception\InsufficientFolderAccessPermissionsException(
+                                       'You are not allowed to read folders',
+                                       1430657869
+                               );
+                       } else {
+                               throw new Exception\InsufficientFolderAccessPermissionsException(
+                                       'You are not allowed to access the given folder: "' . $folder->getName() . '"',
+                                       1375955684
+                               );
+                       }
                }
        }
 
@@ -1363,6 +1370,7 @@ class ResourceStorage implements ResourceStorageInterface {
         * @param bool $useFilters
         * @param bool $recursive
         * @return int Number of files in folder
+        * @throws Exception\InsufficientFolderAccessPermissionsException
         */
        public function countFilesInFolder(Folder $folder, $useFilters = TRUE, $recursive = FALSE) {
                $this->assureFolderReadPermission($folder);
@@ -2010,6 +2018,7 @@ class ResourceStorage implements ResourceStorageInterface {
         * @param bool $useFilters
         * @param bool $recursive
         * @return integer Number of subfolders
+        * @throws Exception\InsufficientFolderAccessPermissionsException
         */
        public function countFoldersInFolder(Folder $folder, $useFilters = TRUE, $recursive = FALSE) {
                $this->assureFolderReadPermission($folder);
index 7784564..d0c61a4 100644 (file)
@@ -173,31 +173,58 @@ class FileListController {
                                $fileStorages = $this->getBackendUser()->getFileStorages();
                                $fileStorage = reset($fileStorages);
                                if ($fileStorage) {
-                                       // Validating the input "id" (the path, directory!) and
-                                       // checking it against the mounts of the user. - now done in the controller
                                        $this->folderObject = $fileStorage->getRootLevelFolder();
                                } else {
                                        throw new \RuntimeException('Could not find any folder to be displayed.', 1349276894);
                                }
                        }
+
+                       if ($this->folderObject && !$this->folderObject->getStorage()->isWithinFileMountBoundaries($this->folderObject)) {
+                               throw new \RuntimeException('Folder not accessible.', 1430409089);
+                       }
+               } catch (Exception\InsufficientFolderAccessPermissionsException $permissionException) {
+                       $this->folderObject = NULL;
+                       $this->errorMessage = GeneralUtility::makeInstance(FlashMessage::class,
+                               sprintf(
+                                       $this->getLanguageService()->getLL('missingFolderPermissionsMessage', TRUE),
+                                       htmlspecialchars($this->id)
+                               ),
+                               $this->getLanguageService()->getLL('missingFolderPermissionsTitle', TRUE),
+                               FlashMessage::NOTICE
+                       );
                } catch (Exception $fileException) {
+                       // Set folder object to null and throw a message later on
+                       $this->folderObject = NULL;
                        // Take the first object of the first storage
                        $fileStorages = $this->getBackendUser()->getFileStorages();
                        $fileStorage = reset($fileStorages);
-                       if ($fileStorage) {
-                               // Set folder object to null and throw a message later on
+                       if ($fileStorage instanceof \TYPO3\CMS\Core\Resource\ResourceStorage) {
                                $this->folderObject = $fileStorage->getRootLevelFolder();
-                       } else {
-                               $this->folderObject = NULL;
+                               if (!$fileStorage->isWithinFileMountBoundaries($this->folderObject)) {
+                                       $this->folderObject = NULL;
+                               }
                        }
                        $this->errorMessage = GeneralUtility::makeInstance(FlashMessage::class,
-                               sprintf($this->getLanguageService()->getLL('folderNotFoundMessage', TRUE),
-                                               htmlspecialchars($this->id)
+                               sprintf(
+                                       $this->getLanguageService()->getLL('folderNotFoundMessage', TRUE),
+                                       htmlspecialchars($this->id)
                                ),
                                $this->getLanguageService()->getLL('folderNotFoundTitle', TRUE),
                                FlashMessage::NOTICE
                        );
+               } catch (\RuntimeException $e) {
+                       $this->folderObject = NULL;
+                       $this->errorMessage = GeneralUtility::makeInstance(FlashMessage::class,
+                               $e->getMessage() . ' (' . $e->getCode() . ')',
+                               $this->getLanguageService()->getLL('folderNotFoundTitle', TRUE),
+                               FlashMessage::NOTICE
+                       );
                }
+
+               if ($this->folderObject && !$this->folderObject->getStorage()->checkFolderActionPermission('read', $this->folderObject)) {
+                       $this->folderObject = NULL;
+               }
+
                // Configure the "menu" - which is used internally to save the values of sorting, displayThumbs etc.
                $this->menuConfig();
        }
index 9d1c296..3953923 100644 (file)
@@ -309,8 +309,13 @@ class FileList extends AbstractRecordList {
 
                // Only render the contents of a browsable storage
                if ($this->folderObject->getStorage()->isBrowsable()) {
-                       $foldersCount = $storage->countFoldersInFolder($this->folderObject);
-                       $filesCount = $storage->countFilesInFolder($this->folderObject);
+                       try {
+                               $foldersCount = $storage->countFoldersInFolder($this->folderObject);
+                               $filesCount = $storage->countFilesInFolder($this->folderObject);
+                       } catch (\TYPO3\CMS\Core\Resource\Exception\InsufficientFolderAccessPermissionsException $e) {
+                               $foldersCount = 0;
+                               $filesCount = 0;
+                       }
 
                        if ($foldersCount <= $this->firstElementNumber) {
                                $foldersFrom = FALSE;
@@ -522,7 +527,11 @@ class FileList extends AbstractRecordList {
                                foreach ($this->fieldArray as $field) {
                                        switch ($field) {
                                                case 'size':
-                                                       $numFiles = $folderObject->getFileCount();
+                                                       try {
+                                                               $numFiles = $folderObject->getFileCount();
+                                                       } catch (\TYPO3\CMS\Core\Resource\Exception\InsufficientFolderAccessPermissionsException $e) {
+                                                               $numFiles = 0;
+                                                       }
                                                        $theData[$field] = $numFiles . ' ' . $this->getLanguageService()->getLL(($numFiles === 1 ? 'file' : 'files'), TRUE);
                                                        break;
                                                case 'rw':
index 3fa0969..4ffdf53 100644 (file)
                        <trans-unit id="storageNotBrowsableMessage">
                                <source>You are trying to access a folder in a storage that is not browsable.</source>
                        </trans-unit>
+                       <trans-unit id="missingFolderPermissionsTitle">
+                               <source>Missing folder permissions</source>
+                       </trans-unit>
+                       <trans-unit id="missingFolderPermissionsMessage">
+                               <source>You have no access to the folder "%s".</source>
+                       </trans-unit>
                        <trans-unit id="folderNotFoundTitle">
                                <source>Folder not found.</source>
                        </trans-unit>