[BUGFIX] Resolve dependencies on extension upload 90/39190/6
authorNicole Cordes <typo3@cordes.co>
Sat, 2 May 2015 12:41:07 +0000 (14:41 +0200)
committerHelmut Hummel <helmut.hummel@typo3.org>
Sat, 2 May 2015 17:06:28 +0000 (19:06 +0200)
Currently no dependency is checked if an extension is installed by
uploading an extension file (t3x, zip). This might break the system if
any dependency needed is not available.

Releases: master, 6.2
Resolves: #62305
Change-Id: I79fc8157c7b2190f4bd857107dedee0a6de67423
Reviewed-on: http://review.typo3.org/39190
Reviewed-by: Andreas Fernandez <typo3@scripting-base.de>
Tested-by: Andreas Fernandez <typo3@scripting-base.de>
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Reviewed-by: Helmut Hummel <helmut.hummel@typo3.org>
Tested-by: Helmut Hummel <helmut.hummel@typo3.org>
typo3/sysext/extensionmanager/Classes/Controller/UploadExtensionFileController.php
typo3/sysext/extensionmanager/Classes/Service/ExtensionManagementService.php
typo3/sysext/extensionmanager/Classes/Utility/InstallUtility.php
typo3/sysext/extensionmanager/Tests/Unit/Controller/UploadExtensionFileControllerTest.php

