[Rt-commit] rt branch, 4.0/multiple-reply-to, created. rt-4.0.22-15-gb079f60

? sunnavy sunnavy at bestpractical.com
Thu Oct 2 13:55:15 EDT 2014


The branch, 4.0/multiple-reply-to has been created
        at  b079f6062fa0f2ad588ffa4f84a976583d0b0532 (commit)

- Log -----------------------------------------------------------------
commit be240a6548bd6147c450cdbc9509319df6bcf33f
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Feb 2 15:28:06 2012 +0400

    extract WhichRightShouldBeChecked function
    
    no functionality changes

diff --git a/lib/RT/Interface/Email/Auth/MailFrom.pm b/lib/RT/Interface/Email/Auth/MailFrom.pm
index b353907..785915e 100644
--- a/lib/RT/Interface/Email/Auth/MailFrom.pm
+++ b/lib/RT/Interface/Email/Auth/MailFrom.pm
@@ -101,83 +101,69 @@ sub GetCurrentUser {
 
     # but before we do that, we need to make sure that the created user would have the right
     # to do what we're doing.
+    my ($right, $error) = WhichRightShouldBeChecked( %args );
+    return ( $args{'CurrentUser'}, 0 ) unless $right;
+
+    unless ( $everyone->PrincipalObj->HasRight( Object => $args{'Queue'},
+                                                Right => $right )
+             || $unpriv->PrincipalObj->HasRight( Object => $args{'Queue'},
+                                                 Right => $right )
+    ) {
+        $RT::Logger->debug( $error );
+        return ( $args{'CurrentUser'}, 0 );
+    }
+
+    $CurrentUser = CreateUser( undef, $Address, $Name, $Address, $args{'Message'} );
+
+    return ( $CurrentUser, 1 );
+}
+
+sub WhichRightShouldBeChecked {
+    my %args = @_;
+
+    my $qname = $args{'Queue'}->Name;
+
     if ( $args{'Ticket'} && $args{'Ticket'}->Id ) {
-        my $qname = $args{'Queue'}->Name;
         # We have a ticket. that means we're commenting or corresponding
         if ( $args{'Action'} =~ /^comment$/i ) {
-
-            # check to see whether "Everyone" or "Unprivileged users" can comment on tickets
-            unless ( $everyone->PrincipalObj->HasRight( Object => $args{'Queue'},
-                                                        Right => 'CommentOnTicket' )
-                     || $unpriv->PrincipalObj->HasRight( Object => $args{'Queue'},
-                                                         Right => 'CommentOnTicket' ) )
-            {
-                $RT::Logger->debug("Unprivileged users have no right to comment on ticket in queue '$qname'");
-                return ( $args{'CurrentUser'}, 0 );
-            }
+            return (
+                'CommentOnTicket',
+                "Unprivileged users have no right to comment on ticket in queue '$qname'",
+            );
         }
         elsif ( $args{'Action'} =~ /^correspond$/i ) {
-
-            # check to see whether "Everybody" or "Unprivileged users" can correspond on tickets
-            unless ( $everyone->PrincipalObj->HasRight( Object => $args{'Queue'},
-                                                        Right  => 'ReplyToTicket' )
-                     || $unpriv->PrincipalObj->HasRight( Object => $args{'Queue'},
-                                                         Right  => 'ReplyToTicket' ) )
-            {
-                $RT::Logger->debug("Unprivileged users have no right to reply to ticket in queue '$qname'");
-                return ( $args{'CurrentUser'}, 0 );
-            }
+            return (
+                'ReplyToTicket',
+                "Unprivileged users have no right to reply to ticket in queue '$qname'",
+            );
         }
         elsif ( $args{'Action'} =~ /^take$/i ) {
-
-            # check to see whether "Everybody" or "Unprivileged users" can correspond on tickets
-            unless ( $everyone->PrincipalObj->HasRight( Object => $args{'Queue'},
-                                                        Right  => 'OwnTicket' )
-                     || $unpriv->PrincipalObj->HasRight( Object => $args{'Queue'},
-                                                         Right  => 'OwnTicket' ) )
-            {
-                $RT::Logger->debug("Unprivileged users have no right to own ticket in queue '$qname'");
-                return ( $args{'CurrentUser'}, 0 );
-            }
-
+            return (
+                'OwnTicket',
+                "Unprivileged users have no right to own ticket in queue '$qname'",
+            );
         }
         elsif ( $args{'Action'} =~ /^resolve$/i ) {
-
-            # check to see whether "Everybody" or "Unprivileged users" can correspond on tickets
-            unless ( $everyone->PrincipalObj->HasRight( Object => $args{'Queue'},
-                                                        Right  => 'ModifyTicket' )
-                     || $unpriv->PrincipalObj->HasRight( Object => $args{'Queue'},
-                                                         Right  => 'ModifyTicket' ) )
-            {
-                $RT::Logger->debug("Unprivileged users have no right to resolve ticket in queue '$qname'");
-                return ( $args{'CurrentUser'}, 0 );
-            }
-
+            return (
+                'ModifyTicket',
+                "Unprivileged users have no right to resolve ticket in queue '$qname'",
+            );
         }
         else {
             $RT::Logger->warning("Action '". ($args{'Action'}||'') ."' is unknown");
-            return ( $args{'CurrentUser'}, 0 );
+            return;
         }
     }
 
     # We're creating a ticket
     elsif ( $args{'Queue'} && $args{'Queue'}->Id ) {
-        my $qname = $args{'Queue'}->Name;
-
         # check to see whether "Everybody" or "Unprivileged users" can create tickets in this queue
-        unless ( $everyone->PrincipalObj->HasRight( Object => $args{'Queue'},
-                                                    Right  => 'CreateTicket' )
-                 || $unpriv->PrincipalObj->HasRight( Object => $args{'Queue'},
-                                                     Right  => 'CreateTicket' ) )
-        {
-            $RT::Logger->debug("Unprivileged users have no right to create ticket in queue '$qname'");
-            return ( $args{'CurrentUser'}, 0 );
-        }
+        return (
+            'CreateTicket',
+            "Unprivileged users have no right to create ticket in queue '$qname'",
+        );
     }
-
-    $CurrentUser = CreateUser( undef, $Address, $Name, $Address, $args{'Message'} );
-
-    return ( $CurrentUser, 1 );
+    return;
 }
 
 RT::Base->_ImportOverlays();

