Commit ce2c6035 authored by mkanat%bugzilla.org's avatar mkanat%bugzilla.org

Bug 440656: Implement Bugzilla::User::visible_bugs and have can_see_bug use it

Patch By Max Kanat-Alexander <mkanat@bugzilla.org> r=LpSolit, a=LpSolit
parent 080a6b71
...@@ -49,6 +49,8 @@ use Bugzilla::Product; ...@@ -49,6 +49,8 @@ use Bugzilla::Product;
use Bugzilla::Classification; use Bugzilla::Classification;
use Bugzilla::Field; use Bugzilla::Field;
use Scalar::Util qw(blessed);
use base qw(Bugzilla::Object Exporter); use base qw(Bugzilla::Object Exporter);
@Bugzilla::User::EXPORT = qw(is_available_username @Bugzilla::User::EXPORT = qw(is_available_username
login_to_id user_id_to_login validate_password login_to_id user_id_to_login validate_password
...@@ -561,44 +563,70 @@ sub can_edit_product { ...@@ -561,44 +563,70 @@ sub can_edit_product {
} }
sub can_see_bug { sub can_see_bug {
my ($self, $bugid) = @_; my ($self, $bug_id) = @_;
my $dbh = Bugzilla->dbh; return @{ $self->visible_bugs([$bug_id]) } ? 1 : 0;
my $sth = $self->{sthCanSeeBug}; }
my $userid = $self->id;
# Get fields from bug, presence of user on cclist, and determine if sub visible_bugs {
# the user is missing any groups required by the bug. The prepared query my ($self, $bugs) = @_;
# is cached because this may be called for every row in buglists or # Allow users to pass in Bug objects and bug ids both.
# every bug in a dependency list. my @bug_ids = map { blessed $_ ? $_->id : $_ } @$bugs;
unless ($sth) {
$sth = $dbh->prepare("SELECT 1, reporter, assigned_to, qa_contact, # We only check the visibility of bugs that we haven't
reporter_accessible, cclist_accessible, # checked yet.
COUNT(cc.who), COUNT(bug_group_map.bug_id) my $visible_cache = $self->{_visible_bugs_cache} ||= {};
FROM bugs my @check_ids = grep(!exists $visible_cache->{$_}, @bug_ids);
LEFT JOIN cc
ON cc.bug_id = bugs.bug_id if (@check_ids) {
AND cc.who = $userid my $dbh = Bugzilla->dbh;
LEFT JOIN bug_group_map my $user_id = $self->id;
ON bugs.bug_id = bug_group_map.bug_id my $sth;
AND bug_group_map.group_ID NOT IN(" . # Speed up the can_see_bug case.
$self->groups_as_string . if (scalar(@check_ids) == 1) {
") WHERE bugs.bug_id = ? $sth = $self->{_sth_one_visible_bug};
AND creation_ts IS NOT NULL " . }
$dbh->sql_group_by('bugs.bug_id', 'reporter, ' . $sth ||= $dbh->prepare(
'assigned_to, qa_contact, reporter_accessible, ' . # This checks for groups that the bug is in that the user
'cclist_accessible')); # *isn't* in. Then, in the Perl code below, we check if
} # the user can otherwise access the bug (for example, by being
$sth->execute($bugid); # the assignee or QA Contact).
my ($ready, $reporter, $owner, $qacontact, $reporter_access, $cclist_access, #
$isoncclist, $missinggroup) = $sth->fetchrow_array(); # The DISTINCT exists because the bug could be in *several*
$sth->finish; # groups that the user isn't in, but they will all return the
$self->{sthCanSeeBug} = $sth; # same result for bug_group_map.bug_id (so DISTINCT filters
return ($ready # out duplicate rows).
&& ((($reporter == $userid) && $reporter_access) "SELECT DISTINCT bugs.bug_id, reporter, assigned_to, qa_contact,
|| (Bugzilla->params->{'useqacontact'} reporter_accessible, cclist_accessible, cc.who,
&& $qacontact && ($qacontact == $userid)) bug_group_map.bug_id
|| ($owner == $userid) FROM bugs
|| ($isoncclist && $cclist_access) LEFT JOIN cc
|| (!$missinggroup))); ON cc.bug_id = bugs.bug_id
AND cc.who = $user_id
LEFT JOIN bug_group_map
ON bugs.bug_id = bug_group_map.bug_id
AND bug_group_map.group_id NOT IN ("
. $self->groups_as_string . ')
WHERE bugs.bug_id IN (' . join(',', ('?') x @check_ids) . ')
AND creation_ts IS NOT NULL ');
if (scalar(@check_ids) == 1) {
$self->{_sth_one_visible_bug} = $sth;
}
$sth->execute(@check_ids);
while (my $row = $sth->fetchrow_arrayref) {
my ($bug_id, $reporter, $owner, $qacontact, $reporter_access,
$cclist_access, $isoncclist, $missinggroup) = @$row;
$visible_cache->{$bug_id} ||=
((($reporter == $user_id) && $reporter_access)
|| (Bugzilla->params->{'useqacontact'}
&& $qacontact && ($qacontact == $user_id))
|| ($owner == $user_id)
|| ($isoncclist && $cclist_access)
|| !$missinggroup) ? 1 : 0;
}
}
return [grep { $visible_cache->{blessed $_ ? $_->id : $_} } @$bugs];
} }
sub can_see_product { sub can_see_product {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment