| [ Index ] |
|
Code source de Mantis 1.1.0rc3 |
1 <?php 2 # Mantis - a php based bugtracking system 3 4 # Copyright (C) 2000 - 2002 Kenzaburo Ito - kenito@300baud.org 5 # Copyright (C) 2002 - 2007 Mantis Team - mantisbt-dev@lists.sourceforge.net 6 7 # Mantis is free software: you can redistribute it and/or modify 8 # it under the terms of the GNU General Public License as published by 9 # the Free Software Foundation, either version 2 of the License, or 10 # (at your option) any later version. 11 # 12 # Mantis is distributed in the hope that it will be useful, 13 # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 # GNU General Public License for more details. 16 # 17 # You should have received a copy of the GNU General Public License 18 # along with Mantis. If not, see <http://www.gnu.org/licenses/>. 19 20 # -------------------------------------------------------- 21 # $Id: user_api.php,v 1.113.2.3 2007-10-14 22:35:35 giallu Exp $ 22 # -------------------------------------------------------- 23 24 $t_core_dir = dirname( __FILE__ ).DIRECTORY_SEPARATOR; 25 26 require_once ( $t_core_dir . 'email_api.php' ); 27 require_once ( $t_core_dir . 'ldap_api.php' ); 28 29 ### User API ### 30 31 #=================================== 32 # Caching 33 #=================================== 34 35 ######################################### 36 # SECURITY NOTE: cache globals are initialized here to prevent them 37 # being spoofed if register_globals is turned on 38 39 $g_cache_user = array(); 40 41 # -------------------- 42 # Cache a user row if necessary and return the cached copy 43 # If the second parameter is true (default), trigger an error 44 # if the user can't be found. If the second parameter is 45 # false, return false if the user can't be found. 46 function user_cache_row( $p_user_id, $p_trigger_errors=true) { 47 global $g_cache_user; 48 49 $c_user_id = db_prepare_int( $p_user_id ); 50 51 if ( isset ( $g_cache_user[$c_user_id] ) ) { 52 return $g_cache_user[$c_user_id]; 53 } 54 55 $t_user_table = config_get( 'mantis_user_table' ); 56 57 $query = "SELECT * 58 FROM $t_user_table 59 WHERE id='$c_user_id'"; 60 $result = db_query( $query ); 61 62 if ( 0 == db_num_rows( $result ) ) { 63 $g_cache_user[$c_user_id] = false; 64 65 if ( $p_trigger_errors ) { 66 trigger_error( ERROR_USER_NOT_FOUND, ERROR ); 67 } 68 69 return false; 70 } 71 72 $row = db_fetch_array( $result ); 73 74 $g_cache_user[$c_user_id] = $row; 75 76 return $row; 77 } 78 79 # -------------------- 80 # Clear the user cache (or just the given id if specified) 81 function user_clear_cache( $p_user_id = null ) { 82 global $g_cache_user; 83 84 if ( null === $p_user_id ) { 85 $g_cache_user = array(); 86 } else { 87 $c_user_id = db_prepare_int( $p_user_id ); 88 unset( $g_cache_user[$c_user_id] ); 89 } 90 91 return true; 92 } 93 94 #=================================== 95 # Boolean queries and ensures 96 #=================================== 97 98 # -------------------- 99 # check to see if user exists by id 100 # return true if it does, false otherwise 101 # 102 # Use user_cache_row() to benefit from caching if called multiple times 103 # and because if the user does exist the data may well be wanted 104 function user_exists( $p_user_id ) { 105 $row = user_cache_row( $p_user_id, false ); 106 107 if ( false === $row ) { 108 return false; 109 } else { 110 return true; 111 } 112 } 113 114 # -------------------- 115 # check to see if project exists by id 116 # if it doesn't exist then error 117 # otherwise let execution continue undisturbed 118 function user_ensure_exists( $p_user_id ) { 119 if ( !user_exists( $p_user_id ) ) { 120 trigger_error( ERROR_USER_NOT_FOUND, ERROR ); 121 } 122 } 123 124 # -------------------- 125 # return true if the username is unique, false if there is already a user 126 # with that username 127 function user_is_name_unique( $p_username ) { 128 $c_username = db_prepare_string( $p_username ); 129 130 $t_user_table = config_get( 'mantis_user_table' ); 131 132 $query = "SELECT username 133 FROM $t_user_table 134 WHERE username='$c_username'"; 135 $result = db_query( $query, 1 ); 136 137 if ( db_num_rows( $result ) > 0 ) { 138 return false; 139 } else { 140 return true; 141 } 142 } 143 144 # -------------------- 145 # Check if the username is unique and trigger an ERROR if it isn't 146 function user_ensure_name_unique( $p_username ) { 147 if ( !user_is_name_unique( $p_username ) ) { 148 trigger_error( ERROR_USER_NAME_NOT_UNIQUE, ERROR ); 149 } 150 } 151 152 # -------------------- 153 # Check if the realname is a valid username (does not account for uniqueness) 154 # Return 0 if it is invalid, The number of matches + 1 155 function user_is_realname_unique( $p_username, $p_realname ) { 156 if ( is_blank( $p_realname ) ) { # don't bother checking if realname is blank 157 return 1; 158 } 159 160 $c_realname = db_prepare_string( $p_realname ); 161 # allow realname to match username 162 $t_count = 0; 163 if ( $p_realname <> $p_username ) { 164 # check realname does not match an existing username 165 if ( user_get_id_by_name( $p_realname ) ) { 166 return 0; 167 } 168 169 # check to see if the realname is unique 170 $t_user_table = config_get( 'mantis_user_table' ); 171 $query = "SELECT id 172 FROM $t_user_table 173 WHERE realname='$c_realname'"; 174 $result = db_query( $query ); 175 $t_count = db_num_rows( $result ); 176 if ( $t_count > 0 ) { 177 # set flags for non-unique realnames 178 if ( config_get( 'differentiate_duplicates' ) ) { 179 user_set_field( $t_user_id, 'duplicate_realname', ON ); 180 for ( $i=0 ; $i < $t_count ; $i++ ) { 181 $t_id = db_result( $result, $i ); 182 user_set_field( $t_id, 'duplicate_realname', ON ); 183 } 184 } 185 } 186 } 187 return $t_count + 1; 188 } 189 190 # -------------------- 191 # Check if the realname is a unique 192 # Trigger an error if the username is not valid 193 function user_ensure_realname_unique( $p_username, $p_realname ) { 194 if ( 1 > user_is_realname_unique( $p_username, $p_realname ) ) { 195 trigger_error( ERROR_USER_REAL_MATCH_USER, ERROR ); 196 } 197 } 198 199 # -------------------- 200 # Check if the realname is a valid (does not account for uniqueness) 201 # true: valid, false: not valid 202 function user_is_realname_valid( $p_realname ) { 203 return ( !string_contains_scripting_chars( $p_realname ) ); 204 } 205 206 # -------------------- 207 # Check if the realname is a valid (does not account for uniqueness), if not, trigger an error 208 function user_ensure_realname_valid( $p_realname ) { 209 if ( !user_is_realname_valid( $p_realname ) ) { 210 trigger_error( ERROR_USER_REAL_NAME_INVALID, ERROR ); 211 } 212 } 213 214 # -------------------- 215 # Check if the username is a valid username (does not account for uniqueness) 216 # realname can match 217 # Return true if it is, false otherwise 218 function user_is_name_valid( $p_username ) { 219 # The DB field is only 32 characters 220 if ( strlen( $p_username ) > 32 ) { 221 return false; 222 } 223 224 # Only allow a basic set of characters 225 if ( 0 == preg_match( config_get( 'user_login_valid_regex' ), $p_username ) ) { 226 return false; 227 } 228 229 # We have a valid username 230 return true; 231 } 232 233 # -------------------- 234 # Check if the username is a valid username (does not account for uniqueness) 235 # Trigger an error if the username is not valid 236 function user_ensure_name_valid( $p_username ) { 237 if ( !user_is_name_valid( $p_username ) ) { 238 trigger_error( ERROR_USER_NAME_INVALID, ERROR ); 239 } 240 } 241 242 # -------------------- 243 # return whether user is monitoring bug for the user id and bug id 244 function user_is_monitoring_bug( $p_user_id, $p_bug_id ) { 245 $c_user_id = db_prepare_int( $p_user_id ); 246 $c_bug_id = db_prepare_int( $p_bug_id ); 247 248 $t_bug_monitor_table = config_get( 'mantis_bug_monitor_table' ); 249 250 $query = "SELECT COUNT(*) 251 FROM $t_bug_monitor_table 252 WHERE user_id='$c_user_id' AND bug_id='$c_bug_id'"; 253 254 $result = db_query( $query ); 255 256 if ( 0 == db_result( $result ) ) { 257 return false; 258 } else { 259 return true; 260 } 261 } 262 263 # -------------------- 264 # return true if the user has access of ADMINISTRATOR or higher, false otherwise 265 function user_is_administrator( $p_user_id ) { 266 $t_access_level = user_get_field( $p_user_id, 'access_level' ); 267 268 if ( $t_access_level >= ADMINISTRATOR ) { 269 return true; 270 } else { 271 return false; 272 } 273 } 274 275 # -------------------- 276 # return true is the user account is protected, false otherwise 277 function user_is_protected( $p_user_id ) { 278 if ( ON == user_get_field( $p_user_id, 'protected' ) ) { 279 return true; 280 } else { 281 return false; 282 } 283 } 284 285 # -------------------- 286 # Trigger an ERROR if the user account is protected 287 function user_ensure_unprotected( $p_user_id ) { 288 if ( user_is_protected( $p_user_id ) ) { 289 trigger_error( ERROR_PROTECTED_ACCOUNT, ERROR ); 290 } 291 } 292 293 # -------------------- 294 # return true is the user account is enabled, false otherwise 295 function user_is_enabled( $p_user_id ) { 296 if ( ON == user_get_field( $p_user_id, 'enabled' ) ) { 297 return true; 298 } else { 299 return false; 300 } 301 } 302 303 # -------------------- 304 # count the number of users at or greater than a specific level 305 function user_count_level( $p_level=ANYBODY ) { 306 $t_level = db_prepare_int( $p_level ); 307 $t_user_table = config_get( 'mantis_user_table' ); 308 $query = "SELECT COUNT(id) FROM $t_user_table WHERE access_level>=$t_level"; 309 $result = db_query( $query ); 310 311 # Get the list of connected users 312 $t_users = db_result( $result ); 313 314 return $t_users; 315 } 316 317 318 # -------------------- 319 # Return an array of user ids that are logged in. 320 # A user is considered logged in if the last visit timestamp is within the 321 # specified session duration. 322 # If the session duration is 0, then no users will be returned. 323 function user_get_logged_in_user_ids( $p_session_duration_in_minutes ) { 324 $t_session_duration_in_minutes = (integer)$p_session_duration_in_minutes; 325 326 # if session duration is 0, then there is no logged in users. 327 if ( $t_session_duration_in_minutes == 0 ) { 328 return array(); 329 } 330 331 # Generate timestamp 332 # @@@ The following code may not be portable accross DBMS. 333 $t_last_timestamp_threshold = mktime( date( "H" ), date( "i" ) -1 * $t_session_duration_in_minutes, date("s"), date("m"), date("d"), date("Y") ); 334 $c_last_timestamp_threshold = date( "Y-m-d H:i:s" , $t_last_timestamp_threshold ); 335 336 $t_user_table = config_get( 'mantis_user_table' ); 337 338 # Execute query 339 $query = "SELECT id FROM $t_user_table WHERE last_visit > '$c_last_timestamp_threshold'"; 340 $result = db_query( $query, 1 ); 341 342 # Get the list of connected users 343 $t_users_connected = array(); 344 while ( $row = db_fetch_array( $result ) ) { 345 $t_users_connected[] = $row['id']; 346 } 347 348 return $t_users_connected; 349 } 350 351 #=================================== 352 # Creation / Deletion / Updating 353 #=================================== 354 355 # -------------------- 356 # Create a user. 357 # returns false if error, the generated cookie string if ok 358 function user_create( $p_username, $p_password, $p_email='', $p_access_level=null, $p_protected=false, $p_enabled=true, $p_realname='' ) { 359 if ( null === $p_access_level ) { 360 $p_access_level = config_get( 'default_new_account_access_level'); 361 } 362 363 $t_password = auth_process_plain_password( $p_password ); 364 365 $c_username = db_prepare_string( $p_username ); 366 $c_realname = db_prepare_string( $p_realname ); 367 $c_password = db_prepare_string( $t_password ); 368 $c_email = db_prepare_string( $p_email ); 369 $c_access_level = db_prepare_int( $p_access_level ); 370 $c_protected = db_prepare_bool( $p_protected ); 371 $c_enabled = db_prepare_bool( $p_enabled ); 372 373 user_ensure_name_valid( $p_username ); 374 user_ensure_name_unique( $p_username ); 375 user_ensure_realname_valid( $p_realname ); 376 user_ensure_realname_unique( $p_username, $p_realname ); 377 email_ensure_valid( $p_email ); 378 379 $t_seed = $p_email . $p_username; 380 $t_cookie_string = auth_generate_unique_cookie_string( $t_seed ); 381 $t_user_table = config_get( 'mantis_user_table' ); 382 383 $query = "INSERT INTO $t_user_table 384 ( username, email, password, date_created, last_visit, 385 enabled, access_level, login_count, cookie_string, realname ) 386 VALUES 387 ( '$c_username', '$c_email', '$c_password', " . db_now() . "," . db_now() . ", 388 $c_enabled, $c_access_level, 0, '$t_cookie_string', '$c_realname')"; 389 db_query( $query ); 390 391 # Create preferences for the user 392 $t_user_id = db_insert_id( $t_user_table ); 393 user_pref_set_default( $t_user_id ); 394 395 # Users are added with protected set to FALSE in order to be able to update 396 # preferences. Now set the real value of protected. 397 if ( $c_protected ) { 398 user_set_field( $t_user_id, 'protected', 1 ); 399 } 400 401 # Send notification email 402 if ( !is_blank( $p_email ) ) { 403 $t_confirm_hash = auth_generate_confirm_hash( $t_user_id ); 404 email_signup( $t_user_id, $p_password, $t_confirm_hash ); 405 } 406 407 return $t_cookie_string; 408 } 409 410 # -------------------- 411 # Signup a user. 412 # If the use_ldap_email config option is on then tries to find email using 413 # ldap. $p_email may be empty, but the user wont get any emails. 414 # returns false if error, the generated cookie string if ok 415 function user_signup( $p_username, $p_email=null ) { 416 if ( null === $p_email ) { 417 $p_email = ''; 418 419 # @@@ I think the ldap_email stuff is a bit borked 420 # Where is it being set? When is it being used? 421 # Shouldn't we override an email that is passed in here? 422 # If the user doesn't exist in ldap, is the account created? 423 # If so, there password won't get set anywhere... (etc) 424 # RJF: I was going to check for the existence of an LDAP email. 425 # however, since we can't create an LDAP account at the moment, 426 # and we don't know the user password in advance, we may not be able 427 # to retrieve it anyway. 428 # I'll re-enable this once a plan has been properly formulated for LDAP 429 # account management and creation. 430 431 /* $t_email = ''; 432 if ( ON == config_get( 'use_ldap_email' ) ) { 433 $t_email = ldap_email_from_username( $p_username ); 434 } 435 436 if ( !is_blank( $t_email ) ) { 437 $p_email = $t_email; 438 } 439 */ 440 } 441 442 $p_email = trim( $p_email ); 443 444 $t_seed = $p_email . $p_username; 445 # Create random password 446 $t_password = auth_generate_random_password( $t_seed ); 447 448 return user_create( $p_username, $t_password, $p_email ); 449 } 450 451 # -------------------- 452 # delete project-specific user access levels. 453 # returns true when successfully deleted 454 function user_delete_project_specific_access_levels( $p_user_id ) { 455 $c_user_id = db_prepare_int($p_user_id); 456 457 user_ensure_unprotected( $p_user_id ); 458 459 $t_project_user_list_table = config_get('mantis_project_user_list_table'); 460 461 $query = "DELETE FROM $t_project_user_list_table 462 WHERE user_id='$c_user_id'"; 463 db_query( $query ); 464 465 user_clear_cache( $p_user_id ); 466 467 return true; 468 } 469 470 # -------------------- 471 # delete profiles for the specified user 472 # returns true when successfully deleted 473 function user_delete_profiles( $p_user_id ) { 474 $c_user_id = db_prepare_int($p_user_id); 475 476 user_ensure_unprotected( $p_user_id ); 477 478 $t_user_profile_table = config_get('mantis_user_profile_table'); 479 480 # Remove associated profiles 481 $query = "DELETE FROM $t_user_profile_table 482 WHERE user_id='$c_user_id'"; 483 db_query( $query ); 484 485 user_clear_cache( $p_user_id ); 486 487 return true; 488 } 489 490 # -------------------- 491 # delete a user account (account, profiles, preferences, project-specific access levels) 492 # returns true when the account was successfully deleted 493 function user_delete( $p_user_id ) { 494 $c_user_id = db_prepare_int($p_user_id); 495 $t_user_table = config_get('mantis_user_table'); 496 497 user_ensure_unprotected( $p_user_id ); 498 499 # Remove associated profiles 500 user_delete_profiles( $p_user_id ); 501 502 # Remove associated preferences 503 user_pref_delete_all( $p_user_id ); 504 505 # Remove project specific access levels 506 user_delete_project_specific_access_levels( $p_user_id ); 507 508 #unset non-unique realname flags if necessary 509 if ( config_get( 'differentiate_duplicates' ) ) { 510 $c_realname = db_prepare_string( user_get_field( $p_user_id, 'realname' ) ); 511 $query = "SELECT id 512 FROM $t_user_table 513 WHERE realname='$c_realname'"; 514 $result = db_query( $query ); 515 $t_count = db_num_rows( $result ); 516 517 if ( $t_count == 2 ) { 518 # unset flags if there are now only 2 unique names 519 for ( $i=0 ; $i < $t_count ; $i++ ) { 520 $t_user_id = db_result( $result, $i ); 521 user_set_field( $t_user_id, 'duplicate_realname', OFF ); 522 } 523 } 524 } 525 526 user_clear_cache( $p_user_id ); 527 528 # Remove account 529 $query = "DELETE FROM $t_user_table 530 WHERE id='$c_user_id'"; 531 db_query( $query ); 532 533 return true; 534 } 535 536 #=================================== 537 # Data Access 538 #=================================== 539 540 # -------------------- 541 # get a user id from a username 542 # return false if the username does not exist 543 function user_get_id_by_name( $p_username ) { 544 $c_username = db_prepare_string( $p_username ); 545 $t_user_table = config_get( 'mantis_user_table' ); 546 547 $query = "SELECT id 548 FROM $t_user_table 549 WHERE username='$c_username'"; 550 $result = db_query( $query ); 551 552 if ( 0 == db_num_rows( $result ) ) { 553 return false; 554 } else { 555 return db_result( $result ); 556 } 557 } 558 559 # -------------------- 560 # return all data associated with a particular user name 561 # return false if the username does not exist 562 function user_get_row_by_name( $p_username ) { 563 $t_user_id = user_get_id_by_name( $p_username ); 564 565 if ( false === $t_user_id ) { 566 return false; 567 } 568 569 $row = user_get_row( $t_user_id ); 570 571 return $row; 572 } 573 574 # -------------------- 575 # return a user row 576 function user_get_row( $p_user_id ) { 577 return user_cache_row( $p_user_id ); 578 } 579 580 # -------------------- 581 # return the specified user field for the user id 582 function user_get_field( $p_user_id, $p_field_name ) { 583 if ( NO_USER == $p_user_id ) { 584 trigger_error( 'user_get_field() for NO_USER', WARNING ); 585 return "@null@"; 586 } 587 588 $row = user_get_row( $p_user_id ); 589 590 if ( isset( $row[$p_field_name] ) ) { 591 return $row[$p_field_name]; 592 } else { 593 error_parameters( $p_field_name ); 594 trigger_error( ERROR_DB_FIELD_NOT_FOUND, WARNING ); 595 return ''; 596 } 597 } 598 599 # -------------------- 600 # lookup the user's email in LDAP or the db as appropriate 601 function user_get_email( $p_user_id ) { 602 $t_email = ''; 603 if ( ON == config_get( 'use_ldap_email' ) ) { 604 $t_email = ldap_email( $p_user_id ); 605 } 606 if ( is_blank( $t_email ) ) { 607 $t_email = user_get_field( $p_user_id, 'email' ); 608 } 609 return $t_email; 610 } 611 612 # -------------------- 613 # lookup the user's realname 614 function user_get_realname( $p_user_id ) { 615 $t_realname = user_get_field( $p_user_id, 'realname' ); 616 617 return $t_realname; 618 } 619 620 # -------------------- 621 # return the username or a string "user<id>" if the user does not exist 622 # if show_realname is set, replace the name with a realname (if set) 623 function user_get_name( $p_user_id ) { 624 $row = user_cache_row( $p_user_id, false ); 625 626 if ( false == $row ) { 627 return lang_get( 'prefix_for_deleted_users' ) . (int)$p_user_id; 628 } else { 629 if ( ON == config_get( 'show_realname' ) ) { 630 if ( is_blank( $row['realname'] ) ) { 631 return $row['username']; 632 } else { 633 if ( isset( $row['duplicate_realname'] ) && ( ON == $row['duplicate_realname'] ) ) { 634 return $row['realname'] . ' (' . $row['username'] . ')'; 635 } else { 636 return $row['realname']; 637 } 638 } 639 } else { 640 return $row['username']; 641 } 642 } 643 } 644 645 646 /** 647 * Return the user avatar image URL 648 * in this first implementation, only gravatar.com avatars are supported 649 * @return array|bool an array( URL, width, height ) or false when the given user has no avatar 650 */ 651 function user_get_avatar( $p_user_id ) { 652 $t_email = strtolower( user_get_email( $p_user_id ) ); 653 if ( is_blank( $t_email ) ) { 654 $t_result = false; 655 } else { 656 $t_default_image = config_get( 'default_avatar' ); 657 $t_size = 80; 658 $t_avatar_url = "http://www.gravatar.com/avatar.php?gravatar_id=" . md5( $t_email ) . 659 "&default=" . urlencode( $t_default_image ) . 660 "&size=" . $t_size . 661 "&rating=G"; 662 $t_result = array( $t_avatar_url, $t_size, $t_size ); 663 } 664 665 return $t_result; 666 } 667 668 669 # -------------------- 670 # return the user's access level 671 # account for private project and the project user lists 672 function user_get_access_level( $p_user_id, $p_project_id = ALL_PROJECTS ) { 673 $t_access_level = user_get_field( $p_user_id, 'access_level' ); 674 675 if ( $t_access_level >= ADMINISTRATOR ) { 676 return $t_access_level; 677 } 678 679 $t_project_access_level = project_get_local_user_access_level( $p_project_id, $p_user_id ); 680 681 if ( false === $t_project_access_level ) { 682 return $t_access_level; 683 } else { 684 return $t_project_access_level; 685 } 686 } 687 688 $g_user_accessible_projects_cache = null; 689 690 # -------------------- 691 # retun an array of project IDs to which the user has access 692 function user_get_accessible_projects( $p_user_id, $p_show_disabled = false ) { 693 global $g_user_accessible_projects_cache; 694 695 if ( null !== $g_user_accessible_projects_cache 696 && auth_get_current_user_id() == $p_user_id 697 && false == $p_show_disabled ) { 698 return $g_user_accessible_projects_cache; 699 } 700 701 if ( access_has_global_level( config_get( 'private_project_threshold' ), $p_user_id ) ) { 702 $t_projects = project_hierarchy_get_subprojects( ALL_PROJECTS, $p_show_disabled ); 703 } else { 704 $c_user_id = db_prepare_int( $p_user_id ); 705 706 $t_project_table = config_get( 'mantis_project_table' ); 707 $t_project_user_list_table = config_get( 'mantis_project_user_list_table' ); 708 $t_project_hierarchy_table = config_get( 'mantis_project_hierarchy_table' ); 709 710 $t_public = VS_PUBLIC; 711 $t_private = VS_PRIVATE; 712 $t_enabled_clause = $p_show_disabled ? '' : 'p.enabled = 1 AND'; 713 714 $query = "SELECT p.id, p.name, ph.parent_id 715 FROM $t_project_table p 716 LEFT JOIN $t_project_user_list_table u 717 ON p.id=u.project_id AND u.user_id=$c_user_id 718 LEFT JOIN $t_project_hierarchy_table ph 719 ON ph.child_id = p.id 720 WHERE $t_enabled_clause 721 ( p.view_state='$t_public' 722 OR (p.view_state='$t_private' 723 AND 724 u.user_id='$c_user_id' ) 725 ) 726 ORDER BY p.name"; 727 728 $result = db_query( $query ); 729 $row_count = db_num_rows( $result ); 730 731 $t_projects = array(); 732 733 for ( $i=0 ; $i < $row_count ; $i++ ) { 734 $row = db_fetch_array( $result ); 735 736 $t_projects[ $row['id'] ] = ( $row['parent_id'] === NULL ) ? 0 : $row['parent_id']; 737 } 738 739 # prune out children where the parents are already listed. Make the list 740 # first, then prune to avoid pruning a parent before the child is found. 741 $t_prune = array(); 742 foreach ( $t_projects as $t_id => $t_parent ) { 743 if ( ( $t_parent !== 0 ) && isset( $t_projects[$t_parent] ) ) { 744 $t_prune[] = $t_id; 745 } 746 } 747 foreach ( $t_prune as $t_id ) { 748 unset( $t_projects[$t_id] ); 749 } 750 $t_projects = array_keys( $t_projects ); 751 } 752 753 if ( auth_get_current_user_id() == $p_user_id ) { 754 $g_user_accessible_projects_cache = $t_projects; 755 } 756 757 return $t_projects; 758 } 759 760 $g_user_accessible_subprojects_cache = null; 761 762 # -------------------- 763 # retun an array of subproject IDs of a certain project to which the user has access 764 function user_get_accessible_subprojects( $p_user_id, $p_project_id, $p_show_disabled = false ) { 765 global $g_user_accessible_subprojects_cache; 766 767 if ( null !== $g_user_accessible_subprojects_cache 768 && auth_get_current_user_id() == $p_user_id 769 && false == $p_show_disabled ) { 770 if ( isset( $g_user_accessible_subprojects_cache[ $p_project_id ] ) ) { 771 return $g_user_accessible_subprojects_cache[ $p_project_id ]; 772 } else { 773 return Array(); 774 } 775 } 776 777 $c_user_id = db_prepare_int( $p_user_id ); 778 $c_project_id = db_prepare_int( $p_project_id ); 779 780 $t_project_table = config_get( 'mantis_project_table' ); 781 $t_project_user_list_table = config_get( 'mantis_project_user_list_table' ); 782 $t_project_hierarchy_table = config_get( 'mantis_project_hierarchy_table' ); 783 784 $t_enabled_clause = $p_show_disabled ? '' : 'p.enabled = 1 AND'; 785 $t_public = VS_PUBLIC; 786 $t_private = VS_PRIVATE; 787 788 if ( access_has_global_level( config_get( 'private_project_threshold' ), $p_user_id ) ) { 789 $query = "SELECT DISTINCT p.id, p.name, ph.parent_id 790 FROM $t_project_table p 791 LEFT JOIN $t_project_hierarchy_table ph 792 ON ph.child_id = p.id 793 WHERE $t_enabled_clause 794 ph.parent_id IS NOT NULL 795 ORDER BY p.name"; 796 } else { 797 $query = "SELECT DISTINCT p.id, p.name, ph.parent_id 798 FROM $t_project_table p 799 LEFT JOIN $t_project_user_list_table u 800 ON p.id = u.project_id AND u.user_id='$c_user_id' 801 LEFT JOIN $t_project_hierarchy_table ph 802 ON ph.child_id = p.id 803 WHERE $t_enabled_clause 804 ph.parent_id IS NOT NULL AND 805 ( p.view_state='$t_public' 806 OR (p.view_state='$t_private' 807 AND 808 u.user_id='$c_user_id' ) 809 ) 810 ORDER BY p.name"; 811 } 812 813 $result = db_query( $query ); 814 $row_count = db_num_rows( $result ); 815 816 $t_projects = array(); 817 818 for ( $i=0 ; $i < $row_count ; $i++ ) { 819 $row = db_fetch_array( $result ); 820 821 if ( !isset( $t_projects[ $row['parent_id'] ] ) ) { 822 $t_projects[ $row['parent_id'] ] = array(); 823 } 824 825 array_push( $t_projects[ $row['parent_id'] ], $row['id'] ); 826 } 827 828 if ( auth_get_current_user_id() == $p_user_id ) { 829 $g_user_accessible_subprojects_cache = $t_projects; 830 } 831 832 if ( !isset( $t_projects[ $p_project_id ] ) ) { 833 $t_projects[ $p_project_id ] = array(); 834 } 835 836 return $t_projects[ $p_project_id ]; 837 } 838 839 # -------------------- 840 function user_get_all_accessible_subprojects( $p_user_id, $p_project_id ) { 841 # @@@ (thraxisp) Should all top level projects be a sub-project of ALL_PROJECTS implicitly? 842 # affects how news and some summaries are generated 843 $t_todo = user_get_accessible_subprojects( $p_user_id, $p_project_id ); 844 $t_subprojects = Array(); 845 846 while ( $t_todo ) { 847 $t_elem = array_shift( $t_todo ); 848 if ( !in_array( $t_elem, $t_subprojects ) ) { 849 array_push( $t_subprojects, $t_elem ); 850 $t_todo = array_merge( $t_todo, user_get_accessible_subprojects( $p_user_id, $t_elem ) ); 851 } 852 } 853 854 return $t_subprojects; 855 } 856 857 # -------------------- 858 # return the number of open assigned bugs to a user in a project 859 function user_get_assigned_open_bug_count( $p_user_id, $p_project_id=ALL_PROJECTS ) { 860 $c_user_id = db_prepare_int($p_user_id); 861 $c_project_id = db_prepare_int($p_project_id); 862 863 $t_bug_table = config_get('mantis_bug_table'); 864 865 $t_where_prj = helper_project_specific_where( $p_project_id, $p_user_id ) . " AND"; 866 867 $t_resolved = config_get('bug_resolved_status_threshold'); 868 869 $query = "SELECT COUNT(*) 870 FROM $t_bug_table 871 WHERE $t_where_prj 872 status<'$t_resolved' AND 873 handler_id='$c_user_id'"; 874 $result = db_query( $query ); 875 876 return db_result( $result ); 877 } 878 879 # -------------------- 880 # return the number of open reported bugs by a user in a project 881 function user_get_reported_open_bug_count( $p_user_id, $p_project_id=ALL_PROJECTS ) { 882 $c_user_id = db_prepare_int($p_user_id); 883 $c_project_id = db_prepare_int($p_project_id); 884 885 $t_bug_table = config_get('mantis_bug_table'); 886 887 $t_where_prj = helper_project_specific_where( $p_project_id, $p_user_id ) . " AND"; 888 889 $t_resolved = config_get('bug_resolved_status_threshold'); 890 891 $query = "SELECT COUNT(*) 892 FROM $t_bug_table 893 WHERE $t_where_prj 894 status<'$t_resolved' AND 895 reporter_id='$c_user_id'"; 896 $result = db_query( $query ); 897 898 return db_result( $result ); 899 } 900 901 # -------------------- 902 # return a profile row 903 function user_get_profile_row( $p_user_id, $p_profile_id ) { 904 $c_user_id = db_prepare_int( $p_user_id ); 905 $c_profile_id = db_prepare_int( $p_profile_id ); 906 907 $t_user_profile_table = config_get( 'mantis_user_profile_table' ); 908 909 $query = "SELECT * 910 FROM $t_user_profile_table 911 WHERE id='$c_profile_id' AND 912 user_id='$c_user_id'"; 913 $result = db_query( $query ); 914 915 if ( 0 == db_num_rows( $result ) ) { 916 trigger_error( ERROR_USER_PROFILE_NOT_FOUND, ERROR ); 917 } 918 919 $row = db_fetch_array( $result ); 920 921 return $row; 922 } 923 924 # -------------------- 925 # Get failed login attempts 926 function user_is_login_request_allowed( $p_user_id ) { 927 $t_max_failed_login_count = config_get( 'max_failed_login_count' ); 928 $t_failed_login_count = user_get_field( $p_user_id, 'failed_login_count' ); 929 return ( $t_failed_login_count < $t_max_failed_login_count 930 || OFF == $t_max_failed_login_count); 931 } 932 933 # -------------------- 934 # Get 'lost password' in progress attempts 935 function user_is_lost_password_request_allowed( $p_user_id ) { 936 if( OFF == config_get( 'lost_password_feature' ) ) { 937 return false; 938 } 939 $t_max_lost_password_in_progress_count = config_get( 'max_lost_password_in_progress_count' ); 940 $t_lost_password_in_progress_count = user_get_field( $p_user_id, 'lost_password_request_count' ); 941 return ( $t_lost_password_in_progress_count < $t_max_lost_password_in_progress_count 942 || OFF == $t_max_lost_password_in_progress_count ); 943 } 944 945 # -------------------- 946 # return the bug filter parameters for the specified user 947 function user_get_bug_filter( $p_user_id, $p_project_id = null ) { 948 if ( null === $p_project_id ) { 949 $t_project_id = helper_get_current_project(); 950 } else { 951 $t_project_id = $p_project_id; 952 } 953 954 $t_view_all_cookie_id = filter_db_get_project_current( $t_project_id, $p_user_id ); 955 $t_view_all_cookie = filter_db_get_filter( $t_view_all_cookie_id, $p_user_id ); 956 $t_cookie_detail = explode( '#', $t_view_all_cookie, 2 ); 957 958 if ( !isset( $t_cookie_detail[1] ) ) { 959 return false; 960 } 961 962 $t_filter = unserialize( $t_cookie_detail[1] ); 963 964 $t_filter = filter_ensure_valid_filter( $t_filter ); 965 966 return $t_filter; 967 } 968 969 #=================================== 970 # Data Modification 971 #=================================== 972 973 # -------------------- 974 # Update the last_visited field to be now 975 function user_update_last_visit( $p_user_id ) { 976 $c_user_id = db_prepare_int( $p_user_id ); 977 978 $t_user_table = config_get( 'mantis_user_table' ); 979 980 $query = "UPDATE $t_user_table 981 SET last_visit= " . db_now() . " 982 WHERE id='$c_user_id'"; 983 984 db_query( $query ); 985 986 user_clear_cache( $p_user_id ); 987 988 # db_query() errors on failure so: 989 return true; 990 } 991 992 # -------------------- 993 # Increment the number of times the user has logegd in 994 # This function is only called from the login.php script 995 function user_increment_login_count( $p_user_id ) { 996 $c_user_id = db_prepare_int( $p_user_id ); 997 998 $t_user_table = config_get( 'mantis_user_table' ); 999 1000 $query = "UPDATE $t_user_table 1001 SET login_count=login_count+1 1002 WHERE id='$c_user_id'"; 1003 1004 db_query( $query ); 1005 1006 user_clear_cache( $p_user_id ); 1007 1008 #db_query() errors on failure so: 1009 return true; 1010 } 1011 1012 # -------------------- 1013 # Reset to zero the failed login attempts 1014 function user_reset_failed_login_count_to_zero( $p_user_id ) { 1015 $c_user_id = db_prepare_int( $p_user_id ); 1016 $t_user_table = config_get( 'mantis_user_table' ); 1017 1018 $query = "UPDATE $t_user_table 1019 SET failed_login_count=0 1020 WHERE id='$c_user_id'"; 1021 db_query( $query ); 1022 1023 user_clear_cache( $p_user_id ); 1024 1025 return true; 1026 } 1027 1028 # -------------------- 1029 # Increment the failed login count by 1 1030 function user_increment_failed_login_count( $p_user_id ) { 1031 $c_user_id = db_prepare_int( $p_user_id ); 1032 $t_user_table = config_get( 'mantis_user_table' ); 1033 1034 $query = "UPDATE $t_user_table 1035 SET failed_login_count=failed_login_count+1 1036 WHERE id='$c_user_id'"; 1037 db_query( $query ); 1038 1039 user_clear_cache( $p_user_id ); 1040 1041 return true; 1042 } 1043 1044 # -------------------- 1045 # Reset to zero the 'lost password' in progress attempts 1046 function user_reset_lost_password_in_progress_count_to_zero( $p_user_id ) { 1047 $c_user_id = db_prepare_int( $p_user_id ); 1048 $t_user_table = config_get( 'mantis_user_table' ); 1049 1050 $query = "UPDATE $t_user_table 1051 SET lost_password_request_count=0 1052 WHERE id='$c_user_id'"; 1053 db_query( $query ); 1054 1055 user_clear_cache( $p_user_id ); 1056 1057 return true; 1058 } 1059 1060 # -------------------- 1061 # Increment the failed login count by 1 1062 function user_increment_lost_password_in_progress_count( $p_user_id ) { 1063 $c_user_id = db_prepare_int( $p_user_id ); 1064 $t_user_table = config_get( 'mantis_user_table' ); 1065 1066 $query = "UPDATE $t_user_table 1067 SET lost_password_request_count=lost_password_request_count+1 1068 WHERE id='$c_user_id'"; 1069 db_query( $query ); 1070 1071 user_clear_cache( $p_user_id ); 1072 1073 return true; 1074 } 1075 1076 # -------------------- 1077 # Set a user field 1078 function user_set_field( $p_user_id, $p_field_name, $p_field_value ) { 1079 $c_user_id = db_prepare_int( $p_user_id ); 1080 $c_field_name = db_prepare_string( $p_field_name ); 1081 $c_field_value = db_prepare_string( $p_field_value ); 1082 1083 if ( $p_field_name != "protected" ) { 1084 user_ensure_unprotected( $p_user_id ); 1085 } 1086 1087 $t_user_table = config_get( 'mantis_user_table' ); 1088 1089 $query = "UPDATE $t_user_table 1090 SET $c_field_name='$c_field_value' 1091 WHERE id='$c_user_id'"; 1092 1093 db_query( $query ); 1094 1095 user_clear_cache( $p_user_id ); 1096 1097 #db_query() errors on failure so: 1098 return true; 1099 } 1100 1101 # -------------------- 1102 # Set the user's default project 1103 function user_set_default_project( $p_user_id, $p_project_id ) { 1104 return user_pref_set_pref( $p_user_id, 'default_project', (int)$p_project_id ); 1105 } 1106 1107 # -------------------- 1108 # Set the user's password to the given string, encoded as appropriate 1109 function user_set_password( $p_user_id, $p_password, $p_allow_protected=false ) { 1110 if ( !$p_allow_protected ) { 1111 user_ensure_unprotected( $p_user_id ); 1112 } 1113 1114 $t_email = user_get_field( $p_user_id, 'email' ); 1115 $t_username = user_get_field( $p_user_id, 'username' ); 1116 1117 # When the password is changed, invalidate the cookie to expire sessions that 1118 # may be active on all browsers. 1119 $t_seed = $t_email . $t_username; 1120 $c_cookie_string = db_prepare_string( auth_generate_unique_cookie_string( $t_seed ) ); 1121 1122 $c_user_id = db_prepare_int( $p_user_id ); 1123 $c_password = db_prepare_string( auth_process_plain_password( $p_password ) ); 1124 $c_user_table = config_get( 'mantis_user_table' ); 1125 1126 $query = "UPDATE $c_user_table 1127 SET password='$c_password', 1128 cookie_string='$c_cookie_string' 1129 WHERE id='$c_user_id'"; 1130 db_query( $query ); 1131 1132 #db_query() errors on failure so: 1133 return true; 1134 } 1135 1136 # -------------------- 1137 # Set the user's email to the given string after checking that it is a valid email 1138 function user_set_email( $p_user_id, $p_email ) { 1139 email_ensure_valid( $p_email ); 1140 1141 return user_set_field( $p_user_id, 'email', $p_email ); 1142 } 1143 1144 # -------------------- 1145 # Set the user's realname to the given string after checking validity 1146 function user_set_realname( $p_user_id, $p_realname ) { 1147 # @@@ TODO: ensure_realname_valid( $p_realname ); 1148 1149 return user_set_field( $p_user_id, 'realname', $p_realname ); 1150 } 1151 1152 # -------------------- 1153 # Set the user's username to the given string after checking that it is valid 1154 function user_set_name( $p_user_id, $p_username ) { 1155 user_ensure_name_valid( $p_username ); 1156 user_ensure_name_unique( $p_username ); 1157 1158 return user_set_field( $p_user_id, 'username', $p_username ); 1159 } 1160 1161 # -------------------- 1162 # Reset the user's password 1163 # Take into account the 'send_reset_password' setting 1164 # - if it is ON, generate a random password and send an email 1165 # (unless the second parameter is false) 1166 # - if it is OFF, set the password to blank 1167 # Return false if the user is protected, true if the password was 1168 # successfully reset 1169 function user_reset_password( $p_user_id, $p_send_email=true ) { 1170 $t_protected = user_get_field( $p_user_id, 'protected' ); 1171 1172 # Go with random password and email it to the user 1173 if ( ON == $t_protected ) { 1174 return false; 1175 } 1176 1177 # @@@ do we want to force blank password instead of random if 1178 # email notifications are turned off? 1179 # How would we indicate that we had done this with a return value? 1180 # Should we just have two functions? (user_reset_password_random() 1181 # and user_reset_password() )? 1182 1183 if ( ( ON == config_get( 'send_reset_password' ) ) && ( ON == config_get( 'enable_email_notification' ) ) ) { 1184 # Create random password 1185 $t_email = user_get_field( $p_user_id, 'email' ); 1186 $t_password = auth_generate_random_password( $t_email ); 1187 $t_password2 = auth_process_plain_password( $t_password ); 1188 1189 user_set_field( $p_user_id, 'password', $t_password2 ); 1190 1191 # Send notification email 1192 if ( $p_send_email ) { 1193 $t_confirm_hash = auth_generate_confirm_hash( $p_user_id ); 1194 email_send_confirm_hash_url( $p_user_id, $t_confirm_hash ); 1195 } 1196 } else { 1197 # use blank password, no emailing 1198 $t_password = auth_process_plain_password( '' ); 1199 user_set_field( $p_user_id, 'password', $t_password ); 1200 # reset the failed login count because in this mode there is no emailing 1201 user_reset_failed_login_count_to_zero( $p_user_id ); 1202 } 1203 1204 return true; 1205 } 1206 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Thu Nov 29 09:42:17 2007 | par Balluche grâce à PHPXref 0.7 |
|