[Rt-commit] rt branch, 4.4/multiple-reply-to, created. rt-4.2.3-73-gbb9337c
? sunnavy
sunnavy at bestpractical.com
Tue Oct 7 12:27:07 EDT 2014
The branch, 4.4/multiple-reply-to has been created
at bb9337cdac4aba19b22c0ca00b888993d98707be (commit)
- Log -----------------------------------------------------------------
commit bb657e933520dab5f5b621377a55731c64614120
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;
commit bb9337cdac4aba19b22c0ca00b888993d98707be
Author: sunnavy <sunnavy at bestpractical.com>
Date: Tue Oct 7 00:01:11 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.pm b/lib/RT/Interface/Email.pm
index 9fc60cc..ff7c53f 100644
--- a/lib/RT/Interface/Email.pm
+++ b/lib/RT/Interface/Email.pm
@@ -219,7 +219,7 @@ sub Gateway {
TMPFAIL("RT couldn't find the queue: " . $args{'queue'})
unless $SystemTicket->id || $SystemQueueObj->id;
- my $CurrentUser = GetCurrentUser(
+ my @CurrentUsers = GetCurrentUser(
Message => $Message,
RawMessageRef => \$args{message},
Ticket => $SystemTicket,
@@ -231,12 +231,12 @@ sub Gateway {
CheckACL(
Action => $actions[0],
Message => $Message,
- CurrentUser => $CurrentUser,
+ CurrentUser => \@CurrentUsers,
Ticket => $SystemTicket,
Queue => $SystemQueueObj,
);
- my $Ticket = RT::Ticket->new($CurrentUser);
+ my $Ticket = RT::Ticket->new($CurrentUsers[0]);
$Ticket->Load( $SystemTicket->Id );
for my $action (@actions) {
@@ -306,15 +306,15 @@ sub Plugins {
Dispatches to the C<@MailPlugins> to find one the provides
C<GetCurrentUser> that recognizes the current user. Mail plugins are
-tried one at a time, and stops after the first to return a current user.
+tried one at a time, and stops after the first to return at least one current user.
Anonymous subroutine references found in C<@MailPlugins> are treated as
C<GetCurrentUser> methods.
The default GetCurrentUser authenticator simply looks at the From:
-address, and loads or creates a user accordingly; see
+address, and loads users or creates a user accordingly; see
L<RT::Interface::Email::Auth::MailFrom>.
-Returns the current user; on failure of any plugin to do so, stops
+Returns a current user list; on failure of any plugin to do so, stops
processing with a permanent failure and sends a generic "Permission
Denied" mail to the user.
@@ -331,13 +331,13 @@ sub GetCurrentUser {
# Since this needs loading, no matter what
for my $Code ( Plugins(Code => 1, Method => "GetCurrentUser") ) {
- my $CurrentUser = $Code->(
+ my @CurrentUsers = $Code->(
Message => $args{Message},
RawMessageRef => $args{RawMessageRef},
Ticket => $args{Ticket},
Queue => $args{Queue},
);
- return $CurrentUser if $CurrentUser and $CurrentUser->id;
+ return @CurrentUsers if @CurrentUsers;
}
# None of the GetCurrentUser plugins found a user. This is
@@ -350,9 +350,9 @@ sub GetCurrentUser {
);
}
-=head3 CheckACL Action => C<action>, CurrentUser => C<user>, Ticket => C<ticket>, Queue => C<queue>
+=head3 CheckACL Action => C<action>, CurrentUser => [C<user>], Ticket => C<ticket>, Queue => C<queue>
-Checks that the currentuser can perform a particular action. While RT's
+Checks that the currentusers can perform a particular action. While RT's
standard permission controls apply, this allows a better error message,
or more limited restrictions on the email gateway.
@@ -376,14 +376,19 @@ sub CheckACL {
@_,
);
- for my $Code ( Plugins( Method => "CheckACL" ) ) {
- return if $Code->(
- Message => $args{Message},
- CurrentUser => $args{CurrentUser},
- Action => $args{Action},
- Ticket => $args{Ticket},
- Queue => $args{Queue},
- );
+ while ( @{ $args{CurrentUser} } ) {
+ my $CurrentUser = $args{CurrentUser}->[0];
+ for my $Code ( Plugins( Method => "CheckACL" ) ) {
+ return
+ if $Code->(
+ Message => $args{Message},
+ CurrentUser => $CurrentUser,
+ Action => $args{Action},
+ Ticket => $args{Ticket},
+ Queue => $args{Queue},
+ );
+ }
+ shift @{$args{CurrentUser}};
}
# Nobody said yes, and nobody said FAILURE; fail closed
@@ -435,19 +440,35 @@ 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 @errors; # Accumulate any errors
foreach my $header ( 'Reply-To', 'From', 'Sender' ) {
my $addr_line = $head->get($header) || next;
- my ($addr) = RT::EmailParser->ParseEmailAddress( $addr_line );
- return ($addr->address, $addr->phrase, @errors) if $addr;
+ my (@addr) = RT::EmailParser->ParseEmailAddress( $addr_line );
+ return (\@addr, @errors) if @addr;
chomp $addr_line;
push @errors, "$header: $addr_line";
}
- return (undef, undef, @errors);
+ return (undef, @errors);
}
=head3 ParseErrorsToAddressFromHead HEAD
diff --git a/lib/RT/Interface/Email/Auth/MailFrom.pm b/lib/RT/Interface/Email/Auth/MailFrom.pm
index 081a570..b66b364 100644
--- a/lib/RT/Interface/Email/Auth/MailFrom.pm
+++ b/lib/RT/Interface/Email/Auth/MailFrom.pm
@@ -64,10 +64,10 @@ This is the default authentication plugin for RT's email gateway; no no
other authentication plugin is found in L<RT_Config/@MailPlugins>, RT
will default to this one.
-This plugin reads the first address found in the C<Reply-To>, C<From>,
-and C<Sender> headers, and loads or creates the user. It performs no
-checking of the identity of the user, and trusts the headers of the
-incoming email.
+This plugin reads addresses found in the C<Reply-To>, C<From>, and C<Sender>
+headers, and loads users or creates a new user for the first address. It
+performs no checking of the identity of the user, and trusts the headers of
+the incoming email.
=cut
@@ -78,35 +78,41 @@ sub GetCurrentUser {
);
# We don't need to do any external lookups
- my ( $Address, $Name, @errors ) = RT::Interface::Email::ParseSenderAddressFromHead( $args{'Message'}->head );
- $RT::Logger->warning("Failed to parse ".join(', ', @errors))
- if @errors;
-
- unless ( $Address ) {
+ my ($addresses, @errors) = RT::Interface::Email::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");
FAILURE("Couldn't parse or find sender's address");
}
- 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;
+ my @CurrentUsers;
+ 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 );
+ push @CurrentUsers, $CurrentUser;
+ }
}
+ unless ( @CurrentUsers ) {
+ my $first_addr = $addresses->[ 0 ];
+ my $user = RT::User->new( RT->SystemUser );
+ $user->LoadOrCreateByEmail(
+ RealName => $first_addr->phrase,
+ EmailAddress => $first_addr->address,
+ Comments => 'Autocreated on ticket submission',
+ );
+
+ my $CurrentUser = RT::CurrentUser->new;
+ $CurrentUser->Load( $user->id );
+ push @CurrentUsers, $CurrentUser;
+ }
- my $user = RT::User->new( RT->SystemUser );
- $user->LoadOrCreateByEmail(
- RealName => $Name,
- EmailAddress => $Address,
- Comments => 'Autocreated on ticket submission',
- );
-
- $CurrentUser = RT::CurrentUser->new;
- $CurrentUser->Load( $user->id );
-
- return $CurrentUser;
+ return @CurrentUsers;
}
1;
-----------------------------------------------------------------------
More information about the rt-commit
mailing list