index 66e3181..2974c96 100644 (file)
@@ -45,10 +45,10 @@ class UploadExtensionFileController extends AbstractController {
        protected $terUtility;
 
        /**
-        * @var \TYPO3\CMS\Extensionmanager\Utility\InstallUtility
+        * @var \TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService
         * @inject
         */
-       protected $installUtility;
+       protected $managementService;
 
        /**
         * @var string
@@ -79,7 +79,7 @@ class UploadExtensionFileController extends AbstractController {
         * Extract an uploaded file and install the matching extension
         *
         * @param bool $overwrite Overwrite existing extension if TRUE
-        * @throws ExtensionManagerException
+        * @throws \TYPO3\CMS\Extbase\Mvc\Exception\StopActionException
         * @return void
         */
        public function extractAction($overwrite = FALSE) {
@@ -105,13 +105,18 @@ class UploadExtensionFileController extends AbstractController {
                                        FlashMessage::OK
                                );
                        } else {
-                               $this->activateExtension($extensionData['extKey']);
-                               $this->addFlashMessage(
-                                       htmlspecialchars($this->translate('extensionList.installedFlashMessage.message', array($extensionData['extKey']))),
-                                       '',
-                                       FlashMessage::OK
-                               );
+                               if ($this->activateExtension($extensionData['extKey'])) {
+                                       $this->addFlashMessage(
+                                               htmlspecialchars($this->translate('extensionList.installedFlashMessage.message', array($extensionData['extKey']))),
+                                               '',
+                                               FlashMessage::OK
+                                       );
+                               } else {
+                                       $this->redirect('unresolvedDependencies', 'List', NULL, array('extensionKey' => $extensionData['extKey']));
+                               }
                        }
+               } catch (\TYPO3\CMS\Extbase\Mvc\Exception\StopActionException $exception) {
+                       throw $exception;
                } catch (\Exception $exception) {
                        $this->removeExtensionAndRestoreFromBackup($fileName);
                        $this->addFlashMessage(htmlspecialchars($exception->getMessage()), '', FlashMessage::ERROR);
@@ -158,10 +163,11 @@ class UploadExtensionFileController extends AbstractController {
 
        /**
         * @param string $extensionKey
-        * @return void
+        * @return bool
         */
        public function activateExtension($extensionKey) {
-               $this->installUtility->install($extensionKey);
+               $extension = $this->managementService->getExtension($extensionKey);
+               return is_array($this->managementService->installExtension($extension));
        }
 
        /**
@@ -181,7 +187,7 @@ class UploadExtensionFileController extends AbstractController {
                if (empty($extensionData['extKey'])) {
                        throw new ExtensionManagerException('Decoding the file went wrong. No extension key found', 1342864309);
                }
-               $isExtensionAvailable = $this->installUtility->isAvailable($extensionData['extKey']);
+               $isExtensionAvailable = $this->managementService->isAvailable($extensionData['extKey']);
                if (!$overwrite && $isExtensionAvailable) {
                        throw new ExtensionManagerException($this->translate('extensionList.overwritingDisabled'), 1342864310);
                }
@@ -209,7 +215,7 @@ class UploadExtensionFileController extends AbstractController {
        protected function getExtensionFromZipFile($file, $fileName, $overwrite = FALSE) {
                // Remove version and extension from filename to determine the extension key
                $extensionKey = $this->getExtensionKeyFromFileName($fileName);
-               $isExtensionAvailable = $this->installUtility->isAvailable($extensionKey);
+               $isExtensionAvailable = $this->managementService->isAvailable($extensionKey);
                if (!$overwrite && $isExtensionAvailable) {
                        throw new ExtensionManagerException('Extension is already available and overwriting is disabled.', 1342864311);
                }
index dac042d..7e8da9d 100644 (file)
@@ -79,11 +79,7 @@ class ExtensionManagementService implements \TYPO3\CMS\Core\SingletonInterface {
        public function markExtensionForInstallation($extensionKey) {
                // We have to check for dependencies of the extension first, before marking it for installation
                // because this extension might have dependencies, which need to be installed first
-               $this->dependencyUtility->checkDependencies(
-                       $this->extensionModelUtility->mapExtensionArrayToModel(
-                               $this->installUtility->enrichExtensionWithDetails($extensionKey)
-                       )
-               );
+               $this->dependencyUtility->checkDependencies($this->getExtension($extensionKey));
                $this->downloadQueue->addExtensionToInstallQueue($extensionKey);
        }
 
@@ -187,6 +183,27 @@ class ExtensionManagementService implements \TYPO3\CMS\Core\SingletonInterface {
        }
 
        /**
+        * @param string $extensionKey
+        * @return Extension
+        * @throws \TYPO3\CMS\Extensionmanager\Exception\ExtensionManagerException
+        */
+       public function getExtension($extensionKey) {
+               return $this->extensionModelUtility->mapExtensionArrayToModel(
+                       $this->installUtility->enrichExtensionWithDetails($extensionKey)
+               );
+       }
+
+       /**
+        * Checks if an extension is available in the system
+        *
+        * @param string $extensionKey
+        * @return bool
+        */
+       public function isAvailable($extensionKey) {
+               return $this->installUtility->isAvailable($extensionKey);
+       }
+
+       /**
         * Download an extension
         *
         * @param Extension $extension
index 04d5045..156bf10 100644 (file)
@@ -194,7 +194,7 @@ class InstallUtility implements \TYPO3\CMS\Core\SingletonInterface {
        /**
         * Checks if an extension is available in the system
         *
-        * @param $extensionKey
+        * @param string $extensionKey
         * @return bool
         */
        public function isAvailable($extensionKey) {
index 34e6cce..d1b223b 100644 (file)
@@ -64,12 +64,12 @@ class UploadExtensionFileControllerTest extends \TYPO3\CMS\Core\Tests\UnitTestCa
         */
        public function getExtensionFromZipFileExtractsExtensionKey($filename, $expectedKey) {
                $fixture = $this->getAccessibleMock(\TYPO3\CMS\Extensionmanager\Controller\UploadExtensionFileController::class, array('dummy'));
-               $installUtilityMock = $this->getMock(\TYPO3\CMS\Extensionmanager\Utility\InstallUtility::class, array(), array(), '', FALSE);
-               $installUtilityMock->expects($this->once())
+               $managementServiceMock = $this->getMock(\TYPO3\CMS\Extensionmanager\Service\ExtensionManagementService::class, array('isAvailable'), array(), '', FALSE);
+               $managementServiceMock->expects($this->once())
                        ->method('isAvailable')
                        ->with($expectedKey)
                        ->will($this->returnValue(FALSE));
-               $fixture->_set('installUtility', $installUtilityMock);
+               $fixture->_set('managementService', $managementServiceMock);
                $fileHandlingUtilityMock = $this->getMock(\TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility::class, array(), array(), '', FALSE);
                $fileHandlingUtilityMock->expects($this->once())->method('unzipExtensionFromFile');
                $fixture->_set('fileHandlingUtility', $fileHandlingUtilityMock);