This commit was generated by cvs2svn to compensate for changes in r4407,
[freeside.git] / rt / lib / RT / EmailParser.pm
index 8ed810c..3a99e5a 100644 (file)
@@ -1,8 +1,8 @@
-# {{{ BEGIN BPS TAGGED BLOCK
+# BEGIN BPS TAGGED BLOCK {{{
 # 
 # COPYRIGHT:
 #  
 # 
 # COPYRIGHT:
 #  
-# This software is Copyright (c) 1996-2004 Best Practical Solutions, LLC 
+# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC 
 #                                          <jesse@bestpractical.com>
 # 
 # (Except where explicitly superseded by other copyright notices)
 #                                          <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.
 # 
 # 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;
 
 
 package RT::EmailParser;
 
 
@@ -77,6 +77,7 @@ ok(require RT::EmailParser);
 
 =head2 new
 
 
 =head2 new
 
+Returns a new RT::EmailParser object
 
 =cut
 
 
 =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
 
 
 =head2 SmartParseMIMEEntityFromScalar { Message => SCALAR_REF, Decode => BOOL }
 
 Parse a message stored in a scalar from scalar_ref
 
-
 =cut
 
 sub SmartParseMIMEEntityFromScalar {
 =cut
 
 sub SmartParseMIMEEntityFromScalar {
@@ -223,8 +140,16 @@ sub SmartParseMIMEEntityFromScalar {
 
 }
 
 
 }
 
+# }}}
+
 # {{{ sub ParseMIMEEntityFromSTDIN
 
 # {{{ sub ParseMIMEEntityFromSTDIN
 
+=head2 ParseMIMEEntityFromSTDIN
+
+Parse a message from standard input
+
+=cut
+
 sub ParseMIMEEntityFromSTDIN {
     my $self = shift;
     my $postprocess = (@_ ? shift : 1);
 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.
 =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.
 
 Returns true if it wins.
 Returns false if it loses.
 
-
 =cut
 
 sub ParseMIMEEntityFromScalar {
 =cut
 
 sub ParseMIMEEntityFromScalar {
@@ -251,6 +177,7 @@ sub ParseMIMEEntityFromScalar {
     $self->_ParseMIMEEntity($message,'parse_data', $postprocess);
 }
 
     $self->_ParseMIMEEntity($message,'parse_data', $postprocess);
 }
 
+# }}}
 
 # {{{ ParseMIMEEntityFromFilehandle *FH
 
 
 # {{{ ParseMIMEEntityFromFilehandle *FH
 
@@ -285,8 +212,8 @@ sub ParseMIMEEntityFromFile {
 }
 
 # }}}
 }
 
 # }}}
-#
-#  {{{ _ParseMIMEEntity {
+
+# {{{ _ParseMIMEEntity
 sub _ParseMIMEEntity {
     my $self = shift;
     my $message = shift;
 sub _ParseMIMEEntity {
     my $self = shift;
     my $message = shift;
@@ -314,7 +241,6 @@ sub _ParseMIMEEntity {
 
 }
 
 
 }
 
-
 # }}}
 
 # {{{ _PostProcessNewEntity 
 # }}}
 
 # {{{ _PostProcessNewEntity 
@@ -330,12 +256,17 @@ sub _PostProcessNewEntity {
 
     #Now we've got a parsed mime object. 
 
 
     #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');
 
 
     # 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;
 
 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);
         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 );
     }
 
         push ( @Addresses, $Address );
     }
@@ -489,7 +413,7 @@ sub ParseAddressFromHeader {
 
 # {{{ IsRTAddress
 
 
 # {{{ IsRTAddress
 
-=item IsRTaddress ADDRESS
+=head2 IsRTaddress ADDRESS
 
 Takes a single parameter, an email address. 
 Returns true if that address matches the $RTAddressRegexp.  
 
 Takes a single parameter, an email address. 
 Returns true if that address matches the $RTAddressRegexp.  
@@ -523,7 +447,7 @@ sub IsRTAddress {
 
 # {{{ CullRTAddresses
 
 
 # {{{ 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.
 
 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 ) {
     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);
 }
     }
     return (@addrlist);
 }
@@ -568,7 +495,7 @@ sub CullRTAddresses {
 # template for the rejection message.
 
 
 # template for the rejection message.
 
 
-=item LookupExternalUserInfo
+=head2 LookupExternalUserInfo
 
  LookupExternalUserInfo is a site-definable method for synchronizing
  incoming users with an external data source. 
 
  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);
 
 
  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. 
 
     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
 # {{{ _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);
     # Temp files should never be recycled, especially when running under perl taint checking
     
     $parser->tmp_recycling(0);
-    
 
 }
 
 
 }