[FEATURE] Allow Storages outside the webroot 60/27760/11
authorSteffen Ritter <info@rs-websystems.de>
Thu, 20 Feb 2014 17:26:20 +0000 (18:26 +0100)
committerSteffen Ritter <info@rs-websystems.de>
Tue, 11 Mar 2014 13:08:45 +0000 (14:08 +0100)
Storages can be marked as not public or be outside of webroot.
There are no direct links to the files posible.

This change adds a eID implementation to create urls to these files.
It also implements a hook in het eID dispatcher that makes is possible
to add custom security/access checks when delivering files.

Releases: 6.2
Resolves: #36420
Change-Id: Ie7fc9c8a674a3200ea2b29d1adc17327d10bd6e5
Reviewed-on: https://review.typo3.org/27760
Reviewed-by: Frans Saris
Tested-by: Frans Saris
Reviewed-by: Fabien Udriot
Tested-by: Fabien Udriot
Reviewed-by: Steffen Ritter
Tested-by: Steffen Ritter
typo3/sysext/core/Classes/Resource/AbstractFile.php
typo3/sysext/core/Classes/Resource/AbstractRepository.php
typo3/sysext/core/Classes/Resource/Driver/AbstractHierarchicalFilesystemDriver.php
typo3/sysext/core/Classes/Resource/Driver/DriverInterface.php
typo3/sysext/core/Classes/Resource/Driver/LocalDriver.php
typo3/sysext/core/Classes/Resource/Hook/FileDumpEIDHookInterface.php [new file with mode: 0644]
typo3/sysext/core/Classes/Resource/ResourceStorage.php
typo3/sysext/core/Resources/PHP/FileDumpEID.php [new file with mode: 0644]
typo3/sysext/core/Tests/Unit/Resource/Driver/LocalDriverTest.php
typo3/sysext/core/Tests/Unit/Resource/ResourceStorageTest.php
typo3/sysext/core/ext_localconf.php

