[ 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: access_api.php,v 1.45.2.1 2007-10-13 22:35:11 giallu Exp $ 22 # -------------------------------------------------------- 23 24 $t_core_dir = dirname( __FILE__ ).DIRECTORY_SEPARATOR; 25 26 require_once ( $t_core_dir . 'constant_inc.php' ); 27 require_once ( $t_core_dir . 'helper_api.php' ); 28 require_once ( $t_core_dir . 'authentication_api.php' ); 29 require_once ( $t_core_dir . 'user_api.php' ); 30 require_once ( $t_core_dir . 'bug_api.php' ); 31 require_once ( $t_core_dir . 'project_api.php' ); 32 33 ### Access Control API ### 34 35 # -------------------- 36 # Function to be called when a user is attempting to access a page that 37 # he/she is not authorised to. This outputs an access denied message then 38 # re-directs to the mainpage. 39 function access_denied() { 40 if ( !auth_is_user_authenticated() ) { 41 if( basename( $_SERVER['SCRIPT_NAME'] ) != 'login_page.php' ) { 42 $t_return_page = $_SERVER['PHP_SELF']; 43 if ( isset( $_SERVER['QUERY_STRING'] ) ) { 44 $t_return_page .= '?' . $_SERVER['QUERY_STRING']; 45 } 46 $t_return_page = string_url( string_sanitize_url( $t_return_page ) ); 47 print_header_redirect( 'login_page.php?return=' . $t_return_page ); 48 } 49 } else { 50 if( auth_get_current_user_id() == user_get_id_by_name( config_get_global( 'anonymous_account') ) ) { 51 if( basename( $_SERVER['SCRIPT_NAME'] ) != 'login_page.php' ) { 52 $t_return_page = $_SERVER['PHP_SELF']; 53 if ( isset( $_SERVER['QUERY_STRING'] ) ) { 54 $t_return_page .= '?' . $_SERVER['QUERY_STRING']; 55 } 56 $t_return_page = string_url( string_sanitize_url( $t_return_page ) ); 57 echo '<center>'; 58 echo '<p>'.error_string(ERROR_ACCESS_DENIED).'</p>'; 59 print_bracket_link( 'login_page.php?return=' . $t_return_page, lang_get( 'click_to_login' ) ); 60 echo '<p></p>'; 61 print_bracket_link( 'main_page.php', lang_get( 'proceed' ) ); 62 63 echo '</center>'; 64 } 65 } else { 66 echo '<center>'; 67 echo '<p>'.error_string(ERROR_ACCESS_DENIED).'</p>'; 68 print_bracket_link( 'main_page.php', lang_get( 'proceed' ) ); 69 echo '</center>'; 70 } 71 } 72 exit; 73 } 74 75 #=================================== 76 # Caching 77 #=================================== 78 79 # SECURITY NOTE: cache globals are initialized here to prevent them 80 # being spoofed if register_globals is turned on 81 82 $g_cache_access_matrix = array(); 83 $g_cache_access_matrix_project_ids = array(); 84 $g_cache_access_matrix_user_ids = array(); 85 86 # -------------------- 87 function access_cache_matrix_project( $p_project_id ) { 88 global $g_cache_access_matrix, $g_cache_access_matrix_project_ids; 89 90 $c_project_id = db_prepare_int( $p_project_id ); 91 92 if ( ALL_PROJECTS == $c_project_id ) { 93 return array(); 94 } 95 96 if ( !in_array( (int)$p_project_id, $g_cache_access_matrix_project_ids ) ) { 97 $t_project_user_list_table = config_get( 'mantis_project_user_list_table' ); 98 99 $query = "SELECT user_id, access_level 100 FROM $t_project_user_list_table 101 WHERE project_id='$c_project_id'"; 102 $result = db_query( $query ); 103 $count = db_num_rows( $result ); 104 for ( $i=0 ; $i < $count ; $i++ ) { 105 $row = db_fetch_array( $result ); 106 107 $g_cache_access_matrix[(int)$row['user_id']][(int)$p_project_id] = (int)$row['access_level']; 108 } 109 110 $g_cache_access_matrix_project_ids[] = (int)$p_project_id; 111 } 112 113 $t_results = array(); 114 115 foreach( $g_cache_access_matrix as $t_user ) { 116 if ( isset( $t_user[(int)$p_project_id] ) ) { 117 $t_results[(int)$p_project_id] = $t_user[(int)$p_project_id]; 118 } 119 } 120 121 return $t_results; 122 } 123 124 # -------------------- 125 function access_cache_matrix_user( $p_user_id ) { 126 global $g_cache_access_matrix, $g_cache_access_matrix_user_ids; 127 128 $c_user_id = db_prepare_int( $p_user_id ); 129 130 if ( !in_array( (int)$p_user_id, $g_cache_access_matrix_user_ids ) ) { 131 $t_project_user_list_table = config_get( 'mantis_project_user_list_table' ); 132 133 $query = "SELECT project_id, access_level 134 FROM $t_project_user_list_table 135 WHERE user_id='$c_user_id'"; 136 $result = db_query( $query ); 137 138 $count = db_num_rows( $result ); 139 140 # make sure we always have an array to return 141 $g_cache_access_matrix[(int)$p_user_id] = array(); 142 143 for ( $i=0 ; $i < $count ; $i++ ) { 144 $row = db_fetch_array( $result ); 145 $g_cache_access_matrix[(int)$p_user_id][(int)$row['project_id']] = (int)$row['access_level']; 146 } 147 148 $g_cache_access_matrix_user_ids[] = (int)$p_user_id; 149 } 150 151 return $g_cache_access_matrix[(int)$p_user_id]; 152 } 153 154 #=================================== 155 # Boolean queries and ensures 156 #=================================== 157 158 # -------------------- 159 # Check the a user's access against the given "threshold" and return true 160 # if the user can access, false otherwise. 161 # $p_access_level may be a single value, or an array. If it is a single 162 # value, treat it as a threshold so return true if user is >= threshold. 163 # If it is an array, look for exact matches to one of the values 164 function access_compare_level( $p_user_access_level, $p_threshold=NOBODY ) { 165 if ( is_array( $p_threshold ) ) { 166 return ( in_array( $p_user_access_level, $p_threshold ) ); 167 } else { 168 return ( $p_user_access_level >= $p_threshold ); 169 } 170 } 171 172 # -------------------- 173 # Get the current user's access 174 # 175 # This function only checks the user's global access level, ignoring any 176 # overrides they might have at a project level 177 function access_get_global_level( $p_user_id = null ) { 178 if ( $p_user_id === null ) { 179 $p_user_id = auth_get_current_user_id(); 180 } 181 182 # Deal with not logged in silently in this case 183 # @@@ we may be able to remove this and just error 184 # and once we default to anon login, we can remove it for sure 185 if ( !auth_is_user_authenticated() ) { 186 return false; 187 } 188 189 return user_get_field( $p_user_id, 'access_level' ); 190 } 191 192 # -------------------- 193 # Check the current user's access against the given value and return true 194 # if the user's access is equal to or higher, false otherwise. 195 # 196 function access_has_global_level( $p_access_level, $p_user_id = null ) { 197 # Short circuit the check in this case 198 if ( NOBODY == $p_access_level ) { 199 return false; 200 } 201 202 if ( $p_user_id === null ) { 203 $p_user_id = auth_get_current_user_id(); 204 } 205 206 $t_access_level = access_get_global_level( $p_user_id ); 207 208 return access_compare_level( $t_access_level, $p_access_level ) ; 209 } 210 211 # -------------------- 212 # Check if the user has the specified global access level 213 # and deny access to the page if not 214 function access_ensure_global_level( $p_access_level, $p_user_id = null ) { 215 if ( !access_has_global_level( $p_access_level, $p_user_id ) ) { 216 access_denied(); 217 } 218 } 219 220 # -------------------- 221 # Get the current user's access level 222 # 223 # This function checks the project access level first (for the current project 224 # if none is specified) and if the user is not listed, it falls back on the 225 # user's global access level. 226 function access_get_project_level( $p_project_id = null, $p_user_id = null ) { 227 # Deal with not logged in silently in this case 228 # @@@ we may be able to remove this and just error 229 # and once we default to anon login, we can remove it for sure 230 if ( !auth_is_user_authenticated() ) { 231 return ANYBODY; 232 } 233 234 if ( null === $p_user_id ) { 235 $p_user_id = auth_get_current_user_id(); 236 } 237 238 if ( null === $p_project_id ) { 239 $p_project_id = helper_get_current_project(); 240 } 241 242 $t_global_access_level = access_get_global_level( $p_user_id ); 243 if ( ( ALL_PROJECTS == $p_project_id ) || ( ADMINISTRATOR == $t_global_access_level ) ) { 244 return $t_global_access_level; 245 } else { 246 $t_project_access_level = access_get_local_level( $p_user_id, $p_project_id ); 247 $t_project_view_state = project_get_field( $p_project_id, 'view_state' ); 248 249 # Try to use the project access level. 250 # If the user is not listed in the project, then try to fall back 251 # to the global access level 252 if ( false === $t_project_access_level ) { 253 254 # If the project is private and the user isn't listed, then they 255 # must have the private_project_threshold access level to get in. 256 if ( VS_PRIVATE == $t_project_view_state ) { 257 if ( access_compare_level( $t_global_access_level, config_get( 'private_project_threshold', null, null, ALL_PROJECTS ) ) ) { 258 return $t_global_access_level; 259 } else { 260 return ANYBODY; 261 } 262 } else { 263 # project access not set, but the project is public 264 return $t_global_access_level; 265 } 266 } else { 267 # project specific access was set 268 return $t_project_access_level; 269 } 270 } 271 } 272 273 # -------------------- 274 # Check the current user's access against the given value and return true 275 # if the user's access is equal to or higher, false otherwise. 276 # 277 function access_has_project_level( $p_access_level, $p_project_id = null, $p_user_id = null ) { 278 # Short circuit the check in this case 279 if ( NOBODY == $p_access_level ) { 280 return false; 281 } 282 283 if ( null === $p_user_id ) { 284 $p_user_id = auth_get_current_user_id(); 285 } 286 if ( null === $p_project_id ) { 287 $p_project_id = helper_get_current_project(); 288 } 289 290 $t_access_level = access_get_project_level( $p_project_id, $p_user_id ); 291 292 return access_compare_level( $t_access_level, $p_access_level ) ; 293 } 294 295 # -------------------- 296 # Check if the user has the specified access level for the given project 297 # and deny access to the page if not 298 function access_ensure_project_level( $p_access_level, $p_project_id = null, $p_user_id = null ) { 299 if ( !access_has_project_level( $p_access_level, $p_project_id, $p_user_id ) ) { 300 access_denied(); 301 } 302 } 303 304 # -------------------- 305 # Check whether the user has the specified access level for any project project 306 function access_has_any_project( $p_access_level, $p_user_id = null ) { 307 # Short circuit the check in this case 308 309 if ( NOBODY == $p_access_level ) { 310 return false; 311 } 312 313 if ( null === $p_user_id ) { 314 $p_user_id = auth_get_current_user_id(); 315 } 316 317 $t_access = false; 318 $t_projects = project_get_all_rows(); 319 foreach ( $t_projects as $t_project ) { 320 $t_access = $t_access || access_has_project_level( $p_access_level, $t_project['id'], $p_user_id ); 321 } 322 323 return ( $t_access ); 324 } 325 326 # -------------------- 327 # Check the current user's access against the given value and return true 328 # if the user's access is equal to or higher, false otherwise. 329 # 330 # This function looks up the bug's project and performs an access check 331 # against that project 332 function access_has_bug_level( $p_access_level, $p_bug_id, $p_user_id = null ) { 333 # Deal with not logged in silently in this case 334 # @@@ we may be able to remove this and just error 335 # and once we default to anon login, we can remove it for sure 336 if ( !auth_is_user_authenticated() ) { 337 return false; 338 } 339 340 if ( $p_user_id === null ) { 341 $p_user_id = auth_get_current_user_id(); 342 } 343 344 $t_project_id = bug_get_field( $p_bug_id, 'project_id' ); 345 # check limit_Reporter (Issue #4769) 346 # reporters can view just issues they reported 347 $t_limit_reporters = config_get( 'limit_reporters' ); 348 if ( ( ON === $t_limit_reporters ) && 349 ( !bug_is_user_reporter( $p_bug_id, $p_user_id ) ) && 350 ( !access_has_project_level( REPORTER + 1, $t_project_id, $p_user_id ) ) ) { 351 return false; 352 } 353 354 # If the bug is private and the user is not the reporter, then the 355 # the user must also have higher access than private_bug_threshold 356 if ( VS_PRIVATE == bug_get_field( $p_bug_id, 'view_state' ) && 357 !bug_is_user_reporter( $p_bug_id, $p_user_id ) ) { 358 $p_access_level = max( $p_access_level, config_get( 'private_bug_threshold' ) ); 359 } 360 361 return access_has_project_level( $p_access_level, $t_project_id, $p_user_id ); 362 } 363 364 # -------------------- 365 # Check if the user has the specified access level for the given bug 366 # and deny access to the page if not 367 function access_ensure_bug_level( $p_access_level, $p_bug_id, $p_user_id=null ) { 368 if ( !access_has_bug_level( $p_access_level, $p_bug_id, $p_user_id ) ) { 369 access_denied(); 370 } 371 } 372 373 # -------------------- 374 # Check the current user's access against the given value and return true 375 # if the user's access is equal to or higher, false otherwise. 376 # 377 # This function looks up the bugnote's bug and performs an access check 378 # against that bug 379 function access_has_bugnote_level( $p_access_level, $p_bugnote_id, $p_user_id=null ) { 380 if ( null===$p_user_id ) { 381 $p_user_id = auth_get_current_user_id(); 382 } 383 384 # If the bug is private and the user is not the reporter, then the 385 # the user must also have higher access than private_bug_threshold 386 if ( VS_PRIVATE == bugnote_get_field( $p_bugnote_id, 'view_state' ) && 387 !bugnote_is_user_reporter( $p_bugnote_id, $p_user_id ) ) { 388 $p_access_level = max( $p_access_level, config_get( 'private_bugnote_threshold' ) ); 389 } 390 391 $t_bug_id = bugnote_get_field( $p_bugnote_id, 'bug_id' ); 392 393 return access_has_bug_level( $p_access_level, $t_bug_id, $p_user_id ); 394 } 395 396 # -------------------- 397 # Check if the user has the specified access level for the given bugnote 398 # and deny access to the page if not 399 function access_ensure_bugnote_level( $p_access_level, $p_bugnote_id, $p_user_id=null ) { 400 if ( !access_has_bugnote_level( $p_access_level, $p_bugnote_id, $p_user_id ) ) { 401 access_denied(); 402 } 403 } 404 405 # -------------------- 406 # Check if the current user can close the specified bug 407 function access_can_close_bug ( $p_bug_id, $p_user_id=null ) { 408 if ( null===$p_user_id ) { 409 $p_user_id = auth_get_current_user_id(); 410 } 411 412 # If allow_reporter_close is enabled, then reporters can always close 413 # their own bugs 414 if ( ON == config_get( 'allow_reporter_close' ) && 415 bug_is_user_reporter( $p_bug_id, $p_user_id ) ) { 416 return true; 417 } 418 419 return access_has_bug_level( access_get_status_threshold( CLOSED ), $p_bug_id, $p_user_id ); 420 } 421 422 # -------------------- 423 # Make sure that the current user can close the specified bug 424 # See access_can_close_bug() for details. 425 function access_ensure_can_close_bug( $p_bug_id, $p_user_id=null ) { 426 if ( !access_can_close_bug( $p_bug_id, $p_user_id ) ) { 427 access_denied(); 428 } 429 } 430 431 # -------------------- 432 # Check if the current user can reopen the specified bug 433 function access_can_reopen_bug ( $p_bug_id, $p_user_id=null ) { 434 if ( $p_user_id === null ) { 435 $p_user_id = auth_get_current_user_id(); 436 } 437 438 # If allow_reporter_reopen is enabled, then reporters can always reopen 439 # their own bugs 440 if ( ON == config_get( 'allow_reporter_reopen' ) && 441 bug_is_user_reporter( $p_bug_id, $p_user_id ) ) { 442 return true; 443 } 444 445 return access_has_bug_level( config_get( 'reopen_bug_threshold' ), $p_bug_id, $p_user_id ); 446 } 447 448 # -------------------- 449 # Make sure that the current user can reopen the specified bug 450 # See access_can_reopen_bug() for details. 451 function access_ensure_can_reopen_bug( $p_bug_id, $p_user_id=null ) { 452 if ( !access_can_reopen_bug( $p_bug_id, $p_user_id ) ) { 453 access_denied(); 454 } 455 } 456 457 #=================================== 458 # Data Access 459 #=================================== 460 461 # get the user's access level specific to this project. 462 # return false (0) if the user has no access override here 463 function access_get_local_level( $p_user_id, $p_project_id ) { 464 $p_project_id = (int)$p_project_id; # 000001 is different from 1. 465 466 $t_project_level = access_cache_matrix_user( $p_user_id ); 467 468 if ( isset( $t_project_level[$p_project_id] ) ) { 469 return $t_project_level[$p_project_id]; 470 } else { 471 return false; 472 } 473 } 474 475 # -------------------- 476 # get the access level required to change the issue to the new status 477 # If there is no specific differentiated access level, use the 478 # generic update_bug_status_threshold 479 function access_get_status_threshold( $p_status, $p_project_id = ALL_PROJECTS ) { 480 $t_thresh_array = config_get( 'set_status_threshold' ); 481 if ( isset( $t_thresh_array[ $p_status ] ) ) { 482 return $t_thresh_array[$p_status]; 483 } else { 484 return config_get( 'update_bug_status_threshold' ); 485 } 486 } 487 ?>
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 |
![]() |