[TASK] Ensure that cli user is admin on extension install and uninstall 15/30715/4
authorMarc Bastian Heinrichs <typo3@mbh-software.de>
Fri, 13 Jun 2014 14:24:57 +0000 (16:24 +0200)
committerErnesto Baschny <ernst@cron-it.de>
Thu, 19 Jun 2014 16:32:57 +0000 (18:32 +0200)
Extension install and uninstall is an admin task. Calling the belonging
CommandController on cli should ensure, that the user has admin
rights.

This adds API to the CommandController to avoid code duplication
in every controller to achieve this.

Distribution packages could be installed via cli without errors now.

Resolves: #59556
Releases: 6.3, 6.2
Change-Id: Icd1b6bf4379322c8bec07531a15d2171b103e076
Reviewed-on: https://review.typo3.org/30715
Reviewed-by: Ernesto Baschny
Tested-by: Ernesto Baschny
typo3/sysext/extbase/Classes/Mvc/Controller/CommandController.php
typo3/sysext/extbase/Tests/Unit/Mvc/Controller/CommandControllerTest.php
typo3/sysext/extensionmanager/Classes/Command/ExtensionCommandController.php

index 4e5cc32..c1ded28 100644 (file)
@@ -24,6 +24,8 @@ namespace TYPO3\CMS\Extbase\Mvc\Controller;
  *
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
+use TYPO3\CMS\Core\Authentication\AbstractUserAuthentication;
+
 /**
  * A controller which processes requests from the command line
  *
@@ -56,6 +58,19 @@ class CommandController implements \TYPO3\CMS\Extbase\Mvc\Controller\CommandCont
        protected $commandMethodName = '';
 
        /**
+        * Whether the command needs admin access to perform its job
+        *
+        * @var bool
+        * @api
+        */
+       protected $requestAdminPermissions = FALSE;
+
+       /**
+        * @var AbstractUserAuthentication
+        */
+       protected $userAuthentication;
+
+       /**
         * @var \TYPO3\CMS\Extbase\Reflection\ReflectionService
         * @inject
         */
@@ -73,6 +88,7 @@ class CommandController implements \TYPO3\CMS\Extbase\Mvc\Controller\CommandCont
        public function injectObjectManager(\TYPO3\CMS\Extbase\Object\ObjectManagerInterface $objectManager) {
                $this->objectManager = $objectManager;
                $this->arguments = $this->objectManager->get('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\Arguments');
+               $this->userAuthentication = isset($GLOBALS['BE_USER']) ? $GLOBALS['BE_USER'] : NULL;
        }
 
        /**
@@ -202,7 +218,9 @@ class CommandController implements \TYPO3\CMS\Extbase\Mvc\Controller\CommandCont
                foreach ($this->arguments as $argument) {
                        $preparedArguments[] = $argument->getValue();
                }
+               $originalRole = $this->ensureAdminRoleIfRequested();
                $commandResult = call_user_func_array(array($this, $this->commandMethodName), $preparedArguments);
+               $this->restoreUserRole($originalRole);
                if (is_string($commandResult) && strlen($commandResult) > 0) {
                        $this->response->appendContent($commandResult);
                } elseif (is_object($commandResult) && method_exists($commandResult, '__toString')) {
@@ -211,6 +229,32 @@ class CommandController implements \TYPO3\CMS\Extbase\Mvc\Controller\CommandCont
        }
 
        /**
+        * Set admin permissions for currently authenticated user if requested
+        * and returns the original state or NULL
+        *
+        * @return NULL|int
+        */
+       protected function ensureAdminRoleIfRequested() {
+               if (!$this->requestAdminPermissions || !$this->userAuthentication || !isset($this->userAuthentication->user['admin'])) {
+                       return NULL;
+               }
+               $originalRole = $this->userAuthentication->user['admin'];
+               $this->userAuthentication->user['admin'] = 1;
+               return $originalRole;
+       }
+
+       /**
+        * Restores the original user role
+        *
+        * @param NULL|int $originalRole
+        */
+       protected function restoreUserRole($originalRole) {
+               if ($originalRole !== NULL) {
+                       $this->userAuthentication->user['admin'] = $originalRole;
+               }
+       }
+
+       /**
         * Outputs specified text to the console window
         * You can specify arguments that will be passed to the text via sprintf
         *
index 7b1695b..daace38 100644 (file)
@@ -37,7 +37,7 @@ class CommandControllerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
        protected $commandController;
 
        public function setUp() {
-               $this->commandController = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\CommandController', array('dummy'));
+               $this->commandController = $this->getAccessibleMock('TYPO3\\CMS\\Extbase\\Mvc\\Controller\\CommandController', array('dummyCommand'));
        }
 
        /**
@@ -90,4 +90,29 @@ class CommandControllerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
                $this->commandController->_set('response', $mockResponse);
                $this->commandController->_call('quit', 123);
        }
+
+       /**
+        * @test
+        */
+       public function settingRequestAdminPropertySetsAdminRoleInUserAuthentication() {
+               $mockedUserAuthentication = $this->getMock('TYPO3\\CMS\\Core\\Authentication\\AbstractUserAuthentication');
+               $mockedUserAuthentication->user['admin'] = 42;
+               $this->commandController->expects($this->once())
+                       ->method('dummyCommand')
+                       ->will(
+                               $this->returnCallback(
+                                       function() use ($mockedUserAuthentication) {
+                                               if ($mockedUserAuthentication->user['admin'] !== 1) {
+                                                       throw new \Exception('User role is not admin');
+                                               }
+                                       }
+                               ));
+               $this->commandController->_set('userAuthentication', $mockedUserAuthentication);
+               $this->commandController->_set('arguments', array());
+               $this->commandController->_set('commandMethodName', 'dummyCommand');
+               $this->commandController->_set('requestAdminPermissions', TRUE);
+               $this->commandController->_call('callCommandMethod');
+
+               $this->assertSame(42, $mockedUserAuthentication->user['admin']);
+       }
 }
index a0296d4..6bd450f 100644 (file)
@@ -37,6 +37,11 @@ use TYPO3\CMS\Extbase\Mvc\Controller\CommandController;
 class ExtensionCommandController extends CommandController {
 
        /**
+        * @var bool
+        */
+       protected $requestAdminPermissions = TRUE;
+
+       /**
         * @var \TYPO3\CMS\Extbase\SignalSlot\Dispatcher
         * @inject
         */