index c6269b1..769abbf 100644 (file)
@@ -202,7 +202,7 @@ abstract class AbstractFile implements FileInterface {
                if ($this->deleted) {
                        throw new \RuntimeException('File has been deleted.', 1329821480);
                }
-               return $this->properties['size'];
+               return $this->properties['size'] ?: array_pop($this->getStorage()->getFileInfoByIdentifier($this->getIdentifier(), array('size')));
        }
 
        /**
@@ -272,9 +272,7 @@ abstract class AbstractFile implements FileInterface {
         * @return array file information
         */
        public function getMimeType() {
-               // TODO this will be slow - use the cached version if possible
-               $stat = $this->getStorage()->getFileInfo($this);
-               return $stat['mimetype'];
+               return $this->properties['mimetype'] ?: array_pop($this->getStorage()->getFileInfoByIdentifier($this->getIdentifier(), array('mimetype')));
        }
 
        /**
index d00c489..cdabd7b 100644 (file)
@@ -204,7 +204,7 @@ abstract class AbstractRepository implements \TYPO3\CMS\Extbase\Persistence\Repo
         * @return string the additional where clause, something like " AND deleted=0 AND hidden=0"
         */
        protected function getWhereClauseForEnabledFields() {
-               if ($this->getEnvironmentMode() === 'FE') {
+               if ($this->getEnvironmentMode() === 'FE' && $GLOBALS['TSFE']->sys_page) {
                        // frontend context
                        $whereClause = $GLOBALS['TSFE']->sys_page->enableFields($this->table);
                        $whereClause .= $GLOBALS['TSFE']->sys_page->deleteClause($this->table);
index d656f4c..6dc77de 100644 (file)
@@ -56,7 +56,8 @@ abstract class AbstractHierarchicalFilesystemDriver extends AbstractDriver {
                $filePath = \TYPO3\CMS\Core\Utility\PathUtility::getCanonicalPath($filePath);
 
                // filePath must be valid
-               if (!$this->isPathValid($filePath)) {
+               // Special case is required by vfsStream in Unit Test context
+               if (!$this->isPathValid($filePath) && substr($filePath, 0, 6) !== 'vfs://') {
                        throw new \TYPO3\CMS\Core\Resource\Exception\InvalidPathException('File ' . $filePath . ' is not valid (".." and "//" is not allowed in path).', 1320286857);
                }
                return $filePath;
index 35e637e..877dcdb 100644 (file)
@@ -65,6 +65,17 @@ interface DriverInterface {
        public function getCapabilities();
 
        /**
+        * Merges the capabilites merged by the user at the storage
+        * configuration into the actual capabilities of the driver
+        * and returns the result.
+        *
+        * @param integer $capabilities
+        *
+        * @return integer
+        */
+       public function mergeConfigurationCapabilities($capabilities);
+
+       /**
         * Returns TRUE if this driver has the given capability.
         *
         * @param integer $capability A capability, as defined in a CAPABILITY_* constant
@@ -128,16 +139,13 @@ interface DriverInterface {
 
        /**
         * Returns the public URL to a file.
+        * Either fully qualified URL or relative to PATH_site (rawurlencoded).
+        *
         *
         * @param string $identifier
-        * @param boolean $relativeToCurrentScript Determines whether the URL
-        *                                         returned should be relative
-        *                                         to the current script, in case
-        *                                         it is relative at all (only
-        *                                         for the LocalDriver)
         * @return string
         */
-       public function getPublicUrl($identifier, $relativeToCurrentScript = FALSE);
+       public function getPublicUrl($identifier);
 
        /**
         * Creates a folder, within a parent folder.
index 17d4071..4197c56 100644 (file)
@@ -64,7 +64,7 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
         *
         * @var string
         */
-       protected $baseUri;
+       protected $baseUri = NULL;
 
        /**
         * @var \TYPO3\CMS\Core\Charset\CharsetConverter
@@ -79,12 +79,44 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
        );
 
        /**
+        * @param array $configuration
+        */
+       public function __construct(array $configuration = array()) {
+               parent::__construct($configuration);
+               // The capabilities default of this driver. See CAPABILITY_* constants for possible values
+               $this->capabilities =
+                       \TYPO3\CMS\Core\Resource\ResourceStorage::CAPABILITY_BROWSABLE
+                       | \TYPO3\CMS\Core\Resource\ResourceStorage::CAPABILITY_PUBLIC
+                       | \TYPO3\CMS\Core\Resource\ResourceStorage::CAPABILITY_WRITABLE;
+       }
+
+       /**
+        * Merges the capabilites merged by the user at the storage
+        * configuration into the actual capabilities of the driver
+        * and returns the result.
+        *
+        * @param integer $capabilities
+        *
+        * @return integer
+        */
+       public function mergeConfigurationCapabilities($capabilities) {
+               $this->capabilities &= $capabilities;
+               return $this->capabilities;
+       }
+
+
+       /**
         * Processes the configuration for this driver.
         *
         * @return void
         */
        public function processConfiguration() {
                $this->absoluteBasePath = $this->calculateBasePath($this->configuration);
+               $this->determineBaseUrl();
+               if ($this->baseUri === NULL) {
+                       // remove public flag
+                       $this->capabilities &= ~\TYPO3\CMS\Core\Resource\ResourceStorage::CAPABILITY_PUBLIC;
+               }
        }
 
        /**
@@ -94,11 +126,6 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
         * @return void
         */
        public function initialize() {
-               $this->determineBaseUrl();
-               // The capabilities of this driver. See CAPABILITY_* constants for possible values
-               $this->capabilities = \TYPO3\CMS\Core\Resource\ResourceStorage::CAPABILITY_BROWSABLE
-                       | \TYPO3\CMS\Core\Resource\ResourceStorage::CAPABILITY_PUBLIC
-                       | \TYPO3\CMS\Core\Resource\ResourceStorage::CAPABILITY_WRITABLE;
        }
 
        /**
@@ -108,11 +135,17 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
         * @return void
         */
        protected function determineBaseUrl() {
-               if (GeneralUtility::isFirstPartOfStr($this->absoluteBasePath, PATH_site)) {
-                       // use site-relative URLs
-                       $this->baseUri = \TYPO3\CMS\Core\Utility\PathUtility::stripPathSitePrefix($this->absoluteBasePath);
-               } elseif (isset($this->configuration['baseUri']) && GeneralUtility::isValidUrl($this->configuration['baseUri'])) {
-                       $this->baseUri = rtrim($this->configuration['baseUri'], '/') . '/';
+               // only calculate baseURI if the storage does not enforce jumpUrl Script
+               if ($this->hasCapability(\TYPO3\CMS\Core\Resource\ResourceStorage::CAPABILITY_PUBLIC)) {
+                       if (GeneralUtility::isFirstPartOfStr($this->absoluteBasePath, PATH_site)) {
+                               // use site-relative URLs
+                               $temporaryBaseUri = \TYPO3\CMS\Core\Utility\PathUtility::stripPathSitePrefix($this->absoluteBasePath);
+                               $uriParts = explode('/', rtrim($temporaryBaseUri, '/'));
+                               array_map('rawurlencode', $uriParts);
+                               $this->baseUri = implode('/', $uriParts) . '/';
+                       } elseif (isset($this->configuration['baseUri']) && GeneralUtility::isValidUrl($this->configuration['baseUri'])) {
+                               $this->baseUri = rtrim($this->configuration['baseUri'], '/') . '/';
+                       }
                }
        }
 
@@ -137,6 +170,7 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
                } else {
                        $absoluteBasePath = $configuration['basePath'];
                }
+               $this->canonicalizeAndCheckFilePath($absoluteBasePath);
                $absoluteBasePath = rtrim($absoluteBasePath, '/') . '/';
                if (!is_dir($absoluteBasePath)) {
                        throw new \TYPO3\CMS\Core\Resource\Exception\InvalidConfigurationException(
@@ -148,29 +182,20 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver {
        }
 
        /**
-        * Returns the public URL to a file. For the local driver, this will always
-        * return a path relative to PATH_site.
+        * Returns the public URL to a file.
+        * For the local driver, this will always return a path relative to PATH_site.
         *
         * @param string $identifier
-        * @param boolean $relativeToCurrentScript Determines whether the URL returned should be relative to the current script,
-        *                                         in case it is relative at all (only for the LocalDriver)
-        *
         * @return string
         * @throws \TYPO3\CMS\Core\Resource\Exception
         */
-       public function getPublicUrl($identifier, $relativeToCurrentScript = FALSE) {
-               if ($this->configuration['pathType'] === 'relative' && rtrim($this->configuration['basePath'], '/') !== '') {
-                       $publicUrl = rtrim($this->configuration['basePath'], '/') . '/' . ltrim($identifier, '/');
-               } elseif (isset($this->baseUri)) {
-                       $publicUrl = $this->baseUri . ltrim($identifier, '/');
-               } else {
-                       throw new \TYPO3\CMS\Core\Resource\Exception('Public URL of file cannot be determined', 1329765518);
-               }
-               // If requested, make the path relative to the current script in order to make it possible
-               // to use the relative file
-               if ($relativeToCurrentScript) {
-                       $publicUrl = PathUtility::getRelativePathTo(PathUtility::dirname((PATH_site . $publicUrl))) .
-                               PathUtility::basename($publicUrl);
+       public function getPublicUrl($identifier) {
+               $publicUrl = NULL;
+               if ($this->baseUri !== NULL) {
+                       $uriParts = explode('/', ltrim($identifier, '/'));
+                       $uriParts = array_map('rawurlencode', $uriParts);
+                       $identifier = implode('/', $uriParts);
+                       $publicUrl = $this->baseUri . $identifier;
                }
                return $publicUrl;
        }
diff --git a/typo3/sysext/core/Classes/Resource/Hook/FileDumpEIDHookInterface.php b/typo3/sysext/core/Classes/Resource/Hook/FileDumpEIDHookInterface.php
new file mode 100644 (file)
index 0000000..93d18ae
--- /dev/null
@@ -0,0 +1,46 @@
+<?php
+namespace TYPO3\CMS\Core\Resource\Hook;
+
+
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2014 Frans Saris <franssaris@gmail.com>
+ * All rights reserved
+ *
+ * This script is part of the TYPO3 project. The TYPO3 project is
+ * free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The GNU General Public License can be found at
+ * http://www.gnu.org/copyleft/gpl.html.
+ * A copy is found in the textfile GPL.txt and important notices to the license
+ * from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *
+ * This script 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 General Public License for more details.
+ *
+ * This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Interface for FileDumpEID Hook to perform some custom security/access checks
+ * when accessing file thought FileDumpEID
+ */
+interface FileDumpEIDHookInterface {
+
+       /**
+        * Perform custom security/access when accessing file
+        * Method should issue 403 if access is rejected
+        * or 401 if authentication is required
+        *
+        * @param \TYPO3\CMS\Core\Resource\ResourceInterface $file
+        * @return void
+        */
+       public function checkFileAccess(\TYPO3\CMS\Core\Resource\ResourceInterface $file);
+}
\ No newline at end of file
index c584566..5500d8e 100644 (file)
@@ -215,8 +215,14 @@ class ResourceStorage {
        public function __construct(Driver\DriverInterface $driver, array $storageRecord) {
                $this->storageRecord = $storageRecord;
                $this->configuration = ResourceFactory::getInstance()->convertFlexFormDataToConfigurationArray($storageRecord['configuration']);
+               $this->capabilities =
+                       ($this->storageRecord['is_browsable'] ? self::CAPABILITY_BROWSABLE : 0) |
+                       ($this->storageRecord['is_public'] ? self::CAPABILITY_PUBLIC : 0) |
+                       ($this->storageRecord['is_writable'] ? self::CAPABILITY_WRITABLE : 0);
+
                $this->driver = $driver;
                $this->driver->setStorageUid($storageRecord['uid']);
+               $this->driver->mergeConfigurationCapabilities($this->capabilities);
                try {
                        $this->driver->processConfiguration();
                } catch (Exception\InvalidConfigurationException $e) {
@@ -225,11 +231,11 @@ class ResourceStorage {
                        $this->markAsPermanentlyOffline();
                }
                $this->driver->initialize();
-               $this->capabilities = ($this->storageRecord['is_browsable'] && $this->driver->hasCapability(self::CAPABILITY_BROWSABLE) ? self::CAPABILITY_BROWSABLE : 0) + ($this->storageRecord['is_public'] && $this->driver->hasCapability(self::CAPABILITY_PUBLIC) ? self::CAPABILITY_PUBLIC : 0) + ($this->storageRecord['is_writable'] && $this->driver->hasCapability(self::CAPABILITY_WRITABLE) ? self::CAPABILITY_WRITABLE : 0);
+               $this->capabilities = $this->driver->getCapabilities();
+
                $this->isDefault = (isset($storageRecord['is_default']) && $storageRecord['is_default'] == 1);
-               // TODO do not set the "public" capability if no public URIs can be generated
-               $this->processConfiguration();
                $this->resetFileAndFolderNameFiltersToDefault();
+               $this->processConfiguration();
        }
 
        /**
@@ -1200,7 +1206,33 @@ class ResourceStorage {
                        $this->emitPreGeneratePublicUrl($resourceObject, $relativeToCurrentScript, array('publicUrl' => &$publicUrl));
                        // If slot did not handle the signal, use the default way to determine public URL
                        if ($publicUrl === NULL) {
-                               $publicUrl = $this->driver->getPublicUrl($resourceObject->getIdentifier(), $relativeToCurrentScript);
+
+                               if ($this->hasCapability(self::CAPABILITY_PUBLIC)) {
+                                       $publicUrl = $this->driver->getPublicUrl($resourceObject->getIdentifier());
+                               }
+
+                               if ($publicUrl === NULL && $resourceObject instanceof FileInterface) {
+                                       $queryParameterArray = array('eID' => 'dumpFile', 't' => '');
+                                       if ($resourceObject instanceof File) {
+                                               $queryParameterArray['f'] = $resourceObject->getUid();
+                                               $queryParameterArray['t'] = 'f';
+                                       } elseif ($resourceObject instanceof ProcessedFile) {
+                                               $queryParameterArray['p'] = $resourceObject->getUid();
+                                               $queryParameterArray['t'] = 'p';
+                                       }
+
+                                       $queryParameterArray['token'] = GeneralUtility::hmac(implode('|', $queryParameterArray), 'resourceStorageDumpFile');
+                                       $publicUrl = 'index.php?' . str_replace('+', '%20', http_build_query($queryParameterArray));
+                               }
+
+                               // If requested, make the path relative to the current script in order to make it possible
+                               // to use the relative file
+                               if ($publicUrl !== NULL && $relativeToCurrentScript && !GeneralUtility::isValidUrl($publicUrl)) {
+                                       $absolutePathToContainingFolder = PathUtility::dirname(PATH_site . $publicUrl);
+                                       $pathPart = PathUtility::getRelativePathTo($absolutePathToContainingFolder);
+                                       $filePart = substr(PATH_site . $publicUrl, strlen($absolutePathToContainingFolder) + 1);
+                                       $publicUrl = $pathPart . $filePart;
+                               }
                        }
                }
                return $publicUrl;
@@ -1466,9 +1498,8 @@ class ResourceStorage {
                        200
                );
                ob_clean();
-               $this->driver->dumpFileContents($file->getIdentifier());
                flush();
-               exit();
+               $this->driver->dumpFileContents($file->getIdentifier());
        }
 
        /**
diff --git a/typo3/sysext/core/Resources/PHP/FileDumpEID.php b/typo3/sysext/core/Resources/PHP/FileDumpEID.php
new file mode 100644 (file)
index 0000000..b8c2201
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+
+/***************************************************************
+ * Copyright notice
+ *
+ * (c) 2014 Steffen Ritter <steffen.ritter@typo3.org>
+ * All rights reserved
+ *
+ * This script is part of the TYPO3 project. The TYPO3 project is
+ * free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * The GNU General Public License can be found at
+ * http://www.gnu.org/copyleft/gpl.html.
+ * A copy is found in the textfile GPL.txt and important notices to the license
+ * from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *
+ * This script 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 General Public License for more details.
+ *
+ * This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+$parameters = array('eID' => 'dumpFile');
+if (\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('t')) {
+       $parameters['t'] = \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('t');
+}
+if (\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('f')) {
+       $parameters['f'] = (int)\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('f');
+}
+if (\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('p')) {
+       $parameters['p'] = (int)\TYPO3\CMS\Core\Utility\GeneralUtility::_GP('p');
+}
+
+if (\TYPO3\CMS\Core\Utility\GeneralUtility::hmac(implode('|', $parameters), 'resourceStorageDumpFile') === \TYPO3\CMS\Core\Utility\GeneralUtility::_GP('token')) {
+       if (isset($parameters['f'])) {
+               $file = \TYPO3\CMS\Core\Resource\ResourceFactory::getInstance()->getFileObject($parameters['f']);
+               if ($file->isDeleted() || $file->isMissing()) {
+                       $file = NULL;
+               }
+       } else {
+               $file = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance('TYPO3\\CMS\\Core\\Resource\\ProcessedFileRepository')->findByUid($parameters['p']);
+               if ($file->isDeleted()) {
+                       $file = NULL;
+               }
+       }
+
+       if ($file === NULL) {
+               \TYPO3\CMS\Core\Utility\HttpUtility::setResponseCodeAndExit(\TYPO3\CMS\Core\Utility\HttpUtility::HTTP_STATUS_404);
+       }
+
+       // Hook: allow some other process to do some security/access checks. Hook should issue 403 if access is rejected
+       if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['FileDumpEID.php']['checkFileAccess'])) {
+               foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['FileDumpEID.php']['checkFileAccess'] as $classRef) {
+                       $hookObject = \TYPO3\CMS\Core\Utility\GeneralUtility::getUserObj($classRef);
+                       if (!$hookObject instanceof \TYPO3\CMS\Core\Resource\Hook\FileDumpEIDHookInterface) {
+                               throw new \UnexpectedValueException('$hookObject must implement interface TYPO3\\CMS\\Core\\Resource\\FileDumpEIDHookInterface', 1394442417);
+                       }
+                       $hookObject->checkFileAccess($file);
+               }
+       }
+       $file->getStorage()->dumpFileContents($file);
+} else {
+       \TYPO3\CMS\Core\Utility\HttpUtility::setResponseCodeAndExit(\TYPO3\CMS\Core\Utility\HttpUtility::HTTP_STATUS_403);
+}
\ No newline at end of file
index abb1043..aae8770 100644 (file)
@@ -369,6 +369,33 @@ class LocalDriverTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCase {
        }
 
        /**
+        * Data provider for getPublicUrlReturnsValidUrlContainingSpecialCharacters().
+        *
+        * @return array
+        */
+       public function getPublicUrlReturnsValidUrlContainingSpecialCharacters_dataProvider() {
+               return array(
+                       array('/single file with some special chars äüö!.txt'),
+                       array('/on subfolder/with special chars äüö!.ext'),
+                       array('/who names a file like !"§$%&()=?*+~"#\'´`<>-.ext'),
+                       array('no leading slash !"§$%&()=?*+~#\'"´`"<>-.txt')
+               );
+       }
+
+       /**
+        * @test
+        * @dataProvider getPublicUrlReturnsValidUrlContainingSpecialCharacters_dataProvider
+        */
+       public function getPublicUrlReturnsValidUrlContainingSpecialCharacters($fileIdentifier) {
+               $baseUri = 'http://example.org/foobar/' . uniqid();
+               $fixture = $this->createDriverFixture(array(
+                       'baseUri' => $baseUri
+               ));
+               $publicUrl = $fixture->getPublicUrl($fileIdentifier);
+               $this->assertTrue(GeneralUtility::isValidUrl($publicUrl), 'getPublicUrl did not return a valid URL:' . $publicUrl);
+       }
+
+       /**
         * @test
         */
        public function fileContentsCanBeWrittenAndRead() {
index 74e24e7..04da355 100644 (file)
@@ -116,9 +116,7 @@ class ResourceStorageTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCa
         */
        protected function createDriverMock($driverConfiguration, \TYPO3\CMS\Core\Resource\ResourceStorage $storageObject = NULL, $mockedDriverMethods = array()) {
                $this->initializeVfs();
-               if ($storageObject == NULL) {
-                       $storageObject = $this->getMock('TYPO3\\CMS\\Core\\Resource\\ResourceStorage', array(), array(), '', FALSE);
-               }
+
 
                if (!isset($driverConfiguration['basePath'])) {
                        $driverConfiguration['basePath'] = $this->getMountRootUrl();
@@ -131,7 +129,9 @@ class ResourceStorageTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCa
                                // when using the AbstractDriver we would be in trouble when wanting to mock away some concrete method
                        $driver = $this->getMock('TYPO3\\CMS\\Core\\Resource\\Driver\\LocalDriver', $mockedDriverMethods, array($driverConfiguration));
                }
-               $storageObject->setDriver($driver);
+               if ($storageObject !== NULL) {
+                       $storageObject->setDriver($driver);
+               }
                $driver->setStorageUid(6);
                $driver->processConfiguration();
                $driver->initialize();
@@ -201,8 +201,15 @@ class ResourceStorageTest extends \TYPO3\CMS\Core\Tests\Unit\Resource\BaseTestCa
                        'is_browsable' => $capabilites['browsable'],
                        'is_online' => TRUE
                );
-               $mockedDriver = $this->createDriverMock(array(), $this->fixture, array('hasCapability'));
-               $mockedDriver->expects($this->any())->method('hasCapability')->will($this->returnValue(TRUE));
+               $mockedDriver = $this->createDriverMock(
+                       array(
+                               'pathType' => 'relative',
+                               'basePath' => 'fileadmin/',
+                               'baseUri' => 'http://www.test.de/'
+                       ),
+                       $this->fixture,
+                       NULL
+               );
                $this->prepareFixture(array(), FALSE, $mockedDriver, $storageRecord);
                $this->assertEquals($capabilites['public'], $this->fixture->isPublic(), 'Capability "public" is not correctly set.');
                $this->assertEquals($capabilites['writable'], $this->fixture->isWritable(), 'Capability "writable" is not correctly set.');
index d56cbd6..66b3a70 100644 (file)
@@ -24,3 +24,5 @@ if (TYPO3_MODE === 'BE' && !(TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_INSTALL)) {
        'TYPO3\\CMS\\Core\\Resource\\Processing\\FileDeletionAspect',
        'removeFromRepository'
 );
+
+$GLOBALS['TYPO3_CONF_VARS']['FE']['eID_include']['dumpFile'] = 'EXT:core/Resources/PHP/FileDumpEID.php';
\ No newline at end of file