[TASK] Cleanup CLI handling of CLI commands 48/51248/4
authorBenni Mack <benni@typo3.org>
Tue, 10 Jan 2017 20:41:05 +0000 (21:41 +0100)
committerWouter Wolters <typo3@wouterwolters.nl>
Tue, 10 Jan 2017 21:56:33 +0000 (22:56 +0100)
The new _CLI_ user authentication is now explictly
set and required in each command (if a user is needed)
during runtime, and not done by the bootstrap anymore,
so this needs to be called separately.

Additionally, some cleanups to the new
CommandLineUserAuthentication is made.

Resolves: #79260
Releases: master
Change-Id: I6a882d083ec6fd878519c1472702f2a724bd7ed3
Reviewed-on: https://review.typo3.org/51248
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
12 files changed:
typo3/sysext/core/Classes/Authentication/CommandLineUserAuthentication.php
typo3/sysext/core/Classes/Console/CommandRequestHandler.php
typo3/sysext/core/Documentation/Changelog/8.0/Feature-73042-IntroduceNativeSupportForSymfonyConsole.rst
typo3/sysext/lowlevel/Classes/Command/CleanFlexFormsCommand.php
typo3/sysext/lowlevel/Classes/Command/DeletedRecordsCommand.php
typo3/sysext/lowlevel/Classes/Command/FilesWithMultipleReferencesCommand.php
typo3/sysext/lowlevel/Classes/Command/LostFilesCommand.php
typo3/sysext/lowlevel/Classes/Command/MissingFilesCommand.php
typo3/sysext/lowlevel/Classes/Command/MissingRelationsCommand.php
typo3/sysext/lowlevel/Classes/Command/OrphanRecordsCommand.php
typo3/sysext/lowlevel/Classes/Command/RteImagesCommand.php
typo3/sysext/lowlevel/Classes/Command/WorkspaceVersionRecordsCommand.php

index d0e2530..e816905 100644 (file)
@@ -35,12 +35,17 @@ class CommandLineUserAuthentication extends BackendUserAuthentication
 
     /**
      * Constructor, only allowed in CLI mode
+     *
+     * @throws \RuntimeException
      */
     public function __construct()
     {
         if (!(TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI)) {
             throw new \RuntimeException('Creating a CLI-based user object on non-CLI level is not allowed', 1483971165);
         }
+        if (!$this->isUserAllowedToLogin()) {
+            throw new \RuntimeException('Login Error: TYPO3 is in maintenance mode at the moment. Only administrators are allowed access.', 1483971855);
+        }
         $this->dontSetCookie = true;
         parent::__construct();
     }
