| [ Index ] |
PHP Cross Reference of Joomla 2.5.4 DE |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Tue Apr 3 11:40:28 2012 | Cross-referenced by PHPXref 0.7.1 |