commit 150269770babc189cfbe6e1a696975a3b9d1a7e3
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Fri Oct 3 00:14:24 2014 +0800

    new address parser to return a list of addresses

diff --git a/lib/RT/Interface/Email.pm b/lib/RT/Interface/Email.pm
index 6afb1c1..94a8bb1 100644
--- a/lib/RT/Interface/Email.pm
+++ b/lib/RT/Interface/Email.pm
@@ -78,8 +78,10 @@ BEGIN {
         &MailError
         &ParseCcAddressesFromHead
         &ParseSenderAddressFromHead
+        &ParseSenderAddressesFromHead
         &ParseErrorsToAddressFromHead
         &ParseAddressFromHeader
+        &ParseAddressesFromHeader
         &Gateway);
 
 }
@@ -1109,6 +1111,22 @@ to investigate the parse failure.
 =cut
 
 sub ParseSenderAddressFromHead {
+    my ( $list, @errors ) = ParseSenderAddressesFromHead(@_);
+    if ( $list ) {
+        return ( $list->[0]->address, $list->[0]->phrase, @errors );
+    }
+    else {
+        return ( undef, undef, @errors );
+    }
+}
+
+=head2 ParseSenderAddressesFromHead HEAD
+
+Takes a MIME::Header object. Returns ([list of addreses], errors)
+
+=cut
+
+sub ParseSenderAddressesFromHead {
     my $head = shift;
     my @sender_headers = ('Reply-To', 'From', 'Sender');
     my @errors;  # Accumulate any errors
@@ -1116,15 +1134,16 @@ sub ParseSenderAddressFromHead {
     #Figure out who's sending this message.
     foreach my $header ( @sender_headers ) {
         my $addr_line = Encode::decode( "UTF-8", $head->get($header) ) || next;
-        my ($addr, $name) = ParseAddressFromHeader( $addr_line );
-        # only return if the address is not empty
-        return ($addr, $name, @errors) if $addr;
+        my @list = ParseAddressesFromHeader( $addr_line );
+        if ( @list ) {
+            return (\@list, @errors);
+        }
 
         chomp $addr_line;
         push @errors, "$header: $addr_line";
     }
 
-    return (undef, undef, @errors);
+    return (undef, @errors);
 }
 
 =head2 ParseErrorsToAddressFromHead HEAD
@@ -1162,18 +1181,26 @@ Takes an address from C<$head->get('Line')> and returns a tuple: user at host, frie
 =cut
 
 sub ParseAddressFromHeader {
+    my @addresses = ParseAddressesFromHeader(@_);
+    if ( @addresses ) {
+        return ($addresses[0]->address, $addresses[0]->phrase);
+    }
+    return undef;
+}
+
+=head2 ParseAddressesFromHeader ADDRESS
+
+Takes an address from C<$head->get('Line')> and returns a list of addresses
+
+=cut
+
+sub ParseAddressesFromHeader {
     my $Addr = shift;
 
     # Some broken mailers send:  ""Vincent, Jesse"" <jesse at fsck.com>. Hate
     $Addr =~ s/\"\"(.*?)\"\"/\"$1\"/g;
-    my @Addresses = RT::EmailParser->ParseEmailAddress($Addr);
-
-    my ($AddrObj) = grep ref $_, @Addresses;
-    unless ( $AddrObj ) {
-        return ( undef, undef );
-    }
-
-    return ( $AddrObj->address, $AddrObj->phrase );
+    my @addresses = grep ref $_, RT::EmailParser->ParseEmailAddress($Addr);
+    return @addresses;
 }
 
 =head2 DeleteRecipientsFromHead HEAD RECIPIENTS

commit 3a876de151034d4c72a6da90cb964530fd9d3264
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Fri Oct 3 00:17:01 2014 +0800

    take into account multiple sender's addresses
    
    use first address that has rights, if none has rights
    then do what we did before.

diff --git a/lib/RT/Interface/Email/Auth/MailFrom.pm b/lib/RT/Interface/Email/Auth/MailFrom.pm
index 785915e..15beee4 100644
--- a/lib/RT/Interface/Email/Auth/MailFrom.pm
+++ b/lib/RT/Interface/Email/Auth/MailFrom.pm
@@ -51,7 +51,7 @@ package RT::Interface::Email::Auth::MailFrom;
 use strict;
 use warnings;
 
-use RT::Interface::Email qw(ParseSenderAddressFromHead CreateUser);
+use RT::Interface::Email qw(ParseSenderAddressesFromHead CreateUser);
 
 # This is what the ordinary, non-enhanced gateway does at the moment.
 
@@ -66,23 +66,13 @@ sub GetCurrentUser {
 
 
     # We don't need to do any external lookups
-    my ( $Address, $Name, @errors ) = ParseSenderAddressFromHead( $args{'Message'}->head );
-    $RT::Logger->warning("Failed to parse ".join(', ', @errors))
-        if @errors;
-
-    unless ( $Address ) {
+    my ($addresses, @errors) = ParseSenderAddressesFromHead( $args{'Message'}->head );
+    $RT::Logger->warning("Failed to parse ".join(', ', @errors)) if @errors;
+    unless ( $addresses ) {
         $RT::Logger->error("Couldn't parse or find sender's address");
         return ( $args{'CurrentUser'}, -1 );
     }
 
-    my $CurrentUser = RT::CurrentUser->new;
-    $CurrentUser->LoadByEmail( $Address );
-    $CurrentUser->LoadByName( $Address ) unless $CurrentUser->Id;
-    if ( $CurrentUser->Id ) {
-        $RT::Logger->debug("Mail from user #". $CurrentUser->Id ." ($Address)" );
-        return ( $CurrentUser, 1 );
-    }
-
     # If the user can't be loaded, we may need to create one. Figure out the acl situation.
     my $unpriv = RT->UnprivilegedUsers();
     unless ( $unpriv->Id ) {
@@ -97,25 +87,51 @@ sub GetCurrentUser {
         return ( $args{'CurrentUser'}, -1 );
     }
 
-    $RT::Logger->debug("Going to create user with address '$Address'" );
-
-    # but before we do that, we need to make sure that the created user would have the right
-    # to do what we're doing.
-    my ($right, $error) = WhichRightShouldBeChecked( %args );
+    my ($right, $right_error) = WhichRightShouldBeChecked( %args );
     return ( $args{'CurrentUser'}, 0 ) unless $right;
 
-    unless ( $everyone->PrincipalObj->HasRight( Object => $args{'Queue'},
-                                                Right => $right )
-             || $unpriv->PrincipalObj->HasRight( Object => $args{'Queue'},
-                                                 Right => $right )
-    ) {
-        $RT::Logger->debug( $error );
-        return ( $args{'CurrentUser'}, 0 );
+    my $check_right = sub {
+        if ( my $user = shift ) {
+            return $user->PrincipalObj->HasRight(
+                Object => $args{'Queue'}, Right => $right
+            );
+        }
+        return
+            $everyone->PrincipalObj->HasRight(
+                Object => $args{'Queue'}, Right => $right
+            ) || $unpriv->PrincipalObj->HasRight(
+                Object => $args{'Queue'}, Right => $right,
+            )
+        ;
+    };
+
+    my $user;
+    foreach my $addr ( @$addresses ) {
+        $RT::Logger->debug("Testing $addr as sender");
+
+        my $CurrentUser = RT::CurrentUser->new;
+        $CurrentUser->LoadByEmail( $addr->address );
+        $CurrentUser->LoadByName( $addr->address ) unless $CurrentUser->Id;
+        if ( $CurrentUser->Id ) {
+            $RT::Logger->debug("$addr belongs to user #". $CurrentUser->Id );
+            return ( $CurrentUser, 1 ) if $check_right->( $CurrentUser );
+
+            $user ||= $CurrentUser;
+            $RT::Logger->debug( "User has $right_error. Skipping $addr" );
+        }
+        elsif ( $check_right->() ) {
+            $RT::Logger->debug("Going to create user $addr" );
+            $CurrentUser = CreateUser(
+                undef, $addr->address, $addr->phrase, $addr->address,
+                $args{'Message'}
+            );
+            return ( $CurrentUser, 1 );
+        } else {
+            $RT::Logger->debug( "Unprivileged users have $right_error. Skipping $addr" );
+        }
     }
-
-    $CurrentUser = CreateUser( undef, $Address, $Name, $Address, $args{'Message'} );
-
-    return ( $CurrentUser, 1 );
+    $RT::Logger->debug("Sender(s) has no enough rights");
+    return $user ? ($user, 1) : ($args{'CurrentUser'}, 0);
 }
 
 sub WhichRightShouldBeChecked {
@@ -128,25 +144,25 @@ sub WhichRightShouldBeChecked {
         if ( $args{'Action'} =~ /^comment$/i ) {
             return (
                 'CommentOnTicket',
-                "Unprivileged users have no right to comment on ticket in queue '$qname'",
+                "no right to comment on ticket in queue '$qname'",
             );
         }
         elsif ( $args{'Action'} =~ /^correspond$/i ) {
             return (
                 'ReplyToTicket',
-                "Unprivileged users have no right to reply to ticket in queue '$qname'",
+                "no right to reply to ticket in queue '$qname'",
             );
         }
         elsif ( $args{'Action'} =~ /^take$/i ) {
             return (
                 'OwnTicket',
-                "Unprivileged users have no right to own ticket in queue '$qname'",
+                "no right to own ticket in queue '$qname'",
             );
         }
         elsif ( $args{'Action'} =~ /^resolve$/i ) {
             return (
                 'ModifyTicket',
-                "Unprivileged users have no right to resolve ticket in queue '$qname'",
+                "no right to resolve ticket in queue '$qname'",
             );
         }
         else {
@@ -160,7 +176,7 @@ sub WhichRightShouldBeChecked {
         # check to see whether "Everybody" or "Unprivileged users" can create tickets in this queue
         return (
             'CreateTicket',
-            "Unprivileged users have no right to create ticket in queue '$qname'",
+            "no right to create ticket in queue '$qname'",
         );
     }
     return;

commit b079f6062fa0f2ad588ffa4f84a976583d0b0532
Author: Ruslan Zakirov <ruz at bestpractical.com>
Date:   Thu Feb 2 22:59:45 2012 +0400

    simple test for multiple reply-to addresses

diff --git a/t/mail/multiple-reply-to.t b/t/mail/multiple-reply-to.t
new file mode 100644
index 0000000..2afa96c
--- /dev/null
+++ b/t/mail/multiple-reply-to.t
@@ -0,0 +1,51 @@
+use strict;
+use warnings;
+
+use RT::Test tests => 7;
+
+diag "grant everybody with CreateTicket right";
+{
+    ok( RT::Test->set_rights(
+        { Principal => 'Everyone', Right => [qw(CreateTicket)], },
+        { Principal => 'Requestor', Right => [qw(ReplyToTicket)], },
+    ), "Granted rights");
+}
+
+{
+    my $text = <<EOF;
+From: user\@example.com
+Subject: test
+
+Blah!
+Foob!
+EOF
+    my ($status, $id) = RT::Test->send_via_mailgate($text);
+    is ($status >> 8, 0, "The mail gateway exited normally");
+    ok ($id, "ticket created");
+
+    $text = <<EOF;
+From: user\@example.com
+Subject: [@{[RT->Config->Get('rtname')]} #$id] test
+
+Blah!
+Foob!
+EOF
+    ($status, my $tid) = RT::Test->send_via_mailgate($text);
+    is ($status >> 8, 0, "The mail gateway exited normally");
+    is ($tid, $id, "ticket updated");
+
+    $text = <<EOF;
+From: somebody\@example.com
+Reply-To: boo\@example.com, user\@example.com
+Subject: [@{[RT->Config->Get('rtname')]} #$id] test
+
+Blah!
+Foob!
+EOF
+    ($status, $tid) = RT::Test->send_via_mailgate($text);
+    is ($status >> 8, 0, "The mail gateway exited normally");
+    is ($tid, $id, "ticket updated");
+}
+
+
+1;

-----------------------------------------------------------------------


More information about the rt-commit mailing list