@@ -56,7 +61,7 @@ class CommandLineUserAuthentication extends BackendUserAuthentication
         $this->setBeUserByName($this->username);
         if (!$this->user['uid']) {
             // create a new BE user in the database
-            if (!$this->checkCliUserExists()) {
+            if (!$this->checkIfCliUserExists()) {
                 $this->createCliUser();
             } else {
                 throw new \RuntimeException('No backend user named "_cli_" could be authenticated, maybe this user is "hidden"?', 1484050401);
@@ -68,20 +73,15 @@ class CommandLineUserAuthentication extends BackendUserAuthentication
         }
         // The groups are fetched and ready for permission checking in this initialization.
         $this->fetchGroupData();
-        if (!$this->isUserAllowedToLogin()) {
-            throw new \RuntimeException('Login Error: TYPO3 is in maintenance mode at the moment. Only administrators are allowed access.', 1483971855);
-        }
         $this->backendSetUC();
+        // activate this functionality for DataHandler
+        $this->uc['recursiveDelete'] = true;
     }
 
     /**
-     * Check if user is logged in and if so, call ->fetchGroupData() to load group information and
-     * access lists of all kind, further check IP, set the ->uc array and send login-notification email if required.
-     * If no user is logged in the default behaviour is to exit with an error message.
-     * This function is called right after ->start() in fx. the TYPO3 Bootstrap.
+     * Logs in the TYPO3 Backend user "_cli_"
      *
      * @param bool $proceedIfNoUserIsLoggedIn if this option is set, then there won't be a redirect to the login screen of the Backend - used for areas in the backend which do not need user rights like the login page.
-     * @throws \RuntimeException
      * @return void
      */
     public function backendCheckLogin($proceedIfNoUserIsLoggedIn = false)
@@ -103,8 +103,10 @@ class CommandLineUserAuthentication extends BackendUserAuthentication
     /**
      * Check if a user with username "_cli_" exists. Deleted users are left out
      * but hidden and start / endtime restricted users are considered.
+     *
+     * @return bool true if the user exists
      */
-    protected function checkCliUserExists()
+    protected function checkIfCliUserExists()
     {
         $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable('be_users');
         $queryBuilder->getRestrictions()
index d3d9f37..20613d2 100644 (file)
@@ -66,21 +66,16 @@ class CommandRequestHandler implements RequestHandlerInterface
     {
         $output = new ConsoleOutput();
 
-        $this->bootstrap->loadExtensionTables();
+        $this->bootstrap
+            ->loadExtensionTables()
+            // create the BE_USER object (not logged in yet)
+            ->initializeBackendUser(CommandLineUserAuthentication::class)
+            ->initializeLanguageObject()
+            // Make sure output is not buffered, so command-line output and interaction can take place
+            ->endOutputBufferingAndCleanPreviousOutput();
 
         // Check if the command to run needs a backend user to be loaded
         $command = $this->getCommandToRun($input);
-        foreach ($this->availableCommands as $data) {
-            if ($data['command'] !== $command) {
-                continue;
-            }
-            if (isset($data['user'])) {
-                $this->initializeBackendUser();
-            }
-        }
-
-        // Make sure output is not buffered, so command-line output and interaction can take place
-        $this->bootstrap->endOutputBufferingAndCleanPreviousOutput();
 
         if (!$command) {
             $cliKeys = array_keys($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['cliKeys']);
@@ -99,23 +94,6 @@ class CommandRequestHandler implements RequestHandlerInterface
     }
 
     /**
-     * Logs in the user _cli_ to the system
-     *
-     * @throws \RuntimeException if a non-admin Backend user could not be loaded
-     */
-    protected function initializeBackendUser()
-    {
-        // create the BE_USER object
-        $this->bootstrap->initializeBackendUser(CommandLineUserAuthentication::class);
-        // log-in the _cli_ user, create the record if it does not exist
-        /** @var CommandLineUserAuthentication $backendUser */
-        $backendUser = $GLOBALS['BE_USER'];
-        $backendUser->authenticate();
-        $this->bootstrap
-            ->initializeLanguageObject();
-    }
-
-    /**
      * This request handler can handle any CLI request
      *
      * @param InputInterface $input
index a5c6679..69e8bf2 100644 (file)
@@ -22,8 +22,8 @@ Registering a command to be available via the `typo3` command line tool works by
 to be executed by `typo3` is an associative array. The key is the name of the command to be called as
 the first argument to `typo3`.
 
-A required parameter when registering a command is the `class` property. Optionally the `user` parameter can be
-set so a backend user is logged in when calling the command.
+A required parameter when registering a command is the `class` property which should inherit from Symfony's
+base Command class.
 
 A `Configuration/Commands.php` could look like this:
 
@@ -34,8 +34,7 @@ A `Configuration/Commands.php` could look like this:
             'class' => \TYPO3\CMS\Backend\Command\LockBackendCommand::class
         ],
         'referenceindex:update' => [
-            'class' => \TYPO3\CMS\Backend\Command\ReferenceIndexUpdateCommand::class,
-            'user' => '_cli_lowlevel'
+            'class' => \TYPO3\CMS\Backend\Command\ReferenceIndexUpdateCommand::class
         ]
     ];
 
index 1125a94..fa21c72 100644 (file)
@@ -21,8 +21,8 @@ use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
 use Symfony\Component\Console\Style\SymfonyStyle;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
-use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Configuration\FlexForm\FlexFormTools;
+use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\DataHandling\DataHandler;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -72,9 +72,8 @@ class CleanFlexFormsCommand extends Command
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
-        // The backend user needs super-powers because datahandler is executed
-        $previouslyAppliedAdminRights = $this->getBackendUser()->user['admin'];
-        $this->getBackendUser()->user['admin'] = 1;
+        // Make sure the _cli_ user is loaded
+        Bootstrap::getInstance()->initializeBackendAuthentication();
 
         $io = new SymfonyStyle($input, $output);
         $io->title($this->getDescription());
@@ -113,9 +112,6 @@ class CleanFlexFormsCommand extends Command
         } else {
             $io->success('Nothing to do - You\'re all set!');
         }
-
-        // Restore backend user administration rights
-        $this->getBackendUser()->user['admin'] = $previouslyAppliedAdminRights;
     }
 
     /**
@@ -283,13 +279,4 @@ class CleanFlexFormsCommand extends Command
             }
         }
     }
-
-    /**
-     * Short-hand function for accessing the current backend user
-     * @return BackendUserAuthentication
-     */
-    protected function getBackendUser(): BackendUserAuthentication
-    {
-        return $GLOBALS['BE_USER'];
-    }
 }
index 7774e06..f15b571 100644 (file)
@@ -21,7 +21,7 @@ use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
 use Symfony\Component\Console\Style\SymfonyStyle;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
-use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
+use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\Query\QueryBuilder;
 use TYPO3\CMS\Core\DataHandling\DataHandler;
@@ -72,9 +72,8 @@ class DeletedRecordsCommand extends Command
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
-        // The backend user needs super-powers because datahandler is executed
-        $previouslyAppliedAdminRights = $this->getBackendUser()->user['admin'];
-        $this->getBackendUser()->user['admin'] = 1;
+        // Make sure the _cli_ user is loaded
+        Bootstrap::getInstance()->initializeBackendAuthentication();
 
         $io = new SymfonyStyle($input, $output);
         $io->title($this->getDescription());
@@ -117,9 +116,6 @@ class DeletedRecordsCommand extends Command
         // actually permanently delete them
         $this->deleteRecords($deletedRecords, $dryRun, $io);
 
-        // Restore backend user administration rights
-        $this->getBackendUser()->user['admin'] = $previouslyAppliedAdminRights;
-
         $io->success('All done!');
     }
 
@@ -306,13 +302,4 @@ class DeletedRecordsCommand extends Command
             }
         }
     }
