[ Index ]

PHP Cross Reference of Joomla 1.5.26 DE

title

Body

[close]

/plugins/authentication/ -> openid.php (source)

   1  <?php
   2  
   3  /**
   4   * @version        $Id: openid.php 14401 2010-01-26 14:10:00Z louis $
   5   * @package        Joomla
   6   * @subpackage    JFramework
   7   * @copyright    Copyright (C) 2005 - 2010 Open Source Matters. All rights reserved.
   8   * @license        GNU/GPL, see LICENSE.php
   9   * Joomla! is free software. This version may have been modified pursuant
  10   * to the GNU General Public License, and as distributed it includes or
  11   * is derivative of works licensed under the GNU General Public License or
  12   * other free or open source software licenses.
  13   * See COPYRIGHT.php for copyright notices and details.
  14   */
  15  
  16  // Check to ensure this file is included in Joomla!
  17  defined('_JEXEC') or die('Restricted access');
  18  
  19  jimport('joomla.plugin.plugin');
  20  
  21  /**
  22   * OpenID Authentication Plugin
  23   *
  24   * @package        Joomla
  25   * @subpackage    openID
  26   * @since 1.5
  27   */
  28  
  29  class plgAuthenticationOpenID extends JPlugin {
  30      /**
  31       * Constructor
  32       *
  33       * For php4 compatability we must not use the __constructor as a constructor for plugins
  34       * because func_get_args ( void ) returns a copy of all passed arguments NOT references.
  35       * This causes problems with cross-referencing necessary for the observer design pattern.
  36       *
  37       * @param     object $subject The object to observe
  38       * @param     array  $config  An array that holds the plugin configuration
  39       * @since 1.5
  40       */
  41  	function plgAuthenticationOpenID(& $subject, $config) {
  42          parent::__construct($subject, $config);        
  43      }
  44  
  45      /**
  46       * This method should handle any authentication and report back to the subject
  47       *
  48       * @access    public
  49       * @param   array     $credentials Array holding the user credentials
  50       * @param     array   $options     Array of extra options (return, entry_url)
  51       * @param    object    $response    Authentication response object
  52       * @return    boolean
  53       * @since 1.5
  54       */
  55  	function onAuthenticate($credentials, $options, & $response) {
  56          $mainframe =& JFactory::getApplication();
  57  
  58          if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
  59              define('Auth_OpenID_RAND_SOURCE', null);
  60          } else {
  61              $f = @fopen('/dev/urandom', 'r');
  62              if ($f !== false) {
  63                  define('Auth_OpenID_RAND_SOURCE', '/dev/urandom');
  64                  fclose($f);
  65              } else {
  66                  $f = @fopen('/dev/random', 'r');
  67                  if ($f !== false) {
  68                      define('Auth_OpenID_RAND_SOURCE', '/dev/urandom');
  69                      fclose($f);
  70                  } else {
  71                      define('Auth_OpenID_RAND_SOURCE', null);
  72                  }
  73              }
  74          }
  75          jimport('openid.consumer');
  76          jimport('joomla.filesystem.folder');
  77  
  78          // Access the session data
  79          $session = & JFactory :: getSession();
  80  
  81          // Create and/or start using the data store
  82          $store_path = JPATH_ROOT . '/tmp/_joomla_openid_store';
  83          if (!JFolder :: exists($store_path) && !JFolder :: create($store_path)) {
  84              $response->type = JAUTHENTICATE_STATUS_FAILURE;
  85              $response->error_message = "Could not create the FileStore directory '$store_path'. " . " Please check the effective permissions.";
  86              return false;
  87          }
  88  
  89          // Create store object
  90          $store = new Auth_OpenID_FileStore($store_path);
  91  
  92          // Create a consumer object
  93          $consumer = new Auth_OpenID_Consumer($store);
  94  
  95          if (!isset ($_SESSION['_openid_consumer_last_token'])) {
  96              // Begin the OpenID authentication process.
  97              if (!$auth_request = $consumer->begin($credentials['username'])) {
  98                  $response->type = JAUTHENTICATE_STATUS_FAILURE;
  99                  $response->error_message = 'Authentication error : could not connect to the openid server';
 100                  return false;
 101              }
 102  
 103              $sreg_request = Auth_OpenID_SRegRequest::build(
 104                      array ('email'),
 105                      array ('fullname','language','timezone')
 106              );
 107          
 108              if ($sreg_request) {
 109                  $auth_request->addExtension($sreg_request);
 110              }
 111              $policy_uris = array();
 112              if ($this->params->get( 'phishing-resistant', 0)) {
 113                  $policy_uris[] = 'http://schemas.openid.net/pape/policies/2007/06/phishing-resistant';
 114              }
 115  
 116              if ($this->params->get( 'multi-factor', 0)) {
 117                  $policy_uris[] = 'http://schemas.openid.net/pape/policies/2007/06/multi-factor';
 118              }
 119  
 120              if ($this->params->get( 'multi-factor-physical', 0)) {
 121                  $policy_uris[] = 'http://schemas.openid.net/pape/policies/2007/06/multi-factor-physical';
 122              }
 123  
 124              $pape_request = new Auth_OpenID_PAPE_Request($policy_uris);
 125              if ($pape_request) {
 126                  $auth_request->addExtension($pape_request);
 127              }
 128  
 129              //Create the entry url
 130              $entry_url = isset ($options['entry_url']) ? $options['entry_url'] : JURI :: base();
 131              $entry_url = JURI :: getInstance($entry_url);
 132  
 133              unset ($options['entry_url']); //We don't need this anymore
 134  
 135              //Create the url query information
 136              $options['return'] = isset($options['return']) ? base64_encode($options['return']) : base64_encode(JURI::base());
 137              $options[JUtility::getToken()] = 1;
 138  
 139              $process_url  = sprintf($entry_url->toString()."?option=com_user&task=login&username=%s", $credentials['username']);
 140              $process_url .= '&'.JURI::buildQuery($options);
 141  
 142              $session->set('return_url', $process_url );
 143  
 144              $trust_url = $entry_url->toString(array (
 145                  'path',
 146                  'host',
 147                  'port',
 148                  'scheme'
 149              ));
 150              $session->set('trust_url', $trust_url);
 151              // For OpenID 1, send a redirect.  For OpenID 2, use a Javascript
 152              // form to send a POST request to the server.
 153              if ($auth_request->shouldSendRedirect()) {
 154                  $redirect_url = $auth_request->redirectURL($trust_url, $process_url);
 155  
 156                  // If the redirect URL can't be built, display an error
 157                  // message.
 158                  if (Auth_OpenID :: isFailure($redirect_url)) {
 159                      displayError("Could not redirect to server: " . $redirect_url->message);
 160                  } else {
 161                      // Send redirect.
 162                      $mainframe->redirect($redirect_url);
 163                      return false;
 164                  }
 165              } else {
 166                  // Generate form markup and render it.
 167                  $form_id = 'openid_message';
 168                  $form_html = $auth_request->htmlMarkup($trust_url, $process_url, false, array (
 169                      'id' => $form_id
 170                  ));
 171                  // Display an error if the form markup couldn't be generated;
 172                  // otherwise, render the HTML.
 173                  if (Auth_OpenID :: isFailure($form_html)) {
 174                      //displayError("Could not redirect to server: " . $form_html->message);
 175                  } else {
 176                      JResponse :: setBody($form_html);
 177                      echo JResponse :: toString($mainframe->getCfg('gzip'));
 178                      $mainframe->close();
 179                      return false;
 180                  }
 181              }
 182          }
 183          $result = $consumer->complete($session->get('return_url'));
 184          switch ($result->status) {
 185              case Auth_OpenID_SUCCESS :
 186                  {
 187                          $sreg_resp = Auth_OpenID_SRegResponse::fromSuccessResponse($result);
 188  
 189                          $sreg = $sreg_resp->contents();
 190                      $usermode = $this->params->get('usermode', 2);
 191  /* in the following code, we deal with the transition from the old openid version to the new openid version
 192     In the old version, the username was always taken straight from the login form.  In the new version, we get a
 193     username back from the openid provider.  This is necessary for a number of reasons.  First, providers such as
 194     yahoo.com allow you to enter only the provider name in the username field (i.e. yahoo.com or flickr.com).  Taking
 195     this as the username would obviously cause problems because everybody who had an id from yahoo.com would have username
 196     yahoo.com.  Second, it is necessary because with the old way, we rely on the user entering the id the same every time.
 197     This is bad because if the user enters the http:// one time and not the second time, they end up as two different users.
 198     There are two possible settings here - the first setting, is to always use the new way, which is to get the username from
 199     the provider after authentication.  The second setting is to check if the username exists that we got from the provider.  If it
 200     doesn't, then we check if the entered username exists.  If it does, then we update the database with the username from the provider
 201     and continue happily along with the new username.
 202     We had talked about a third option, which would be to always used the old way, but that seems insecure in the case of somebody using
 203     a yahoo.com ID.
 204  */
 205                      if ($usermode && $usermode == 1) {
 206                          $response->username = $result->getDisplayIdentifier();
 207                      } else {
 208                          // first, check if the provider provided username exists in the database
 209                          $db = &JFactory::getDBO();
 210                          $query = 'SELECT username FROM #__users'.
 211                              ' WHERE username='.$db->Quote($result->getDisplayIdentifier()).
 212                              ' AND password=\'\'';
 213                          $db->setQuery($query);
 214                          $dbresult = $db->loadObject();
 215                          if ($dbresult) {
 216                              // if so, we set our username value to the provided value
 217                              $response->username = $result->getDisplayIdentifier();
 218                          } else {
 219                              // if it doesn't, we check if the username from the from exists in the database
 220                              $query = 'SELECT username FROM #__users'.
 221                                  ' WHERE username='.$db->Quote( $credentials['username'] ).
 222                                  ' AND password=\'\'';
 223                              $db->setQuery($query);
 224                              $dbresult = $db->loadObject();
 225                              if ($dbresult) {
 226                                  // if it does, we update the database
 227                                  $query = 'UPDATE #__users SET username='.$db->Quote($result->getDisplayIdentifier()).
 228                                      ' WHERE username='.$db->Quote($credentials['username']);
 229                                  $db->setQuery($query);
 230                                  $db->query();
 231                                  if (!$db->query()) {
 232                                      $response->status = JAUTHENTICATE_STATUS_FAILURE;
 233                                      $response->error_message = $db->getErrorMsg();
 234                                      //break out of the switch if we hit an error with our query
 235                                      break;
 236                                  }
 237                              }
 238                              $response->username = $result->getDisplayIdentifier();
 239                              // we return the username provided by the openid provider
 240                          }
 241                      }
 242                      $response->status = JAUTHENTICATE_STATUS_SUCCESS;
 243                      $response->error_message = '';
 244                      if (!isset($sreg['email'])) {
 245                          $response->email = str_replace( array('http://', 'https://'), '', $response->username );
 246                          $response->email = str_replace( '/', '-', $response->email );
 247                          $response->email .= '@openid.';
 248                      } else {
 249                          $response->email = $sreg['email'];
 250                      }
 251                      $response->fullname = isset ($sreg['fullname']) ? $sreg['fullname'] : $response->username;
 252                      $response->language = isset ($sreg['language']) ? $sreg['language'] : '';
 253                      $response->timezone = isset ($sreg['timezone']) ? $sreg['timezone'] : '';
 254                  }
 255                  break;
 256  
 257              case Auth_OpenID_CANCEL :
 258                  {
 259                      $response->status = JAUTHENTICATE_STATUS_CANCEL;
 260                      $response->error_message = 'Authentication cancelled';
 261                  }
 262                  break;
 263  
 264              case Auth_OpenID_FAILURE :
 265                  {
 266                      $response->status = JAUTHENTICATE_STATUS_FAILURE;
 267                      $response->error_message = 'Authentication failed';
 268                  }
 269                  break;
 270          }
 271      }
 272  
 273      //    function 
 274  }


Generated: Wed Mar 28 15:54:07 2012 Cross-referenced by PHPXref 0.7.1