Skip to content

Commit

Permalink
Implement limited view for monitored issues
Browse files Browse the repository at this point in the history
The user that has a limited view now can also see the issues he is
monitoring.

Fixes: #15466
  • Loading branch information
cproensa committed Feb 4, 2020
1 parent c4c8b76 commit 97d6c38
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 9 deletions.
13 changes: 9 additions & 4 deletions core/access_api.php
Expand Up @@ -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;
}
}
Expand Down
36 changes: 31 additions & 5 deletions core/classes/BugFilterQuery.class.php
Expand Up @@ -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 );

Expand All @@ -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.
Expand Down Expand Up @@ -611,20 +620,37 @@ 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 )
. ' AND {bug}.handler_id = ' . $this->param( $t_user_id )
. ' 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 );

Expand Down

0 comments on commit 97d6c38

Please sign in to comment.