Skip to content

Commit

Permalink
Enable limit_reporters options at project/user level
Browse files Browse the repository at this point in the history
Fixes: #9534
  • Loading branch information
cproensa committed Feb 4, 2020
1 parent 2901b0e commit cfd90a9
Show file tree
Hide file tree
Showing 8 changed files with 63 additions and 43 deletions.
4 changes: 1 addition & 3 deletions bug_update_page.php
Expand Up @@ -277,9 +277,7 @@

# Do not allow the bug's reporter to edit the Reporter field
# when limit_reporters is ON
if( ON == config_get( 'limit_reporters' )
&& !access_has_project_level( access_threshold_min_level( config_get( 'report_bug_threshold', null, null, $t_bug->project_id ) ) + 1, $t_bug->project_id )
) {
if( access_has_limited_view_for_reporter( $t_bug->project_id ) ) {
echo string_attribute( user_get_name( $t_bug->reporter_id ) );
} else {
if ( $f_reporter_edit ) {
Expand Down
9 changes: 3 additions & 6 deletions changelog_page.php
Expand Up @@ -252,9 +252,7 @@ function print_project_header_changelog( $p_project_name ) {

$t_project_header_printed = false;

$t_limit_reporters = config_get( 'limit_reporters' );
$t_report_bug_threshold = config_get( 'report_bug_threshold', null, null, $t_project_id );
$t_access_limit_reporters_applies = !access_has_project_level( access_threshold_min_level( $t_report_bug_threshold ) + 1, $t_project_id );
$t_access_limit_reporters_applies = access_has_limited_view_for_reporter( $t_project_id );

foreach( $t_version_rows as $t_version_row ) {
$t_version_header_printed = false;
Expand Down Expand Up @@ -295,9 +293,8 @@ function print_project_header_changelog( $p_project_name ) {

# check limit_Reporter (Issue #4770)
# reporters can view just issues they reported
if( ON == $t_limit_reporters
&& $t_access_limit_reporters_applies
&& !bug_is_user_reporter( $t_row['id'], $t_user_id ) ) {
if( $t_access_limit_reporters_applies
&& !bug_is_user_reporter( $t_row['id'], $t_user_id ) ) {
continue;
}

Expand Down
67 changes: 49 additions & 18 deletions core/access_api.php
Expand Up @@ -515,24 +515,10 @@ function access_has_bug_level( $p_access_level, $p_bug_id, $p_user_id = null ) {

# check limit_Reporter (Issue #4769)
# reporters can view just issues they reported
$t_limit_reporters = config_get( 'limit_reporters', null, $p_user_id, $t_project_id );
if( $t_limit_reporters && !$t_bug_is_user_reporter ) {
# Here we only need to check that the current user has an access level
# higher than the lowest needed to report issues (report_bug_threshold).
# To improve performance, esp. when processing for several projects, we
# build a static array holding that threshold for each project
static $s_thresholds = array();
if( !isset( $s_thresholds[$t_project_id] ) ) {
$t_report_bug_threshold = config_get( 'report_bug_threshold', null, $p_user_id, $t_project_id );
if( empty( $t_report_bug_threshold ) ) {
$s_thresholds[$t_project_id] = NOBODY;
} else {
$s_thresholds[$t_project_id] = access_threshold_min_level( $t_report_bug_threshold ) + 1;
}
}
if( !access_compare_level( $t_access_level, $s_thresholds[$t_project_id] ) ) {
return false;
}
if( access_has_limited_view_for_reporter( $t_project_id, $p_user_id )
&& !$t_bug_is_user_reporter ) {
# deny access if user is affected by this option, and he is not reporter
return false;
}

# If the bug is private and the user is not the reporter, then
Expand Down Expand Up @@ -895,3 +881,48 @@ function access_parse_array( array $p_access ) {

return $t_access_level;
}

/**
* Return an access threshold for which a user is not affected by the 'limit_reporters'
* option. Also, if the option is disabled globally, or for the specific user/project,
* a threshold of ANYBODY will be returned, meaning that any user can bypass this limitation.
*
* @param integer $p_project_id Project id, or null for current project
* @param integer $p_user_id User id, or null for current user
* @return mixed A threshold definition
*/
function access_threshold_reporter_unlimited_view( $p_project_id = null, $p_user_id = null ) {
$t_limit_reporters_option = config_get( 'limit_reporters', null, $p_user_id, $p_project_id );
if( ON != $t_limit_reporters_option ) {
return ANYBODY;
}

$t_user = null === $p_user_id ? auth_get_current_user_id() : $p_user_id;
$t_project = null === $p_project_id ? helper_get_current_project() : $p_project_id;

# To improve performance, esp. when processing for several projects, we
# build a static array holding that threshold for each project
static $s_thresholds = array();
if( !isset( $s_thresholds[$t_project] ) ) {
$t_report_bug_threshold = config_get( 'report_bug_threshold', null, $t_user, $t_project );
if( empty( $t_report_bug_threshold ) ) {
$s_thresholds[$t_project] = NOBODY;
} else {
$s_thresholds[$t_project] = access_threshold_min_level( $t_report_bug_threshold ) + 1;
}
}
return $s_thresholds[$t_project];
}

/**
* Returns true if the user is limited to view only the issues reported by him,
* in the specified project.
* @param integer $p_project_id Project id, or null for current project
* @param integer $p_user_id User id, or null for current user
* @return boolean Whether limited view applies
*/
function access_has_limited_view_for_reporter( $p_project_id = null, $p_user_id = null ) {
$t_can_view = access_threshold_reporter_unlimited_view( $p_project_id, $p_user_id );
$t_project_level = access_get_project_level( $p_project_id, $p_user_id );
return !access_compare_level( $t_project_level, $t_can_view );
}
6 changes: 2 additions & 4 deletions core/classes/BugFilterQuery.class.php
Expand Up @@ -538,8 +538,6 @@ protected function build_projects() {
return;
}

$t_limit_reporters = config_get( 'limit_reporters' );

# this array is to be populated with project ids for which we only want to show public issues. This is due to the limited
# access of the current user.
$t_public_only_project_ids = array();
Expand All @@ -554,8 +552,8 @@ protected function build_projects() {
project_cache_array_rows( $t_included_project_ids );

foreach( $t_included_project_ids as $t_pid ) {
if( ( ON === $t_limit_reporters ) && ( !access_has_project_level( access_threshold_min_level( config_get( 'report_bug_threshold', null, $t_user_id, $t_pid ) ) + 1, $t_pid, $t_user_id ) ) ) {
# project is limited, only view own reported bugs
if( access_has_limited_view_for_reporter( $t_pid, $t_user_id ) ) {
# project is limited, only can view own reported bugs
$t_limit_reporter_project_ids[] = $t_pid;
# as we will check the user is reporter for each bug, and reporter can view his own private bugs, there's no need to check for private bug access
continue;
Expand Down
7 changes: 2 additions & 5 deletions core/filter_form_api.php
Expand Up @@ -190,11 +190,8 @@ function print_filter_reporter_id( array $p_filter = null ) {
?>
<select class="input-xs" <?php echo filter_select_modifier( $p_filter ) ?> name="<?php echo FILTER_PROPERTY_REPORTER_ID;?>[]">
<?php
# if current user is a reporter, and limited reports set to ON, only display that name
# @@@ thraxisp - access_has_project_level checks greater than or equal to,
# this assumed that there aren't any holes above REPORTER where the limit would apply
#
if( ( ON === config_get( 'limit_reporters' ) ) && ( !access_has_project_level( access_threshold_min_level( config_get( 'report_bug_threshold' ) ) + 1 ) ) ) {
# if current user is a reporter, and limited_reporters is set to ON, only display that name
if( access_has_limited_view_for_reporter() ) {
$t_id = auth_get_current_user_id();
$t_username = user_get_name( $t_id );
$t_display_name = string_attribute( $t_username );
Expand Down
2 changes: 1 addition & 1 deletion manage_config_work_threshold_page.php
Expand Up @@ -394,7 +394,7 @@ function get_section_end() {
get_capability_row( lang_get( 'remove_users_monitoring_issue' ), 'monitor_delete_others_bug_threshold' );
get_capability_boolean( lang_get( 'set_status_assigned' ), 'auto_set_status_to_assigned' );
get_capability_enum( lang_get( 'assigned_status' ), 'bug_assigned_status', 'status' );
get_capability_boolean( lang_get( 'limit_access' ), 'limit_reporters', true );
get_capability_boolean( lang_get( 'limit_access' ), 'limit_reporters' );
get_section_end();

# Notes
Expand Down
2 changes: 1 addition & 1 deletion manage_config_work_threshold_set.php
Expand Up @@ -178,7 +178,7 @@ function set_capability_enum( $p_threshold, $p_all_projects_only = false ) {
set_capability_row( 'monitor_delete_others_bug_threshold' );
set_capability_boolean( 'auto_set_status_to_assigned' );
set_capability_enum( 'bug_assigned_status' );
set_capability_boolean( 'limit_reporters', true );
set_capability_boolean( 'limit_reporters' );

# Notes
set_capability_row( 'add_bugnote_threshold' );
Expand Down
9 changes: 4 additions & 5 deletions roadmap_page.php
Expand Up @@ -247,9 +247,6 @@ function print_project_header_roadmap( $p_project_name ) {
$t_project_name = project_get_field( $t_project_id, 'name' );
$t_can_view_private = access_has_project_level( config_get( 'private_bug_threshold' ), $t_project_id );

$t_limit_reporters = config_get( 'limit_reporters' );
$t_user_access_level_is_reporter = ( config_get( 'report_bug_threshold', null, null, $t_project_id ) == access_get_project_level( $t_project_id ) );

$t_resolved = config_get( 'bug_resolved_status_threshold' );

$t_version_rows = array_reverse( version_get_all_rows( $t_project_id ) );
Expand All @@ -259,6 +256,8 @@ function print_project_header_roadmap( $p_project_name ) {

$t_project_header_printed = false;

$t_access_limit_reporters_applies = access_has_limited_view_for_reporter( $t_project_id );

foreach( $t_version_rows as $t_version_row ) {
if( $t_version_row['released'] == 1 ) {
continue;
Expand Down Expand Up @@ -302,8 +301,8 @@ function print_project_header_roadmap( $p_project_name ) {

# check limit_Reporter (Issue #4770)
# reporters can view just issues they reported
if( ON === $t_limit_reporters && $t_user_access_level_is_reporter &&
!bug_is_user_reporter( $t_row['id'], $t_user_id )) {
if( $t_access_limit_reporters_applies
&& !bug_is_user_reporter( $t_row['id'], $t_user_id ) ) {
continue;
}

Expand Down

0 comments on commit cfd90a9

Please sign in to comment.