From bee459e8be50b73593928fc5653de3933bfde6f6 Mon Sep 17 00:00:00 2001 From: "mkanat%bugzilla.org" <> Date: Tue, 17 Oct 2006 13:24:18 +0000 Subject: Bug 353994: [email_in] Make the email interface able to update (process) bugs Patch By Max Kanat-Alexander r=colin, r=ghendricks, a=myk --- email_in.pl | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- process_bug.cgi | 97 +++++++++++++++++++++++++++++++++++--------------- 2 files changed, 175 insertions(+), 29 deletions(-) diff --git a/email_in.pl b/email_in.pl index c213554a8..4d20d52cc 100644 --- a/email_in.pl +++ b/email_in.pl @@ -194,6 +194,66 @@ sub post_bug { require 'post_bug.cgi'; } +sub process_bug { + my ($fields_in) = @_; + + my %fields = %$fields_in; + + my $bug_id = $fields{'bug_id'}; + $fields{'id'} = $bug_id; + delete $fields{'bug_id'}; + + debug_print("Updating Bug $fields{id}..."); + + ValidateBugID($bug_id); + my $bug = new Bugzilla::Bug($bug_id); + + if ($fields{'assigned_to'}) { + $fields{'knob'} = 'reassign'; + } + if (my $status = $fields{'bug_status'}) { + $fields{'knob'} = 'confirm' if $status =~ /NEW/i; + $fields{'knob'} = 'accept' if $status =~ /ASSIGNED/i; + $fields{'knob'} = 'clearresolution' if $status =~ /REOPENED/i; + $fields{'knob'} = 'verify' if $status =~ /VERIFIED/i; + $fields{'knob'} = 'close' if $status =~ /CLOSED/i; + } + if ($fields{'dup_id'}) { + $fields{'knob'} = 'duplicate'; + } + if ($fields{'resolution'}) { + $fields{'knob'} = 'resolve'; + } + + # Make sure we don't get prompted if we have to change the default + # groups. + if ($fields{'product'}) { + $fields{'addtonewgroup'} = 0; + } + + foreach my $field (REQUIRED_PROCESS_FIELDS) { + my $value = $bug->$field; + if (ref $value) { + $value = join(',', @$value); + } + $fields{$field} ||= $value; + } + + # Make it possible to remove CCs. + if ($fields{'removecc'}) { + $fields{'cc'} = [split(',', $fields{'removecc'})]; + $fields{'removecc'} = 1; + } + + my $cgi = Bugzilla->cgi; + foreach my $field (keys %fields) { + $cgi->param(-name => $field, -value => $fields{$field}); + } + $cgi->param('longdesclength', scalar $bug->longdescs); + + require 'process_bug.cgi'; +} + ###################### # Helper Subroutines # ###################### @@ -318,7 +378,12 @@ my $user = Bugzilla::User->new({ name => $username }) Bugzilla->set_user($user); -post_bug($mail_fields); +if ($mail_fields->{'bug_id'}) { + process_bug($mail_fields); +} +else { + post_bug($mail_fields); +} __END__ @@ -383,6 +448,46 @@ C must be a valid Bugzilla account. Note that signatures must start with '-- ', the standard signature border. +=head2 Modifying an Existing Bug + +Bugzilla determines what bug you want to modify in one of two ways: + +=over + +=item * + +Your subject starts with [Bug 123456] -- then it modifies bug 123456. + +=item * + +You include C<@bug_id = 123456> in the first lines of the email. + +=back + +If you do both, C<@bug_id> takes precedence. + +You send your email in the same format as for creating a bug, except +that you only specify the fields you want to change. If the very +first non-blank line of the email doesn't begin with C<@>, then it +will be assumed that you are only adding a comment to the bug. + +Note that when updating a bug, the C header is ignored, +except for getting the bug ID. If you want to change the bug's summary, +you have to specify C<@short_desc> as one of the fields to change. + +Please remember not to include any extra text in your emails, as that +text will also be added as a comment. This includes any text that your +email client automatically quoted and included, if this is a reply to +another email. + +=head3 Adding/Removing CCs + +You can't just add CCs to a bug by using the C<@cc> parameter like you +can when you're filing a bug. To add CCs, you can specify them in a +comma-separated list in C<@newcc>. + +To remove CCs, specify them as a comma-separated list in C<@removecc>. + =head2 Errors If your request cannot be completed for any reason, Bugzilla will diff --git a/process_bug.cgi b/process_bug.cgi index e671b9d76..dbe62f606 100755 --- a/process_bug.cgi +++ b/process_bug.cgi @@ -47,6 +47,7 @@ use lib qw(.); use Bugzilla; use Bugzilla::Constants; use Bugzilla::Bug; +use Bugzilla::BugMail; use Bugzilla::Mailer; use Bugzilla::User; use Bugzilla::Util; @@ -104,6 +105,20 @@ sub AnyDefaultGroups { return $any_default; } +# Used to send email when an update is done. +sub send_results { + my ($bug_id, $vars) = @_; + my $template = Bugzilla->template; + if (Bugzilla->usage_mode == USAGE_MODE_EMAIL) { + Bugzilla::BugMail::Send($bug_id, $vars->{'mailrecipients'}); + } + else { + $template->process("bug/process/results.html.tmpl", $vars) + || ThrowTemplateError($template->error()); + } + $vars->{'header_done'} = 1; +} + ###################################################################### # Begin Data/Security Validation ###################################################################### @@ -231,7 +246,7 @@ Bugzilla::Flag::validate($cgi, $cgi->param('id')); # End Data/Security Validation ###################################################################### -print $cgi->header(); +print $cgi->header() unless Bugzilla->usage_mode == USAGE_MODE_EMAIL; $vars->{'title_tag'} = "bug_processed"; # Set the title if we can see a mid-air coming. This test may have false @@ -364,6 +379,24 @@ if (((defined $cgi->param('id') && $cgi->param('product') ne $oldproduct) # a verification form. if (!$vok || !$cok || !$mok || (AnyDefaultGroups() && !defined $cgi->param('addtonewgroup'))) { + + if (Bugzilla->usage_mode == USAGE_MODE_EMAIL) { + if (!$vok) { + ThrowUserError('version_not_valid', { + version => $cgi->param('version'), + product => $cgi->param('product')}); + } + if (!$cok) { + ThrowUserError('component_not_valid', { + product => $cgi->param('product'), + name => $cgi->param('component')}); + } + if (!$mok) { + ThrowUserError('milestone_not_valid', { + product => $cgi->param('product'), + milestone => $cgi->param('target_milestone')}); + } + } if (!$vok || !$cok || !$mok) { $vars->{'verify_fields'} = 1; @@ -433,6 +466,12 @@ sub DuplicateUserConfirm { $cgi->param('confirm_add_duplicate', '1'); return; } + elsif (Bugzilla->usage_mode == USAGE_MODE_EMAIL) { + # The email interface defaults to the safe alternative, which is + # not CC'ing the user. + $cgi->param('confirm_add_duplicate', 0); + return; + } $vars->{'cclist_accessible'} = $dbh->selectrow_array( q{SELECT cclist_accessible FROM bugs WHERE bug_id = ?}, @@ -548,10 +587,7 @@ if ($action eq Bugzilla->params->{'move-button-text'}) { $vars->{'mailrecipients'} = { 'changer' => $user->login }; $vars->{'id'} = $id; $vars->{'type'} = "move"; - - $template->process("bug/process/results.html.tmpl", $vars) - || ThrowTemplateError($template->error()); - $vars->{'header_done'} = 1; + send_results($id, $vars); } # Prepare and send all data about these bugs to the new database my $to = Bugzilla->params->{'move-to-address'}; @@ -578,10 +614,12 @@ if ($action eq Bugzilla->params->{'move-button-text'}) { MessageToMTA($msg); # End the response page. - $template->process("bug/navigate.html.tmpl", $vars) - || ThrowTemplateError($template->error()); - $template->process("global/footer.html.tmpl", $vars) - || ThrowTemplateError($template->error()); + unless (Bugzilla->usage_mode == USAGE_MODE_EMAIL) { + $template->process("bug/navigate.html.tmpl", $vars) + || ThrowTemplateError($template->error()); + $template->process("global/footer.html.tmpl", $vars) + || ThrowTemplateError($template->error()); + } exit; } @@ -2061,20 +2099,17 @@ foreach my $id (@idlist) { # Let the user know the bug was changed and who did and didn't # receive email about the change. - $template->process("bug/process/results.html.tmpl", $vars) - || ThrowTemplateError($template->error()); - $vars->{'header_done'} = 1; - + send_results($id, $vars); + if ($duplicate) { $vars->{'mailrecipients'} = { 'changer' => Bugzilla->user->login }; $vars->{'id'} = $duplicate; $vars->{'type'} = "dupe"; - # Let the user know a duplication notation was added to the original bug. - $template->process("bug/process/results.html.tmpl", $vars) - || ThrowTemplateError($template->error()); - $vars->{'header_done'} = 1; + # Let the user know a duplication notation was added to the + # original bug. + send_results($duplicate, $vars); } if ($check_dep_bugs) { @@ -2083,12 +2118,11 @@ foreach my $id (@idlist) { $vars->{'id'} = $k; $vars->{'type'} = "dep"; - # Let the user (if he is able to see the bug) know we checked to see - # if we should email notice of this change to users with a relationship - # to the dependent bug and who did and didn't receive email about it. - $template->process("bug/process/results.html.tmpl", $vars) - || ThrowTemplateError($template->error()); - $vars->{'header_done'} = 1; + # Let the user (if he is able to see the bug) know we checked to + # see if we should email notice of this change to users with a + # relationship to the dependent bug and who did and didn't + # receive email about it. + send_results($k, $vars); } } } @@ -2107,7 +2141,10 @@ if (defined $cgi->param('id')) { $action = 'nothing'; } -if ($action eq 'next_bug') { +if (Bugzilla->usage_mode == USAGE_MODE_EMAIL) { + # Do nothing. +} +elsif ($action eq 'next_bug') { my $next_bug; my $cur = lsearch(\@bug_list, $cgi->param("id")); if ($cur >= 0 && $cur < $#bug_list) { @@ -2144,7 +2181,11 @@ if ($action eq 'next_bug') { } # End the response page. -$template->process("bug/navigate.html.tmpl", $vars) - || ThrowTemplateError($template->error()); -$template->process("global/footer.html.tmpl", $vars) - || ThrowTemplateError($template->error()); +unless (Bugzilla->usage_mode == USAGE_MODE_EMAIL) { + $template->process("bug/navigate.html.tmpl", $vars) + || ThrowTemplateError($template->error()); + $template->process("global/footer.html.tmpl", $vars) + || ThrowTemplateError($template->error()); +} + +1; -- cgit v1.2.3-24-g4f1b