X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=rt%2Flib%2FRT%2FEmailParser.pm;h=3a99e5a5ebd02e1ae8ae31633c18d54cf7073a73;hp=8ed810c561ca8dd4f1c8e4c98a02bcfbaa198f46;hb=673b9a458d9138523026963df6fa3b4683e09bae;hpb=f7fd2a3e34da751cbc02bbf215e99c6dc89adc15 diff --git a/rt/lib/RT/EmailParser.pm b/rt/lib/RT/EmailParser.pm index 8ed810c56..3a99e5a5e 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-2004 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC # # # (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,6 +77,7 @@ ok(require RT::EmailParser); =head2 new +Returns a new RT::EmailParser object =cut @@ -89,96 +90,12 @@ sub new { } - -# {{{ 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); - } -} - -# }}} - +# {{{ sub SmartParseMIMEEntityFromScalar =head2 SmartParseMIMEEntityFromScalar { Message => SCALAR_REF, Decode => BOOL } Parse a message stored in a scalar from scalar_ref - =cut sub SmartParseMIMEEntityFromScalar { @@ -223,8 +140,16 @@ sub SmartParseMIMEEntityFromScalar { } +# }}} + # {{{ sub ParseMIMEEntityFromSTDIN +=head2 ParseMIMEEntityFromSTDIN + +Parse a message from standard input + +=cut + sub ParseMIMEEntityFromSTDIN { my $self = shift; my $postprocess = (@_ ? shift : 1); @@ -233,6 +158,8 @@ sub ParseMIMEEntityFromSTDIN { # }}} +# {{{ ParseMIMEEntityFromScalar + =head2 ParseMIMEEntityFromScalar $message Takes either a scalar or a reference to a scalr which contains a stringified MIME message. @@ -241,7 +168,6 @@ Parses it. Returns true if it wins. Returns false if it loses. - =cut sub ParseMIMEEntityFromScalar { @@ -251,6 +177,7 @@ sub ParseMIMEEntityFromScalar { $self->_ParseMIMEEntity($message,'parse_data', $postprocess); } +# }}} # {{{ ParseMIMEEntityFromFilehandle *FH @@ -285,8 +212,8 @@ sub ParseMIMEEntityFromFile { } # }}} -# -# {{{ _ParseMIMEEntity { + +# {{{ _ParseMIMEEntity sub _ParseMIMEEntity { my $self = shift; my $message = shift; @@ -314,7 +241,6 @@ sub _ParseMIMEEntity { } - # }}} # {{{ _PostProcessNewEntity @@ -330,12 +256,17 @@ 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; } @@ -346,17 +277,10 @@ sub _PostProcessNewEntity { sub ParseTicketId { my $self = shift; + $RT::Logger->warnings("RT::EmailParser->ParseTicketId deprecated. You should be using RT::Interface::Email"); - 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); - } + require RT::Interface::Email; + RT::Interface::Email::ParseTicketId(@_); } # }}} @@ -393,10 +317,10 @@ sub ParseCcAddressesFromHead { my $Address = $AddrObj->address; my $user = RT::User->new($RT::SystemUser); $Address = $user->CanonicalizeEmailAddress($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) ); + 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) ); push ( @Addresses, $Address ); } @@ -489,7 +413,7 @@ sub ParseAddressFromHeader { # {{{ IsRTAddress -=item IsRTaddress ADDRESS +=head2 IsRTaddress ADDRESS Takes a single parameter, an email address. Returns true if that address matches the $RTAddressRegexp. @@ -523,7 +447,7 @@ sub IsRTAddress { # {{{ CullRTAddresses -=item CullRTAddresses ARRAY +=head2 CullRTAddresses ARRAY Takes a single argument, an array of email addresses. Returns the same array with any IsRTAddress()es weeded out. @@ -544,7 +468,10 @@ sub CullRTAddresses { my @addrlist; foreach my $addr( @addresses ) { - push (@addrlist, $addr) unless IsRTAddress("", $addr); + # 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); } return (@addrlist); } @@ -568,7 +495,7 @@ sub CullRTAddresses { # template for the rejection message. -=item LookupExternalUserInfo +=head2 LookupExternalUserInfo LookupExternalUserInfo is a site-definable method for synchronizing incoming users with an external data source. @@ -581,12 +508,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. @@ -641,6 +568,7 @@ sub Entity { } # }}} + # {{{ _SetupMIMEParser =head2 _SetupMIMEParser $parser @@ -686,7 +614,6 @@ sub _SetupMIMEParser { # Temp files should never be recycled, especially when running under perl taint checking $parser->tmp_recycling(0); - }