Commit b54625a0 authored by bugreport%peshkin.net's avatar bugreport%peshkin.net

Bug 186093: Move CanSeeBug to User.pm and make User.pm usable by templates

r=kiko a=justdave
parent 50e28bb8
...@@ -133,7 +133,7 @@ sub initBug { ...@@ -133,7 +133,7 @@ sub initBug {
} }
} }
$self->{'whoid'} = $user_id; $self->{'who'} = new Bugzilla::User($user_id);
my $query = " my $query = "
SELECT SELECT
...@@ -156,7 +156,7 @@ sub initBug { ...@@ -156,7 +156,7 @@ sub initBug {
&::SendSQL($query); &::SendSQL($query);
my @row = (); my @row = ();
if ((@row = &::FetchSQLData()) && &::CanSeeBug($bug_id, $self->{'whoid'})) { if ((@row = &::FetchSQLData()) && $self->{'who'}->can_see_bug($bug_id)) {
my $count = 0; my $count = 0;
my %fields; my %fields;
foreach my $field ("bug_id", "alias", "product_id", "product", "version", foreach my $field ("bug_id", "alias", "product_id", "product", "version",
......
...@@ -720,7 +720,7 @@ sub NewProcessOnePerson ($$$$$$$$$$$$$) { ...@@ -720,7 +720,7 @@ sub NewProcessOnePerson ($$$$$$$$$$$$$) {
# see the action of restricting the bug itself; the bug will just # see the action of restricting the bug itself; the bug will just
# quietly disappear from their radar. # quietly disappear from their radar.
# #
return unless CanSeeBug($id, $userid); return unless $user->can_see_bug($id);
# Drop any non-insiders if the comment is private # Drop any non-insiders if the comment is private
return if (Param("insidergroup") && return if (Param("insidergroup") &&
...@@ -733,7 +733,7 @@ sub NewProcessOnePerson ($$$$$$$$$$$$$) { ...@@ -733,7 +733,7 @@ sub NewProcessOnePerson ($$$$$$$$$$$$$) {
my $save_id = $dep_id; my $save_id = $dep_id;
detaint_natural($dep_id) || warn("Unexpected Error: \@depbugs contains a non-numeric value: '$save_id'") detaint_natural($dep_id) || warn("Unexpected Error: \@depbugs contains a non-numeric value: '$save_id'")
&& return; && return;
return unless CanSeeBug($dep_id, $userid); return unless $user->can_see_bug($dep_id);
} }
my %mailhead = %defmailhead; my %mailhead = %defmailhead;
......
...@@ -185,7 +185,7 @@ sub validate { ...@@ -185,7 +185,7 @@ sub validate {
my $requestee = Bugzilla::User->new_from_login($requestee_email); my $requestee = Bugzilla::User->new_from_login($requestee_email);
# Throw an error if the user can't see the bug. # Throw an error if the user can't see the bug.
if (!&::CanSeeBug($bug_id, $requestee->id)) if (!$requestee->can_see_bug($bug_id))
{ {
ThrowUserError("flag_requestee_unauthorized", ThrowUserError("flag_requestee_unauthorized",
{ flag_type => $flag->{'type'}, { flag_type => $flag->{'type'},
...@@ -592,7 +592,7 @@ sub notify { ...@@ -592,7 +592,7 @@ sub notify {
|| next; || next;
next if $flag->{'target'}->{'bug'}->{'restricted'} next if $flag->{'target'}->{'bug'}->{'restricted'}
&& !&::CanSeeBug($flag->{'target'}->{'bug'}->{'id'}, $ccuser->id); && !$ccuser->can_see_bug($flag->{'target'}->{'bug'}->{'id'});
next if $flag->{'target'}->{'attachment'}->{'isprivate'} next if $flag->{'target'}->{'attachment'}->{'isprivate'}
&& Param("insidergroup") && Param("insidergroup")
&& !$ccuser->in_group(Param("insidergroup")); && !$ccuser->in_group(Param("insidergroup"));
......
...@@ -226,7 +226,7 @@ sub validate { ...@@ -226,7 +226,7 @@ sub validate {
my $requestee = Bugzilla::User->new_from_login($requestee_email); my $requestee = Bugzilla::User->new_from_login($requestee_email);
# Throw an error if the user can't see the bug. # Throw an error if the user can't see the bug.
if (!&::CanSeeBug($bug_id, $requestee->id)) if (!$requestee->can_see_bug($bug_id))
{ {
ThrowUserError("flag_requestee_unauthorized", ThrowUserError("flag_requestee_unauthorized",
{ flag_type => $flag_type, { flag_type => $flag_type,
......
...@@ -244,6 +244,75 @@ sub in_group { ...@@ -244,6 +244,75 @@ sub in_group {
return defined($res); return defined($res);
} }
sub can_see_bug {
my ($self, $bugid) = @_;
my $dbh = Bugzilla->dbh;
my $sth = $self->{sthCanSeeBug};
my $userid = $self->{id};
# Get fields from bug, presence of user on cclist, and determine if
# the user is missing any groups required by the bug. The prepared query
# is cached because this may be called for every row in buglists or
# every bug in a dependency list.
unless ($sth) {
$sth = $dbh->prepare("SELECT reporter, assigned_to, qa_contact,
reporter_accessible, cclist_accessible,
COUNT(cc.who), COUNT(bug_group_map.bug_id)
FROM bugs
LEFT JOIN cc
ON cc.bug_id = bugs.bug_id
AND cc.who = $userid
LEFT JOIN bug_group_map
ON bugs.bug_id = bug_group_map.bug_id
AND bug_group_map.group_ID NOT IN(" .
join(',',(-1, values(%{$self->groups}))) .
") WHERE bugs.bug_id = ? GROUP BY bugs.bug_id");
}
$sth->execute($bugid);
my ($reporter, $owner, $qacontact, $reporter_access, $cclist_access,
$isoncclist, $missinggroup) = $sth->fetchrow_array();
$self->{sthCanSeeBug} = $sth;
return ( (($reporter == $userid) && $reporter_access)
|| (Param('qacontact') && ($qacontact == $userid) && $userid)
|| ($owner == $userid)
|| ($isoncclist && $cclist_access)
|| (!$missinggroup) );
}
sub get_selectable_products {
my ($self, $by_id) = @_;
if (defined $self->{SelectableProducts}) {
my %list = @{$self->{SelectableProducts}};
return \%list if $by_id;
return values(%list);
}
my $query = "SELECT id, name " .
"FROM products " .
"LEFT JOIN group_control_map " .
"ON group_control_map.product_id = products.id ";
if (Param('useentrygroupdefault')) {
$query .= "AND group_control_map.entry != 0 ";
} else {
$query .= "AND group_control_map.membercontrol = " .
CONTROLMAPMANDATORY . " ";
}
$query .= "AND group_id NOT IN(" .
join(',', (-1,values(%{Bugzilla->user->groups}))) . ") " .
"WHERE group_id IS NULL ORDER BY name";
my $dbh = Bugzilla->dbh;
my $sth = $dbh->prepare($query);
$sth->execute();
my @products = ();
while (my @row = $sth->fetchrow_array) {
push(@products, @row);
}
$self->{SelectableProducts} = \@products;
my %list = @products;
return \%list if $by_id;
return values(%list);
}
# visible_groups_inherited returns a reference to a list of all the groups # visible_groups_inherited returns a reference to a list of all the groups
# whose members are visible to this user. # whose members are visible to this user.
sub visible_groups_inherited { sub visible_groups_inherited {
...@@ -939,6 +1008,10 @@ intended for cases where we are not looking at the currently logged in user, ...@@ -939,6 +1008,10 @@ intended for cases where we are not looking at the currently logged in user,
and only need to make a quick check for the group, where calling C<groups> and only need to make a quick check for the group, where calling C<groups>
and getting all of the groups would be overkill. and getting all of the groups would be overkill.
=item C<can_see_bug(bug_id)>
Determines if the user can see the specified bug.
=item C<derive_groups> =item C<derive_groups>
Bugzilla allows for group inheritance. When data about the user (or any of the Bugzilla allows for group inheritance. When data about the user (or any of the
...@@ -947,6 +1020,13 @@ care of by the constructor. However, when updating the email address, the ...@@ -947,6 +1020,13 @@ care of by the constructor. However, when updating the email address, the
user may be placed into different groups, based on a new email regexp. This user may be placed into different groups, based on a new email regexp. This
method should be called in such a case to force reresolution of these groups. method should be called in such a case to force reresolution of these groups.
=item C<get_selectable_products(by_id)>
Returns an alphabetical list of product names from which
the user can select bugs. If the $by_id parameter is true, it returns
a hash where the keys are the product ids and the values are the
product names.
=item C<visible_groups_inherited> =item C<visible_groups_inherited>
Returns a list of all groups whose members should be visible to this user. Returns a list of all groups whose members should be visible to this user.
......
...@@ -172,7 +172,7 @@ sub ValidateBugID { ...@@ -172,7 +172,7 @@ sub ValidateBugID {
return if $skip_authorization; return if $skip_authorization;
return if CanSeeBug($id, $::userid); return if Bugzilla->user->can_see_bug($id);
# The user did not pass any of the authorization tests, which means they # The user did not pass any of the authorization tests, which means they
# are not authorized to see the bug. Display an error and stop execution. # are not authorized to see the bug. Display an error and stop execution.
......
...@@ -630,48 +630,6 @@ sub GetFieldDefs { ...@@ -630,48 +630,6 @@ sub GetFieldDefs {
} }
sub CanSeeBug {
my ($id, $userid) = @_;
# Query the database for the bug, retrieving a boolean value that
# represents whether or not the user is authorized to access the bug.
# if no groups are found --> user is permitted to access
# if no user is found for any group --> user is not permitted to access
my $query = "SELECT bugs.bug_id, reporter, assigned_to, qa_contact," .
" reporter_accessible, cclist_accessible," .
" cc.who IS NOT NULL," .
" COUNT(DISTINCT(bug_group_map.group_id)) as cntbugingroups," .
" COUNT(DISTINCT(user_group_map.group_id)) as cntuseringroups" .
" FROM bugs" .
" LEFT JOIN cc ON bugs.bug_id = cc.bug_id" .
" AND cc.who = $userid" .
" LEFT JOIN bug_group_map ON bugs.bug_id = bug_group_map.bug_id" .
" LEFT JOIN user_group_map ON" .
" user_group_map.group_id = bug_group_map.group_id" .
" AND user_group_map.isbless = 0" .
" AND user_group_map.user_id = $userid" .
" WHERE bugs.bug_id = $id GROUP BY bugs.bug_id";
PushGlobalSQLState();
SendSQL($query);
my ($found_id, $reporter, $assigned_to, $qa_contact,
$rep_access, $cc_access,
$found_cc, $found_groups, $found_members)
= FetchSQLData();
PopGlobalSQLState();
return (
($found_groups == 0)
|| (($userid > 0) &&
(
($assigned_to == $userid)
|| (Param('useqacontact') && $qa_contact == $userid)
|| (($reporter == $userid) && $rep_access)
|| ($found_cc && $cc_access)
|| ($found_groups == $found_members)
))
);
}
sub ValidatePassword { sub ValidatePassword {
# Determines whether or not a password is valid (i.e. meets Bugzilla's # Determines whether or not a password is valid (i.e. meets Bugzilla's
...@@ -947,7 +905,7 @@ sub GetAttachmentLink { ...@@ -947,7 +905,7 @@ sub GetAttachmentLink {
my ($bugid, $isobsolete, $desc) = FetchSQLData(); my ($bugid, $isobsolete, $desc) = FetchSQLData();
my $title = ""; my $title = "";
my $className = ""; my $className = "";
if (CanSeeBug($bugid, $::userid)) { if (Bugzilla->user->can_see_bug($bugid)) {
$title = $desc; $title = $desc;
} }
if ($isobsolete) { if ($isobsolete) {
...@@ -1018,7 +976,7 @@ sub GetBugLink { ...@@ -1018,7 +976,7 @@ sub GetBugLink {
$title .= " $bug_res"; $title .= " $bug_res";
$post = '</span>'; $post = '</span>';
} }
if (CanSeeBug($bug_num, $::userid)) { if (Bugzilla->user->can_see_bug($bug_num)) {
$title .= " - $bug_desc"; $title .= " - $bug_desc";
} }
$::buglink{$bug_num} = [$pre, value_quote($title), $post]; $::buglink{$bug_num} = [$pre, value_quote($title), $post];
......
...@@ -75,7 +75,7 @@ my @bugs; ...@@ -75,7 +75,7 @@ my @bugs;
foreach my $bug_id (split(/[:,]/, $buglist)) { foreach my $bug_id (split(/[:,]/, $buglist)) {
detaint_natural($bug_id) || next; detaint_natural($bug_id) || next;
CanSeeBug($bug_id, $::userid) || next; Bugzilla->user->can_see_bug($bug_id) || next;
SendSQL("$generic_query AND bugs.bug_id = $bug_id"); SendSQL("$generic_query AND bugs.bug_id = $bug_id");
my %bug; my %bug;
......
...@@ -493,8 +493,9 @@ sub DuplicateUserConfirm { ...@@ -493,8 +493,9 @@ sub DuplicateUserConfirm {
SendSQL("SELECT reporter FROM bugs WHERE bug_id = " . SqlQuote($dupe)); SendSQL("SELECT reporter FROM bugs WHERE bug_id = " . SqlQuote($dupe));
my $reporter = FetchOneColumn(); my $reporter = FetchOneColumn();
my $rep_user = Bugzilla::User->new($reporter);
if (CanSeeBug($original, $reporter)) { if ($rep_user->can_see_bug($original)) {
$::FORM{'confirm_add_duplicate'} = "1"; $::FORM{'confirm_add_duplicate'} = "1";
return; return;
} }
...@@ -1773,7 +1774,7 @@ foreach my $id (@idlist) { ...@@ -1773,7 +1774,7 @@ foreach my $id (@idlist) {
# now show the next bug # now show the next bug
if ($next_bug) { if ($next_bug) {
if (detaint_natural($next_bug) && CanSeeBug($next_bug, $::userid)) { if (detaint_natural($next_bug) && Bugzilla->user->can_see_bug($next_bug)) {
my $bug = new Bugzilla::Bug($next_bug, $::userid); my $bug = new Bugzilla::Bug($next_bug, $::userid);
ThrowCodeError("bug_error", { bug => $bug }) if $bug->error; ThrowCodeError("bug_error", { bug => $bug }) if $bug->error;
......
...@@ -170,7 +170,7 @@ foreach my $k (keys(%seen)) { ...@@ -170,7 +170,7 @@ foreach my $k (keys(%seen)) {
$summary ||= ''; $summary ||= '';
# Resolution and summary are shown only if user can see the bug # Resolution and summary are shown only if user can see the bug
if (!CanSeeBug($k, $::userid)) { if (!Bugzilla->user->can_see_bug($k)) {
$resolution = $summary = ''; $resolution = $summary = '';
} }
......
...@@ -146,7 +146,7 @@ sub GetBug { ...@@ -146,7 +146,7 @@ sub GetBug {
my ($id) = @_; my ($id) = @_;
my $bug = {}; my $bug = {};
if (CanSeeBug($id, $::userid)) { if (Bugzilla->user->can_see_bug($id)) {
SendSQL("SELECT 1, SendSQL("SELECT 1,
bug_status, bug_status,
short_desc, short_desc,
......
...@@ -185,7 +185,7 @@ sub show_user { ...@@ -185,7 +185,7 @@ sub show_user {
# and they can see there are votes 'missing', but not on what bug # and they can see there are votes 'missing', but not on what bug
# they are. This seems a reasonable compromise; the alternative is # they are. This seems a reasonable compromise; the alternative is
# to lie in the totals. # to lie in the totals.
next if !CanSeeBug($id, $userid); next if !Bugzilla->user->can_see_bug($id);
push (@bugs, { id => $id, push (@bugs, { id => $id,
summary => $summary, summary => $summary,
......
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