-
-    /**
-     * Short-hand function for accessing the current backend user
-     * @return BackendUserAuthentication
-     */
-    protected function getBackendUser(): BackendUserAuthentication
-    {
-        return $GLOBALS['BE_USER'];
-    }
 }
index 28d8cc0..9b36faa 100644 (file)
@@ -20,6 +20,7 @@ use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
 use Symfony\Component\Console\Style\SymfonyStyle;
+use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\ReferenceIndex;
 use TYPO3\CMS\Core\Utility\ArrayUtility;
@@ -82,6 +83,9 @@ If you want to get more detailed information, use the --verbose option.')
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
+        // Make sure the _cli_ user is loaded
+        Bootstrap::getInstance()->initializeBackendAuthentication();
+
         $io = new SymfonyStyle($input, $output);
         $io->title($this->getDescription());
 
index 3f876f1..edcd633 100644 (file)
@@ -20,6 +20,7 @@ use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
 use Symfony\Component\Console\Style\SymfonyStyle;
+use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\ReferenceIndex;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -87,6 +88,9 @@ If you want to get more detailed information, use the --verbose option.')
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
+        // Make sure the _cli_ user is loaded
+        Bootstrap::getInstance()->initializeBackendAuthentication();
+
         $io = new SymfonyStyle($input, $output);
         $io->title($this->getDescription());
 
index 2d0f1db..192290c 100644 (file)
@@ -20,6 +20,7 @@ use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
 use Symfony\Component\Console\Style\SymfonyStyle;
+use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\ReferenceIndex;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -82,6 +83,9 @@ If you want to get more detailed information, use the --verbose option.')
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
+        // Make sure the _cli_ user is loaded
+        Bootstrap::getInstance()->initializeBackendAuthentication();
+
         $io = new SymfonyStyle($input, $output);
         $io->title($this->getDescription());
 
index 8abedc6..d7d1346 100644 (file)
@@ -21,6 +21,7 @@ use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
 use Symfony\Component\Console\Style\SymfonyStyle;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
+use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\ReferenceIndex;
 use TYPO3\CMS\Core\Utility\ArrayUtility;
