eZ Publish  [trunk]
ezuserloginhandler.php
Go to the documentation of this file.
00001 <?php
00002 /**
00003  * File containing the eZUserLoginHandler class.
00004  *
00005  * @copyright Copyright (C) 1999-2012 eZ Systems AS. All rights reserved.
00006  * @license http://www.gnu.org/licenses/gpl-2.0.txt GNU General Public License v2
00007  * @version //autogentag//
00008  * @package kernel
00009  */
00010 
00011 /*!
00012   \class eZUserLoginHandler ezuserloginhandler.php
00013   \ingroup eZDatatype
00014   \brief The class eZUserLoginHandler does
00015 
00016 */
00017 
00018 class eZUserLoginHandler
00019 {
00020     const AVAILABLE_ARRAY = 'eZLoginHandlerAvailbleArray'; // stores untested login handlers for login
00021     const STEP = 'eZLoginHandlerStep';
00022     const USER_INFO = 'eZLoginHandlerUserInfo';
00023     const LAST_CHECK_REDIRECT = 'eZLoginHandlerLastCheckRedirect';
00024     const FORCE_LOGIN = 'eZLoginHandlerForceLogin';
00025     const LAST_HANDLER_NAME = 'eZLoginHandlerLastHandlerName';
00026 
00027     const STEP_PRE_CHECK_USER_INFO = 0;
00028     const STEP_PRE_COLLECT_USER_INFO = 1;
00029     const STEP_POST_COLLECT_USER_INFO = 2;
00030     const STEP_CHECK_USER = 3;
00031     const STEP_LOGIN_USER = 4;
00032 
00033     /*!
00034      Constructor
00035     */
00036     function eZUserLoginHandler()
00037     {
00038     }
00039 
00040     /*!
00041      \static
00042      Clean up session variables used by the login procedure.
00043     */
00044     static function sessionCleanup()
00045     {
00046         $http = eZHTTPTool::instance();
00047 
00048         $valueList = array( self::AVAILABLE_ARRAY,
00049                             self::STEP,
00050                             self::USER_INFO,
00051                             self::LAST_CHECK_REDIRECT,
00052                             self::FORCE_LOGIN );
00053 
00054         foreach ( $valueList as $value )
00055         {
00056             if ( $http->hasSessionVariable( $value ) )
00057             {
00058                 $http->removeSessionVariable( $value );
00059             }
00060         }
00061 
00062         $ini = eZINI::instance();
00063         $handlerList = array( 'standard' );
00064         if ( $ini->hasVariable( 'UserSettings', 'LoginHandler' ) )
00065         {
00066             $handlerList = $ini->variable( 'UserSettings', 'LoginHandler' );
00067         }
00068 
00069         foreach( $handlerList as $handler )
00070         {
00071             $loginHandler = eZUserLoginHandler::instance( $handler );
00072             if ( $loginHandler )
00073             {
00074                 $loginHandler->sessionCleanup();
00075             }
00076         }
00077     }
00078 
00079     /**
00080      * Returns a new instance of the eZUser class pr $protocol.
00081      *
00082      * @param string $protocol If not set to 'standard' (default), then the code will look
00083      *        for handler first in kernel/classes/datatypes/ezuser/, then according to
00084      *        site.ini[UserSettings]ExtensionDirectory settings
00085      * @return eZUser
00086      */
00087     static function instance( $protocol = "standard" )
00088     {
00089         $triedFiles = array();
00090         if ( $protocol == "standard" )
00091         {
00092             $impl = new eZUser( 0 );
00093             return $impl;
00094         }
00095         else
00096         {
00097             $ezuserFile = 'kernel/classes/datatypes/ezuser/ez' . strtolower( $protocol ) . 'user.php';
00098             $triedFiles[] = $ezuserFile;
00099             if ( file_exists( $ezuserFile ) )
00100             {
00101                 include_once( $ezuserFile );
00102                 $className = 'eZ' . $protocol . 'User';
00103                 $impl = new $className();
00104                 return $impl;
00105             }
00106             else // check in extensions
00107             {
00108                 $ini = eZINI::instance();
00109                 $extensionDirectories = $ini->variable( 'UserSettings', 'ExtensionDirectory' );
00110                 $directoryList = eZExtension::expandedPathList( $extensionDirectories, 'login_handler' );
00111 
00112                 foreach( $directoryList as $directory )
00113                 {
00114                     $userFile = $directory . '/ez' . strtolower( $protocol ) . 'user.php';
00115                     $triedFiles[] = $userFile;
00116 
00117                     if ( file_exists( $userFile ) )
00118                     {
00119                         include_once( $userFile );
00120                         $className = 'eZ' . $protocol . 'User';
00121                         $impl = new $className();
00122                         return $impl;
00123                     }
00124                 }
00125             }
00126         }
00127         // if no one appropriate instance was found
00128         eZDebug::writeWarning( "Unable to find user login handler '$protocol', searched for these files: " . implode( ', ', $triedFiles ), __METHOD__ );
00129         $impl = null;
00130         return $impl;
00131     }
00132 
00133     /**
00134      * Check if user login is required. If so, use login handler to redirect user.
00135      *
00136      * @since 4.4
00137      * @param array $siteBasics
00138      * @param eZURI $uri
00139      * @return array|true|false|null An associative array on redirect with 'module' and 'function' keys, true on successful
00140      *                               and false/null on #fail.
00141      */
00142     public static function preCheck( array &$siteBasics, eZURI $uri )
00143     {
00144         if ( !$siteBasics['user-object-required'] )
00145         {
00146             return null;
00147         }
00148 
00149         $ini = eZINI::instance();
00150         $requireUserLogin = ( $ini->variable( 'SiteAccessSettings', 'RequireUserLogin' ) == 'true' );
00151         $forceLogin = false;
00152         if ( eZSession::hasStarted() )
00153         {
00154             $http = eZHTTPTool::instance();
00155             $forceLogin = $http->hasSessionVariable( self::FORCE_LOGIN );
00156         }
00157         if ( !$requireUserLogin && !$forceLogin )
00158         {
00159             return null;
00160         }
00161         return self::checkUser( $siteBasics, $uri );
00162     }
00163 
00164     /*!
00165      \static
00166      Check user redirection for current loginhandler.
00167 
00168      \param siteBasics
00169      \param possible redirect url
00170      \param login handler, standard by default. If set to false, handler type will be fetched from ini settings.
00171 
00172      \return  true if user is logged in successfully.
00173               null or false if failed.
00174               redirect specification, array ( module, view ).
00175     */
00176     static function checkUser( &$siteBasics, &$url )
00177     {
00178         $http = eZHTTPTool::instance();
00179 
00180         if ( !$http->hasSessionVariable( self::STEP ) )
00181         {
00182             $http->setSessionVariable( self::STEP, self::STEP_PRE_CHECK_USER_INFO );
00183         }
00184 
00185         $loginStep =& $http->sessionVariable( self::STEP );
00186 
00187         if ( $http->hasSessionVariable( self::FORCE_LOGIN ) &&
00188              $loginStep < self::STEP_PRE_COLLECT_USER_INFO )
00189         {
00190             $loginStep = self::STEP_PRE_COLLECT_USER_INFO;
00191         }
00192 
00193         switch( $loginStep )
00194         {
00195             case self::STEP_PRE_CHECK_USER_INFO:
00196             {
00197                 $ini = eZINI::instance();
00198                 $handlerList = array( 'standard' );
00199                 if ( $ini->hasVariable( 'UserSettings', 'LoginHandler' ) )
00200                 {
00201                     $handlerList = $ini->variable( 'UserSettings', 'LoginHandler' );
00202                 }
00203 
00204                 if ( $http->hasSessionVariable( self::LAST_HANDLER_NAME ) )
00205                 {
00206                     $http->removeSessionVariable( self::LAST_HANDLER_NAME );
00207                 }
00208 
00209                 foreach( $handlerList as $handler )
00210                 {
00211                     $userObject = eZUserLoginHandler::instance( $handler );
00212                     if ( $userObject )
00213                     {
00214                         $check = $userObject->checkUser( $siteBasics, $url );
00215                         if ( $check === null ) // No login needed.
00216                         {
00217                             eZUserLoginHandler::sessionCleanup();
00218                             return null;
00219                         }
00220                         $http->setSessionVariable( self::LAST_CHECK_REDIRECT, $check );
00221                         $http->setSessionVariable( self::LAST_HANDLER_NAME, $handler );
00222                     }
00223                 }
00224 
00225                 $http->setSessionVariable( self::STEP, self::STEP_PRE_COLLECT_USER_INFO );
00226                 return eZUserLoginHandler::checkUser( $siteBasics, $url );
00227             } break;
00228 
00229             case self::STEP_PRE_COLLECT_USER_INFO:
00230             {
00231                 $http->setSessionVariable( self::STEP, self::STEP_POST_COLLECT_USER_INFO );
00232 
00233                 $handler = null;
00234                 if ( $http->hasSessionVariable( self::LAST_HANDLER_NAME ) )
00235                 {
00236                     $handlerName = $http->sessionVariable( self::LAST_HANDLER_NAME );
00237                     $handler = eZUserLoginHandler::instance( $handlerName );
00238                 }
00239                 if ( $handler )
00240                 {
00241                     return $handler->preCollectUserInfo();
00242                 }
00243                 else
00244                 {
00245                     $redirect =& $http->sessionVariable( self::LAST_CHECK_REDIRECT );
00246                     if ( !$redirect )
00247                     {
00248                         $redirect = array( 'module' => 'user', 'function' => 'login' );
00249                     }
00250                     return $redirect;
00251                 }
00252             } break;
00253 
00254             case self::STEP_POST_COLLECT_USER_INFO:
00255             {
00256                 $http->setSessionVariable( self::STEP, self::STEP_LOGIN_USER );
00257 
00258                 $handler = null;
00259                 if ( $http->hasSessionVariable( self::LAST_HANDLER_NAME ) )
00260                 {
00261                     $handlerName = $http->sessionVariable( self::LAST_HANDLER_NAME );
00262                     $handler = eZUserLoginHandler::instance( $handlerName );
00263                 }
00264 
00265                 if ( $handler ) //and $handlerName != 'standard' )
00266                 {
00267                     // Use specified login handler to handle Login info input
00268                     if ( !$handler->postCollectUserInfo() ) // Catch cancel of information collection
00269                     {
00270                         eZUserLoginHandler::sessionCleanup();
00271                         eZHTTPTool::redirect( '/' );
00272                         eZExecution::cleanExit();
00273                     }
00274                 }
00275                 return eZUserLoginHandler::checkUser( $siteBasics, $url );
00276             } break;
00277 
00278             case self::STEP_LOGIN_USER:
00279             {
00280                 $ini = eZINI::instance();
00281                 $handlerList = array( 'standard' );
00282                 if ( $ini->hasVariable( 'UserSettings', 'LoginHandler' ) )
00283                 {
00284                     $handlerList = $ini->variable( 'UserSettings', 'LoginHandler' );
00285                 }
00286 
00287                 $userInfoArray =& $http->sessionVariable( self::USER_INFO );
00288                 $http->removeSessionVariable( self::USER_INFO );
00289 
00290                 if ( $http->hasSessionVariable( self::FORCE_LOGIN ) )
00291                 {
00292                     $http->removeSessionVariable( self::FORCE_LOGIN );
00293                 }
00294 
00295                 $user = null;
00296                 if ( is_array( $userInfoArray ) and $userInfoArray['login'] and $userInfoArray['password'] )
00297                 {
00298                     foreach( $handlerList as $handler )
00299                     {
00300                         $userObject = eZUserLoginHandler::instance( $handler );
00301                         if ( $userObject )
00302                         {
00303                             $user = $userObject->loginUser( $userInfoArray['login'], $userInfoArray['password'] );
00304                             if ( is_subclass_of( $user, 'eZUser' ) )
00305                             {
00306                                 eZUserLoginHandler::sessionCleanup();
00307                                 return null;
00308                             }
00309                             else if ( is_array( $user ) )
00310                             {
00311                                 eZUserLoginHandler::sessionCleanup();
00312                                 return $user;
00313                             }
00314                         }
00315                     }
00316                 }
00317 
00318                 $http->setSessionVariable( self::STEP, self::STEP_PRE_CHECK_USER_INFO );
00319                 return eZUserLoginHandler::checkUser( $siteBasics, $url );
00320             } break;
00321         }
00322     }
00323 
00324     /*!
00325      Set session variable to force login
00326     */
00327     static function forceLogin()
00328     {
00329         $http = eZHTTPTool::instance();
00330         $http->setSessionVariable( self::FORCE_LOGIN, 1 );
00331     }
00332 }
00333 
00334 ?>