Commit 740e0366 authored by bugreport%peshkin.net's avatar bugreport%peshkin.net

Bug 315332 fix several bugs in process_bug.cgi when 'strict_isolation' is on

Patch by Joel Peshkin <bugreport@peshkin.net> r=lpsolit, a=justdave
parent da94d077
...@@ -1299,17 +1299,6 @@ sub ValidateDependencies { ...@@ -1299,17 +1299,6 @@ sub ValidateDependencies {
return %deps; return %deps;
} }
#Verify if the new assignee belongs to the group of
#the product that the bug(s) is in.
sub can_add_user_to_bug {
my ($prod_id, $id, $uid) = @_;
my $user = new Bugzilla::User($uid);
if (!$user->can_edit_product($prod_id)) {
ThrowUserError("invalid_user_group", { 'user' =>
$user->login, bug_id => $id });
}
}
sub AUTOLOAD { sub AUTOLOAD {
use vars qw($AUTOLOAD); use vars qw($AUTOLOAD);
my $attr = $AUTOLOAD; my $attr = $AUTOLOAD;
......
...@@ -164,19 +164,20 @@ foreach my $field ("dependson", "blocked") { ...@@ -164,19 +164,20 @@ foreach my $field ("dependson", "blocked") {
# ValidateBugID is called without $field here so that it will # ValidateBugID is called without $field here so that it will
# throw an error if any of the changed bugs are not visible. # throw an error if any of the changed bugs are not visible.
ValidateBugID($id); ValidateBugID($id);
if (!CheckCanChangeField($field, $bug->bug_id, 0, 1)) {
$vars->{'privs'} = $PrivilegesRequired;
$vars->{'field'} = $field;
ThrowUserError("illegal_change", $vars);
}
if (Param("strict_isolation")) { if (Param("strict_isolation")) {
my $deltabug = new Bugzilla::Bug($id, $user); my $deltabug = new Bugzilla::Bug($id, $user->id);
if (!$user->can_edit_product($deltabug->{'product_id'})) { if (!$user->can_edit_product($deltabug->{'product_id'})) {
$vars->{'field'} = $field; $vars->{'field'} = $field;
ThrowUserError("illegal_change_deps", $vars); ThrowUserError("illegal_change_deps", $vars);
} }
} }
} }
if ((@$added || @$removed)
&& (!CheckCanChangeField($field, $bug->bug_id, 0, 1))) {
$vars->{'privs'} = $PrivilegesRequired;
$vars->{'field'} = $field;
ThrowUserError("illegal_change", $vars);
}
} else { } else {
# Bugzilla does not support mass-change of dependencies so they # Bugzilla does not support mass-change of dependencies so they
# are not validated. To prevent a URL-hacking risk, the dependencies # are not validated. To prevent a URL-hacking risk, the dependencies
...@@ -855,6 +856,8 @@ foreach my $field ("rep_platform", "priority", "bug_severity", ...@@ -855,6 +856,8 @@ foreach my $field ("rep_platform", "priority", "bug_severity",
} }
my $prod_id; my $prod_id;
my $prod_changed;
my @newprod_ids;
if ($cgi->param('product') ne $cgi->param('dontchange')) { if ($cgi->param('product') ne $cgi->param('dontchange')) {
$prod_id = get_product_id($cgi->param('product')); $prod_id = get_product_id($cgi->param('product'));
$prod_id || $prod_id ||
...@@ -862,17 +865,23 @@ if ($cgi->param('product') ne $cgi->param('dontchange')) { ...@@ -862,17 +865,23 @@ if ($cgi->param('product') ne $cgi->param('dontchange')) {
{product => $cgi->param('product')}); {product => $cgi->param('product')});
DoComma(); DoComma();
@newprod_ids = ($prod_id);
$prod_changed = 1;
$::query .= "product_id = $prod_id"; $::query .= "product_id = $prod_id";
} else { } else {
SendSQL("SELECT DISTINCT product_id FROM bugs WHERE bug_id IN (" . @newprod_ids = @{$dbh->selectcol_arrayref("SELECT DISTINCT product_id
join(',', @idlist) . ") " . $dbh->sql_limit(2)); FROM bugs
$prod_id = FetchOneColumn(); WHERE bug_id IN (" .
$prod_id = undef if (FetchOneColumn()); join(',', @idlist) .
")")};
if (scalar(@newprod_ids) == 1) {
($prod_id) = @newprod_ids;
}
} }
my $comp_id; my $comp_id;
if ($cgi->param('component') ne $cgi->param('dontchange')) { if ($cgi->param('component') ne $cgi->param('dontchange')) {
if (!defined $prod_id) { if (scalar(@newprod_ids) > 1) {
ThrowUserError("no_component_change_for_multiple_products"); ThrowUserError("no_component_change_for_multiple_products");
} }
$comp_id = get_component_id($prod_id, $comp_id = get_component_id($prod_id,
...@@ -1005,9 +1014,16 @@ if (defined $cgi->param('newcc') ...@@ -1005,9 +1014,16 @@ if (defined $cgi->param('newcc')
# only way to keep these informations when bugs are reassigned by # only way to keep these informations when bugs are reassigned by
# component as $cgi->param('assigned_to') and $cgi->param('qa_contact') # component as $cgi->param('assigned_to') and $cgi->param('qa_contact')
# are not the right fields to look at. # are not the right fields to look at.
# If the assignee or qacontact is changed, the new one is checked when
# changed information is validated. If not, then the unchanged assignee
# or qacontact may have to be validated later.
my $assignee; my $assignee;
my $qacontact; my $qacontact;
my $qacontact_checked = 0;
my $assignee_checked = 0;
my %usercache = ();
if (defined $cgi->param('qa_contact') if (defined $cgi->param('qa_contact')
&& $cgi->param('knob') ne "reassignbycomponent") && $cgi->param('knob') ne "reassignbycomponent")
...@@ -1016,11 +1032,22 @@ if (defined $cgi->param('qa_contact') ...@@ -1016,11 +1032,22 @@ if (defined $cgi->param('qa_contact')
# The QA contact cannot be deleted from show_bug.cgi for a single bug! # The QA contact cannot be deleted from show_bug.cgi for a single bug!
if ($name ne $cgi->param('dontchange')) { if ($name ne $cgi->param('dontchange')) {
$qacontact = DBNameToIdAndCheck($name) if ($name ne ""); $qacontact = DBNameToIdAndCheck($name) if ($name ne "");
if (Param("strict_isolation")) { if ($qacontact && Param("strict_isolation")) {
my $product_id = get_product_id($cgi->param('product')); $usercache{$qacontact} ||= Bugzilla::User->new($qacontact);
Bugzilla::Bug::can_add_user_to_bug( my $qa_user = $usercache{$qacontact};
$product_id, $cgi->param('id'), $qacontact); foreach my $product_id (@newprod_ids) {
if (!$qa_user->can_edit_product($product_id)) {
my $product_name = get_product_name($product_id);
ThrowUserError('invalid_user_group',
{'users' => $qa_user->login,
'product' => $product_name,
'bug_id' => (scalar(@idlist) > 1)
? undef : $idlist[0]
});
}
}
} }
$qacontact_checked = 1;
DoComma(); DoComma();
if($qacontact) { if($qacontact) {
$::query .= "qa_contact = $qacontact"; $::query .= "qa_contact = $qacontact";
...@@ -1082,18 +1109,28 @@ SWITCH: for ($cgi->param('knob')) { ...@@ -1082,18 +1109,28 @@ SWITCH: for ($cgi->param('knob')) {
} }
ChangeStatus('NEW'); ChangeStatus('NEW');
DoComma(); DoComma();
if (defined $cgi->param('assigned_to')) { if (defined $cgi->param('assigned_to')
my $uid = DBNameToIdAndCheck($cgi->param('assigned_to')); && trim($cgi->param('assigned_to')) ne "") {
$assignee = DBNameToIdAndCheck(trim($cgi->param('assigned_to')));
if (Param("strict_isolation")) { if (Param("strict_isolation")) {
my $product_id = get_product_id($cgi->param('product')); $usercache{$assignee} ||= Bugzilla::User->new($assignee);
Bugzilla::Bug::can_add_user_to_bug( my $assign_user = $usercache{$assignee};
$product_id, $cgi->param('id'), $uid); foreach my $product_id (@newprod_ids) {
if (!$assign_user->can_edit_product($product_id)) {
my $product_name = get_product_name($product_id);
ThrowUserError('invalid_user_group',
{'users' => $assign_user->login,
'product' => $product_name,
'bug_id' => (scalar(@idlist) > 1)
? undef : $idlist[0]
});
}
}
} }
} elsif (!defined $cgi->param('assigned_to') } else {
|| trim($cgi->param('assigned_to')) eq "") {
ThrowUserError("reassign_to_empty"); ThrowUserError("reassign_to_empty");
} }
$assignee = DBNameToIdAndCheck(trim($cgi->param('assigned_to'))); $assignee_checked = 1;
$::query .= "assigned_to = $assignee"; $::query .= "assigned_to = $assignee";
last SWITCH; last SWITCH;
}; };
...@@ -1290,6 +1327,75 @@ sub LogDependencyActivity { ...@@ -1290,6 +1327,75 @@ sub LogDependencyActivity {
return 0; return 0;
} }
if (Param("strict_isolation")) {
my @blocked_cc = ();
foreach my $pid (keys %cc_add) {
$usercache{$pid} ||= Bugzilla::User->new($pid);
my $cc_user = $usercache{$pid};
foreach my $product_id (@newprod_ids) {
if (!$cc_user->can_edit_product($product_id)) {
push (@blocked_cc, $cc_user->login);
last;
}
}
}
if (scalar(@blocked_cc)) {
ThrowUserError("invalid_user_group",
{'users' => \@blocked_cc,
'bug_id' => (scalar(@idlist) > 1) ? undef : $idlist[0]});
}
}
if ($prod_changed && Param("strict_isolation")) {
my $sth_cc = $dbh->prepare("SELECT who
FROM cc
WHERE bug_id = ?");
my $sth_bug = $dbh->prepare("SELECT assigned_to, qa_contact
FROM bugs
WHERE bug_id = ?");
my $prod_name = get_product_name($prod_id);
foreach my $id (@idlist) {
$sth_cc->execute($id);
my @blocked_cc = ();
while (my ($pid) = $sth_cc->fetchrow_array) {
$usercache{$pid} ||= Bugzilla::User->new($pid);
my $cc_user = $usercache{$pid};
if (!$cc_user->can_edit_product($prod_id)) {
push (@blocked_cc, $cc_user->login);
}
}
if (scalar(@blocked_cc)) {
ThrowUserError('invalid_user_group',
{'users' => \@blocked_cc,
'bug_id' => $id,
'product' => $prod_name});
}
$sth_bug->execute($id);
my ($assignee, $qacontact) = $sth_bug->fetchrow_array;
if (!$assignee_checked) {
$usercache{$assignee} ||= Bugzilla::User->new($assignee);
my $assign_user = $usercache{$assignee};
if (!$assign_user->can_edit_product($prod_id)) {
ThrowUserError('invalid_user_group',
{'users' => $assign_user->login,
'bug_id' => $id,
'product' => $prod_name});
}
}
if (!$qacontact_checked && $qacontact) {
$usercache{$qacontact} ||= Bugzilla::User->new($qacontact);
my $qa_user = $usercache{$qacontact};
if (!$qa_user->can_edit_product($prod_id)) {
ThrowUserError('invalid_user_group',
{'users' => $qa_user->login,
'bug_id' => $id,
'product' => $prod_name});
}
}
}
}
# This loop iterates once for each bug to be processed (i.e. all the # This loop iterates once for each bug to be processed (i.e. all the
# bugs selected when this script is called with multiple bugs selected # bugs selected when this script is called with multiple bugs selected
# from buglist.cgi, or just the one bug when called from # from buglist.cgi, or just the one bug when called from
...@@ -1397,15 +1503,6 @@ foreach my $id (@idlist) { ...@@ -1397,15 +1503,6 @@ foreach my $id (@idlist) {
ThrowUserError("illegal_change", $vars); ThrowUserError("illegal_change", $vars);
} }
} }
if ($cgi->param('assigned_to') && Param("strict_isolation")) {
my $uid = DBNameToIdAndCheck($cgi->param('assigned_to'));
Bugzilla::Bug::can_add_user_to_bug(
$bug_obj->{'product_id'}, $id, $uid);
}
if ($cgi->param('qa_contact') && Param("strict_isolation")) {
Bugzilla::Bug::can_add_user_to_bug(
$bug_obj->{'product_id'}, $id, $qacontact);
}
# When editing multiple bugs, users can specify a list of keywords to delete # When editing multiple bugs, users can specify a list of keywords to delete
# from bugs. If the list matches the current set of keywords on those bugs, # from bugs. If the list matches the current set of keywords on those bugs,
...@@ -1543,7 +1640,7 @@ foreach my $id (@idlist) { ...@@ -1543,7 +1640,7 @@ foreach my $id (@idlist) {
} }
} }
$query .= " where bug_id = $id"; $query .= " where bug_id = $id";
if ($::comma ne "") { if ($::comma ne "") {
SendSQL($query); SendSQL($query);
} }
...@@ -1621,21 +1718,7 @@ foreach my $id (@idlist) { ...@@ -1621,21 +1718,7 @@ foreach my $id (@idlist) {
$oncc{FetchOneColumn()} = 1; $oncc{FetchOneColumn()} = 1;
} }
my (@added, @removed, @blocked_cc) = (); my (@added, @removed) = ();
if (Param("strict_isolation")) {
foreach my $pid (keys %cc_add) {
my $user = Bugzilla::User->new($pid);
if (!$user->can_edit_product($bug_obj->{'product_id'})) {
push (@blocked_cc, $cc_add{$pid});
}
}
if (scalar(@blocked_cc)) {
my $blocked_cc = join(", ", @blocked_cc);
ThrowUserError("invalid_user_group",
{'user' => $blocked_cc , bug_id => $id });
}
}
foreach my $pid (keys %cc_add) { foreach my $pid (keys %cc_add) {
# If this person isn't already on the cc list, add them # If this person isn't already on the cc list, add them
......
...@@ -670,8 +670,19 @@ ...@@ -670,8 +670,19 @@
[% ELSIF error == "invalid_user_group" %] [% ELSIF error == "invalid_user_group" %]
[% title = "Invalid User Group" %] [% title = "Invalid User Group" %]
User '[% user FILTER html %]' is not able to edit the [% IF users.size > 1 %] Users [% ELSE %] User [% END %]
[% terms.bug %] '[% bug_id FILTER html %]'. '[% users.join(', ') FILTER html %]'
[% IF users.size > 1 %] are [% ELSE %] is [% END %]
not able to edit the
[% IF product %]
'[% product FILTER html %]'
[% END %]
[%+ field_descs.product FILTER html %]
[% IF bug_id %]
for [% terms.bug %] '[% bug_id FILTER html %]'.
[% ELSE %]
for at least one [% terms.bug %] being changed.
[% END %]
[% ELSIF error == "invalid_username" %] [% ELSIF error == "invalid_username" %]
[% title = "Invalid Username" %] [% title = "Invalid Username" %]
......
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