summaryrefslogtreecommitdiff
path: root/rt/lib/RT/EmailParser.pm
diff options
context:
space:
mode:
Diffstat (limited to 'rt/lib/RT/EmailParser.pm')
-rw-r--r--rt/lib/RT/EmailParser.pm163
1 files changed, 118 insertions, 45 deletions
diff --git a/rt/lib/RT/EmailParser.pm b/rt/lib/RT/EmailParser.pm
index 3a99e5a5e..8ed810c56 100644
--- a/rt/lib/RT/EmailParser.pm
+++ b/rt/lib/RT/EmailParser.pm
@@ -1,8 +1,8 @@
-# BEGIN BPS TAGGED BLOCK {{{
+# {{{ BEGIN BPS TAGGED BLOCK
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2004 Best Practical Solutions, LLC
# <jesse@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -42,7 +42,7 @@
# works based on those contributions, and sublicense and distribute
# those contributions and any derivatives thereof.
#
-# END BPS TAGGED BLOCK }}}
+# }}} END BPS TAGGED BLOCK
package RT::EmailParser;
@@ -77,7 +77,6 @@ ok(require RT::EmailParser);
=head2 new
-Returns a new RT::EmailParser object
=cut
@@ -90,12 +89,96 @@ sub new {
}
-# {{{ sub SmartParseMIMEEntityFromScalar
+
+# {{{ sub debug
+
+sub debug {
+ my $val = shift;
+ my ($debug);
+ if ($val) {
+ $RT::Logger->debug( $val . "\n" );
+ if ($debug) {
+ print STDERR "$val\n";
+ }
+ }
+ if ($debug) {
+ return (1);
+ }
+}
+
+# }}}
+
+# {{{ sub CheckForLoops
+
+sub CheckForLoops {
+ my $self = shift;
+
+ my $head = $self->Head;
+
+ #If this instance of RT sent it our, we don't want to take it in
+ my $RTLoop = $head->get("X-RT-Loop-Prevention") || "";
+ chomp($RTLoop); #remove that newline
+ if ( $RTLoop =~ /^\Q$RT::rtname\E/o ) {
+ return (1);
+ }
+
+ # TODO: We might not trap the case where RT instance A sends a mail
+ # to RT instance B which sends a mail to ...
+ return (undef);
+}
+
+# }}}
+
+# {{{ sub CheckForSuspiciousSender
+
+sub CheckForSuspiciousSender {
+ my $self = shift;
+
+ #if it's from a postmaster or mailer daemon, it's likely a bounce.
+
+ #TODO: better algorithms needed here - there is no standards for
+ #bounces, so it's very difficult to separate them from anything
+ #else. At the other hand, the Return-To address is only ment to be
+ #used as an error channel, we might want to put up a separate
+ #Return-To address which is treated differently.
+
+ #TODO: search through the whole email and find the right Ticket ID.
+
+ my ( $From, $junk ) = $self->ParseSenderAddressFromHead();
+
+ if ( ( $From =~ /^mailer-daemon/i ) or ( $From =~ /^postmaster/i ) ) {
+ return (1);
+
+ }
+
+ return (undef);
+
+}
+
+# }}}
+
+# {{{ sub CheckForAutoGenerated
+sub CheckForAutoGenerated {
+ my $self = shift;
+ my $head = $self->Head;
+
+ my $Precedence = $head->get("Precedence") || "";
+ if ( $Precedence =~ /^(bulk|junk)/i ) {
+ return (1);
+ }
+ else {
+ return (undef);
+ }
+}
+
+# }}}
+
=head2 SmartParseMIMEEntityFromScalar { Message => SCALAR_REF, Decode => BOOL }
Parse a message stored in a scalar from scalar_ref
+
=cut
sub SmartParseMIMEEntityFromScalar {
@@ -140,16 +223,8 @@ sub SmartParseMIMEEntityFromScalar {
}
-# }}}
-
# {{{ sub ParseMIMEEntityFromSTDIN
-=head2 ParseMIMEEntityFromSTDIN
-
-Parse a message from standard input
-
-=cut
-
sub ParseMIMEEntityFromSTDIN {
my $self = shift;
my $postprocess = (@_ ? shift : 1);
@@ -158,8 +233,6 @@ sub ParseMIMEEntityFromSTDIN {
# }}}
-# {{{ ParseMIMEEntityFromScalar
-
=head2 ParseMIMEEntityFromScalar $message
Takes either a scalar or a reference to a scalr which contains a stringified MIME message.
@@ -168,6 +241,7 @@ Parses it.
Returns true if it wins.
Returns false if it loses.
+
=cut
sub ParseMIMEEntityFromScalar {
@@ -177,7 +251,6 @@ sub ParseMIMEEntityFromScalar {
$self->_ParseMIMEEntity($message,'parse_data', $postprocess);
}
-# }}}
# {{{ ParseMIMEEntityFromFilehandle *FH
@@ -212,8 +285,8 @@ sub ParseMIMEEntityFromFile {
}
# }}}
-
-# {{{ _ParseMIMEEntity
+#
+# {{{ _ParseMIMEEntity {
sub _ParseMIMEEntity {
my $self = shift;
my $message = shift;
@@ -241,6 +314,7 @@ sub _ParseMIMEEntity {
}
+
# }}}
# {{{ _PostProcessNewEntity
@@ -256,17 +330,12 @@ sub _PostProcessNewEntity {
#Now we've got a parsed mime object.
- # Unfold headers that are have embedded newlines
- # Better do this before conversion or it will break
- # with multiline encoded Subject (RFC2047) (fsck.com #5594)
-
- $self->Head->unfold;
-
-
# try to convert text parts into utf-8 charset
RT::I18N::SetMIMEEntityToEncoding($self->{'entity'}, 'utf-8');
+ # Unfold headers that are have embedded newlines
+ $self->Head->unfold;
}
@@ -277,10 +346,17 @@ sub _PostProcessNewEntity {
sub ParseTicketId {
my $self = shift;
- $RT::Logger->warnings("RT::EmailParser->ParseTicketId deprecated. You should be using RT::Interface::Email");
- require RT::Interface::Email;
- RT::Interface::Email::ParseTicketId(@_);
+ my $Subject = shift;
+
+ if ( $Subject =~ s/\[\Q$RT::rtname\E\s+\#(\d+)\s*\]//i ) {
+ my $id = $1;
+ $RT::Logger->debug("Found a ticket ID. It's $id");
+ return ($id);
+ }
+ else {
+ return (undef);
+ }
}
# }}}
@@ -317,10 +393,10 @@ sub ParseCcAddressesFromHead {
my $Address = $AddrObj->address;
my $user = RT::User->new($RT::SystemUser);
$Address = $user->CanonicalizeEmailAddress($Address);
- next if ( lc $args{'CurrentUser'}->EmailAddress eq lc $Address );
- next if ( lc $args{'QueueObj'}->CorrespondAddress eq lc $Address );
- next if ( lc $args{'QueueObj'}->CommentAddress eq lc $Address );
- next if ( $self->IsRTAddress($Address) );
+ next if ( $args{'CurrentUser'}->EmailAddress =~ /^$Address$/i );
+ next if ( $args{'QueueObj'}->CorrespondAddress =~ /^$Address$/i );
+ next if ( $args{'QueueObj'}->CommentAddress =~ /^$Address$/i );
+ next if ( IsRTAddress($Address) );
push ( @Addresses, $Address );
}
@@ -413,7 +489,7 @@ sub ParseAddressFromHeader {
# {{{ IsRTAddress
-=head2 IsRTaddress ADDRESS
+=item IsRTaddress ADDRESS
Takes a single parameter, an email address.
Returns true if that address matches the $RTAddressRegexp.
@@ -447,7 +523,7 @@ sub IsRTAddress {
# {{{ CullRTAddresses
-=head2 CullRTAddresses ARRAY
+=item CullRTAddresses ARRAY
Takes a single argument, an array of email addresses.
Returns the same array with any IsRTAddress()es weeded out.
@@ -468,10 +544,7 @@ sub CullRTAddresses {
my @addrlist;
foreach my $addr( @addresses ) {
- # We use the class instead of the instance
- # because sloppy code calls this method
- # without a $self
- push (@addrlist, $addr) unless RT::EmailParser->IsRTAddress($addr);
+ push (@addrlist, $addr) unless IsRTAddress("", $addr);
}
return (@addrlist);
}
@@ -495,7 +568,7 @@ sub CullRTAddresses {
# template for the rejection message.
-=head2 LookupExternalUserInfo
+=item LookupExternalUserInfo
LookupExternalUserInfo is a site-definable method for synchronizing
incoming users with an external data source.
@@ -508,12 +581,12 @@ sub CullRTAddresses {
It returns (FoundInExternalDatabase, ParamHash);
- FoundInExternalDatabase must be set to 1 before return if the user
- was found in the external database.
+ FoundInExternalDatabase must be set to 1 before return if the user was
+ found in the external database.
- ParamHash is a Perl parameter hash which can contain at least the
- following fields. These fields are used to populate RT's users
- database when the user is created.
+ ParamHash is a Perl parameter hash which can contain at least the following
+ fields. These fields are used to populate RT's users database when the user
+ is created
EmailAddress is the email address that RT should use for this user.
Name is the 'Name' attribute RT should use for this user.
@@ -568,7 +641,6 @@ sub Entity {
}
# }}}
-
# {{{ _SetupMIMEParser
=head2 _SetupMIMEParser $parser
@@ -614,6 +686,7 @@ sub _SetupMIMEParser {
# Temp files should never be recycled, especially when running under perl taint checking
$parser->tmp_recycling(0);
+
}