Commit 4f4c25bb authored by travis%sedsystems.ca's avatar travis%sedsystems.ca

Bug 266579 : Users without privs can confirm bugs by assigning to themselves…

Bug 266579 : Users without privs can confirm bugs by assigning to themselves first, without having canconfirm privs Patch by LpSolit@gmail.com r=myk a=justdave
parent 61a49f22
...@@ -404,20 +404,22 @@ sub user { ...@@ -404,20 +404,22 @@ sub user {
# Display everything as if they have all the permissions in the # Display everything as if they have all the permissions in the
# world; their permissions will get checked when they log in and # world; their permissions will get checked when they log in and
# actually try to make the change. # actually try to make the change.
my $privileged = (!Bugzilla->user->id) my $unknown_privileges = !Bugzilla->user->id
|| Bugzilla->user->in_group("editbugs") || Bugzilla->user->in_group("editbugs");
|| Bugzilla->user->id == $self->{'assigned_to'}{'id'} my $canedit = $unknown_privileges
|| (Param('useqacontact') && $self->{'qa_contact'} && || Bugzilla->user->id == $self->{'assigned_to'}{'id'}
Bugzilla->user->id == $self->{'qa_contact'}{'id'}); || (Param('useqacontact')
my $isreporter = Bugzilla->user->id && && $self->{'qa_contact'}
Bugzilla->user->id == $self->{'reporter'}{'id'}; && Bugzilla->user->id == $self->{'qa_contact'}{'id'});
my $canconfirm = $unknown_privileges
my $canedit = $privileged || $isreporter; || Bugzilla->user->in_group("canconfirm");
my $canconfirm = $privileged || Bugzilla->user->in_group("canconfirm"); my $isreporter = Bugzilla->user->id
&& Bugzilla->user->id == $self->{'reporter'}{'id'};
$self->{'user'} = {canmove => $canmove,
canconfirm => $canconfirm, $self->{'user'} = {canmove => $canmove,
canedit => $canedit,}; canconfirm => $canconfirm,
canedit => $canedit,
isreporter => $isreporter};
return $self->{'user'}; return $self->{'user'};
} }
......
...@@ -317,7 +317,11 @@ $vars->{'component_'} = \@components; ...@@ -317,7 +317,11 @@ $vars->{'component_'} = \@components;
$default{'component_'} = formvalue('component'); $default{'component_'} = formvalue('component');
$vars->{'assigned_to'} = formvalue('assigned_to'); $vars->{'assigned_to'} = formvalue('assigned_to');
$vars->{'assigned_to_disabled'} = !UserInGroup('editbugs');
$vars->{'cc'} = formvalue('cc'); $vars->{'cc'} = formvalue('cc');
$vars->{'cc_disabled'} = 0;
$vars->{'product'} = $product; $vars->{'product'} = $product;
$vars->{'bug_file_loc'} = formvalue('bug_file_loc', "http://"); $vars->{'bug_file_loc'} = formvalue('bug_file_loc', "http://");
$vars->{'short_desc'} = formvalue('short_desc'); $vars->{'short_desc'} = formvalue('short_desc');
......
...@@ -130,7 +130,7 @@ my $sql_product = SqlQuote($::FORM{'product'}); ...@@ -130,7 +130,7 @@ my $sql_product = SqlQuote($::FORM{'product'});
my $sql_component = SqlQuote($::FORM{'component'}); my $sql_component = SqlQuote($::FORM{'component'});
# Default assignee is the component owner. # Default assignee is the component owner.
if ($::FORM{'assigned_to'} eq "") { if (!UserInGroup("editbugs") || $::FORM{'assigned_to'} eq "") {
SendSQL("SELECT initialowner FROM components " . SendSQL("SELECT initialowner FROM components " .
"WHERE id = $component_id"); "WHERE id = $component_id");
$::FORM{'assigned_to'} = FetchOneColumn(); $::FORM{'assigned_to'} = FetchOneColumn();
......
...@@ -23,11 +23,13 @@ ...@@ -23,11 +23,13 @@
# Dave Miller <justdave@syndicomm.com> # Dave Miller <justdave@syndicomm.com>
# Christopher Aillon <christopher@aillon.com> # Christopher Aillon <christopher@aillon.com>
# Myk Melez <myk@mozilla.org> # Myk Melez <myk@mozilla.org>
# Frédéric Buclin <LpSolit@netscape.net>
use strict; use strict;
my $UserInEditGroupSet = -1; my $UserInEditGroupSet = -1;
my $UserInCanConfirmGroupSet = -1; my $UserInCanConfirmGroupSet = -1;
my $PrivilegesRequired = 0;
use lib qw(.); use lib qw(.);
...@@ -237,14 +239,10 @@ if ((($::FORM{'id'} && $::FORM{'product'} ne $::oldproduct) ...@@ -237,14 +239,10 @@ if ((($::FORM{'id'} && $::FORM{'product'} ne $::oldproduct)
$vars->{'oldvalue'} = $::oldproduct; $vars->{'oldvalue'} = $::oldproduct;
$vars->{'newvalue'} = $::FORM{'product'}; $vars->{'newvalue'} = $::FORM{'product'};
$vars->{'field'} = 'product'; $vars->{'field'} = 'product';
ThrowUserError("illegal_change", $vars->{'privs'} = $PrivilegesRequired;
{ oldvalue => $::oldproduct, ThrowUserError("illegal_change", $vars, "abort");
newvalue => $::FORM{'product'}, }
field => 'product',
},
"abort");
}
CheckFormField(\%::FORM, 'product', \@::legal_product); CheckFormField(\%::FORM, 'product', \@::legal_product);
my $prod = $::FORM{'product'}; my $prod = $::FORM{'product'};
...@@ -350,34 +348,18 @@ sub CheckCanChangeField { ...@@ -350,34 +348,18 @@ sub CheckCanChangeField {
# START DO_NOT_CHANGE # START DO_NOT_CHANGE
my ($field, $bugid, $oldvalue, $newvalue) = (@_); my ($field, $bugid, $oldvalue, $newvalue) = (@_);
# Convert email IDs into addresses for $oldvalue
if (($field eq "assigned_to") ||
($field eq "reporter") ||
($field eq "qa_contact"))
{
if ($oldvalue =~ /^\d+$/) {
if ($oldvalue == 0) {
$oldvalue = "";
} else {
$oldvalue = DBID_to_name($oldvalue);
}
}
}
# Return true if they haven't changed this field at all. # Return true if they haven't changed this field at all.
if ($oldvalue eq $newvalue) { if ($oldvalue eq $newvalue) {
return 1; return 1;
} } elsif (trim($oldvalue) eq trim($newvalue)) {
elsif (trim($oldvalue) eq trim($newvalue)) {
return 1; return 1;
# numeric fields need to be compared using == # numeric fields need to be compared using ==
} elsif (($field eq "estimated_time" || $field eq "remaining_time") && } elsif (($field eq "estimated_time" || $field eq "remaining_time")
$oldvalue == $newvalue) { && $oldvalue == $newvalue)
{
return 1; return 1;
} }
# A resolution change is always accompanied by a status change. So, we # A resolution change is always accompanied by a status change. So, we
# always OK resolution changes; if they really can't do this, we will # always OK resolution changes; if they really can't do this, we will
# notice it when status is checked. # notice it when status is checked.
...@@ -390,7 +372,15 @@ sub CheckCanChangeField { ...@@ -390,7 +372,15 @@ sub CheckCanChangeField {
if ($field =~ /^longdesc/) { if ($field =~ /^longdesc/) {
return 1; return 1;
} }
# Ignore the assigned_to field if the bug is not being reassigned
if ($field eq "assigned_to"
&& $::FORM{'knob'} ne "reassignbycomponent"
&& $::FORM{'knob'} ne "reassign")
{
return 1;
}
# START DO_NOT_CHANGE # START DO_NOT_CHANGE
# Find out whether the user is a member of the "editbugs" and/or # Find out whether the user is a member of the "editbugs" and/or
# "canconfirm" groups. $UserIn*GroupSet are caches of the return value of # "canconfirm" groups. $UserIn*GroupSet are caches of the return value of
...@@ -403,23 +393,31 @@ sub CheckCanChangeField { ...@@ -403,23 +393,31 @@ sub CheckCanChangeField {
$UserInCanConfirmGroupSet = UserInGroup("canconfirm"); $UserInCanConfirmGroupSet = UserInGroup("canconfirm");
} }
# END DO_NOT_CHANGE # END DO_NOT_CHANGE
# Allow anyone with "editbugs" to change anything. # If the user isn't allowed to change a field, we must tell him who can.
# We store the required permission set into the $PrivilegesRequired
# variable which gets passed to the error template.
#
# $PrivilegesRequired = 0 : no privileges required;
# $PrivilegesRequired = 1 : the reporter, owner or an empowered user;
# $PrivilegesRequired = 2 : the owner or an empowered user;
# $PrivilegesRequired = 3 : an empowered user.
# Allow anyone with "editbugs" privs to change anything.
if ($UserInEditGroupSet) { if ($UserInEditGroupSet) {
return 1; return 1;
} }
# Allow anyone with "canconfirm" to confirm bugs. # *Only* users with "canconfirm" privs can confirm bugs.
if ($UserInCanConfirmGroupSet) { if ($field eq "canconfirm"
if (($field eq "canconfirm") || || ($field eq "bug_status"
(($field eq "bug_status") && && $oldvalue eq $::unconfirmedstate
($oldvalue eq $::unconfirmedstate) && && IsOpenedState($newvalue)))
IsOpenedState($newvalue))) {
{ $PrivilegesRequired = 3;
return 1; return $UserInCanConfirmGroupSet;
}
} }
# START DO_NOT_CHANGE # START DO_NOT_CHANGE
# $reporterid, $ownerid and $qacontactid are caches of the results of # $reporterid, $ownerid and $qacontactid are caches of the results of
# the call to find out the owner, reporter and qacontact of the current bug. # the call to find out the owner, reporter and qacontact of the current bug.
...@@ -431,46 +429,48 @@ sub CheckCanChangeField { ...@@ -431,46 +429,48 @@ sub CheckCanChangeField {
} }
# END DO_NOT_CHANGE # END DO_NOT_CHANGE
# Allow the owner to change anything. # Allow the owner to change anything else.
if ($ownerid eq $whoid) { if ($ownerid == $whoid) {
return 1; return 1;
} }
# Allow the QA contact to change anything. # Allow the QA contact to change anything else.
if (Param('useqacontact') && ($qacontactid eq $whoid)) { if (Param('useqacontact') && ($qacontactid == $whoid)) {
return 1; return 1;
} }
# The reporter's a more complicated case... # The reporter is a more complicated case...
if ($reporterid eq $whoid) { if ($reporterid == $whoid) {
# Reporter may not: $PrivilegesRequired = 2;
# - confirm his own bugs (this assumes he doesn't have canconfirm, or we
# would have returned "1" earlier) # The reporter may not:
if (($field eq "bug_status") && # - reassign bugs, unless the bugs are assigned to him;
($oldvalue eq $::unconfirmedstate) && # in that case we will have already returned 1 above
IsOpenedState($newvalue)) # when checking for the owner of the bug.
{ if ($field eq "assigned_to") {
return 0; return 0;
} }
# - change the QA contact
# - change the target milestone if ($field eq "qa_contact") {
if ($field eq "target_milestone") {
return 0; return 0;
} }
# - change the target milestone
if ($field eq "target_milestone") {
return 0;
}
# - change the priority (unless he could have set it originally) # - change the priority (unless he could have set it originally)
if (($field eq "priority") && if ($field eq "priority"
!Param('letsubmitterchoosepriority')) && !Param('letsubmitterchoosepriority'))
{ {
return 0; return 0;
} }
# Allow the reporter to change anything else.
# Allow reporter to change anything else.
return 1; return 1;
} }
# If we haven't returned by this point, then the user doesn't have the # If we haven't returned by this point, then the user doesn't have the
# necessary permissions to change this field. # necessary permissions to change this field.
$PrivilegesRequired = 1;
return 0; return 0;
} }
...@@ -619,19 +619,23 @@ sub ChangeStatus { ...@@ -619,19 +619,23 @@ sub ChangeStatus {
} else { } else {
$::query .= "bug_status = " . SqlQuote($str); $::query .= "bug_status = " . SqlQuote($str);
} }
$::FORM{'bug_status'} = $str; # Used later for call to # If bugs are reassigned and their status is "UNCONFIRMED", they
# CheckCanChangeField to make sure this # should keep this status instead of "NEW" as suggested here.
# is really kosher. # This point is checked for each bug later in the code.
$::FORM{'bug_status'} = $str;
} }
} }
sub ChangeResolution { sub ChangeResolution {
my ($str) = (@_); my ($str) = (@_);
if (!$::FORM{'dontchange'} || if (!$::FORM{'dontchange'}
($str ne $::FORM{'dontchange'})) { || $str ne $::FORM{'dontchange'})
{
DoComma(); DoComma();
$::query .= "resolution = " . SqlQuote($str); $::query .= "resolution = " . SqlQuote($str);
$::FORM{'resolution'} = $str; # Used later by CheckCanChangeField # We define this variable here so that customized installations
# may set rules based on the resolution in CheckCanChangeField.
$::FORM{'resolution'} = $str;
} }
} }
...@@ -761,18 +765,6 @@ if (Param("usebugaliases") && defined($::FORM{'alias'})) { ...@@ -761,18 +765,6 @@ if (Param("usebugaliases") && defined($::FORM{'alias'})) {
} }
} }
if (defined $::FORM{'qa_contact'}) {
my $name = trim($::FORM{'qa_contact'});
if ($name ne $::FORM{'dontchange'}) {
my $id = 0;
if ($name ne "") {
$id = DBNameToIdAndCheck($name);
}
DoComma();
$::query .= "qa_contact = $id";
}
}
# jeff.hedlund@matrixsi.com time tracking data processing: # jeff.hedlund@matrixsi.com time tracking data processing:
if (UserInGroup(Param('timetrackinggroup'))) { if (UserInGroup(Param('timetrackinggroup'))) {
foreach my $field ("estimated_time", "remaining_time") { foreach my $field ("estimated_time", "remaining_time") {
...@@ -874,6 +866,26 @@ if (defined $::FORM{newcc} || defined $::FORM{removecc} || defined $::FORM{massc ...@@ -874,6 +866,26 @@ if (defined $::FORM{newcc} || defined $::FORM{removecc} || defined $::FORM{massc
} }
} }
# Store the new assignee and QA contact IDs (if any). This is the
# only way to keep these informations when bugs are reassigned by
# component as $::FORM{'assigned_to'} and $::FORM{'qa_contact'}
# are not the right fields to look at.
my $assignee;
my $qacontact;
if (defined $::FORM{'qa_contact'}
&& $::FORM{'knob'} ne "reassignbycomponent")
{
$qacontact = 0;
my $name = trim($::FORM{'qa_contact'});
# The QA contact cannot be deleted from show_bug.cgi for a single bug!
if ($name ne $::FORM{'dontchange'}) {
$qacontact = DBNameToIdAndCheck($name) if ($name ne "");
DoComma();
$::query .= "qa_contact = $qacontact";
}
}
CheckFormFieldDefined(\%::FORM, 'knob'); CheckFormFieldDefined(\%::FORM, 'knob');
SWITCH: for ($::FORM{'knob'}) { SWITCH: for ($::FORM{'knob'}) {
...@@ -907,19 +919,20 @@ SWITCH: for ($::FORM{'knob'}) { ...@@ -907,19 +919,20 @@ SWITCH: for ($::FORM{'knob'}) {
ThrowUserError("resolving_remaining_time"); ThrowUserError("resolving_remaining_time");
} }
} }
# Check here, because its the only place we require the resolution
CheckFormField(\%::FORM, 'resolution', \@::settable_resolution);
# don't resolve as fixed while still unresolved blocking bugs # don't resolve as fixed while still unresolved blocking bugs
if (Param("noresolveonopenblockers") && ($::FORM{'resolution'} eq 'FIXED')) { if (Param("noresolveonopenblockers")
my @dependencies = CountOpenDependencies(@idlist); && $::FORM{'resolution'} eq 'FIXED')
if (scalar @dependencies > 0) { {
ThrowUserError("still_unresolved_bugs", my @dependencies = CountOpenDependencies(@idlist);
if (scalar @dependencies > 0) {
ThrowUserError("still_unresolved_bugs",
{ dependencies => \@dependencies, { dependencies => \@dependencies,
dependency_count => scalar @dependencies }); dependency_count => scalar @dependencies });
} }
} }
# Check here, because its the only place we require the resolution
CheckFormField(\%::FORM, 'resolution', \@::settable_resolution);
ChangeStatus('RESOLVED'); ChangeStatus('RESOLVED');
ChangeResolution($::FORM{'resolution'}); ChangeResolution($::FORM{'resolution'});
last SWITCH; last SWITCH;
...@@ -930,12 +943,13 @@ SWITCH: for ($::FORM{'knob'}) { ...@@ -930,12 +943,13 @@ SWITCH: for ($::FORM{'knob'}) {
} }
ChangeStatus('NEW'); ChangeStatus('NEW');
DoComma(); DoComma();
if (!defined$::FORM{'assigned_to'} || if (!defined $::FORM{'assigned_to'}
trim($::FORM{'assigned_to'}) eq "") { || trim($::FORM{'assigned_to'}) eq "")
{
ThrowUserError("reassign_to_empty"); ThrowUserError("reassign_to_empty");
} }
my $newid = DBNameToIdAndCheck(trim($::FORM{'assigned_to'})); $assignee = DBNameToIdAndCheck(trim($::FORM{'assigned_to'}));
$::query .= "assigned_to = $newid"; $::query .= "assigned_to = $assignee";
last SWITCH; last SWITCH;
}; };
/^reassignbycomponent$/ && CheckonComment( "reassignbycomponent" ) && do { /^reassignbycomponent$/ && CheckonComment( "reassignbycomponent" ) && do {
...@@ -951,14 +965,13 @@ SWITCH: for ($::FORM{'knob'}) { ...@@ -951,14 +965,13 @@ SWITCH: for ($::FORM{'knob'}) {
ChangeStatus('NEW'); ChangeStatus('NEW');
SendSQL("SELECT initialowner FROM components " . SendSQL("SELECT initialowner FROM components " .
"WHERE components.id = $comp_id"); "WHERE components.id = $comp_id");
my $newid = FetchOneColumn(); $assignee = FetchOneColumn();
DoComma(); DoComma();
$::query .= "assigned_to = $newid"; $::query .= "assigned_to = $assignee";
if (Param("useqacontact")) { if (Param("useqacontact")) {
SendSQL("SELECT initialqacontact FROM components " . SendSQL("SELECT initialqacontact FROM components " .
"WHERE components.id = $comp_id"); "WHERE components.id = $comp_id");
my $qacontact = FetchOneColumn(); $qacontact = FetchOneColumn() || 0;
$qacontact = 0 unless (defined $qacontact && $qacontact != 0);
DoComma(); DoComma();
$::query .= "qa_contact = $qacontact"; $::query .= "qa_contact = $qacontact";
} }
...@@ -1130,8 +1143,6 @@ foreach my $id (@idlist) { ...@@ -1130,8 +1143,6 @@ foreach my $id (@idlist) {
"group_control_map AS oldcontrolmap READ, " . "group_control_map AS oldcontrolmap READ, " .
"group_control_map AS newcontrolmap READ, " . "group_control_map AS newcontrolmap READ, " .
"group_control_map READ"); "group_control_map READ");
my @oldvalues = SnapShotBug($id);
my %oldhash;
# Fun hack. @::log_columns only contains the component_id, # Fun hack. @::log_columns only contains the component_id,
# not the name (since bug 43600 got fixed). So, we need to have # not the name (since bug 43600 got fixed). So, we need to have
# this id ready for the loop below, otherwise anybody can # this id ready for the loop below, otherwise anybody can
...@@ -1143,31 +1154,58 @@ foreach my $id (@idlist) { ...@@ -1143,31 +1154,58 @@ foreach my $id (@idlist) {
$::FORM{'component_id'} = $::FORM{'component_id'} =
get_component_id($product_id, $::FORM{'component'}); get_component_id($product_id, $::FORM{'component'});
} }
# It may sound crazy to set %formhash for each bug as $::FORM{}
# will not change, but %formhash is modified below and we prefer
# to set it again.
my $i = 0; my $i = 0;
my @oldvalues = SnapShotBug($id);
my %oldhash;
my %formhash;
foreach my $col (@::log_columns) { foreach my $col (@::log_columns) {
# Consider NULL db entries to be equivalent to the empty string # Consider NULL db entries to be equivalent to the empty string
$oldvalues[$i] = '' unless defined($oldvalues[$i]); $oldvalues[$i] = '' unless defined $oldvalues[$i];
$oldhash{$col} = $oldvalues[$i]; $oldhash{$col} = $oldvalues[$i];
if (exists $::FORM{$col}) { $formhash{$col} = $::FORM{$col} if defined $::FORM{$col};
if (!CheckCanChangeField($col, $id, $oldvalues[$i], $::FORM{$col})) { $i++;
# More fun hacking... don't display component_id }
my $vars; # If the user is reassigning bugs, we need to:
if ($col eq 'component_id') { # - convert $newhash{'assigned_to'} and $newhash{'qa_contact'}
$vars->{'oldvalue'} = # email addresses into their corresponding IDs;
get_component_name($oldhash{'component_id'}); # - update $newhash{'bug_status'} to its real state if the bug
$vars->{'newvalue'} = $::FORM{'component'}; # is in the unconfirmed state.
$vars->{'field'} = 'component'; $formhash{'qa_contact'} = $qacontact if Param('useqacontact');
} if ($::FORM{'knob'} eq 'reassignbycomponent'
else { || $::FORM{'knob'} eq 'reassign')
$vars->{'oldvalue'} = $oldvalues[$i]; {
$vars->{'newvalue'} = $::FORM{$col}; $formhash{'assigned_to'} = $assignee;
$vars->{'field'} = $col; if ($oldhash{'bug_status'} eq $::unconfirmedstate) {
} $formhash{'bug_status'} = $oldhash{'bug_status'};
ThrowUserError("illegal_change", $vars, "abort"); }
}
foreach my $col (@::log_columns) {
if (exists $formhash{$col}
&& !CheckCanChangeField($col, $id, $oldhash{$col}, $formhash{$col}))
{
my $vars;
if ($col eq 'component_id') {
# Display the component name
$vars->{'oldvalue'} = get_component_name($oldhash{$col});
$vars->{'newvalue'} = $::FORM{'component'};
$vars->{'field'} = 'component';
} elsif ($col eq 'assigned_to' || $col eq 'qa_contact') {
# Display the assignee or QA contact email address
$vars->{'oldvalue'} = DBID_to_name($oldhash{$col});
$vars->{'newvalue'} = DBID_to_name($formhash{$col});
$vars->{'field'} = $col;
} else {
$vars->{'oldvalue'} = $oldhash{$col};
$vars->{'newvalue'} = $formhash{$col};
$vars->{'field'} = $col;
} }
$vars->{'privs'} = $PrivilegesRequired;
ThrowUserError("illegal_change", $vars, "abort");
} }
$i++;
} }
# 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
...@@ -1184,6 +1222,7 @@ foreach my $id (@idlist) { ...@@ -1184,6 +1222,7 @@ foreach my $id (@idlist) {
$vars->{'oldvalue'} = $oldhash{keywords}; $vars->{'oldvalue'} = $oldhash{keywords};
$vars->{'newvalue'} = "no keywords"; $vars->{'newvalue'} = "no keywords";
$vars->{'field'} = "keywords"; $vars->{'field'} = "keywords";
$vars->{'privs'} = $PrivilegesRequired;
ThrowUserError("illegal_change", $vars, "abort"); ThrowUserError("illegal_change", $vars, "abort");
} }
......
...@@ -187,6 +187,7 @@ function set_assign_to() { ...@@ -187,6 +187,7 @@ function set_assign_to() {
[% INCLUDE global/userselect.html.tmpl [% INCLUDE global/userselect.html.tmpl
name => "assigned_to" name => "assigned_to"
value => assigned_to value => assigned_to
disabled => assigned_to_disabled
size => 32 size => 32
emptyok => 1 emptyok => 1
%] %]
...@@ -200,6 +201,7 @@ function set_assign_to() { ...@@ -200,6 +201,7 @@ function set_assign_to() {
[% INCLUDE global/userselect.html.tmpl [% INCLUDE global/userselect.html.tmpl
name => "cc" name => "cc"
value => cc value => cc
disabled => cc_disabled
size => 45 size => 45
emptyok => 1 emptyok => 1
multiple => 5 multiple => 5
......
...@@ -43,19 +43,20 @@ ...@@ -43,19 +43,20 @@
[% knum = knum + 1 %] [% knum = knum + 1 %]
[% END %] [% END %]
[% IF bug.user.canedit %] [% IF bug.isopened && bug.bug_status != "ASSIGNED" && bug.user.canedit
[% IF bug.isopened %] && (!bug.isunconfirmed || bug.user.canconfirm) %]
[% IF bug.bug_status != "ASSIGNED" && bug.user.canconfirm %] <input type="radio" id="knob-accept" name="knob" value="accept">
<input type="radio" id="knob-accept" name="knob" value="accept"> <label for="knob-accept">
<label for="knob-accept"> Accept [% terms.bug %] (
Accept [% terms.bug %] ( [% IF bug.isunconfirmed %]confirm [% terms.bug %], [% END %]change
[% IF bug.isunconfirmed %]confirm [% terms.bug %], [% END %]change status to <b>ASSIGNED</b>)
status to <b>ASSIGNED</b>) </label>
</label> <br>
<br> [% knum = knum + 1 %]
[% knum = knum + 1 %] [% END %]
[% END %]
[% IF bug.user.canedit || bug.user.isreporter %]
[% IF bug.isopened %]
[% IF bug.resolution %] [% IF bug.resolution %]
<input type="radio" id="knob-clear" name="knob" value="clearresolution"> <input type="radio" id="knob-clear" name="knob" value="clearresolution">
<label for="knob-clear"> <label for="knob-clear">
...@@ -90,45 +91,47 @@ ...@@ -90,45 +91,47 @@
<br> <br>
[% knum = knum + 1 %] [% knum = knum + 1 %]
<input type="radio" id="knob-reassign" name="knob" value="reassign"> [% IF bug.user.canedit %]
<label for="knob-reassign"> <input type="radio" id="knob-reassign" name="knob" value="reassign">
<a href="page.cgi?id=fields.html#assigned_to">Reassign</a> <label for="knob-reassign">
[% terms.bug %] to <a href="page.cgi?id=fields.html#assigned_to">Reassign</a>
</label> [% terms.bug %] to
[% safe_assigned_to = FILTER js; bug.assigned_to.login; END %]
[% INCLUDE global/userselect.html.tmpl
name => "assigned_to"
value => bug.assigned_to.login
size => 32
onchange => "if ((this.value != '$safe_assigned_to') && (this.value != '')) {
document.changeform.knob[$knum].checked=true;
}"
%]
<br>
[% IF bug.isunconfirmed && bug.user.canconfirm %]
&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" id="andconfirm" name="andconfirm">
<label for="andconfirm">
and confirm [% terms.bug %] (change status to <b>NEW</b>)
</label> </label>
[% safe_assigned_to = FILTER js; bug.assigned_to.login; END %]
[% INCLUDE global/userselect.html.tmpl
name => "assigned_to"
value => bug.assigned_to.login
size => 32
onchange => "if ((this.value != '$safe_assigned_to') && (this.value != '')) {
document.changeform.knob[$knum].checked=true;
}"
%]
<br> <br>
[% END %] [% IF bug.isunconfirmed && bug.user.canconfirm %]
[% knum = knum + 1 %] &nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" id="andconfirm" name="andconfirm">
<label for="andconfirm">
and confirm [% terms.bug %] (change status to <b>NEW</b>)
</label>
<br>
[% END %]
[% knum = knum + 1 %]
<input type="radio" id="knob-reassign-cmp" name="knob" value="reassignbycomponent"> <input type="radio" id="knob-reassign-cmp" name="knob" value="reassignbycomponent">
<label for="knob-reassign-cmp"> <label for="knob-reassign-cmp">
Reassign [% terms.bug %] to owner Reassign [% terms.bug %] to owner
[% " and QA contact" IF Param('useqacontact') %] [% " and QA contact" IF Param('useqacontact') %]
of selected component of selected component
</label>
<br>
[% IF bug.isunconfirmed && bug.user.canconfirm %]
&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" id="compconfirm" name="compconfirm">
<label for="compconfirm">
and confirm [% terms.bug %] (change status to <b>NEW</b>)
</label> </label>
<br> <br>
[% IF bug.isunconfirmed && bug.user.canconfirm %]
&nbsp;&nbsp;&nbsp;&nbsp;<input type="checkbox" id="compconfirm" name="compconfirm">
<label for="compconfirm">
and confirm [% terms.bug %] (change status to <b>NEW</b>)
</label>
<br>
[% END %]
[% knum = knum + 1 %]
[% END %] [% END %]
[% knum = knum + 1 %]
[% ELSE %] [% ELSE %]
[% IF bug.resolution != "MOVED" || [% IF bug.resolution != "MOVED" ||
(bug.resolution == "MOVED" && bug.user.canmove) %] (bug.resolution == "MOVED" && bug.user.canmove) %]
......
...@@ -436,10 +436,14 @@ ...@@ -436,10 +436,14 @@
You tried to change the You tried to change the
<strong>[% field_descs.$field FILTER html %]</strong> field <strong>[% field_descs.$field FILTER html %]</strong> field
from <em>[% oldvalue FILTER html %]</em> to from <em>[% oldvalue FILTER html %]</em> to
<em>[% newvalue FILTER html %]</em>, <em>[% newvalue FILTER html %]</em>, but only
but only the owner or submitter of the [% terms.bug %], or a [% IF privs < 3 %]
sufficiently empowered user, may change that field. the owner
[% IF privs < 2 %] or reporter [% END %]
of the [% terms.bug %], or
[% END %]
a sufficiently empowered user may change that field.
[% ELSIF error == "illegal_changed_in_last_x_days" %] [% ELSIF error == "illegal_changed_in_last_x_days" %]
[% title = "Your Search Makes No Sense" %] [% title = "Your Search Makes No Sense" %]
The <em>Changed in last ___ days</em> field must be a simple number. The <em>Changed in last ___ days</em> field must be a simple number.
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
# name: mandatory; field name # name: mandatory; field name
# value: optional; default field value/selection # value: optional; default field value/selection
# onchange: optional; onchange attribute value # onchange: optional; onchange attribute value
# disabled: optional; if true, the field is disabled
# accesskey: optional, input only; accesskey attribute value # accesskey: optional, input only; accesskey attribute value
# size: optional, input only; size attribute value # size: optional, input only; size attribute value
# emptyok: optional, select only; if true, prepend menu option to start of select # emptyok: optional, select only; if true, prepend menu option to start of select
...@@ -30,6 +31,7 @@ ...@@ -30,6 +31,7 @@
[% IF Param("usemenuforusers") %] [% IF Param("usemenuforusers") %]
<select name="[% name FILTER html %]" <select name="[% name FILTER html %]"
[% IF onchange %] onchange="[% onchange FILTER html %]" [% END %] [% IF onchange %] onchange="[% onchange FILTER html %]" [% END %]
[% IF disabled %] disabled="[% disabled FILTER html %]" [% END %]
[% IF accesskey %] accesskey="[% accesskey FILTER html %]" [% END %] [% IF accesskey %] accesskey="[% accesskey FILTER html %]" [% END %]
[% IF multiple %] multiple="multiple" size="[% multiple FILTER html %]" [% END %] [% IF multiple %] multiple="multiple" size="[% multiple FILTER html %]" [% END %]
> >
...@@ -48,9 +50,10 @@ ...@@ -48,9 +50,10 @@
<input <input
name="[% name FILTER html %]" name="[% name FILTER html %]"
value="[% value FILTER html %]" value="[% value FILTER html %]"
[% IF onchange %] onchange="[% onchange FILTER html %]" [% END %]
[% IF disabled %] disabled="[% disabled FILTER html %]" [% END %]
[% IF accesskey %] accesskey="[% accesskey FILTER html %]" [% END %] [% IF accesskey %] accesskey="[% accesskey FILTER html %]" [% END %]
[% IF size %] size="[% size FILTER html %]" [% END %] [% IF size %] size="[% size FILTER html %]" [% END %]
[% IF onchange %] onchange="[% onchange FILTER html %]" [% END %]
> >
[% END %] [% END %]
......
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