summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFrédéric Buclin <LpSolit@gmail.com>2010-11-04 18:09:30 +0100
committerFrédéric Buclin <LpSolit@gmail.com>2010-11-04 18:09:30 +0100
commitdc7395379aee87d98692a15e29a64055fc02801d (patch)
tree6384ad244c45e3f48ed241cba2f64c22c9aeae44
parenta3c3abffe5a964685d596a82261fde79b416107a (diff)
downloadbugzilla-dc7395379aee87d98692a15e29a64055fc02801d.tar.gz
bugzilla-dc7395379aee87d98692a15e29a64055fc02801d.tar.xz
Bug 596611: Add a hook to email_in.pl
r/a=mkanat
-rw-r--r--Bugzilla/Hook.pm28
-rwxr-xr-xemail_in.pl6
-rw-r--r--extensions/Example/Extension.pm42
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) = @_;