diff --git a/core/access_api.php b/core/access_api.php index 5e2ec2e586..3e50f218df 100644 --- a/core/access_api.php +++ b/core/access_api.php @@ -513,12 +513,17 @@ function access_has_bug_level( $p_access_level, $p_bug_id, $p_user_id = null ) { $t_bug_is_user_reporter = bug_is_user_reporter( $p_bug_id, $p_user_id ); # Check special limits - # Limited view means this user can only view the issues they reported and/or is handling + # Limited view means this user can only view the issues they reported, is handling, or monitoring $t_limited_view = access_has_limited_view( $t_project_id, $p_user_id ); - if( $t_limited_view ) { - $t_bug_is_user_handler = bug_is_user_handler( $p_bug_id, $p_user_id ); - if( !$t_bug_is_user_reporter && !$t_bug_is_user_handler ) { + $t_allowed = $t_bug_is_user_reporter; + if( !$t_allowed ) { + $t_allowed = bug_is_user_handler( $p_bug_id, $p_user_id ); + } + if( !$t_allowed ) { + $t_allowed = user_is_monitoring_bug( $p_user_id, $p_bug_id ); + } + if( !$t_allowed ) { return false; } } diff --git a/core/classes/BugFilterQuery.class.php b/core/classes/BugFilterQuery.class.php index 64921d6b70..dae39026ef 100644 --- a/core/classes/BugFilterQuery.class.php +++ b/core/classes/BugFilterQuery.class.php @@ -549,13 +549,20 @@ protected function build_projects() { # wont differentiate for public or private issues, becasue the reporter of a private issue can always see it. $t_limit_reporter_project_ids = array(); - # this array is populated with projects where the user can view only public issues for which he is the handler user + # this array is populated with projects where the user can view public issues for which he is the handler user $t_limit_handler_public_only_project_ids = array(); - # this array is populated with projects where the user can view only issues for which he is the handler user + # this array is populated with projects where the user can view issues for which he is the handler user # but also has acces to those that are private. $t_limit_handler_public_and_private_project_ids = array(); + # this array is populated with projects where the user can view public issues he is monitoring + $t_limit_monitoring_public_project_ids = array(); + + # this array is populated with projects where the user can view issues he is monitoring + # but also has acces to those that are private. + $t_limit_monitoring_public_and_private_project_ids = array(); + # make sure the project rows are cached, as they will be used to check access levels. project_cache_array_rows( $t_included_project_ids ); @@ -567,11 +574,13 @@ protected function build_projects() { # if we have a reduced access to show only own reported or handled issues, we want to show both # cases: at least those reported by the user, and also those handled by the suer - # for handled issues, check if the user can access private issues + # for handled or monitored issues, check if the user can access private issues if( $t_can_see_private ) { $t_limit_handler_public_and_private_project_ids[] = $t_pid; + $t_limit_monitoring_public_and_private_project_ids[] = $t_pid; } else { $t_limit_handler_public_only_project_ids[] = $t_pid; + $t_limit_monitoring_public_project_ids[] = $t_pid; } # for own reported issues, they will always be accesible whether private or public. @@ -611,13 +620,13 @@ protected function build_projects() { $t_query_projects_or[] = $this->sql_in( '{bug}.project_id', $t_projects_for_reporter_visibility ) . ' AND {bug}.reporter_id = ' . $this->param( $t_user_id ); } - # for projects where access is limited to assigned issues (public or private issues) + # for projects where access is limited, search for assigned issues (public or private issues) if( !empty( $t_limit_handler_public_and_private_project_ids ) ) { log_event( LOG_FILTERING, 'project_ids (with access limited to own handled issues, public/private) = @P' . implode( ', @P', $t_limit_handler_public_and_private_project_ids ) ); $t_query_projects_or[] = $this->sql_in( '{bug}.project_id', $t_limit_handler_public_and_private_project_ids ) . ' AND {bug}.handler_id = ' . $this->param( $t_user_id ); } - # for projects where access is limited to assigned issues (only public issues) + # for projects where access is limited, search for assigned issues (only public issues) if( !empty( $t_limit_handler_public_only_project_ids ) ) { log_event( LOG_FILTERING, 'project_ids (with access limited to own handled issues, only public) = @P' . implode( ', @P', $t_limit_handler_public_only_project_ids ) ); $t_query_projects_or[] = $this->sql_in( '{bug}.project_id', $t_limit_handler_public_only_project_ids ) @@ -625,6 +634,23 @@ protected function build_projects() { . ' AND {bug}.view_state = ' . $this->param( VS_PUBLIC ); } + # for projects where access is limited, search monitored issues (public or private issues) + if( !empty( $t_limit_monitoring_public_and_private_project_ids ) ) { + log_event( LOG_FILTERING, 'project_ids (with access limited to monitored issues, public/private) = @P' . implode( ', @P', $t_limit_monitoring_public_and_private_project_ids ) ); + $t_query_projects_or[] = $this->sql_in( '{bug}.project_id', $t_limit_monitoring_public_and_private_project_ids ) + . ' AND EXISTS ( SELECT 1 FROM {bug_monitor} bm WHERE bm.user_id = ' . $this->param( $t_user_id ) + . ' AND bm.bug_id = {bug}.id )'; + } + + # for projects where access is limited, search monitored issues (only public issues) + if( !empty( $t_limit_monitoring_public_project_ids ) ) { + log_event( LOG_FILTERING, 'project_ids (with access limited to monitored issues, only public) = @P' . implode( ', @P', $t_limit_monitoring_public_project_ids ) ); + $t_query_projects_or[] = $this->sql_in( '{bug}.project_id', $t_limit_monitoring_public_project_ids ) + . ' AND {bug}.view_state = ' . $this->param( VS_PUBLIC ) + . ' AND EXISTS ( SELECT 1 FROM {bug_monitor} bm WHERE bm.user_id = ' . $this->param( $t_user_id ) + . ' AND bm.bug_id = {bug}.id )'; + } + $t_project_query = '(' . implode( ' OR ', $t_query_projects_or ) . ')'; log_event( LOG_FILTERING, 'project query = ' . $t_project_query );