Example #1
0
 /**
  * Authenticate user
  * This method can 
  * - authenticate user throught authentification process
  * - load already authenticated user in current session (or SSO)
  * - disconnect user
  *
  * @param array $params : indexed array of authentification parameters (default : nothing)
  * Accepted array keys are :
  * - authenticate : boolean : default true if disconnect is not set
  * - disconnect : boolean : default false
  * - login : string : user login to authenticate
  * - password : string : user password to authenticate
  * - remember : boolean : default false
  * - tokenName : string
  * - token : string
  * - type : string : type of authentification (admin|frontend) : default APPLICATION_USER_TYPE contant
  * - ... and any parameter needed by authentifications processes handled by modules
  * @return void
  * @access public
  * @static
  */
 public static function authenticate($params = array())
 {
     //first clean old sessions datas from database
     CMS_session::_cleanSessions();
     // Get Zend Auth instance
     $auth = Zend_Auth::getInstance();
     // Use CMS_auth as session storage space
     $auth->setStorage(new Zend_Auth_Storage_Session('atm-auth'));
     //set authentification type
     if (!isset($params['type'])) {
         $params['type'] = APPLICATION_USER_TYPE;
     }
     //set permanent auth status
     if (isset($params['remember']) && $params['remember']) {
         self::$_permanent = true;
     } else {
         $params['remember'] = false;
     }
     //clear auth storage if disconnection is queried and set default authenticate value
     if (isset($params['disconnect']) && $params['disconnect']) {
         //log disconection if user exists
         $storageValue = $auth->getStorage()->read();
         if (io::isPositiveInteger($storageValue)) {
             //load user
             $user = CMS_profile_usersCatalog::getByID($storageValue);
             if ($user) {
                 //log new session
                 $log = new CMS_log();
                 $log->logMiscAction(CMS_log::LOG_ACTION_DISCONNECT, $user, 'IP: ' . @$_SERVER['REMOTE_ADDR'] . ', UA: ' . @$_SERVER['HTTP_USER_AGENT']);
             }
         }
         //clear session content
         CMS_session::deleteSession(true);
         if (!isset($params['authenticate'])) {
             $params['authenticate'] = false;
         }
     } else {
         $params['disconnect'] = false;
         if (!isset($params['authenticate'])) {
             $params['authenticate'] = true;
         }
     }
     //init authenticated boolean
     $authenticated = false;
     //keep old storage value, because storage will be reseted by each module authentification
     $storageValue = $auth->getStorage()->read();
     //loop on each authentification types suupported
     foreach (array('credentials', 'session', 'cookie', 'sso') as $authType) {
         //load modules
         $modules = CMS_modulesCatalog::getAll('id');
         //get last module
         $module = array_pop($modules);
         //set authentification type as param
         $params['authType'] = $authType;
         //then try it for each modules
         do {
             //if module has auth method, try it
             if (method_exists($module, 'getAuthAdapter')) {
                 //overwrite auth storage value with old value
                 $auth->getStorage()->write($storageValue);
                 //get module auth adapter
                 $authAdapter = $module->getAuthAdapter($params);
                 //authenticate user
                 self::$_result = $auth->authenticate($authAdapter);
                 //To debug Auth process easily, discomment this line
                 //CMS_grandFather::log($_SERVER['SCRIPT_NAME'].' - '.$module->getCodename().' - Auth type : '.$authType.'/'.$params['type'].' - Auth result : '.self::$_result->getCode().($auth->hasIdentity() ? ' - Identity : '.$auth->getIdentity() : '').' - Message : '.(sizeof(self::$_result->getMessages()) == 1 ? array_pop(self::$_result->getMessages()) : print_r(self::$_result->getMessages(), true)));
                 switch (self::$_result->getCode()) {
                     case Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND:
                         //user crendentials does not exists (ex: no login/pass provided)
                         //nothing for now
                         break;
                     case Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID:
                         //invalid login/pass
                         //nothing for now
                         break;
                     case Zend_Auth_Result::SUCCESS:
                         if ($auth->hasIdentity()) {
                             // get user from identity found
                             $user = $authAdapter->getUser($auth->getIdentity());
                             //check if user is valid
                             if (isset($user) && $user && !$user->hasError() && !$user->isDeleted() && $user->isActive()) {
                                 $authenticated = true;
                                 //overwrite auth identity with valid user Id
                                 $auth->getStorage()->write($user->getUserId());
                             } else {
                                 unset($user);
                             }
                         }
                         break;
                     case Zend_Auth_Result::FAILURE:
                         //user found but has error during loading (user inactive or deleted)
                         //nothing for now
                         break;
                     default:
                         //other unidentified cases : thrown an error
                         CMS_grandFather::raiseError('Authentification return code ' . self::$_result->getCode() . ' for module ' . $module->getCodename() . ' with parameters ' . print_r($params, true));
                         break;
                 }
             }
             //get next last module
             $module = array_pop($modules);
         } while (!$authenticated && $module);
         //if user is authenticated, break authentification foreach
         if ($authenticated) {
             break;
         }
     }
     //if authenticated : set or refresh session datas in table, regenerate session Id
     if ($authenticated && $user) {
         $q = new CMS_query("\n\t\t\tselect \n\t\t\t\tid_ses, cookie_expire_ses\n\t\t\tfrom \n\t\t\t\tsessions \n\t\t\twhere \n\t\t\t\tphpid_ses='" . sensitiveIO::sanitizeSQLString(Zend_Session::getId()) . "' \n\t\t\t\tand user_ses='" . sensitiveIO::sanitizeSQLString($user->getUserId()) . "'");
         //get old session Id
         $oldSessionId = Zend_Session::getId();
         if ($q->getNumRows() > 0) {
             //if session already exists : update it
             //regenerate session Id randomly (arround 1/100 times)
             //removed : cause session instability
             /*if (!rand(0, 100)) {
             			//session id should not be regenerated each times because in case of a lot of concurrent calls, session can be destroyed
             			Zend_Session::regenerateId();
             		}*/
             $r = $q->getArray();
             $id = $r['id_ses'];
             //Cookie
             if (self::$_permanent || $r['cookie_expire_ses'] != '0000-00-00 00:00:00') {
                 self::$_permanent = true;
                 // Cookie expire in APPLICATION_COOKIE_EXPIRATION days
                 $expires = time() + 60 * 60 * 24 * APPLICATION_COOKIE_EXPIRATION;
                 CMS_session::setCookie(CMS_session::getAutoLoginCookieName(), base64_encode($id . '|' . Zend_Session::getId()), $expires);
             }
             //DB session
             $sql = "\n\t\t\t\t\tupdate \n\t\t\t\t\t\tsessions \n\t\t\t\t\tset\n\t\t\t\t\t\tlastTouch_ses=NOW(),\n\t\t\t\t\t\tuser_ses='" . sensitiveIO::sanitizeSQLString($user->getUserId()) . "',\n\t\t\t\t\t\tphpid_ses='" . sensitiveIO::sanitizeSQLString(Zend_Session::getId()) . "',\n\t\t\t\t\t\tremote_addr_ses='" . sensitiveIO::sanitizeSQLString(@$_SERVER['REMOTE_ADDR']) . "'";
             if (self::$_permanent) {
                 $sql .= ",\n\t\t\t\t\t\tcookie_expire_ses = DATE_ADD(NOW(), INTERVAL " . APPLICATION_COOKIE_EXPIRATION . " DAY)";
             }
             $sql .= "\n\t\t\t\t\twhere\n\t\t\t\t\t \tid_ses='" . sensitiveIO::sanitizeSQLString($id) . "'";
             $q = new CMS_query($sql);
             //if autologin : log it
             if (in_array(CMS_auth::AUTH_AUTOLOGIN_VALID, self::$_result->getMessages())) {
                 //log autologin session
                 $log = new CMS_log();
                 $log->logMiscAction(CMS_log::LOG_ACTION_AUTO_LOGIN, $user, 'IP: ' . @$_SERVER['REMOTE_ADDR'] . ', UA: ' . @$_SERVER['HTTP_USER_AGENT']);
             }
         } else {
             //otherwhise, create user session
             //regenerate session Id
             Zend_Session::regenerateId();
             //delete old session record if any
             $q = new CMS_query("\n\t\t\t\t\tdelete\n\t\t\t\t\tfrom \n\t\t\t\t\t\tsessions \n\t\t\t\t\twhere \n\t\t\t\t\t\tphpid_ses='" . sensitiveIO::sanitizeSQLString($oldSessionId) . "'");
             //insert new session record
             $sql = "\n\t\t\t\t\tinsert into\n\t\t\t\t\t\tsessions\n\t\t\t\t\tset\n\t\t\t\t\t\tlastTouch_ses=NOW(),\n\t\t\t\t\t\tphpid_ses='" . sensitiveIO::sanitizeSQLString(Zend_Session::getId()) . "',\n\t\t\t\t\t\tuser_ses='" . sensitiveIO::sanitizeSQLString($user->getUserId()) . "',\n\t\t\t\t\t\tremote_addr_ses='" . sensitiveIO::sanitizeSQLString(@$_SERVER['REMOTE_ADDR']) . "'\n\t\t\t\t";
             if (self::$_permanent) {
                 $sql .= ",\n\t\t\t\t\tcookie_expire_ses = DATE_ADD(NOW(), INTERVAL " . APPLICATION_COOKIE_EXPIRATION . " DAY)";
             }
             $q = new CMS_query($sql);
             if (!$q->hasError() && self::$_permanent) {
                 // Cookie expire in APPLICATION_COOKIE_EXPIRATION days
                 $expires = time() + 60 * 60 * 24 * APPLICATION_COOKIE_EXPIRATION;
                 CMS_session::setCookie(CMS_session::getAutoLoginCookieName(), base64_encode($q->getLastInsertedID() . '|' . Zend_Session::getId()), $expires);
             }
             //log new session
             $log = new CMS_log();
             $log->logMiscAction(CMS_log::LOG_ACTION_LOGIN, $user, 'Permanent cookie: ' . (self::$_permanent ? 'Yes' : 'No') . ', IP: ' . @$_SERVER['REMOTE_ADDR'] . ', UA: ' . @$_SERVER['HTTP_USER_AGENT']);
         }
         //set user as currently logged user
         self::$_userID = $user->getUserId();
     } else {
         if (APPLICATION_USER_TYPE == "frontend" && APPLICATION_ENFORCES_ACCESS_CONTROL) {
             //set public user as currently logged user
             self::$_userID = ANONYMOUS_PROFILEUSER_ID;
         }
     }
     //for backward compatibility
     $_SESSION["cms_context"] = new CMS_context();
 }