[ Index ]

PHP Cross Reference of Joomla 2.5.4 DE

title

Body

[close]

/libraries/joomla/user/ -> helper.php (source)

   1  <?php
   2  /**
   3   * @package     Joomla.Platform
   4   * @subpackage  User
   5   *
   6   * @copyright   Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
   7   * @license     GNU General Public License version 2 or later; see LICENSE
   8   */
   9  
  10  defined('JPATH_PLATFORM') or die;
  11  
  12  /**
  13   * Authorisation helper class, provides static methods to perform various tasks relevant
  14   * to the Joomla user and authorisation classes
  15   *
  16   * This class has influences and some method logic from the Horde Auth package
  17   *
  18   * @package     Joomla.Platform
  19   * @subpackage  User
  20   * @since       11.1
  21   */
  22  abstract class JUserHelper
  23  {
  24      /**
  25       * Method to add a user to a group.
  26       *
  27       * @param   integer  $userId   The id of the user.
  28       * @param   integer  $groupId  The id of the group.
  29       *
  30       * @return  mixed  Boolean true on success, Exception on error.
  31       *
  32       * @since   11.1
  33       */
  34  	public static function addUserToGroup($userId, $groupId)
  35      {
  36          // Get the user object.
  37          $user = new JUser((int) $userId);
  38  
  39          // Add the user to the group if necessary.
  40          if (!in_array($groupId, $user->groups))
  41          {
  42              // Get the title of the group.
  43              $db = JFactory::getDbo();
  44              $query = $db->getQuery(true);
  45              $query->select($db->quoteName('title'));
  46              $query->from($db->quoteName('#__usergroups'));
  47              $query->where($db->quoteName('id') . ' = ' . (int) $groupId);
  48              $db->setQuery($query);
  49              $title = $db->loadResult();
  50  
  51              // Check for a database error.
  52              if ($db->getErrorNum())
  53              {
  54                  return new Exception($db->getErrorMsg());
  55              }
  56  
  57              // If the group does not exist, return an exception.
  58              if (!$title)
  59              {
  60                  return new Exception(JText::_('JLIB_USER_EXCEPTION_ACCESS_USERGROUP_INVALID'));
  61              }
  62  
  63              // Add the group data to the user object.
  64              $user->groups[$title] = $groupId;
  65  
  66              // Store the user object.
  67              if (!$user->save())
  68              {
  69                  return new Exception($user->getError());
  70              }
  71          }
  72  
  73          // Set the group data for any preloaded user objects.
  74          $temp = JFactory::getUser((int) $userId);
  75          $temp->groups = $user->groups;
  76  
  77          // Set the group data for the user object in the session.
  78          $temp = JFactory::getUser();
  79          if ($temp->id == $userId)
  80          {
  81              $temp->groups = $user->groups;
  82          }
  83  
  84          return true;
  85      }
  86  
  87      /**
  88       * Method to get a list of groups a user is in.
  89       *
  90       * @param   integer  $userId  The id of the user.
  91       *
  92       * @return  mixed  Array on success, JException on error.
  93       *
  94       * @since   11.1
  95       */
  96  	public static function getUserGroups($userId)
  97      {
  98          // Get the user object.
  99          $user = JUser::getInstance((int) $userId);
 100  
 101          return isset($user->groups) ? $user->groups : array();
 102      }
 103  
 104      /**
 105       * Method to remove a user from a group.
 106       *
 107       * @param   integer  $userId   The id of the user.
 108       * @param   integer  $groupId  The id of the group.
 109       *
 110       * @return  mixed  Boolean true on success, JException on error.
 111       *
 112       * @since   11.1
 113       */
 114  	public static function removeUserFromGroup($userId, $groupId)
 115      {
 116          // Get the user object.
 117          $user = JUser::getInstance((int) $userId);
 118  
 119          // Remove the user from the group if necessary.
 120          $key = array_search($groupId, $user->groups);
 121          if ($key !== false)
 122          {
 123              // Remove the user from the group.
 124              unset($user->groups[$key]);
 125  
 126              // Store the user object.
 127              if (!$user->save())
 128              {
 129                  return new JException($user->getError());
 130              }
 131          }
 132  
 133          // Set the group data for any preloaded user objects.
 134          $temp = JFactory::getUser((int) $userId);
 135          $temp->groups = $user->groups;
 136  
 137          // Set the group data for the user object in the session.
 138          $temp = JFactory::getUser();
 139          if ($temp->id == $userId)
 140          {
 141              $temp->groups = $user->groups;
 142          }
 143  
 144          return true;
 145      }
 146  
 147      /**
 148       * Method to set the groups for a user.
 149       *
 150       * @param   integer  $userId  The id of the user.
 151       * @param   array    $groups  An array of group ids to put the user in.
 152       *
 153       * @return  mixed  Boolean true on success, Exception on error.
 154       *
 155       * @since   11.1
 156       */
 157  	public static function setUserGroups($userId, $groups)
 158      {
 159          // Get the user object.
 160          $user = JUser::getInstance((int) $userId);
 161  
 162          // Set the group ids.
 163          JArrayHelper::toInteger($groups);
 164          $user->groups = $groups;
 165  
 166          // Get the titles for the user groups.
 167          $db = JFactory::getDbo();
 168          $query = $db->getQuery(true);
 169          $query->select($db->quoteName('id') . ', ' . $db->quoteName('title'));
 170          $query->from($db->quoteName('#__usergroups'));
 171          $query->where($db->quoteName('id') . ' = ' . implode(' OR ' . $db->quoteName('id') . ' = ', $user->groups));
 172          $db->setQuery($query);
 173          $results = $db->loadObjectList();
 174  
 175          // Check for a database error.
 176          if ($db->getErrorNum())
 177          {
 178              return new Exception($db->getErrorMsg());
 179          }
 180  
 181          // Set the titles for the user groups.
 182          for ($i = 0, $n = count($results); $i < $n; $i++)
 183          {
 184              $user->groups[$results[$i]->id] = $results[$i]->title;
 185          }
 186  
 187          // Store the user object.
 188          if (!$user->save())
 189          {
 190              return new Exception($user->getError());
 191          }
 192  
 193          // Set the group data for any preloaded user objects.
 194          $temp = JFactory::getUser((int) $userId);
 195          $temp->groups = $user->groups;
 196  
 197          // Set the group data for the user object in the session.
 198          $temp = JFactory::getUser();
 199          if ($temp->id == $userId)
 200          {
 201              $temp->groups = $user->groups;
 202          }
 203  
 204          return true;
 205      }
 206  
 207      /**
 208       * Gets the user profile information
 209       *
 210       * @param   integer  $userId  The id of the user.
 211       *
 212       * @return  object
 213       *
 214       * @since   11.1
 215       */
 216  	public function getProfile($userId = 0)
 217      {
 218          if ($userId == 0)
 219          {
 220              $user    = JFactory::getUser();
 221              $userId    = $user->id;
 222          }
 223  
 224          // Get the dispatcher and load the user's plugins.
 225          $dispatcher    = JDispatcher::getInstance();
 226          JPluginHelper::importPlugin('user');
 227  
 228          $data = new JObject;
 229          $data->id = $userId;
 230  
 231          // Trigger the data preparation event.
 232          $dispatcher->trigger('onContentPrepareData', array('com_users.profile', &$data));
 233  
 234          return $data;
 235      }
 236  
 237      /**
 238       * Method to activate a user
 239       *
 240       * @param   string  $activation  Activation string
 241       *
 242       * @return  boolean  True on success
 243       *
 244       * @since   11.1
 245       */
 246  	public static function activateUser($activation)
 247      {
 248          // Initialize some variables.
 249          $db = JFactory::getDbo();
 250          $query = $db->getQuery(true);
 251  
 252          // Let's get the id of the user we want to activate
 253          $query->select($db->quoteName('id'));
 254          $query->from($db->quoteName('#__users'));
 255          $query->where($db->quoteName('activation') . ' = ' . $db->quote($activation));
 256          $query->where($db->quoteName('block') . ' = 1');
 257          $query->where($db->quoteName('lastvisitDate') . ' = ' . $db->quote('0000-00-00 00:00:00'));
 258          $db->setQuery($query);
 259          $id = intval($db->loadResult());
 260  
 261          // Is it a valid user to activate?
 262          if ($id)
 263          {
 264              $user = JUser::getInstance((int) $id);
 265  
 266              $user->set('block', '0');
 267              $user->set('activation', '');
 268  
 269              // Time to take care of business.... store the user.
 270              if (!$user->save())
 271              {
 272                  JError::raiseWarning("SOME_ERROR_CODE", $user->getError());
 273                  return false;
 274              }
 275          }
 276          else
 277          {
 278              JError::raiseWarning("SOME_ERROR_CODE", JText::_('JLIB_USER_ERROR_UNABLE_TO_FIND_USER'));
 279              return false;
 280          }
 281  
 282          return true;
 283      }
 284  
 285      /**
 286       * Returns userid if a user exists
 287       *
 288       * @param   string  $username  The username to search on.
 289       *
 290       * @return  integer  The user id or 0 if not found.
 291       *
 292       * @since   11.1
 293       */
 294  	public static function getUserId($username)
 295      {
 296          // Initialise some variables
 297          $db = JFactory::getDbo();
 298          $query = $db->getQuery(true);
 299          $query->select($db->quoteName('id'));
 300          $query->from($db->quoteName('#__users'));
 301          $query->where($db->quoteName('username') . ' = ' . $db->quote($username));
 302          $db->setQuery($query, 0, 1);
 303          return $db->loadResult();
 304      }
 305  
 306      /**
 307       * Formats a password using the current encryption.
 308       *
 309       * @param   string   $plaintext     The plaintext password to encrypt.
 310       * @param   string   $salt          The salt to use to encrypt the password. []
 311       *                                  If not present, a new salt will be
 312       *                                  generated.
 313       * @param   string   $encryption    The kind of password encryption to use.
 314       *                                  Defaults to md5-hex.
 315       * @param   boolean  $show_encrypt  Some password systems prepend the kind of
 316       *                                  encryption to the crypted password ({SHA},
 317       *                                  etc). Defaults to false.
 318       *
 319       * @return  string  The encrypted password.
 320       *
 321       * @since   11.1
 322       */
 323  	public static function getCryptedPassword($plaintext, $salt = '', $encryption = 'md5-hex', $show_encrypt = false)
 324      {
 325          // Get the salt to use.
 326          $salt = JUserHelper::getSalt($encryption, $salt, $plaintext);
 327  
 328          // Encrypt the password.
 329          switch ($encryption)
 330          {
 331              case 'plain':
 332                  return $plaintext;
 333  
 334              case 'sha':
 335                  $encrypted = base64_encode(mhash(MHASH_SHA1, $plaintext));
 336                  return ($show_encrypt) ? '{SHA}' . $encrypted : $encrypted;
 337  
 338              case 'crypt':
 339              case 'crypt-des':
 340              case 'crypt-md5':
 341              case 'crypt-blowfish':
 342                  return ($show_encrypt ? '{crypt}' : '') . crypt($plaintext, $salt);
 343  
 344              case 'md5-base64':
 345                  $encrypted = base64_encode(mhash(MHASH_MD5, $plaintext));
 346                  return ($show_encrypt) ? '{MD5}' . $encrypted : $encrypted;
 347  
 348              case 'ssha':
 349                  $encrypted = base64_encode(mhash(MHASH_SHA1, $plaintext . $salt) . $salt);
 350                  return ($show_encrypt) ? '{SSHA}' . $encrypted : $encrypted;
 351  
 352              case 'smd5':
 353                  $encrypted = base64_encode(mhash(MHASH_MD5, $plaintext . $salt) . $salt);
 354                  return ($show_encrypt) ? '{SMD5}' . $encrypted : $encrypted;
 355  
 356              case 'aprmd5':
 357                  $length = strlen($plaintext);
 358                  $context = $plaintext . '$apr1$' . $salt;
 359                  $binary = JUserHelper::_bin(md5($plaintext . $salt . $plaintext));
 360  
 361                  for ($i = $length; $i > 0; $i -= 16)
 362                  {
 363                      $context .= substr($binary, 0, ($i > 16 ? 16 : $i));
 364                  }
 365                  for ($i = $length; $i > 0; $i >>= 1)
 366                  {
 367                      $context .= ($i & 1) ? chr(0) : $plaintext[0];
 368                  }
 369  
 370                  $binary = JUserHelper::_bin(md5($context));
 371  
 372                  for ($i = 0; $i < 1000; $i++)
 373                  {
 374                      $new = ($i & 1) ? $plaintext : substr($binary, 0, 16);
 375                      if ($i % 3)
 376                      {
 377                          $new .= $salt;
 378                      }
 379                      if ($i % 7)
 380                      {
 381                          $new .= $plaintext;
 382                      }
 383                      $new .= ($i & 1) ? substr($binary, 0, 16) : $plaintext;
 384                      $binary = JUserHelper::_bin(md5($new));
 385                  }
 386  
 387                  $p = array();
 388                  for ($i = 0; $i < 5; $i++)
 389                  {
 390                      $k = $i + 6;
 391                      $j = $i + 12;
 392                      if ($j == 16)
 393                      {
 394                          $j = 5;
 395                      }
 396                      $p[] = JUserHelper::_toAPRMD5((ord($binary[$i]) << 16) | (ord($binary[$k]) << 8) | (ord($binary[$j])), 5);
 397                  }
 398  
 399                  return '$apr1$' . $salt . '$' . implode('', $p) . JUserHelper::_toAPRMD5(ord($binary[11]), 3);
 400  
 401              case 'md5-hex':
 402              default:
 403                  $encrypted = ($salt) ? md5($plaintext . $salt) : md5($plaintext);
 404                  return ($show_encrypt) ? '{MD5}' . $encrypted : $encrypted;
 405          }
 406      }
 407  
 408      /**
 409       * Returns a salt for the appropriate kind of password encryption.
 410       * Optionally takes a seed and a plaintext password, to extract the seed
 411       * of an existing password, or for encryption types that use the plaintext
 412       * in the generation of the salt.
 413       *
 414       * @param   string  $encryption  The kind of password encryption to use.
 415       *                               Defaults to md5-hex.
 416       * @param   string  $seed        The seed to get the salt from (probably a
 417       *                               previously generated password). Defaults to
 418       *                               generating a new seed.
 419       * @param   string  $plaintext   The plaintext password that we're generating
 420       *                               a salt for. Defaults to none.
 421       *
 422       * @return  string  The generated or extracted salt.
 423       *
 424       * @since   11.1
 425       */
 426  	public static function getSalt($encryption = 'md5-hex', $seed = '', $plaintext = '')
 427      {
 428          // Encrypt the password.
 429          switch ($encryption)
 430          {
 431              case 'crypt':
 432              case 'crypt-des':
 433                  if ($seed)
 434                  {
 435                      return substr(preg_replace('|^{crypt}|i', '', $seed), 0, 2);
 436                  }
 437                  else
 438                  {
 439                      return substr(md5(mt_rand()), 0, 2);
 440                  }
 441                  break;
 442  
 443              case 'crypt-md5':
 444                  if ($seed)
 445                  {
 446                      return substr(preg_replace('|^{crypt}|i', '', $seed), 0, 12);
 447                  }
 448                  else
 449                  {
 450                      return '$1$' . substr(md5(mt_rand()), 0, 8) . '$';
 451                  }
 452                  break;
 453  
 454              case 'crypt-blowfish':
 455                  if ($seed)
 456                  {
 457                      return substr(preg_replace('|^{crypt}|i', '', $seed), 0, 16);
 458                  }
 459                  else
 460                  {
 461                      return '$2$' . substr(md5(mt_rand()), 0, 12) . '$';
 462                  }
 463                  break;
 464  
 465              case 'ssha':
 466                  if ($seed)
 467                  {
 468                      return substr(preg_replace('|^{SSHA}|', '', $seed), -20);
 469                  }
 470                  else
 471                  {
 472                      return mhash_keygen_s2k(MHASH_SHA1, $plaintext, substr(pack('h*', md5(mt_rand())), 0, 8), 4);
 473                  }
 474                  break;
 475  
 476              case 'smd5':
 477                  if ($seed)
 478                  {
 479                      return substr(preg_replace('|^{SMD5}|', '', $seed), -16);
 480                  }
 481                  else
 482                  {
 483                      return mhash_keygen_s2k(MHASH_MD5, $plaintext, substr(pack('h*', md5(mt_rand())), 0, 8), 4);
 484                  }
 485                  break;
 486  
 487              case 'aprmd5': /* 64 characters that are valid for APRMD5 passwords. */
 488                  $APRMD5 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
 489  
 490                  if ($seed)
 491                  {
 492                      return substr(preg_replace('/^\$apr1\$(.{8}).*/', '\\1', $seed), 0, 8);
 493                  }
 494                  else
 495                  {
 496                      $salt = '';
 497                      for ($i = 0; $i < 8; $i++)
 498                      {
 499                          $salt .= $APRMD5{rand(0, 63)};
 500                      }
 501                      return $salt;
 502                  }
 503                  break;
 504  
 505              default:
 506                  $salt = '';
 507                  if ($seed)
 508                  {
 509                      $salt = $seed;
 510                  }
 511                  return $salt;
 512                  break;
 513          }
 514      }
 515  
 516      /**
 517       * Generate a random password
 518       *
 519       * @param   integer  $length  Length of the password to generate
 520       *
 521       * @return  string  Random Password
 522       *
 523       * @since   11.1
 524       */
 525  	public static function genRandomPassword($length = 8)
 526      {
 527          $salt = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
 528          $base = strlen($salt);
 529          $makepass = '';
 530  
 531          /*
 532           * Start with a cryptographic strength random string, then convert it to
 533           * a string with the numeric base of the salt.
 534           * Shift the base conversion on each character so the character
 535           * distribution is even, and randomize the start shift so it's not
 536           * predictable.
 537           */
 538          $random = JCrypt::genRandomBytes($length + 1);
 539          $shift = ord($random[0]);
 540          for ($i = 1; $i <= $length; ++$i)
 541          {
 542              $makepass .= $salt[($shift + ord($random[$i])) % $base];
 543              $shift += ord($random[$i]);
 544          }
 545  
 546          return $makepass;
 547      }
 548  
 549      /**
 550       * Converts to allowed 64 characters for APRMD5 passwords.
 551       *
 552       * @param   string   $value  The value to convert.
 553       * @param   integer  $count  The number of characters to convert.
 554       *
 555       * @return  string  $value converted to the 64 MD5 characters.
 556       *
 557       * @since   11.1
 558       */
 559  	protected static function _toAPRMD5($value, $count)
 560      {
 561          /* 64 characters that are valid for APRMD5 passwords. */
 562          $APRMD5 = './0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
 563  
 564          $aprmd5 = '';
 565          $count = abs($count);
 566          while (--$count)
 567          {
 568              $aprmd5 .= $APRMD5[$value & 0x3f];
 569              $value >>= 6;
 570          }
 571          return $aprmd5;
 572      }
 573  
 574      /**
 575       * Converts hexadecimal string to binary data.
 576       *
 577       * @param   string  $hex  Hex data.
 578       *
 579       * @return  string  Binary data.
 580       *
 581       * @since   11.1
 582       */
 583  	private static function _bin($hex)
 584      {
 585          $bin = '';
 586          $length = strlen($hex);
 587          for ($i = 0; $i < $length; $i += 2)
 588          {
 589              $tmp = sscanf(substr($hex, $i, 2), '%x');
 590              $bin .= chr(array_shift($tmp));
 591          }
 592          return $bin;
 593      }
 594  }


Generated: Tue Apr 3 11:40:28 2012 Cross-referenced by PHPXref 0.7.1