diff options
-rw-r--r-- | Bugzilla/Hook.pm | 28 | ||||
-rwxr-xr-x | email_in.pl | 6 | ||||
-rw-r--r-- | extensions/Example/Extension.pm | 42 |
3 files changed, 76 insertions, 0 deletions
diff --git a/Bugzilla/Hook.pm b/Bugzilla/Hook.pm index 8958b7785..f6fff241a 100644 --- a/Bugzilla/Hook.pm +++ b/Bugzilla/Hook.pm @@ -569,6 +569,34 @@ L</config_add_panels> if you want to add new panels. =back +=head2 email_in_before_parse + +This happens right after an inbound email is converted into an Email::MIME +object, but before we start parsing the email to extract field data. This +means the email has already been decoded for you. It gives you a chance +to interact with the email itself before L<email_in> starts parsing its content. + +=over + +=item C<mail> - An Email::MIME object. The decoded incoming email. + +=item C<fields> - A hashref. The hash which will contain extracted data. + +=back + +=head2 email_in_after_parse + +This happens after all the data has been extracted from the email, but before +the reporter is validated, during L<email_in>. This lets you do things after +the normal parsing of the email, such as sanitizing field data, changing the +user account being used to file a bug, etc. + +=over + +=item C<fields> - A hashref. The hash containing the extracted field data. + +=back + =head2 enter_bug_entrydefaultvars B<DEPRECATED> - Use L</template_before_process> instead. diff --git a/email_in.pl b/email_in.pl index 78ac32ca6..393061cd5 100755 --- a/email_in.pl +++ b/email_in.pl @@ -54,6 +54,7 @@ use Bugzilla::Mailer; use Bugzilla::Token; use Bugzilla::User; use Bugzilla::Util; +use Bugzilla::Hook; ############# # Constants # @@ -76,6 +77,8 @@ sub parse_mail { $input_email = Email::MIME->new($mail_text); my %fields = %{ $switch{'default'} || {} }; + Bugzilla::Hook::process('email_in_before_parse', { mail => $input_email, + fields => \%fields }); my $summary = $input_email->header('Subject'); if ($summary =~ /\[\S+ (\d+)\](.*)/i) { @@ -394,6 +397,9 @@ Bugzilla->usage_mode(USAGE_MODE_EMAIL); my @mail_lines = <STDIN>; my $mail_text = join("", @mail_lines); my $mail_fields = parse_mail($mail_text); + +Bugzilla::Hook::process('email_in_after_parse', { fields => $mail_fields }); + my $attachments = delete $mail_fields->{'attachments'}; my $username = $mail_fields->{'reporter'}; diff --git a/extensions/Example/Extension.pm b/extensions/Example/Extension.pm index f16ddf725..b1d091794 100644 --- a/extensions/Example/Extension.pm +++ b/extensions/Example/Extension.pm @@ -278,6 +278,48 @@ sub config_modify_panels { push(@{ $verify_class->{choices} }, 'Example'); } +sub email_in_before_parse { + my ($self, $args) = @_; + + my $subject = $args->{mail}->header('Subject'); + # Correctly extract the bug ID from email subjects of the form [Bug comp/NNN]. + if ($subject =~ /\[.*(\d+)\].*/) { + $args->{fields}->{bug_id} = $1; + } +} + +sub email_in_after_parse { + my ($self, $args) = @_; + my $reporter = $args->{fields}->{reporter}; + my $dbh = Bugzilla->dbh; + + # No other check needed if this is a valid regular user. + return if login_to_id($reporter); + + # The reporter is not a regular user. We create an account for him, + # but he can only comment on existing bugs. + # This is useful for people who reply by email to bugmails received + # in mailing-lists. + if ($args->{fields}->{bug_id}) { + # WARNING: we return now to skip the remaining code below. + # You must understand that removing this line would make the code + # below effective! Do it only if you are OK with the behavior + # described here. + return; + + Bugzilla::User->create({ login_name => $reporter, cryptpassword => '*' }); + + # For security reasons, delete all fields unrelated to comments. + foreach my $field (keys %{$args->{fields}}) { + next if $field =~ /^(?:bug_id|comment|reporter)$/; + delete $args->{fields}->{$field}; + } + } + else { + ThrowUserError('invalid_username', { name => $reporter }); + } +} + sub flag_end_of_update { my ($self, $args) = @_; |