@@ -98,6 +99,9 @@ If you want to get more detailed information, use the --verbose option.')
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
+        // Make sure the _cli_ user is loaded
+        Bootstrap::getInstance()->initializeBackendAuthentication();
+
         $io = new SymfonyStyle($input, $output);
         $io->title($this->getDescription());
 
index 4139cc1..6fc02a9 100644 (file)
@@ -21,7 +21,7 @@ use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
 use Symfony\Component\Console\Style\SymfonyStyle;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
-use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
+use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Database\Connection;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\DataHandling\DataHandler;
@@ -71,9 +71,8 @@ Manual repair suggestions:
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
-        // The backend user needs super-powers because datahandler is executed
-        $previouslyAppliedAdminRights = $this->getBackendUser()->user['admin'];
-        $this->getBackendUser()->user['admin'] = 1;
+        // Make sure the _cli_ user is loaded
+        Bootstrap::getInstance()->initializeBackendAuthentication();
 
         $io = new SymfonyStyle($input, $output);
         $io->title($this->getDescription());
@@ -138,9 +137,6 @@ Manual repair suggestions:
         } else {
             $io->success('No orphan records found.');
         }
-
-        // Restore backend user administration rights
-        $this->getBackendUser()->user['admin'] = $previouslyAppliedAdminRights;
     }
 
     /**
@@ -280,13 +276,4 @@ Manual repair suggestions:
             }
         }
     }
-
-    /**
-     * Short-hand function for accessing the current backend user
-     * @return BackendUserAuthentication
-     */
-    protected function getBackendUser(): BackendUserAuthentication
-    {
-        return $GLOBALS['BE_USER'];
-    }
 }
index 85213a3..d4f6bdf 100644 (file)
@@ -20,6 +20,7 @@ use Symfony\Component\Console\Input\InputInterface;
 use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
 use Symfony\Component\Console\Style\SymfonyStyle;
+use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\ReferenceIndex;
 use TYPO3\CMS\Core\Utility\File\BasicFileUtility;
@@ -88,6 +89,9 @@ If you want to get more detailed information, use the --verbose option.')
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
+        // Make sure the _cli_ user is loaded
+        Bootstrap::getInstance()->initializeBackendAuthentication();
+
         $io = new SymfonyStyle($input, $output);
         $io->title($this->getDescription());
 
index 0d528fd..350d54b 100644 (file)
@@ -21,7 +21,7 @@ use Symfony\Component\Console\Input\InputOption;
 use Symfony\Component\Console\Output\OutputInterface;
 use Symfony\Component\Console\Style\SymfonyStyle;
 use TYPO3\CMS\Backend\Utility\BackendUtility;
-use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
+use TYPO3\CMS\Core\Core\Bootstrap;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
 use TYPO3\CMS\Core\DataHandling\DataHandler;
@@ -106,9 +106,8 @@ class WorkspaceVersionRecordsCommand extends Command
      */
     protected function execute(InputInterface $input, OutputInterface $output)
     {
-        // The backend user needs super-powers because datahandler is executed
-        $previouslyAppliedAdminRights = $this->getBackendUser()->user['admin'];
-        $this->getBackendUser()->user['admin'] = 1;
+        // Make sure the _cli_ user is loaded
+        Bootstrap::getInstance()->initializeBackendAuthentication();
 
         $io = new SymfonyStyle($input, $output);
         $io->title($this->getDescription());
@@ -258,10 +257,6 @@ class WorkspaceVersionRecordsCommand extends Command
                 $io->note('No action specified, just displaying statistics. See --action option for details.');
                 break;
         }
-
-        // Restore backend user administration rights
-        $this->getBackendUser()->user['admin'] = $previouslyAppliedAdminRights;
-
         $io->success('All done!');
     }
 
@@ -692,14 +687,4 @@ class WorkspaceVersionRecordsCommand extends Command
         }
         return $tables;
     }
-
-    /**
-     * Short-hand function for accessing the current backend user
-     *
-     * @return BackendUserAuthentication
-     */
-    protected function getBackendUser(): BackendUserAuthentication
-    {
-        return $GLOBALS['BE_USER'];
-    }
 }