[ Index ] |
PHP Cross Reference of Eventum |
[Summary view] [Print] [Text view]
1 <?php 2 /* vim: set expandtab tabstop=4 shiftwidth=4 encoding=utf-8: */ 3 // +----------------------------------------------------------------------+ 4 // | Eventum - Issue Tracking System | 5 // +----------------------------------------------------------------------+ 6 // | Copyright (c) 2003, 2004, 2005, 2006, 2007 MySQL AB | 7 // | | 8 // | This program is free software; you can redistribute it and/or modify | 9 // | it under the terms of the GNU General Public License as published by | 10 // | the Free Software Foundation; either version 2 of the License, or | 11 // | (at your option) any later version. | 12 // | | 13 // | This program is distributed in the hope that it will be useful, | 14 // | but WITHOUT ANY WARRANTY; without even the implied warranty of | 15 // | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 16 // | GNU General Public License for more details. | 17 // | | 18 // | You should have received a copy of the GNU General Public License | 19 // | along with this program; if not, write to: | 20 // | | 21 // | Free Software Foundation, Inc. | 22 // | 59 Temple Place - Suite 330 | 23 // | Boston, MA 02111-1307, USA. | 24 // +----------------------------------------------------------------------+ 25 // | Authors: João Prado Maia <jpm@mysql.com> | 26 // +----------------------------------------------------------------------+ 27 // 28 // @(#) $Id: class.auth.php 3394 2007-11-04 08:33:06Z balsdorf $ 29 // 30 31 require_once (APP_INC_PATH . "class.error_handler.php"); 32 require_once (APP_INC_PATH . "class.project.php"); 33 require_once (APP_INC_PATH . "class.user.php"); 34 require_once (APP_INC_PATH . "class.customer.php"); 35 require_once (APP_INC_PATH . "class.date.php"); 36 require_once(APP_CONFIG_PATH . "private_key.php"); 37 38 /** 39 * Class to handle authentication issues. 40 * 41 * @version 1.0 42 * @author João Prado Maia <jpm@mysql.com> 43 */ 44 class Auth 45 { 46 /** 47 * Method used to save the login information into a log file. It will be 48 * useful for administrative purposes, so we know which customers were able 49 * to login. 50 * 51 * @access public 52 * @param string $email The email associated with the user 53 * @param string $type Whether it was a successful login or not 54 * @param string $extra The reason for not being a successful login 55 */ 56 function saveLoginAttempt($email, $type, $extra = false) 57 { 58 $msg = Date_API::getCurrentDateGMT() . " - Login attempt by '$email' was "; 59 if ($type == 'success') { 60 $msg .= "successful.\n"; 61 } else { 62 $msg .= "not successful because of '$extra'.\n"; 63 } 64 $fp = @fopen(APP_LOGIN_LOG, "a"); 65 @fwrite($fp, $msg); 66 @fclose($fp); 67 } 68 69 70 /** 71 * Method used to get the requested URI for the 'current' page the user is 72 * trying to access. This is used to get the appropriate URL and save it 73 * if the user does not have the login cookie. 74 * 75 * @access public 76 * @return string The requested URI for the current page 77 */ 78 function getRequestedURL() 79 { 80 return urlencode($_SERVER["REQUEST_URI"]); 81 } 82 83 84 /** 85 * Method used to check for the appropriate authentication for a specific 86 * page. It will check for the cookie name provided and redirect the user 87 * to another page if needed. 88 * 89 * @access public 90 * @param string $cookie_name The name of the cookie to check for 91 * @param string $failed_url The URL to redirect to if the user is not authenticated 92 * @param boolean $is_popup Flag to tell the function if the current page is a popup window or not 93 * @return void 94 */ 95 function checkAuthentication($cookie_name, $failed_url = NULL, $is_popup = false) 96 { 97 if ($failed_url == NULL) { 98 $failed_url = APP_RELATIVE_URL . "index.php?err=5"; 99 } 100 $failed_url .= "&url=" . Auth::getRequestedURL(); 101 if (!isset($_COOKIE[$cookie_name])) { 102 Auth::redirect($failed_url, $is_popup); 103 } 104 $cookie = $_COOKIE[$cookie_name]; 105 $cookie = unserialize(base64_decode($cookie)); 106 if (!Auth::isValidCookie($cookie)) { 107 Auth::removeCookie($cookie_name); 108 Auth::redirect($failed_url, $is_popup); 109 } 110 if (Auth::isPendingUser($cookie["email"])) { 111 Auth::removeCookie($cookie_name); 112 Auth::redirect(APP_RELATIVE_URL . "index.php?err=9", $is_popup); 113 } 114 if (!Auth::isActiveUser($cookie["email"])) { 115 Auth::removeCookie($cookie_name); 116 Auth::redirect(APP_RELATIVE_URL . "index.php?err=7", $is_popup); 117 } 118 119 $usr_id = Auth::getUserID(); 120 121 // check the session 122 Session::verify($usr_id); 123 124 if (!defined('SKIP_LANGUAGE_INIT')) { 125 Language::setPreference(); 126 } 127 128 // check whether the project selection is set or not 129 $prj_id = Auth::getCurrentProject(); 130 if (empty($prj_id)) { 131 // redirect to select project page 132 Auth::redirect(APP_RELATIVE_URL . "select_project.php?url=" . Auth::getRequestedURL(), $is_popup); 133 } 134 // check the expiration date for a 'Customer' type user 135 $customer_id = User::getCustomerID($usr_id); 136 $contact_id = User::getCustomerContactID($usr_id); 137 if ((!empty($customer_id)) && ($customer_id != -1) && 138 (!empty($contact_id)) && (Customer::hasCustomerIntegration($prj_id))) { 139 140 Customer::authenticateCustomer($prj_id, $customer_id, $contact_id); 141 } 142 143 // auto switch project 144 if (isset($_GET['switch_prj_id'])) { 145 Auth::setCurrentProject($_GET['switch_prj_id'], false); 146 Auth::redirect($_SERVER['PHP_SELF'] . '?' . str_replace("switch_prj_id=" . $_GET['switch_prj_id'], "", $_SERVER['QUERY_STRING'])); 147 } 148 149 // if the current session is still valid, then renew the expiration 150 Auth::createLoginCookie($cookie_name, $cookie['email']); 151 // renew the project cookie as well 152 $prj_cookie = Auth::getCookieInfo(APP_PROJECT_COOKIE); 153 Auth::setCurrentProject($prj_id, $prj_cookie["remember"]); 154 } 155 156 157 /** 158 * Method to check whether an user is pending its confirmation 159 * or not. 160 * 161 * @access public 162 * @param string $email The email address to be checked 163 * @return boolean 164 */ 165 function isPendingUser($email) 166 { 167 $status = User::getStatusByEmail($email); 168 if ($status != 'pending') { 169 return false; 170 } else { 171 return true; 172 } 173 } 174 175 176 /** 177 * Method to check whether an user is active or not. 178 * 179 * @access public 180 * @param string $email The email address to be checked 181 * @return boolean 182 */ 183 function isActiveUser($email) 184 { 185 $status = User::getStatusByEmail($email); 186 if ($status != 'active') { 187 return false; 188 } else { 189 return true; 190 } 191 } 192 193 194 /** 195 * Method to check if the user has cookie support enabled in his browser or 196 * not. 197 * 198 * @access public 199 * @param string $cookie_name The name of the cookie to check for 200 * @return boolean 201 */ 202 function hasCookieSupport($cookie_name) 203 { 204 if (@!in_array($cookie_name, array_keys($_COOKIE))) { 205 return false; 206 } else { 207 return true; 208 } 209 } 210 211 212 /** 213 * Method to check if the user has a valid cookie. 214 * 215 * @access public 216 * @param string $cookie_name The name of the cookie to check for 217 * @return boolean 218 */ 219 function hasValidCookie($cookie_name) 220 { 221 $cookie = @$_COOKIE[$cookie_name]; 222 $cookie = unserialize(base64_decode($cookie)); 223 if (!Auth::isValidCookie($cookie)) { 224 return false; 225 } else { 226 return true; 227 } 228 } 229 230 231 /** 232 * Method used to get the unserialized contents of the specified cookie 233 * name. 234 * 235 * @access public 236 * @param string $cookie_name The name of the cookie to check for 237 * @return array The unserialized contents of the cookie 238 */ 239 function getCookieInfo($cookie_name) 240 { 241 $cookie = @$_COOKIE[$cookie_name]; 242 return unserialize(base64_decode($cookie)); 243 } 244 245 246 /** 247 * Method used to check whether a cookie is valid or not. 248 * 249 * @access public 250 * @param array $cookie The unserialized contents of the cookie 251 * @return boolean 252 */ 253 function isValidCookie($cookie) 254 { 255 if ((empty($cookie["email"])) || (empty($cookie["hash"])) || 256 ($cookie["hash"] != md5($GLOBALS["private_key"] . md5($cookie["login_time"]) . $cookie["email"]))) { 257 return false; 258 } else { 259 $usr_id = User::getUserIDByEmail(@$cookie["email"]); 260 if (empty($usr_id)) { 261 return false; 262 } else { 263 return true; 264 } 265 } 266 } 267 268 269 /** 270 * Method used to create the login cookie in the user's machine. 271 * 272 * @access public 273 * @param string $cookie_name The cookie name to be created 274 * @param string $email The email address to be stored in the cookie 275 * @return void 276 */ 277 function createLoginCookie($cookie_name, $email) 278 { 279 $time = time(); 280 $cookie = array( 281 "email" => $email, 282 "login_time" => $time, 283 "hash" => md5($GLOBALS["private_key"] . md5($time) . $email), 284 ); 285 $cookie = base64_encode(serialize($cookie)); 286 Auth::setCookie($cookie_name, $cookie, APP_COOKIE_EXPIRE); 287 } 288 289 290 /** 291 * Method used to redirect people to another URL. 292 * 293 * @access public 294 * @param string $new_url The URL the user should be redirected to 295 * @param boolean $is_popup Whether the current window is a popup or not 296 * @return void 297 */ 298 function redirect($new_url, $is_popup = false) 299 { 300 if ($is_popup) { 301 $html = '<script language="JavaScript"> 302 <!-- 303 if (window.opener) { 304 window.opener.location.href = "' . $new_url . '"; 305 window.close(); 306 } else { 307 location.href = "' . $new_url . '"; 308 } 309 //--> 310 </script>'; 311 echo $html; 312 exit; 313 } else { 314 // IIS 5 has problems with "Location" header so don't use it under IIS 315 if (strstr($_SERVER['SERVER_SOFTWARE'], 'IIS')) { 316 // IIS 317 header("Refresh: 0; URL=$new_url"); 318 } else { 319 // all servers that work correctly 320 header("Location: $new_url"); 321 } 322 exit; 323 } 324 } 325 326 327 /** 328 * Method used to remove a cookie from the user's browser. 329 * 330 * @access public 331 * @param string $cookie_name The name of the cookie that needs to be deleted 332 * @return void 333 */ 334 function removeCookie($cookie_name) 335 { 336 Auth::setCookie($cookie_name, '', time()-36000); 337 } 338 339 340 /** 341 * Checks whether an user exists or not in the database. 342 * 343 * @access public 344 * @param string $email The email address to check for 345 * @return boolean 346 */ 347 function userExists($email) 348 { 349 if (empty($email)) { 350 return false; 351 } else { 352 $stmt = "SELECT 353 usr_email 354 FROM 355 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "user 356 WHERE 357 usr_email='" . Misc::escapeString($email) . "'"; 358 $info = $GLOBALS["db_api"]->dbh->getOne($stmt); 359 if (PEAR::isError($info)) { 360 Error_Handler::logError(array($info->getMessage(), $info->getDebugInfo()), __FILE__, __LINE__); 361 return false; 362 } elseif (empty($info)) { 363 return false; 364 } else { 365 return true; 366 } 367 } 368 } 369 370 371 /** 372 * Checks whether the provided password match against the email 373 * address provided. 374 * 375 * @access public 376 * @param string $email The email address to check for 377 * @param string $password The password of the user to check for 378 * @return boolean 379 */ 380 function isCorrectPassword($email, $password) 381 { 382 $stmt = "SELECT 383 usr_password 384 FROM 385 " . APP_DEFAULT_DB . "." . APP_TABLE_PREFIX . "user 386 WHERE 387 usr_email='" . Misc::escapeString($email) . "' AND 388 usr_id != " . APP_SYSTEM_USER_ID; 389 $passwd = $GLOBALS["db_api"]->dbh->getOne($stmt); 390 if (PEAR::isError($passwd)) { 391 Error_Handler::logError(array($passwd->getMessage(), $passwd->getDebugInfo()), __FILE__, __LINE__); 392 return false; 393 } else { 394 if ($passwd != Auth::hashPassword($password)) { 395 return false; 396 } else { 397 return true; 398 } 399 } 400 } 401 402 403 /** 404 * Gets the current user ID. 405 * 406 * @access public 407 * @return integer The ID of the user 408 */ 409 function getUserID() 410 { 411 $info = Auth::getCookieInfo(APP_COOKIE); 412 if (empty($info)) { 413 return ''; 414 } else { 415 return User::getUserIDByEmail($info["email"]); 416 } 417 } 418 419 420 /** 421 * Gets the current selected project from the project cookie. 422 * 423 * @access public 424 * @return integer The project ID 425 */ 426 function getCurrentProject() 427 { 428 $cookie = Auth::getCookieInfo(APP_PROJECT_COOKIE); 429 if (empty($cookie)) { 430 return ""; 431 } 432 $usr_id = Auth::getUserID(); 433 $projects = Project::getAssocList($usr_id); 434 if ($usr_id == APP_SYSTEM_USER_ID) { 435 return isset($cookie['prj_id']) ? (int )$cookie['prj_id'] : null; 436 } 437 if (!in_array($cookie["prj_id"], array_keys($projects))) { 438 Auth::redirect(APP_RELATIVE_URL . "select_project.php?err=1"); 439 } 440 return $cookie["prj_id"]; 441 } 442 443 444 /** 445 * Gets the current project name from the user's project cookie. 446 * 447 * @access public 448 * @return string The current project name 449 */ 450 function getCurrentProjectName() 451 { 452 $proj_id = Auth::getCurrentProject(); 453 if (!empty($proj_id)) { 454 return Project::getName($proj_id); 455 } 456 } 457 458 459 /** 460 * Gets the current role in the current project. 461 * 462 * @access public 463 * @return integer The current role ID 464 */ 465 function getCurrentRole() 466 { 467 $prj_id = Auth::getCurrentProject(); 468 $usr_id = Auth::getUserID(); 469 if ((!empty($prj_id)) && (!empty($usr_id))) { 470 return User::getRoleByUser($usr_id, $prj_id); 471 } else { 472 return 1; 473 } 474 } 475 476 477 /** 478 * Sets the current selected project for the user session. 479 * 480 * @access public 481 * @param integer $project The project ID 482 * @param integer $remember Whether to automatically remember the setting or not 483 * @return void 484 */ 485 function setCurrentProject($project, $remember) 486 { 487 $cookie = array( 488 "prj_id" => $project, 489 "remember" => $remember 490 ); 491 $cookie = base64_encode(serialize($cookie)); 492 Auth::setCookie(APP_PROJECT_COOKIE, $cookie, APP_PROJECT_COOKIE_EXPIRE); 493 Auth::createFakeCookie(Auth::getUserID(), $project); 494 } 495 496 497 /** 498 * Creates a fake cookie so processes not run from a browser can access current user and project 499 * 500 * @param integer $usr_id The ID of the user. 501 * @param integer $prj_id The ID of the project. 502 */ 503 function createFakeCookie($usr_id, $project = false) 504 { 505 require_once(APP_CONFIG_PATH . "private_key.php"); 506 507 $user_details = User::getDetails($usr_id); 508 509 $time = time(); 510 $cookie = array( 511 "email" => $user_details['usr_email'], 512 "login_time" => $time, 513 "hash" => md5($GLOBALS["private_key"] . md5($time) . $user_details['usr_email']), 514 ); 515 $_COOKIE[APP_COOKIE] = base64_encode(serialize($cookie)); 516 if ($project) { 517 $cookie = array( 518 "prj_id" => $project, 519 "remember" => false 520 ); 521 } 522 $_COOKIE[APP_PROJECT_COOKIE] = base64_encode(serialize($cookie)); 523 } 524 525 526 /** 527 * Hashes the password according to APP_HASH_TYPE constant 528 * 529 * @access public 530 * @param string $password The plain text password 531 * @return string The hashed password 532 */ 533 function hashPassword($password) 534 { 535 if (APP_HASH_TYPE == 'MD5-64') { 536 return base64_encode(pack('H*',md5($password))); 537 } else { 538 // default to md5 539 return md5($password); 540 } 541 } 542 543 544 /** 545 * Sets a cookie in the browser 546 * 547 * @param string $name The name of the cookie 548 * @param string $value The value of the cookie 549 * @param string $expiration The expiration data of the cookie 550 */ 551 function setCookie($name, $value, $expiration) 552 { 553 if (is_null(APP_COOKIE_DOMAIN)) { 554 555 setcookie($name, $value, $expiration, APP_COOKIE_URL); 556 } else { 557 setcookie($name, $value, $expiration, APP_COOKIE_URL, APP_COOKIE_DOMAIN); 558 } 559 } 560 561 } 562 563 // benchmarking the included file (aka setup time) 564 if (APP_BENCHMARK) { 565 $GLOBALS['bench']->setMarker('Included Auth Class'); 566 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Dec 19 21:21:33 2007 | Cross-referenced by PHPXref 0.7 |