[Rt-commit] r5599 - in rt/branches/3.6-RELEASE: . bin etc
html/Admin/Groups html/REST/1.0/NoAuth html/SelfService
html/Ticket html/Ticket/Elements lib lib/RT lib/RT/Condition
lib/RT/Interface lib/RT/Interface/Web lib/RT/URI
lib/t/regression sbin
jesse at bestpractical.com
jesse at bestpractical.com
Tue Jul 18 17:51:40 EDT 2006
Author: jesse
Date: Tue Jul 18 17:51:35 2006
New Revision: 5599
Added:
rt/branches/3.6-RELEASE/lib/t/regression/23-web_attachments.t
Modified:
rt/branches/3.6-RELEASE/ (props changed)
rt/branches/3.6-RELEASE/bin/rt-crontool.in
rt/branches/3.6-RELEASE/config.layout
rt/branches/3.6-RELEASE/etc/RT_Config.pm.in
rt/branches/3.6-RELEASE/html/Admin/Groups/index.html
rt/branches/3.6-RELEASE/html/REST/1.0/Forms/ticket/default
rt/branches/3.6-RELEASE/html/REST/1.0/NoAuth/mail-gateway
rt/branches/3.6-RELEASE/html/SelfService/Create.html
rt/branches/3.6-RELEASE/html/Ticket/Create.html
rt/branches/3.6-RELEASE/html/Ticket/Display.html
rt/branches/3.6-RELEASE/html/Ticket/Elements/PreviewScrips
rt/branches/3.6-RELEASE/html/Ticket/Elements/ShowHistory
rt/branches/3.6-RELEASE/html/Ticket/Elements/ShowRequestor
rt/branches/3.6-RELEASE/lib/RT.pm.in
rt/branches/3.6-RELEASE/lib/RT/Attachment_Overlay.pm
rt/branches/3.6-RELEASE/lib/RT/Condition/Generic.pm
rt/branches/3.6-RELEASE/lib/RT/CustomField_Overlay.pm
rt/branches/3.6-RELEASE/lib/RT/Date.pm
rt/branches/3.6-RELEASE/lib/RT/Interface/Email.pm
rt/branches/3.6-RELEASE/lib/RT/Interface/Web.pm
rt/branches/3.6-RELEASE/lib/RT/Interface/Web/Handler.pm
rt/branches/3.6-RELEASE/lib/RT/Link_Overlay.pm
rt/branches/3.6-RELEASE/lib/RT/Links_Overlay.pm
rt/branches/3.6-RELEASE/lib/RT/Ticket_Overlay.pm
rt/branches/3.6-RELEASE/lib/RT/Tickets_Overlay.pm
rt/branches/3.6-RELEASE/lib/RT/Transaction_Overlay.pm
rt/branches/3.6-RELEASE/lib/RT/URI.pm
rt/branches/3.6-RELEASE/lib/RT/URI/base.pm
rt/branches/3.6-RELEASE/lib/RT/URI/fsck_com_rt.pm
rt/branches/3.6-RELEASE/lib/t/regression/06mailgateway.t
rt/branches/3.6-RELEASE/lib/t/regression/22search_tix_by_txn.t
rt/branches/3.6-RELEASE/sbin/rt-setup-database.in
Log:
r37203 at truegrounds: jesse | 2006-07-18 13:08:57 -0400
r30313 at truegrounds: jesse | 2006-03-23 01:36:27 -0500
* Better mp2 bulletproofing
r30314 at truegrounds: jesse | 2006-03-23 01:36:42 -0500
r37202 at truegrounds: jesse | 2006-07-18 12:49:01 -0400
r31084 at truegrounds (orig r4814): jesse | 2006-03-23 22:40:37 -0500
r10436 at hualien: jesse | 2006-03-23 22:40:25 -0500
* It helps when there aren't typos
r31117 at truegrounds (orig r4847): alexmv | 2006-03-28 15:50:07 -0500
r11918 at zoq-fot-pik: chmrr | 2006-03-28 15:49:56 -0500
* Backport TXN fixes from 3.7 and 3.5
r31194 at truegrounds (orig r4924): jesse | 2006-03-30 21:07:23 -0500
r10636 at hualien: jesse | 2006-03-31 11:06:57 +0900
RT-Ticket: 7398
RT-Status: resolved
RT-Update: correspond
* Added a "RH" RedHat layout option to config.layout -- Paulo Matos
r31317 at truegrounds (orig r5047): ruz | 2006-04-17 20:40:06 -0400
* check and report error to the logs
r31330 at truegrounds (orig r5060): jesse | 2006-04-24 10:49:40 -0400
r11842 at hualien: jesse | 2006-04-24 10:49:13 -0400
The following patch adds the useful LastUpdated field to the fields
returned through the REST interface.
David - who starts to wonder if his patches are actually read by someone :-)
--
David Schweikert | phone: +41 44 632 7019
System manager ISG.EE | walk: ETH Zentrum, ETL F24.1
ETH Zurich, Switzerland | web: http://people.ee.ethz.ch/dws
r31334 at truegrounds (orig r5064): ruz | 2006-04-24 16:42:43 -0400
* max subject is 200 character long
r31335 at truegrounds (orig r5065): ruz | 2006-04-24 17:25:15 -0400
* convert only if $enc'oding contains something
r31336 at truegrounds (orig r5066): ruz | 2006-04-24 20:21:32 -0400
* simple tests for Attachments manipulation from web interface
r31385 at truegrounds (orig r5115): ruz | 2006-04-25 19:24:45 -0400
* (cond) && 'selected' outputs 0 if condition fails on my system
r31386 at truegrounds (orig r5116): ruz | 2006-04-25 19:35:09 -0400
* get queue ID from page
r31388 at truegrounds (orig r5118): jesse | 2006-04-25 22:43:31 -0400
r11882 at hualien: jesse | 2006-04-25 22:43:11 -0400
* Mark Eichin picked up that http://lists.fsck.com/pipermail/rt-devel/2004-August/006216.html had never been applied.
rt ls -l broke because of it, if your RT server wasn't at /
r31453 at truegrounds (orig r5183): jesse | 2006-05-08 22:31:56 -0400
r13313 at hualien: jesse | 2006-05-08 12:01:55 -0400
* Finding disabled groups should actually find them, now
r31454 at truegrounds (orig r5184): jesse | 2006-05-08 22:32:10 -0400
r13314 at hualien: jesse | 2006-05-08 12:14:26 -0400
* Minor reformatting
r31455 at truegrounds (orig r5185): jesse | 2006-05-08 22:32:19 -0400
r13315 at hualien: jesse | 2006-05-08 22:31:30 -0400
* Mail gateway refactoring to make added functioanlity a bit easier.
No (intentional) functional changes.
r31456 at truegrounds (orig r5186): jesse | 2006-05-08 22:56:20 -0400
r13330 at hualien: jesse | 2006-05-08 22:55:56 -0400
* Reed Loden caught a perltidy error that, somewhat terrifiyingly, was still a valid mason page
r31457 at truegrounds (orig r5187): jesse | 2006-05-09 00:48:10 -0400
r13332 at hualien: jesse | 2006-05-09 00:47:49 -0400
* Mismatched parens
r31476 at truegrounds (orig r5206): ruz | 2006-05-11 16:48:53 -0400
* return values checking and more logging on errors
r31477 at truegrounds (orig r5207): ruz | 2006-05-11 16:56:24 -0400
* more checks on attachments processing
r31478 at truegrounds (orig r5208): ruz | 2006-05-11 18:24:17 -0400
* if ( not $xxx || $xxx->foo ) is equivalent to
if ( not ( $xxx || $xxx->foo ) ) due to perl5 rules
which is not expected behaviour
r31479 at truegrounds (orig r5209): ruz | 2006-05-11 18:31:58 -0400
* user do next steps:
1) open ticket #1
2) click reply
3) upload attachment
4) open ticket #2 in another browser window
5) send reply to the ticket #1
RT looses uploaded attachment due to step 4) as RT tries
to add attchement to the ticket #2 and drops them from session.
As solution don't ProcessTicketMessage if there is attachments,
but only if there is real update message.
r31486 at truegrounds (orig r5216): ruz | 2006-05-12 16:54:41 -0400
* add Timezone argument in SetToMidnight
r31487 at truegrounds (orig r5217): ruz | 2006-05-12 17:02:54 -0400
* use SetToMidnight( Timezone => 'server' ) to calc start and end of the day
r31488 at truegrounds (orig r5218): ruz | 2006-05-12 20:31:33 -0400
* get rid of "masks earlier declaration" warnings
r31508 at truegrounds (orig r5238): ruz | 2006-05-16 18:39:59 -0400
* really noisy warning
*NOTE* that option we use is not described in config
r31519 at truegrounds (orig r5249): ruz | 2006-05-18 12:17:47 -0400
* add bug comment
r31526 at truegrounds (orig r5256): ruz | 2006-05-18 21:45:58 -0400
* allow to complete actions in mail plugins
r31527 at truegrounds (orig r5257): ruz | 2006-05-18 21:53:40 -0400
* minor
r31538 at truegrounds (orig r5268): jesse | 2006-05-19 17:17:41 -0400
r13935 at hualien: jesse | 2006-05-19 17:17:27 -0400
* There were divergent copies of this code. The EmailParser code was more correct
r31580 at truegrounds (orig r5310): ruz | 2006-05-26 20:39:49 -0400
* when we could parse URI, for example object doesn't exist
fallback to RT::URI::base resolver, so $uri->IsLocal and
other methods wouldn't die but return undef
r31585 at truegrounds (orig r5315): ruz | 2006-05-28 07:19:20 -0400
* Use "Requestor.id = $requestor->id" search instead of search by email address
as latter is not indexed
r31587 at truegrounds (orig r5317): ruz | 2006-05-30 16:13:02 -0400
* If current user changes owner from somebody else to nobody user,
the action fails with "You can only reassign tickets that you own
or that are unowned", but we must change owner if he has no right
to own tickets in dest queue. Do it with Force and with SystemUser
context.
r31670 at truegrounds (orig r5400): ruz | 2006-06-16 20:40:24 -0400
* not default mail plugins has been broken during last refactoring
** move a code back into its scope
** don't forget to store $_ in $Class when $_ matches ^RT::Interface::Email
r35569 at truegrounds (orig r5476): ruz | 2006-06-27 17:21:07 -0400
* nothing special, small changes I'd changed during
the hunt over a bug
r35573 at truegrounds (orig r5480): ruz | 2006-06-27 20:05:49 -0400
* minor formatting
r35575 at truegrounds (orig r5482): ruz | 2006-06-28 17:25:18 -0400
* add tests for unsafe mailgate commands
* fix bugs that were introduced during Email.pm refactoring
r35589 at truegrounds (orig r5496): ruz | 2006-06-30 16:09:08 -0400
Changes:
* new config option $OldestTransactionsFirst that allow
administrator to reverse order of transactions on
history page
r36191 at truegrounds (orig r5520): ruz | 2006-07-04 01:36:46 -0400
* forgot to add option to config
r36192 at truegrounds (orig r5521): ruz | 2006-07-04 01:38:03 -0400
* report error when couldn't create CF
r36193 at truegrounds (orig r5522): ruz | 2006-07-04 01:39:21 -0400
* we never should call exit from libs
r36205 at truegrounds (orig r5534): ruz | 2006-07-06 11:19:46 -0400
rt-crontool
* add --transaction argument with two possible values: 'first' and 'last'
* add --transaction-type argument to allow users select type of transactions
** these transactions would be passed to scrips for processing, so users
can use conditions, actions and templates that check or use properties of
transaction
* also some existant actions, conditions and templates require scrip or
scrip action objects to process normally, as we have no these objects
available we now pass void (not loaded) objects. This change would allow
users to use notify actions with crontool.
r36241 at truegrounds (orig r5570): kevinr | 2006-07-13 16:21:31 -0400
r14836 at sad-girl-in-snow: kevinr | 2006-07-13 16:17:43 -0400
* The RT::Condition::Generic docs were wrong... fixed.
Modified: rt/branches/3.6-RELEASE/bin/rt-crontool.in
==============================================================================
--- rt/branches/3.6-RELEASE/bin/rt-crontool.in (original)
+++ rt/branches/3.6-RELEASE/bin/rt-crontool.in Tue Jul 18 17:51:35 2006
@@ -75,19 +75,28 @@
}
my ( $search, $condition, $action, $search_arg, $condition_arg, $action_arg,
- $template_id, $help, $verbose );
-GetOptions( "search=s" => \$search,
- "search-arg=s" => \$search_arg,
- "condition=s" => \$condition,
- "condition-arg=s" => \$condition_arg,
- "action-arg=s" => \$action_arg,
- "action=s" => \$action,
- "template-id=s" => \$template_id,
- "help" => \$help,
- "verbose|v" => \$verbose );
+ $template_id, $transaction, $transaction_type, $help, $verbose );
+GetOptions( "search=s" => \$search,
+ "search-arg=s" => \$search_arg,
+ "condition=s" => \$condition,
+ "condition-arg=s" => \$condition_arg,
+ "action-arg=s" => \$action_arg,
+ "action=s" => \$action,
+ "template-id=s" => \$template_id,
+ "transaction=s" => \$transaction,
+ "transaction-type=s" => \$transaction_type,
+ "help" => \$help,
+ "verbose|v" => \$verbose );
help() if $help or not $search or not $action;
+$transaction ||= 'first';
+unless ( $transaction =~ /^(first|last)$/i ) {
+ print STDERR loc("--transaction argument could be only 'first' or 'last'");
+ exit 1;
+}
+$transaction = lc($transaction) eq 'first'? 'ASC': 'DESC';
+
# We _must_ have a search object
load_module($search);
load_module($action) if ($action);
@@ -99,6 +108,8 @@
$template_obj = RT::Template->new($CurrentUser);
$template_obj->Load($template_id);
}
+my $void_scrip = RT::Scrip->new( $CurrentUser );
+my $void_scrip_action = RT::ScripAction->new( $CurrentUser );
#At the appointed time:
@@ -119,11 +130,20 @@
while ( my $ticket = $tickets->Next() ) {
print $ticket->Id() . ": " if ($verbose);
+ my $transaction = get_transaction($ticket);
+ print loc("Using transaction #[_1]...", $transaction->id)
+ if $verbose && $transaction;
+
# perform some more advanced check
if ($condition) {
- my $condition_obj = $condition->new( TicketObj => $ticket,
- Argument => $condition_arg,
- CurrentUser => $CurrentUser );
+ my $condition_obj = $condition->new(
+ TransactionObj => $transaction,
+ TicketObj => $ticket,
+ ScripObj => $void_scrip,
+ TemplateObj => $template_obj,
+ Argument => $condition_arg,
+ CurrentUser => $CurrentUser,
+ );
# if the condition doesn't apply, get out of here
@@ -133,10 +153,13 @@
#prepare our action
my $action_obj = $action->new(
- TicketObj => $ticket,
- TemplateObj => $template_obj,
- Argument => $action_arg,
- CurrentUser => $CurrentUser
+ TicketObj => $ticket,
+ TransactionObj => $transaction,
+ TemplateObj => $template_obj,
+ Argument => $action_arg,
+ ScripObj => $void_scrip,
+ ScripActionObj => $void_scrip_action,
+ CurrentUser => $CurrentUser,
);
#if our preparation, move onto the next ticket
@@ -148,6 +171,26 @@
print loc("Action committed.\n") if ($verbose);
}
+=head2 get_transaction
+
+Takes ticket and returns its transaction acording to command
+line arguments C<--transaction> and <--transaction-type>.
+
+=cut
+
+sub get_transaction {
+ my $ticket = shift;
+ my $txns = $ticket->Transactions;
+ $txns->OrderByCols(
+ { FIELD => 'Created', ORDER => $transaction },
+ { FIELD => 'id', ORDER => $transaction },
+ );
+ $txns->Limit( FIELD => 'Type', VALUE => $transaction_type )
+ if $transaction_type;
+ $txns->RowsPerPage(1);
+ return $txns->First;
+}
+
# {{{ load_module
=head2 load_module
@@ -207,6 +250,15 @@
. loc( "[_1] - An argument to pass to [_2]", "--action-argument", "--action" )
. "\n";
print " "
+ . loc( "[_1] - Specify id of the template you want to use", "--template-id" )
+ . "\n";
+ print " "
+ . loc( "[_1] - Specify if you want to use either 'first' or 'last' tarnsaction", "--transaction" )
+ . "\n";
+ print " "
+ . loc( "[_1] - Specify the type of a transaction you want to use", "--transaction-type" )
+ . "\n";
+ print " "
. loc( "[_1] - Output status updates to STDOUT", "--verbose" ) . "\n";
print "\n";
print "\n";
Modified: rt/branches/3.6-RELEASE/config.layout
==============================================================================
--- rt/branches/3.6-RELEASE/config.layout (original)
+++ rt/branches/3.6-RELEASE/config.layout Tue Jul 18 17:51:35 2006
@@ -127,3 +127,26 @@
customlexdir: ${customdir}/po
customlibdir: ${customdir}/lib
</Layout>
+
+# RH path layout.
+<Layout RH>
+ prefix: /usr/
+ exec_prefix: ${prefix}
+ bindir: ${exec_prefix}/bin
+ sbindir: ${exec_prefix}/sbin
+ sysconfdir: /etc/rt
+ mandir: ${prefix}/man
+ libdir: ${prefix}/lib/rt
+ datadir: /var/rt
+ htmldir: ${datadir}/html
+ manualdir: ${datadir}/doc
+ localstatedir: /var/
+ logfiledir: ${localstatedir}/log/rt
+ masonstatedir: ${localstatedir}/rt/mason_data
+ sessionstatedir: ${localstatedir}/rt/session_data
+ customdir: ${prefix}/local/rt
+ custometcdir: ${customdir}/etc
+ customhtmldir: ${customdir}/html
+ customlexdir: ${customdir}/po
+ customlibdir: ${customdir}/lib
+</Layout>
Modified: rt/branches/3.6-RELEASE/etc/RT_Config.pm.in
==============================================================================
--- rt/branches/3.6-RELEASE/etc/RT_Config.pm.in (original)
+++ rt/branches/3.6-RELEASE/etc/RT_Config.pm.in Tue Jul 18 17:51:35 2006
@@ -439,6 +439,11 @@
Set($DefaultSummaryRows, 10);
+# By default, RT shows newest transactions at the bottom of the ticket
+# history page, if you want see them at the top set this to '0'.
+
+Set($OldestTransactionsFirst, '1');
+
# $HomepageComponents is an arrayref of allowed components on a user's
# customized homepage ("RT at a glance").
Modified: rt/branches/3.6-RELEASE/html/Admin/Groups/index.html
==============================================================================
--- rt/branches/3.6-RELEASE/html/Admin/Groups/index.html (original)
+++ rt/branches/3.6-RELEASE/html/Admin/Groups/index.html Tue Jul 18 17:51:35 2006
@@ -78,6 +78,10 @@
my $title = loc('Select a group');
my $caption;
+if ($FindDisabledGroups) {
+ $Groups->FindAllRows();
+}
+
if (length $GroupString) {
$caption = loc("Groups matching search criteria");
if ($GroupField =~ /^CustomField-(\d+)/) {
Modified: rt/branches/3.6-RELEASE/html/REST/1.0/Forms/ticket/default
==============================================================================
--- rt/branches/3.6-RELEASE/html/REST/1.0/Forms/ticket/default (original)
+++ rt/branches/3.6-RELEASE/html/REST/1.0/Forms/ticket/default Tue Jul 18 17:51:35 2006
@@ -58,7 +58,7 @@
my ($c, $o, $k, $e) = ("", [], {}, 0);
my %data = %$changes;
my $ticket = new RT::Ticket $session{CurrentUser};
-my @dates = qw(Created Starts Started Due Resolved Told);
+my @dates = qw(Created Starts Started Due Resolved Told LastUpdated);
my @people = qw(Requestors Cc AdminCc);
my @create = qw(Queue Requestor Subject Cc AdminCc Owner Status Priority
InitialPriority FinalPriority TimeEstimated TimeWorked
Modified: rt/branches/3.6-RELEASE/html/REST/1.0/NoAuth/mail-gateway
==============================================================================
--- rt/branches/3.6-RELEASE/html/REST/1.0/NoAuth/mail-gateway (original)
+++ rt/branches/3.6-RELEASE/html/REST/1.0/NoAuth/mail-gateway Tue Jul 18 17:51:35 2006
@@ -53,26 +53,30 @@
</%ARGS>
<%init>
$m->comp('/Elements/Callback', _CallbackName => 'Pre', %ARGS);
-use RT::Interface::Email;
+use RT::Interface::Email (); # It's an exporter, but we don't care
$r->content_type('text/plain; charset=utf-8');
$m->error_format('text');
-my ( $status, $error, $Ticket ) = RT::Interface::Email::Gateway(\%ARGS);
- if ($status == -75 ) {
-$m->out("temporary failure - ". $error);
- }
- elsif ($status == 1) {
-$m->out('ok');
- if ( $Ticket->Id ) {
-$m->out('Ticket: '. $Ticket->Id);
-$m->out('Queue: '. $Ticket->QueueObj->Name );
-$m->out('Owner: '. $Ticket->OwnerObj->Name);
-$m->out('Status: '. $Ticket->Status );
-$m->out('Subject: '. $Ticket->Subject );
-$m->out('Requestor: '. $Ticket->Requestors->MemberEmailAddressesAsString );
- }
- } else {
-$m->out('not ok - '.$error);
- }
-
+my ( $status, $error, $Ticket ) = RT::Interface::Email::Gateway( \%ARGS );
+if ( $status == 1 ) {
+ $m->out('ok');
+ if ( $Ticket->Id ) {
+ $m->out( 'Ticket: ' . $Ticket->Id );
+ $m->out( 'Queue: ' . $Ticket->QueueObj->Name );
+ $m->out( 'Owner: ' . $Ticket->OwnerObj->Name );
+ $m->out( 'Status: ' . $Ticket->Status );
+ $m->out( 'Subject: ' . $Ticket->Subject );
+ $m->out(
+ 'Requestor: ' . $Ticket->Requestors->MemberEmailAddressesAsString );
+ }
+}
+else {
+ $RT::Logger->error( "Could not record email: " . $error );
+ if ( $status == -75 ) {
+ $m->out( "temporary failure - " . $error );
+ }
+ else {
+ $m->out( 'not ok - ' . $error );
+ }
+}
$m->abort();
</%init>
Modified: rt/branches/3.6-RELEASE/html/SelfService/Create.html
==============================================================================
--- rt/branches/3.6-RELEASE/html/SelfService/Create.html (original)
+++ rt/branches/3.6-RELEASE/html/SelfService/Create.html Tue Jul 18 17:51:35 2006
@@ -79,7 +79,7 @@
<&|/l&>Subject</&>:
</td>
<td class="value">
-<input name="Subject" size="60" maxsize="100" value="" />
+<input name="Subject" size="60" maxsize="200" value="" />
</td>
</tr>
<tr>
Modified: rt/branches/3.6-RELEASE/html/Ticket/Create.html
==============================================================================
--- rt/branches/3.6-RELEASE/html/Ticket/Create.html (original)
+++ rt/branches/3.6-RELEASE/html/Ticket/Create.html Tue Jul 18 17:51:35 2006
@@ -107,7 +107,7 @@
<&|/l&>Subject</&>:
</td>
<td class="value" colspan="5">
-<input name="Subject" size="60" maxsize="100" value="<%$ARGS{Subject} || ''%>" />
+<input name="Subject" size="60" maxsize="200" value="<%$ARGS{Subject} || ''%>" />
</td>
</tr>
<tr>
Modified: rt/branches/3.6-RELEASE/html/Ticket/Display.html
==============================================================================
--- rt/branches/3.6-RELEASE/html/Ticket/Display.html (original)
+++ rt/branches/3.6-RELEASE/html/Ticket/Display.html Tue Jul 18 17:51:35 2006
@@ -127,17 +127,19 @@
}
$ARGS{'UpdateContent'} =~ s/\r\n/\n/g if defined $ARGS{'UpdateContent'};
- if ( $ARGS{'UpdateTimeWorked'} ||
- $session{'Attachments'} ||
- ( defined $ARGS{'UpdateContent'}
- && $ARGS{'UpdateContent'} ne ''
- && $ARGS{'UpdateContent'} ne "-- \n"
- . $session{'CurrentUser'}->UserObj->Signature )) {
- $ARGS{UpdateAttachments} = $session{'Attachments'};
- ProcessUpdateMessage( ARGSRef => \%ARGS,
- Actions => \@Actions,
- TicketObj => $TicketObj );
- delete $session{'Attachments'};
+ if ( $ARGS{'UpdateTimeWorked'} || (
+ defined $ARGS{'UpdateContent'}
+ && $ARGS{'UpdateContent'} ne ''
+ && $ARGS{'UpdateContent'} ne "-- \n"
+ . $session{'CurrentUser'}->UserObj->Signature ) )
+ {
+ $ARGS{UpdateAttachments} = $session{'Attachments'};
+ ProcessUpdateMessage(
+ ARGSRef => \%ARGS,
+ Actions => \@Actions,
+ TicketObj => $TicketObj,
+ );
+ delete $session{'Attachments'};
}
#Process status updates
my @BasicActions = ProcessTicketBasics(ARGSRef => \%ARGS, TicketObj=>$TicketObj);
Modified: rt/branches/3.6-RELEASE/html/Ticket/Elements/PreviewScrips
==============================================================================
--- rt/branches/3.6-RELEASE/html/Ticket/Elements/PreviewScrips (original)
+++ rt/branches/3.6-RELEASE/html/Ticket/Elements/PreviewScrips Tue Jul 18 17:51:35 2006
@@ -86,6 +86,9 @@
TimeTaken => $ARGS{'UpdateTimeWorked'},
DryRun => 1
);
+unless ( $Transaction ) {
+ $RT::Logger->error("Coulfn't fire '$action' action: $Description");
+}
my @non_recipients = $TicketObj->SquelchMailTo;
Modified: rt/branches/3.6-RELEASE/html/Ticket/Elements/ShowHistory
==============================================================================
--- rt/branches/3.6-RELEASE/html/Ticket/Elements/ShowHistory (original)
+++ rt/branches/3.6-RELEASE/html/Ticket/Elements/ShowHistory Tue Jul 18 17:51:35 2006
@@ -134,8 +134,16 @@
} else {
$Transactions = $Ticket->Transactions;
}
-my $i;
+
+my $OldestFirst = $RT::OldestTransactionsFirst? 'DESC': 'ASC';
+$Transactions->OrderByCols( { FIELD => 'Created',
+ ORDER => $OldestFirst },
+ { FIELD => 'id',
+ ORDER => $OldestFirst },
+ );
+
+my $i;
$Attachments ||= $m->comp('/Ticket/Elements/FindAttachments', Ticket => $Ticket, Tickets => $Tickets || undef);
$AttachmentContent ||= $m->comp('/Ticket/Elements/LoadTextAttachments', Ticket => $Ticket);
Modified: rt/branches/3.6-RELEASE/html/Ticket/Elements/ShowRequestor
==============================================================================
--- rt/branches/3.6-RELEASE/html/Ticket/Elements/ShowRequestor (original)
+++ rt/branches/3.6-RELEASE/html/Ticket/Elements/ShowRequestor Tue Jul 18 17:51:35 2006
@@ -47,18 +47,15 @@
my $rows = 10;
my $people = $Ticket->Requestors->UserMembersObj;
while (my $requestor=$people->Next) {
+next if $requestor->Privileged;
my $name=$requestor->RealName || $requestor->EmailAddress;
my $tickets = RT::Tickets->new($session{'CurrentUser'});
my $has_right_adminusers = $session{'CurrentUser'}->HasRight(Object => $RT::System, Right => 'AdminUsers');
-$tickets->LimitWatcher(TYPE => 'Requestor', VALUE => $requestor->EmailAddress );
-$tickets->LimitStatus( VALUE => 'open');
-$tickets->LimitStatus( VALUE => 'new');
+$tickets->FromSQL( "Requestor.id = ". $requestor->id ." AND (Status = 'open' OR Status = 'new')" );
$tickets->RowsPerPage($rows);
-$tickets->OrderBy(FIELD => 'Priority',
- ORDER => 'DESC');
+$tickets->OrderBy(FIELD => 'Priority', ORDER => 'DESC');
</%PERL>
-% unless ($requestor->Privileged) {
<&| /Widgets/TitleBox, title_href => $has_right_adminusers ? "$RT::WebPath/Admin/Users/Modify.html?id=".$requestor->id : undef, title=> loc("More about [_1]", $name) &>
%# Additional information about this user. Empty by default.
@@ -80,7 +77,6 @@
</&>
-% }
%}
<%ARGS>
$Ticket=>undef
Modified: rt/branches/3.6-RELEASE/lib/RT.pm.in
==============================================================================
--- rt/branches/3.6-RELEASE/lib/RT.pm.in (original)
+++ rt/branches/3.6-RELEASE/lib/RT.pm.in Tue Jul 18 17:51:35 2006
@@ -311,19 +311,13 @@
#When we call die, trap it and log->crit with the value of the die.
- $SIG{__DIE__} = sub {
- unless ($^S || !defined $^S ) {
- $RT::Handle->Rollback();
- $RT::Logger->crit("$_[0]");
- # XXX: we should never exit, even if we are not in eval context
- # could someone explane this code?
- exit(-1);
- }
- else {
- # Get out of here if we're in an eval
- die $_[0];
- }
- };
+$SIG{__DIE__} = sub {
+ unless ($^S || !defined $^S ) {
+ $RT::Handle->Rollback();
+ $RT::Logger->crit("$_[0]");
+ }
+ die $_[0];
+};
# }}}
Modified: rt/branches/3.6-RELEASE/lib/RT/Attachment_Overlay.pm
==============================================================================
--- rt/branches/3.6-RELEASE/lib/RT/Attachment_Overlay.pm (original)
+++ rt/branches/3.6-RELEASE/lib/RT/Attachment_Overlay.pm Tue Jul 18 17:51:35 2006
@@ -295,7 +295,7 @@
eval {return( Encode::decode_utf8($content))} || return ($content);
}
- eval { Encode::from_to($content, 'utf8' => $enc);};
+ eval { Encode::from_to($content, 'utf8' => $enc) } if $enc;
if ($@) {
$RT::Logger->error("Could not convert attachment from assumed utf8 to '$enc' :".$@);
}
Modified: rt/branches/3.6-RELEASE/lib/RT/Condition/Generic.pm
==============================================================================
--- rt/branches/3.6-RELEASE/lib/RT/Condition/Generic.pm (original)
+++ rt/branches/3.6-RELEASE/lib/RT/Condition/Generic.pm Tue Jul 18 17:51:35 2006
@@ -50,7 +50,7 @@
=head1 SYNOPSIS
use RT::Condition::Generic;
- my $foo = new RT::Condition::IsApplicable(
+ my $foo = RT::Condition::Generic->new(
TransactionObj => $tr,
TicketObj => $ti,
ScripObj => $scr,
Modified: rt/branches/3.6-RELEASE/lib/RT/CustomField_Overlay.pm
==============================================================================
--- rt/branches/3.6-RELEASE/lib/RT/CustomField_Overlay.pm (original)
+++ rt/branches/3.6-RELEASE/lib/RT/CustomField_Overlay.pm Tue Jul 18 17:51:35 2006
@@ -941,10 +941,10 @@
if ( $ObjectCF->Id ) {
return ( 0, $self->loc("That is already the current value") );
}
- my ( $ret, $msg ) =
+ my ( $oid, $msg ) =
$ObjectCF->Create( ObjectId => $id, CustomField => $self->Id );
- return ( $ret, $msg );
+ return ( $oid, $msg );
}
@@ -976,9 +976,10 @@
unless ( $ObjectCF->Id ) {
return ( 0, $self->loc("This custom field does not apply to that object") );
}
- my ( $ret, $msg ) = $ObjectCF->Delete;
+ # XXX: Delete doesn't return anything
+ my ( $oid, $msg ) = $ObjectCF->Delete;
- return ( $ret, $msg );
+ return ( $oid, $msg );
}
# {{{ AddValueForObject
Modified: rt/branches/3.6-RELEASE/lib/RT/Date.pm
==============================================================================
--- rt/branches/3.6-RELEASE/lib/RT/Date.pm (original)
+++ rt/branches/3.6-RELEASE/lib/RT/Date.pm Tue Jul 18 17:51:35 2006
@@ -225,23 +225,28 @@
# {{{ sub SetToMidnight
-=head2 SetToMidnight
+=head2 SetToMidnight [Timezone => 'utc']
-Sets the date to midnight (at the beginning of the day) GMT
+Sets the date to midnight (at the beginning of the day).
Returns the unixtime at midnight.
+Arguments:
+
+=over 4
+
+=item Timezone - Timezone context C<server> or C<UTC>
+
=cut
sub SetToMidnight {
my $self = shift;
-
- use Time::Local;
- my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday) = gmtime($self->Unix);
- $self->Unix(timegm (0,0,0,$mday,$mon,$year,$wday,$yday));
-
+ my %args = ( Timezone => 'UTC', @_ );
+ if ( lc $args{'Timezone'} eq 'server' ) {
+ $self->Unix( Time::Local::timelocal( 0,0,0,(localtime $self->Unix)[3..7] ) );
+ } else {
+ $self->Unix( Time::Local::timegm( 0,0,0,(gmtime $self->Unix)[3..7] ) );
+ }
return ($self->Unix);
-
-
}
Modified: rt/branches/3.6-RELEASE/lib/RT/Interface/Email.pm
==============================================================================
--- rt/branches/3.6-RELEASE/lib/RT/Interface/Email.pm (original)
+++ rt/branches/3.6-RELEASE/lib/RT/Interface/Email.pm Tue Jul 18 17:51:35 2006
@@ -1,38 +1,38 @@
# BEGIN BPS TAGGED BLOCK {{{
-#
+#
# COPYRIGHT:
#
# This software is Copyright (c) 1996-2006 Best Practical Solutions, LLC
# <jesse at bestpractical.com>
-#
+#
# (Except where explicitly superseded by other copyright notices)
-#
-#
+#
+#
# LICENSE:
-#
+#
# This work is made available to you under the terms of Version 2 of
# the GNU General Public License. A copy of that license should have
# been provided with this software, but in any event can be snarfed
# from www.gnu.org.
-#
+#
# This work is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
-#
+#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-#
-#
+#
+#
# CONTRIBUTION SUBMISSION POLICY:
-#
+#
# (The following paragraph is not intended to limit the rights granted
# to you to modify and distribute this software under the terms of
# the GNU General Public License and is only of importance to you if
# you choose to contribute your changes and enhancements to the
# community by submitting them to Best Practical Solutions, LLC.)
-#
+#
# By intentionally submitting any modifications, corrections or
# derivatives to this work, or any other work intended for use with
# Request Tracker, to Best Practical Solutions, LLC, you confirm that
@@ -41,7 +41,7 @@
# royalty-free, perpetual, license to use, copy, create derivative
# works based on those contributions, and sublicense and distribute
# those contributions and any derivatives thereof.
-#
+#
# END BPS TAGGED BLOCK }}}
package RT::Interface::Email;
@@ -50,31 +50,32 @@
use MIME::Entity;
use RT::EmailParser;
use File::Temp;
+use UNIVERSAL::require;
BEGIN {
use Exporter ();
- use vars qw ($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
-
+ use vars qw ( @ISA @EXPORT_OK);
+
# set the version for version checking
- $VERSION = do { my @r = (q$Revision: 1.2 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r }; # must be all one line, for MakeMaker
-
- @ISA = qw(Exporter);
-
+ our $VERSION = 2.0;
+
+ @ISA = qw(Exporter);
+
# your exported package globals go here,
# as well as any optionally exported functions
- @EXPORT_OK = qw(
- &CreateUser
- &GetMessageContent
- &CheckForLoops
- &CheckForSuspiciousSender
- &CheckForAutoGenerated
- &CheckForBounce
- &MailError
- &ParseCcAddressesFromHead
- &ParseSenderAddressFromHead
- &ParseErrorsToAddressFromHead
- &ParseAddressFromHeader
- &Gateway);
+ @EXPORT_OK = qw(
+ &CreateUser
+ &GetMessageContent
+ &CheckForLoops
+ &CheckForSuspiciousSender
+ &CheckForAutoGenerated
+ &CheckForBounce
+ &MailError
+ &ParseCcAddressesFromHead
+ &ParseSenderAddressFromHead
+ &ParseErrorsToAddressFromHead
+ &ParseAddressFromHeader
+ &Gateway);
}
@@ -103,19 +104,18 @@
=cut
+# {{{ sub CheckForLoops
-# {{{ sub CheckForLoops
-
-sub CheckForLoops {
+sub CheckForLoops {
my $head = shift;
-
+
#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 eq "$RT::rtname") {
- return (1);
+ chomp($RTLoop); #remove that newline
+ if ( $RTLoop eq "$RT::rtname" ) {
+ 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);
@@ -129,23 +129,24 @@
my $head = 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) = ParseSenderAddressFromHead($head);
-
- if (($From =~ /^mailer-daemon\@/i) or
- ($From =~ /^postmaster\@/i)){
- return (1);
-
+ my ( $From, $junk ) = ParseSenderAddressFromHead($head);
+
+ if ( ( $From =~ /^mailer-daemon\@/i )
+ or ( $From =~ /^postmaster\@/i ) )
+ {
+ return (1);
+
}
-
+
return (undef);
}
@@ -155,15 +156,15 @@
# {{{ sub CheckForAutoGenerated
sub CheckForAutoGenerated {
my $head = shift;
-
- my $Precedence = $head->get("Precedence") || "" ;
- if ($Precedence =~ /^(bulk|junk)/i) {
- return (1);
+
+ my $Precedence = $head->get("Precedence") || "";
+ if ( $Precedence =~ /^(bulk|junk)/i ) {
+ return (1);
}
-
+
# First Class mailer uses this as a clue.
my $FCJunk = $head->get("X-FC-Machinegenerated") || "";
- if ($FCJunk =~ /^true/i) {
+ if ( $FCJunk =~ /^true/i ) {
return (1);
}
@@ -175,9 +176,9 @@
# {{{ sub CheckForBounce
sub CheckForBounce {
my $head = shift;
-
- my $ReturnPath = $head->get("Return-path") || "" ;
- return ($ReturnPath =~ /<>/);
+
+ my $ReturnPath = $head->get("Return-path") || "";
+ return ( $ReturnPath =~ /<>/ );
}
# }}}
@@ -195,11 +196,12 @@
sub IsRTAddress {
my $address = shift || '';
- # Example: the following rule would tell RT not to Cc
+ # Example: the following rule would tell RT not to Cc
# "tickets at noc.example.com"
- if ( defined($RT::RTAddressRegexp) &&
- $address =~ /$RT::RTAddressRegexp/i ) {
- return(1);
+ if ( defined($RT::RTAddressRegexp)
+ && $address =~ /$RT::RTAddressRegexp/i )
+ {
+ return (1);
} else {
return (undef);
}
@@ -217,56 +219,61 @@
=cut
sub CullRTAddresses {
- return (grep { IsRTAddress($_) } @_);
+ return ( grep { IsRTAddress($_) } @_ );
}
# }}}
-# {{{ sub MailError
+# {{{ sub MailError
sub MailError {
- my %args = (To => $RT::OwnerEmail,
- Bcc => undef,
- From => $RT::CorrespondAddress,
- Subject => 'There has been an error',
- Explanation => 'Unexplained error',
- MIMEObj => undef,
- Attach => undef,
- LogLevel => 'crit',
- @_);
-
-
- $RT::Logger->log(level => $args{'LogLevel'},
- message => $args{'Explanation'}
- );
- my $entity = MIME::Entity->build( Type =>"multipart/mixed",
- From => $args{'From'},
- Bcc => $args{'Bcc'},
- To => $args{'To'},
- Subject => $args{'Subject'},
- Precedence => 'bulk',
- 'X-RT-Loop-Prevention' => $RT::rtname,
- );
+ my %args = (
+ To => $RT::OwnerEmail,
+ Bcc => undef,
+ From => $RT::CorrespondAddress,
+ Subject => 'There has been an error',
+ Explanation => 'Unexplained error',
+ MIMEObj => undef,
+ Attach => undef,
+ LogLevel => 'crit',
+ @_
+ );
+
+ $RT::Logger->log(
+ level => $args{'LogLevel'},
+ message => $args{'Explanation'}
+ );
+ my $entity = MIME::Entity->build(
+ Type => "multipart/mixed",
+ From => $args{'From'},
+ Bcc => $args{'Bcc'},
+ To => $args{'To'},
+ Subject => $args{'Subject'},
+ Precedence => 'bulk',
+ 'X-RT-Loop-Prevention' => $RT::rtname,
+ );
+
+ $entity->attach( Data => $args{'Explanation'} . "\n" );
- $entity->attach( Data => $args{'Explanation'}."\n");
-
my $mimeobj = $args{'MIMEObj'};
if ($mimeobj) {
$mimeobj->sync_headers();
$entity->add_part($mimeobj);
}
-
- if ($args{'Attach'}) {
- $entity->attach(Data => $args{'Attach'}, Type => 'message/rfc822');
+
+ if ( $args{'Attach'} ) {
+ $entity->attach( Data => $args{'Attach'}, Type => 'message/rfc822' );
}
- if ($RT::MailCommand eq 'sendmailpipe') {
- open (MAIL, "|$RT::SendmailPath $RT::SendmailBounceArguments $RT::SendmailArguments") || return(0);
+ if ( $RT::MailCommand eq 'sendmailpipe' ) {
+ open( MAIL,
+ "|$RT::SendmailPath $RT::SendmailBounceArguments $RT::SendmailArguments"
+ )
+ || return (0);
print MAIL $entity->as_string;
close(MAIL);
- }
- else {
- $entity->send($RT::MailCommand, $RT::MailParams);
+ } else {
+ $entity->send( $RT::MailCommand, $RT::MailParams );
}
}
@@ -275,37 +282,39 @@
# {{{ Create User
sub CreateUser {
- my ($Username, $Address, $Name, $ErrorsTo, $entity) = @_;
+ my ( $Username, $Address, $Name, $ErrorsTo, $entity ) = @_;
my $NewUser = RT::User->new($RT::SystemUser);
- my ($Val, $Message) =
- $NewUser->Create(Name => ($Username || $Address),
- EmailAddress => $Address,
- RealName => $Name,
- Password => undef,
- Privileged => 0,
- Comments => 'Autocreated on ticket submission'
- );
-
+ my ( $Val, $Message ) = $NewUser->Create(
+ Name => ( $Username || $Address ),
+ EmailAddress => $Address,
+ RealName => $Name,
+ Password => undef,
+ Privileged => 0,
+ Comments => 'Autocreated on ticket submission'
+ );
+
unless ($Val) {
-
+
# Deal with the race condition of two account creations at once
#
if ($Username) {
$NewUser->LoadByName($Username);
}
-
- unless ($NewUser->Id) {
+
+ unless ( $NewUser->Id ) {
$NewUser->LoadByEmail($Address);
}
-
- unless ($NewUser->Id) {
- MailError( To => $ErrorsTo,
- Subject => "User could not be created",
- Explanation => "User creation failed in mailgateway: $Message",
- MIMEObj => $entity,
- LogLevel => 'crit'
- );
+
+ unless ( $NewUser->Id ) {
+ MailError(
+ To => $ErrorsTo,
+ Subject => "User could not be created",
+ Explanation =>
+ "User creation failed in mailgateway: $Message",
+ MIMEObj => $entity,
+ LogLevel => 'crit'
+ );
}
}
@@ -313,21 +322,25 @@
my $CurrentUser = RT::CurrentUser->new();
$CurrentUser->LoadByEmail($Address);
- unless ($CurrentUser->id) {
- $RT::Logger->warning("Couldn't load user '$Address'.". "giving up");
- MailError( To => $ErrorsTo,
- Subject => "User could not be loaded",
- Explanation => "User '$Address' could not be loaded in the mail gateway",
- MIMEObj => $entity,
- LogLevel => 'crit'
- );
+ unless ( $CurrentUser->id ) {
+ $RT::Logger->warning(
+ "Couldn't load user '$Address'." . "giving up" );
+ MailError(
+ To => $ErrorsTo,
+ Subject => "User could not be loaded",
+ Explanation =>
+ "User '$Address' could not be loaded in the mail gateway",
+ MIMEObj => $entity,
+ LogLevel => 'crit'
+ );
}
return $CurrentUser;
}
+
# }}}
-# {{{ ParseCcAddressesFromHead
+# {{{ ParseCcAddressesFromHead
=head2 ParseCcAddressesFromHead HASHREF
@@ -337,32 +350,34 @@
email address and anything that the configuration sub RT::IsRTAddress matches.
=cut
-
+
sub ParseCcAddressesFromHead {
- my %args = ( Head => undef,
- QueueObj => undef,
- CurrentUser => undef,
- @_ );
-
+ my %args = (
+ Head => undef,
+ QueueObj => undef,
+ CurrentUser => undef,
+ @_
+ );
+
my (@Addresses);
-
- my @ToObjs = Mail::Address->parse($args{'Head'}->get('To'));
- my @CcObjs = Mail::Address->parse($args{'Head'}->get('Cc'));
-
- foreach my $AddrObj (@ToObjs, @CcObjs) {
- my $Address = $AddrObj->address;
- $Address = $args{'CurrentUser'}->UserObj->CanonicalizeEmailAddress($Address);
- next if ($args{'CurrentUser'}->EmailAddress =~ /^\Q$Address\E$/i);
- next if ($args{'QueueObj'}->CorrespondAddress =~ /^\Q$Address\E$/i);
- next if ($args{'QueueObj'}->CommentAddress =~ /^\Q$Address\E$/i);
- next if (RT::EmailParser->IsRTAddress($Address));
-
- push (@Addresses, $Address);
+
+ my @ToObjs = Mail::Address->parse( $args{'Head'}->get('To') );
+ my @CcObjs = Mail::Address->parse( $args{'Head'}->get('Cc') );
+
+ foreach my $AddrObj ( @ToObjs, @CcObjs ) {
+ my $Address = $AddrObj->address;
+ $Address = $args{'CurrentUser'}
+ ->UserObj->CanonicalizeEmailAddress($Address);
+ next if ( $args{'CurrentUser'}->EmailAddress =~ /^\Q$Address\E$/i );
+ next if ( $args{'QueueObj'}->CorrespondAddress =~ /^\Q$Address\E$/i );
+ next if ( $args{'QueueObj'}->CommentAddress =~ /^\Q$Address\E$/i );
+ next if ( RT::EmailParser->IsRTAddress($Address) );
+
+ push( @Addresses, $Address );
}
return (@Addresses);
}
-
# }}}
# {{{ ParseSenderAdddressFromHead
@@ -376,12 +391,14 @@
sub ParseSenderAddressFromHead {
my $head = shift;
+
#Figure out who's sending this message.
- my $From = $head->get('Reply-To') ||
- $head->get('From') ||
- $head->get('Sender');
- return (ParseAddressFromHeader($From));
+ my $From = $head->get('Reply-To')
+ || $head->get('From')
+ || $head->get('Sender');
+ return ( ParseAddressFromHeader($From) );
}
+
# }}}
# {{{ ParseErrorsToAdddressFromHead
@@ -396,18 +413,22 @@
sub ParseErrorsToAddressFromHead {
my $head = shift;
+
#Figure out who's sending this message.
- foreach my $header ('Return-path', 'Errors-To' , 'Reply-To', 'From', 'Sender' ) {
- # If there's a header of that name
- my $headerobj = $head->get($header);
- if ($headerobj) {
- my ($addr, $name ) = ParseAddressFromHeader($headerobj);
- # If it's got actual useful content...
- return ($addr) if ($addr);
- }
+ foreach my $header ( 'Errors-To', 'Reply-To', 'From', 'Sender' ) {
+
+ # If there's a header of that name
+ my $headerobj = $head->get($header);
+ if ($headerobj) {
+ my ( $addr, $name ) = ParseAddressFromHeader($headerobj);
+
+ # If it's got actual useful content...
+ return ($addr) if ($addr);
+ }
}
}
+
# }}}
# {{{ ParseAddressFromHeader
@@ -418,31 +439,28 @@
=cut
-
-sub ParseAddressFromHeader{
+sub ParseAddressFromHeader {
my $Addr = shift;
-
- # Perl 5.8.0 breaks when doing regex matches on utf8
- Encode::_utf8_off($Addr) if $] == 5.008;
+
my @Addresses = Mail::Address->parse($Addr);
-
+
my $AddrObj = $Addresses[0];
- unless (ref($AddrObj)) {
- return(undef,undef);
+ unless ( ref($AddrObj) ) {
+ return ( undef, undef );
}
-
- my $Name = ($AddrObj->phrase || $AddrObj->comment || $AddrObj->address);
-
+
+ my $Name = ( $AddrObj->phrase || $AddrObj->comment || $AddrObj->address );
+
#Lets take the from and load a user object.
my $Address = $AddrObj->address;
- return ($Address, $Name);
+ return ( $Address, $Name );
}
-# }}}
-# {{{ sub ParseTicketId
+# }}}
+# {{{ sub ParseTicketId
sub ParseTicketId {
my $Subject = shift;
@@ -454,15 +472,13 @@
my $id = $1;
$RT::Logger->debug("Found a ticket ID. It's $id");
return ($id);
- }
- else {
+ } else {
return (undef);
}
}
# }}}
-
=head2 Gateway ARGSREF
@@ -501,50 +517,53 @@
sub Gateway {
my $argsref = shift;
+ my %args = (
+ action => 'correspond',
+ queue => '1',
+ ticket => undef,
+ message => undef,
+ %$argsref
+ );
- my %args = %$argsref;
-
- # Set some reasonable defaults
- $args{'action'} ||= 'correspond';
- $args{'queue'} ||= '1';
+ my $SystemTicket;
+ my $Right;
# Validate the action
- my ($status, @actions) = IsCorrectAction( $args{'action'} );
- unless ( $status ) {
-
- # Can't safely loc this. What object do we loc around?
- $RT::Logger->crit("Mail gateway called with an invalid action paramenter '".$actions[0]."' for queue '".$args{'queue'}."'");
-
- return ( -75, "Invalid 'action' parameter", undef );
+ my ( $status, @actions ) = IsCorrectAction( $args{'action'} );
+ unless ($status) {
+ return (
+ -75,
+ "Invalid 'action' parameter "
+ . $actions[0]
+ . " for queue "
+ . $args{'queue'},
+ undef
+ );
}
my $parser = RT::EmailParser->new();
+ $parser->SmartParseMIMEEntityFromScalar( Message => $args{'message'} );
+ my $Message = $parser->Entity();
- $parser->SmartParseMIMEEntityFromScalar( Message => $args{'message'});
-
- if (!$parser->Entity()) {
+ unless ($Message) {
MailError(
To => $RT::OwnerEmail,
Subject => "RT Bounce: Unparseable message",
Explanation => "RT couldn't process the message below",
- Attach => $args{'message'}
+ Attach => $args{'message'}
);
- return(0,"Failed to parse this message. Something is likely badly wrong with the message");
+ return ( 0,
+ "Failed to parse this message. Something is likely badly wrong with the message"
+ );
}
- my $Message = $parser->Entity();
- my $head = $Message->head;
-
- my ( $CurrentUser, $AuthStat, $error );
-
- # Initalize AuthStat so comparisons work correctly
- $AuthStat = -9999999;
+ my $head = $Message->head;
my $ErrorsTo = ParseErrorsToAddressFromHead($head);
my $MessageId = $head->get('Message-ID')
- || "<no-message-id-" . time . rand(2000) . "\@.$RT::Organization>";
+ || "<no-message-id-" . time . rand(2000) . "\@.$RT::Organization>";
#Pull apart the subject line
my $Subject = $head->get('Subject') || '';
@@ -552,13 +571,12 @@
$args{'ticket'} ||= ParseTicketId($Subject);
- my $SystemTicket;
- my $Right = 'CreateTicket';
- if ( $args{'ticket'} ) {
- $SystemTicket = RT::Ticket->new($RT::SystemUser);
- $SystemTicket->Load( $args{'ticket'} );
- # if there's an existing ticket, this must be a reply
- $Right = 'ReplyToTicket';
+ $SystemTicket = RT::Ticket->new($RT::SystemUser);
+ $SystemTicket->Load( $args{'ticket'} ) if ( $args{'ticket'} ) ;
+ if ( $SystemTicket->id ) {
+ $Right = 'ReplyToTicket';
+ } else {
+ $Right = 'CreateTicket';
}
#Set up a queue object
@@ -566,190 +584,124 @@
$SystemQueueObj->Load( $args{'queue'} );
# We can safely have no queue of we have a known-good ticket
- unless ( $args{'ticket'} || $SystemQueueObj->id ) {
+ unless ( $SystemTicket->id || $SystemQueueObj->id ) {
return ( -75, "RT couldn't find the queue: " . $args{'queue'}, undef );
}
- # Authentication Level
+ # Authentication Level ($AuthStat)
# -1 - Get out. this user has been explicitly declined
# 0 - User may not do anything (Not used at the moment)
# 1 - Normal user
# 2 - User is allowed to specify status updates etc. a la enhanced-mailgate
+ my ( $CurrentUser, $AuthStat, $error );
+
+ # Initalize AuthStat so comparisons work correctly
+ $AuthStat = -9999999;
push @RT::MailPlugins, "Auth::MailFrom" unless @RT::MailPlugins;
- # Since this needs loading, no matter what
+ # if plugin returns AuthStat -2 we skip action
+ # NOTE: this is experimental API and it would be changed
+ my %skip_action = ();
+ # Since this needs loading, no matter what
foreach (@RT::MailPlugins) {
- my $Code;
- my $NewAuthStat;
+ my ($Code, $NewAuthStat);
if ( ref($_) eq "CODE" ) {
$Code = $_;
- }
- else {
- $_ = "RT::Interface::Email::".$_ unless $_ =~ /^RT::Interface::Email::/;
- eval "require $_;";
- if ($@) {
- $RT::Logger->crit("Couldn't load module '$_': $@");
- next;
- }
+ } else {
+ my $Class = $_;
+ $Class = "RT::Interface::Email::" . $Class
+ unless $Class =~ /^RT::Interface::Email::/;
+ $Class->require or
+ do { $RT::Logger->error("Couldn't load $Class: $@"); next };
+
no strict 'refs';
- if ( !defined( $Code = *{ $_ . "::GetCurrentUser" }{CODE} ) ) {
- $RT::Logger->crit("No GetCurrentUser code found in $_ module");
+ unless ( defined( $Code = *{ $Class . "::GetCurrentUser" }{CODE} ) ) {
+ $RT::Logger->crit( "No 'GetCurrentUser' function found in '$Class' module");
next;
}
}
- foreach my $action ( @actions ) {
-
+ foreach my $action (@actions) {
( $CurrentUser, $NewAuthStat ) = $Code->(
- Message => $Message,
+ Message => $Message,
RawMessageRef => \$args{'message'},
- CurrentUser => $CurrentUser,
- AuthLevel => $AuthStat,
- Action => $action,
- Ticket => $SystemTicket,
- Queue => $SystemQueueObj
+ CurrentUser => $CurrentUser,
+ AuthLevel => $AuthStat,
+ Action => $action,
+ Ticket => $SystemTicket,
+ Queue => $SystemQueueObj
);
-
- # If a module returns a "-1" then we discard the ticket, so.
- $AuthStat = -1 if $NewAuthStat == -1;
-
- # You get the highest level of authentication you were assigned.
- $AuthStat = $NewAuthStat if $NewAuthStat > $AuthStat;
+# You get the highest level of authentication you were assigned, unless you get the magic -1
+# If a module returns a "-1" then we discard the ticket, so.
+ $AuthStat = $NewAuthStat
+ if ( $NewAuthStat > $AuthStat or $NewAuthStat == -1 or $NewAuthStat == -2 );
last if $AuthStat == -1;
- }
+ $skip_action{$action}++ if $AuthStat == -2;
+ }
last if $AuthStat == -1;
}
-
# {{{ If authentication fails and no new user was created, get out.
- if ( !$CurrentUser or !$CurrentUser->Id or $AuthStat == -1 ) {
+ if ( !$CurrentUser || !$CurrentUser->id || $AuthStat == -1 ) {
# If the plugins refused to create one, they lose.
unless ( $AuthStat == -1 ) {
-
- # Notify the RT Admin of the failure.
- # XXX Should this be configurable?
- MailError(
- To => $RT::OwnerEmail,
- Subject => "Could not load a valid user",
- Explanation => <<EOT,
-RT could not load a valid user, and RT's configuration does not allow
-for the creation of a new user for this email ($ErrorsTo).
-
-You might need to grant 'Everyone' the right '$Right' for the
-queue @{[$args{'queue'}]}.
-
-EOT
- MIMEObj => $Message,
- LogLevel => 'error'
+ _NoAuthorizedUserFound(
+ Right => $Right,
+ Message => $Message,
+ Requestor => $ErrorsTo,
+ Queue => $args{'queue'}
);
- # Also notify the requestor that his request has been dropped.
- MailError(
- To => $ErrorsTo,
- Subject => "Could not load a valid user",
- Explanation => <<EOT,
-RT could not load a valid user, and RT's configuration does not allow
-for the creation of a new user for your email.
-
-EOT
- MIMEObj => $Message,
- LogLevel => 'error'
- );
}
return ( 0, "Could not load a valid user", undef );
}
- # }}}
-
- # {{{ Lets check for mail loops of various sorts.
- my $IsBounce = CheckForBounce($head);
-
- my $IsAutoGenerated = CheckForAutoGenerated($head);
-
- my $IsSuspiciousSender = CheckForSuspiciousSender($head);
-
- my $IsALoop = CheckForLoops($head);
-
- my $SquelchReplies = 0;
-
- #If the message is autogenerated, we need to know, so we can not
- # send mail to the sender
- if ( $IsBounce || $IsSuspiciousSender || $IsAutoGenerated || $IsALoop ) {
- $SquelchReplies = 1;
- $ErrorsTo = $RT::OwnerEmail;
- }
-
- # }}}
-
- # {{{ Drop it if it's disallowed
+ # If we got a user, but they don't have the right to say things
if ( $AuthStat == 0 ) {
MailError(
To => $ErrorsTo,
Subject => "Permission Denied",
- Explanation => "You do not have permission to communicate with RT",
- MIMEObj => $Message
+ Explanation =>
+ "You do not have permission to communicate with RT",
+ MIMEObj => $Message
);
- }
-
- # }}}
- # {{{ Warn someone if it's a loop
-
- # Warn someone if it's a loop, before we drop it on the ground
- if ($IsALoop) {
- $RT::Logger->crit("RT Recieved mail ($MessageId) from itself.");
-
- #Should we mail it to RTOwner?
- if ($RT::LoopsToRTOwner) {
- MailError(
- To => $RT::OwnerEmail,
- Subject => "RT Bounce: $Subject",
- Explanation => "RT thinks this message may be a bounce",
- MIMEObj => $Message
- );
- }
-
- #Do we actually want to store it?
- return ( 0, "Message Bounced", undef ) unless ($RT::StoreLoops);
- }
-
- # }}}
-
- # {{{ Squelch replies if necessary
- # Don't let the user stuff the RT-Squelch-Replies-To header.
- if ( $head->get('RT-Squelch-Replies-To') ) {
- $head->add(
- 'RT-Relocated-Squelch-Replies-To',
- $head->get('RT-Squelch-Replies-To')
+ return (
+ 0,
+ "$ErrorsTo tried to submit a message to "
+ . $args{'Queue'}
+ . " without permission.",
+ undef
);
- $head->delete('RT-Squelch-Replies-To');
}
- if ($SquelchReplies) {
-
- # Squelch replies to the sender, and also leave a clue to
- # allow us to squelch ALL outbound messages. This way we
- # can punt the logic of "what to do when we get a bounce"
- # to the scrip. We might want to notify nobody. Or just
- # the RT Owner. Or maybe all Privileged watchers.
- my ( $Sender, $junk ) = ParseSenderAddressFromHead($head);
- $head->add( 'RT-Squelch-Replies-To', $Sender );
- $head->add( 'RT-DetectedAutoGenerated', 'true' );
+ # {{{ Lets check for mail loops of various sorts.
+ my ($continue, $result);
+ ( $continue, $ErrorsTo, $result ) = _HandleMachineGeneratedMail(
+ Message => $Message,
+ ErrorsTo => $ErrorsTo,
+ Subject => $Subject,
+ MessageId => $MessageId
+ );
+
+ unless ($continue) {
+ return ( 0, $result, undef );
}
+
+ # strip actions we should skip
+ @actions = grep !$skip_action{$_}, @actions;
- # }}}
+ # if plugin's updated SystemTicket then update arguments
+ $args{'ticket'} = $SystemTicket->Id if $SystemTicket && $SystemTicket->Id;
my $Ticket = RT::Ticket->new($CurrentUser);
- # {{{ If we don't have a ticket Id, we're creating a new ticket
- if ( (!$SystemTicket || !$SystemTicket->Id) &&
- grep /^(comment|correspond)$/, @actions ) {
-
- # {{{ Create a new ticket
+ if ( !$args{'ticket'} && grep /^(comment|correspond)$/, @actions )
+ {
my @Cc;
my @Requestors = ( $CurrentUser->id );
@@ -776,42 +728,39 @@
Explanation => $ErrStr,
MIMEObj => $Message
);
- $RT::Logger->error("Create failed: $id / $Transaction / $ErrStr ");
- return ( 0, "Ticket creation failed", $Ticket );
+ return ( 0, "Ticket creation failed: $ErrStr", $Ticket );
}
- # strip comments&corresponds from the actions we don't need record twice
- @actions = grep !/^(comment|correspond)$/, @actions;
- $args{'ticket'} = $id;
- # }}}
- }
+ # strip comments&corresponds from the actions we don't need
+ # to record them if we've created the ticket just now
+ @actions = grep !/^(comment|correspond)$/, @actions;
+ $args{'ticket'} = $id;
- $Ticket->Load( $args{'ticket'} );
- unless ( $Ticket->Id ) {
- my $message = "Could not find a ticket with id " . $args{'ticket'};
- MailError(
- To => $ErrorsTo,
- Subject => "Message not recorded",
- Explanation => $message,
- MIMEObj => $Message
- );
-
- return ( 0, $message );
+ } else {
+
+ $Ticket->Load( $args{'ticket'} );
+ unless ( $Ticket->Id ) {
+ my $error = "Could not find a ticket with id " . $args{'ticket'};
+ MailError(
+ To => $ErrorsTo,
+ Subject => "Message not recorded",
+ Explanation => $error,
+ MIMEObj => $Message
+ );
+
+ return ( 0, $error );
+ }
}
# }}}
- foreach my $action( @actions ) {
+ foreach my $action (@actions) {
+
# If the action is comment, add a comment.
- if ( $action =~ /^(comment|correspond)$/i ) {
- my ( $status, $msg );
- if ( $action =~ /^correspond$/i ) {
- ( $status, $msg ) = $Ticket->Correspond( MIMEObj => $Message );
- }
- else {
- ( $status, $msg ) = $Ticket->Comment( MIMEObj => $Message );
- }
+ if ( $action =~ /^(?:comment|correspond)$/i ) {
+ my $method = ucfirst lc $action;
+ my ( $status, $msg ) = $Ticket->$method( MIMEObj => $Message );
unless ($status) {
-
+
#Warn the sender that we couldn't actually submit the comment.
MailError(
To => $ErrorsTo,
@@ -819,79 +768,201 @@
Explanation => $msg,
MIMEObj => $Message
);
- return ( 0, "Message not recorded", $Ticket );
- }
- }
- elsif ($RT::UnsafeEmailCommands && $action =~ /^take$/i ) {
- my ( $status, $msg ) = $Ticket->SetOwner( $CurrentUser->id );
- unless ($status) {
-
- #Warn the sender that we couldn't actually submit the comment.
- MailError(
- To => $ErrorsTo,
- Subject => "Ticket not taken",
- Explanation => $msg,
- MIMEObj => $Message
- );
- return ( 0, "Ticket not taken", $Ticket );
- }
- }
- elsif ( $RT::UnsafeEmailCommands && $action =~ /^resolve$/i ) {
- my ( $status, $msg ) = $Ticket->SetStatus( 'resolved' );
- unless ($status) {
- #Warn the sender that we couldn't actually submit the comment.
- MailError(
- To => $ErrorsTo,
- Subject => "Ticket not resolved",
- Explanation => $msg,
- MIMEObj => $Message
- );
- return ( 0, "Ticket not resolved", $Ticket );
+ return ( 0, "Message not recorded: $msg", $Ticket );
}
+ } elsif ($RT::UnsafeEmailCommands) {
+ my ( $status, $msg ) = _RunUnsafeAction(
+ Action => $action,
+ ErrorsTo => $ErrorsTo,
+ Message => $Message,
+ Ticket => $Ticket,
+ CurrentUser => $CurrentUser,
+ );
+ return ($status, $msg, $Ticket) unless $status == 1;
}
-
- else {
-
- #Return mail to the sender with an error
+ }
+ return ( 1, "Success", $Ticket );
+}
+
+sub _RunUnsafeAction {
+ my %args = (
+ Action => undef,
+ ErrorsTo => undef,
+ Message => undef,
+ Ticket => undef,
+ CurrentUser => undef,
+ @_
+ );
+
+ if ( $args{'Action'} =~ /^take$/i ) {
+ my ( $status, $msg ) = $args{'Ticket'}->SetOwner( $args{'CurrentUser'}->id );
+ unless ($status) {
MailError(
- To => $ErrorsTo,
- Subject => "RT Configuration error",
- Explanation => "'"
- . $args{'action'}
- . "' not a recognized action."
- . " Your RT administrator has misconfigured "
- . "the mail aliases which invoke RT",
- MIMEObj => $Message
+ To => $args{'ErrorsTo'},
+ Subject => "Ticket not taken",
+ Explanation => $msg,
+ MIMEObj => $args{'Message'}
);
- $RT::Logger->crit( $args{'action'} . " type unknown for $MessageId" );
- return (
- -75,
- "Configuration error: "
- . $args{'action'}
- . " not a recognized action",
- $Ticket
+ return ( 0, "Ticket not taken" );
+ }
+ } elsif ( $args{'Action'} =~ /^resolve$/i ) {
+ my ( $status, $msg ) = $args{'Ticket'}->SetStatus('resolved');
+ unless ($status) {
+
+ #Warn the sender that we couldn't actually submit the comment.
+ MailError(
+ To => $args{'ErrorsTo'},
+ Subject => "Ticket not resolved",
+ Explanation => $msg,
+ MIMEObj => $args{'Message'}
);
-
+ return ( 0, "Ticket not resolved" );
}
+ } else {
+ return ( 0, "Not supported unsafe action $args{'Action'}", $args{'Ticket'} );
}
+ return ( 1, "Success" );
+}
- return ( 1, "Success", $Ticket );
+=head2 _NoAuthorizedUserFound
+
+Emails the RT Owner and the requestor when the auth plugins return "No auth user found"
+
+=cut
+
+sub _NoAuthorizedUserFound {
+ my %args = (
+ Right => undef,
+ Message => undef,
+ Requestor => undef,
+ Queue => undef,
+ @_
+ );
+
+ # Notify the RT Admin of the failure.
+ MailError(
+ To => $RT::OwnerEmail,
+ Subject => "Could not load a valid user",
+ Explanation => <<EOT,
+RT could not load a valid user, and RT's configuration does not allow
+for the creation of a new user for this email (@{[$args{Requestor}]}).
+
+You might need to grant 'Everyone' the right '@{[$args{Right}]}' for the
+queue @{[$args{'Queue'}]}.
+
+EOT
+ MIMEObj => $args{'Message'},
+ LogLevel => 'error'
+ );
+
+ # Also notify the requestor that his request has been dropped.
+ MailError(
+ To => $args{'Requestor'},
+ Subject => "Could not load a valid user",
+ Explanation => <<EOT,
+RT could not load a valid user, and RT's configuration does not allow
+for the creation of a new user for your email.
+
+EOT
+ MIMEObj => $args{'Message'},
+ LogLevel => 'error'
+ );
}
-sub IsCorrectAction
-{
- my $action = shift;
- my @actions = split /-/, $action;
- foreach ( @actions ) {
- return (0, $_) unless /^(?:comment|correspond|take|resolve)$/;
- }
- return (1, @actions);
+=head2 _HandleMachineGeneratedMail
+
+Takes named params:
+ Message
+ ErrorsTo
+ Subject
+
+Checks the message to see if it's a bounce, if it looks like a loop, if it's autogenerated, etc.
+Returns a triple of ("Should we continue (boolean)", "New value for $ErrorsTo", "Status message");
+
+=cut
+
+sub _HandleMachineGeneratedMail {
+ my %args = ( Message => undef, ErrorsTo => undef, Subject => undef, MessageId => undef, @_ );
+ my $head = $args{'Message'}->head;
+ my $ErrorsTo = $args{'ErrorsTo'};
+
+ my $IsBounce = CheckForBounce($head);
+
+ my $IsAutoGenerated = CheckForAutoGenerated($head);
+
+ my $IsSuspiciousSender = CheckForSuspiciousSender($head);
+
+ my $IsALoop = CheckForLoops($head);
+
+ my $SquelchReplies = 0;
+
+ #If the message is autogenerated, we need to know, so we can not
+ # send mail to the sender
+ if ( $IsBounce || $IsSuspiciousSender || $IsAutoGenerated || $IsALoop ) {
+ $SquelchReplies = 1;
+ $ErrorsTo = $RT::OwnerEmail;
+ }
+
+ # Warn someone if it's a loop, before we drop it on the ground
+ if ($IsALoop) {
+ $RT::Logger->crit("RT Recieved mail (".$args{MessageId}.") from itself.");
+
+ #Should we mail it to RTOwner?
+ if ($RT::LoopsToRTOwner) {
+ MailError(
+ To => $RT::OwnerEmail,
+ Subject => "RT Bounce: ".$args{'Subject'},
+ Explanation => "RT thinks this message may be a bounce",
+ MIMEObj => $args{Message}
+ );
+ }
+
+ #Do we actually want to store it?
+ return ( 0, $ErrorsTo, "Message Bounced" ) unless ($RT::StoreLoops);
+ }
+
+ # Squelch replies if necessary
+ # Don't let the user stuff the RT-Squelch-Replies-To header.
+ if ( $head->get('RT-Squelch-Replies-To') ) {
+ $head->add(
+ 'RT-Relocated-Squelch-Replies-To',
+ $head->get('RT-Squelch-Replies-To')
+ );
+ $head->delete('RT-Squelch-Replies-To');
+ }
+
+ if ($SquelchReplies) {
+
+ # Squelch replies to the sender, and also leave a clue to
+ # allow us to squelch ALL outbound messages. This way we
+ # can punt the logic of "what to do when we get a bounce"
+ # to the scrip. We might want to notify nobody. Or just
+ # the RT Owner. Or maybe all Privileged watchers.
+ my ( $Sender, $junk ) = ParseSenderAddressFromHead($head);
+ $head->add( 'RT-Squelch-Replies-To', $Sender );
+ $head->add( 'RT-DetectedAutoGenerated', 'true' );
+ }
+ return ( 1, $ErrorsTo, "Handled machine detection" );
}
+=head2 IsCorrectAction
+
+Returns a list of valid actions we've found for this message
+
+=cut
+
+sub IsCorrectAction {
+ my $action = shift;
+ my @actions = split /-/, $action;
+ foreach (@actions) {
+ return ( 0, $_ ) unless /^(?:comment|correspond|take|resolve)$/;
+ }
+ return ( 1, @actions );
+}
eval "require RT::Interface::Email_Vendor";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Email_Vendor.pm});
+die $@ if ( $@ && $@ !~ qr{^Can't locate RT/Interface/Email_Vendor.pm} );
eval "require RT::Interface::Email_Local";
-die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Email_Local.pm});
+die $@ if ( $@ && $@ !~ qr{^Can't locate RT/Interface/Email_Local.pm} );
1;
Modified: rt/branches/3.6-RELEASE/lib/RT/Interface/Web.pm
==============================================================================
--- rt/branches/3.6-RELEASE/lib/RT/Interface/Web.pm (original)
+++ rt/branches/3.6-RELEASE/lib/RT/Interface/Web.pm Tue Jul 18 17:51:35 2006
@@ -339,9 +339,18 @@
Body => $ARGS{'Content'},
);
- if ($ARGS{'Attachments'}) {
- $MIMEObj->make_multipart;
- $MIMEObj->add_part($_) foreach values %{$ARGS{'Attachments'}};
+ if ( $ARGS{'Attachments'} ) {
+ my $rv = $MIMEObj->make_multipart;
+ $RT::Logger->error("Couldn't make multipart message")
+ if !$rv || $rv !~ /^(?:DONE|ALREADY)$/;
+
+ foreach ( values %{$ARGS{'Attachments'}} ) {
+ unless ( $_ ) {
+ $RT::Logger->error("Couldn't add empty attachemnt");
+ next;
+ }
+ $MIMEObj->add_part($_);
+ }
}
my %create_args = (
Modified: rt/branches/3.6-RELEASE/lib/RT/Interface/Web/Handler.pm
==============================================================================
--- rt/branches/3.6-RELEASE/lib/RT/Interface/Web/Handler.pm (original)
+++ rt/branches/3.6-RELEASE/lib/RT/Interface/Web/Handler.pm Tue Jul 18 17:51:35 2006
@@ -107,9 +107,10 @@
umask(0077);
if ($CGI::MOD_PERL) { local $@; eval {
+
chown( Apache->server->uid, Apache->server->gid,
$RT::MasonSessionDir )
- } }
+ }}
# Die if WebSessionDir doesn't exist or we can't write to it
stat($RT::MasonSessionDir);
Modified: rt/branches/3.6-RELEASE/lib/RT/Link_Overlay.pm
==============================================================================
--- rt/branches/3.6-RELEASE/lib/RT/Link_Overlay.pm (original)
+++ rt/branches/3.6-RELEASE/lib/RT/Link_Overlay.pm Tue Jul 18 17:51:35 2006
@@ -267,8 +267,8 @@
=cut
sub TargetObj {
- my $self = shift;
- return $self->TargetURI->Object;
+ my $self = shift;
+ return $self->TargetURI->Object;
}
# }}}
Modified: rt/branches/3.6-RELEASE/lib/RT/Links_Overlay.pm
==============================================================================
--- rt/branches/3.6-RELEASE/lib/RT/Links_Overlay.pm (original)
+++ rt/branches/3.6-RELEASE/lib/RT/Links_Overlay.pm Tue Jul 18 17:51:35 2006
@@ -153,19 +153,17 @@
my $self = shift;
my $Link = $self->SUPER::Next();
- if ((defined($Link)) and (ref($Link))) {
- # Skip links to local objects thast are deleted
- if ($Link->TargetURI->IsLocal and UNIVERSAL::isa($Link->TargetObj,"RT::Ticket")
- and $Link->TargetObj->__Value('status') eq "deleted") {
- return $self->Next;
- } elsif ($Link->BaseURI->IsLocal and UNIVERSAL::isa($Link->BaseObj,"RT::Ticket")
- and $Link->BaseObj->__Value('status') eq "deleted") {
- return $self->Next;
- } else {
- return $Link;
- }
+ return $Link unless $Link && ref $Link;
+
+ # Skip links to local objects thast are deleted
+ if ( $Link->TargetURI->IsLocal and UNIVERSAL::isa($Link->TargetObj,"RT::Ticket")
+ and $Link->TargetObj->__Value('status') eq "deleted") {
+ return $self->Next;
+ } elsif ($Link->BaseURI->IsLocal and UNIVERSAL::isa($Link->BaseObj,"RT::Ticket")
+ and $Link->BaseObj->__Value('status') eq "deleted") {
+ return $self->Next;
} else {
- return undef;
+ return $Link;
}
}
Modified: rt/branches/3.6-RELEASE/lib/RT/Ticket_Overlay.pm
==============================================================================
--- rt/branches/3.6-RELEASE/lib/RT/Ticket_Overlay.pm (original)
+++ rt/branches/3.6-RELEASE/lib/RT/Ticket_Overlay.pm Tue Jul 18 17:51:35 2006
@@ -441,9 +441,9 @@
if ( $args{'Due'} ) {
$Due->Set( Format => 'ISO', Value => $args{'Due'} );
}
- elsif ( $QueueObj->DefaultDueIn ) {
+ elsif ( my $due_in = $QueueObj->DefaultDueIn ) {
$Due->SetToNow;
- $Due->AddDays( $QueueObj->DefaultDueIn );
+ $Due->AddDays( $due_in );
}
my $Starts = new RT::Date( $self->CurrentUser );
@@ -1330,6 +1330,10 @@
@_
);
+ # XXX, FIXME, BUG: if only email is provided then we only check
+ # for ModifyTicket right, but must try to get PrincipalId and
+ # check Watch* rights too if user exist
+
# {{{ Check ACLS
#If the watcher we're trying to add is for the current user
if ( $self->CurrentUser->PrincipalId eq $args{'PrincipalId'}
@@ -1997,11 +2001,16 @@
)
)
{
- $self->Untake();
+ my $clone = RT::Ticket->new( $RT::SystemUser );
+ $clone->Load( $self->Id );
+ unless ( $clone->Id ) {
+ return ( 0, $self->loc("Couldn't load copy of ticket #[_1].", $self->Id) );
+ }
+ my ($status, $msg) = $clone->SetOwner( $RT::Nobody->Id, 'Force' );
+ $RT::Logger->error("Couldn't set owner on queue change: $msg") unless $status;
}
return ( $self->_Set( Field => 'Queue', Value => $NewQueueObj->Id() ) );
-
}
# }}}
@@ -3057,23 +3066,23 @@
return ( 0, $self->loc("Could not change owner. ") . $msg );
}
- $RT::Handle->Commit();
- my $trans;
- ( $trans, $msg, undef ) = $self->_NewTransaction(
- Type => $Type,
- Field => 'Owner',
- NewValue => $NewOwnerObj->Id,
- OldValue => $OldOwnerObj->Id,
- TimeTaken => 0 );
+ $RT::Handle->Commit();
- if ($trans) {
+ ($val, $msg) = $self->_NewTransaction(
+ Type => $Type,
+ Field => 'Owner',
+ NewValue => $NewOwnerObj->Id,
+ OldValue => $OldOwnerObj->Id,
+ TimeTaken => 0,
+ );
+
+ if ( $val ) {
$msg = $self->loc( "Owner changed from [_1] to [_2]",
$OldOwnerObj->Name, $NewOwnerObj->Name );
# TODO: make sure the trans committed properly
}
- return ( $trans, $msg );
-
+ return ( $val, $msg );
}
# }}}
Modified: rt/branches/3.6-RELEASE/lib/RT/Tickets_Overlay.pm
==============================================================================
--- rt/branches/3.6-RELEASE/lib/RT/Tickets_Overlay.pm (original)
+++ rt/branches/3.6-RELEASE/lib/RT/Tickets_Overlay.pm Tue Jul 18 17:51:35 2006
@@ -471,11 +471,8 @@
die "Incorrect Meta Data for $field"
unless ( defined $meta->[1] );
- use POSIX 'strftime';
-
my $date = RT::Date->new( $sb->CurrentUser );
$date->Set( Format => 'unknown', Value => $value );
- my $time = $date->Unix;
if ( $op eq "=" ) {
@@ -483,10 +480,10 @@
# particular single day. in the database, we need to check for >
# and < the edges of that day.
- my $daystart = strftime( "%Y-%m-%d %H:%M",
- gmtime( $time - ( $time % 86400 ) ) );
- my $dayend = strftime( "%Y-%m-%d %H:%M",
- gmtime( $time + ( 86399 - $time % 86400 ) ) );
+ $date->SetToMidnight( Timezone => 'server' );
+ my $daystart = $date->ISO;
+ $date->AddDay;
+ my $dayend = $date->ISO;
$sb->_OpenParen;
@@ -509,11 +506,10 @@
}
else {
- $value = strftime( "%Y-%m-%d %H:%M", gmtime($time) );
$sb->_SQLLimit(
FIELD => $meta->[1],
OPERATOR => $op,
- VALUE => $value,
+ VALUE => $date->ISO,
@rest,
);
}
@@ -566,7 +562,6 @@
my $date = RT::Date->new( $sb->CurrentUser );
$date->Set( Format => 'unknown', Value => $value );
- my $time = $date->Unix;
$sb->_OpenParen;
if ( $op eq "=" ) {
@@ -575,10 +570,10 @@
# particular single day. in the database, we need to check for >
# and < the edges of that day.
- my $daystart = strftime( "%Y-%m-%d %H:%M",
- gmtime( $time - ( $time % 86400 ) ) );
- my $dayend = strftime( "%Y-%m-%d %H:%M",
- gmtime( $time + ( 86399 - $time % 86400 ) ) );
+ $date->SetToMidnight( Timezone => 'server' );
+ my $daystart = $date->ISO;
+ $date->AddDay;
+ my $dayend = $date->ISO;
$sb->_SQLLimit(
ALIAS => $sb->{_sql_transalias},
@@ -608,7 +603,7 @@
ALIAS => $sb->{_sql_transalias},
FIELD => 'Created',
OPERATOR => $op,
- VALUE => $value,
+ VALUE => $date->ISO,
CASESENSITIVE => 0,
@rest
);
Modified: rt/branches/3.6-RELEASE/lib/RT/Transaction_Overlay.pm
==============================================================================
--- rt/branches/3.6-RELEASE/lib/RT/Transaction_Overlay.pm (original)
+++ rt/branches/3.6-RELEASE/lib/RT/Transaction_Overlay.pm Tue Jul 18 17:51:35 2006
@@ -152,7 +152,13 @@
my $id = $self->SUPER::Create(%params);
$self->Load($id);
- $self->_Attach( $args{'MIMEObj'} ) if defined $args{'MIMEObj'};
+ if ( defined $args{'MIMEObj'} ) {
+ my ($id, $msg) = $self->_Attach( $args{'MIMEObj'} );
+ unless ( $id ) {
+ $RT::Logger->error("Couldn't add attachment: $msg");
+ return ( 0, $self->loc("Couldn't add attachment") );
+ }
+ }
#Provide a way to turn off scrips if we need to
@@ -476,11 +482,11 @@
}
my $Attachment = new RT::Attachment( $self->CurrentUser );
- $Attachment->Create(
+ my ($id, $msg) = $Attachment->Create(
TransactionId => $self->Id,
Attachment => $MIMEObject
);
- return ( $Attachment, $self->loc("Attachment created") );
+ return ( $Attachment, $msg || $self->loc("Attachment created") );
}
Modified: rt/branches/3.6-RELEASE/lib/RT/URI.pm
==============================================================================
--- rt/branches/3.6-RELEASE/lib/RT/URI.pm (original)
+++ rt/branches/3.6-RELEASE/lib/RT/URI.pm Tue Jul 18 17:51:35 2006
@@ -143,7 +143,7 @@
unless ($self->Resolver->ParseURI($uri)) {
$RT::Logger->warning("Resolver ".ref($self->Resolver)." could not parse $uri");
- $self->{resolver} = undef; # clear resolver
+ $self->{resolver} = RT::URI::base->new( $self->CurrentUser ); # clear resolver
return (undef);
}
Modified: rt/branches/3.6-RELEASE/lib/RT/URI/base.pm
==============================================================================
--- rt/branches/3.6-RELEASE/lib/RT/URI/base.pm (original)
+++ rt/branches/3.6-RELEASE/lib/RT/URI/base.pm Tue Jul 18 17:51:35 2006
@@ -81,12 +81,8 @@
my $self = shift;
my $obj = shift;
$self->{'uri'} = "unknown-object:".ref($obj);
-
-
}
-
-
sub ParseURI {
my $self = shift;
my $uri = shift;
Modified: rt/branches/3.6-RELEASE/lib/RT/URI/fsck_com_rt.pm
==============================================================================
--- rt/branches/3.6-RELEASE/lib/RT/URI/fsck_com_rt.pm (original)
+++ rt/branches/3.6-RELEASE/lib/RT/URI/fsck_com_rt.pm Tue Jul 18 17:51:35 2006
@@ -128,7 +128,7 @@
sub URIForObject {
my $self = shift;
my $obj = shift;
- return ($self->LocalURIPrefix."/".$self->ObjectType($obj)."/". $obj->Id);
+ return ($self->LocalURIPrefix ."/". $self->ObjectType($obj) ."/". $obj->Id);
}
@@ -143,12 +143,12 @@
my $self = shift;
my $uri = shift;
- if ( $uri =~ /^(\d+)$/ ) {
+ if ( $uri =~ /^\d+$/ ) {
my $ticket = RT::Ticket->new( $self->CurrentUser );
- $ticket->Load($uri);
+ $ticket->Load( $uri );
$self->{'uri'} = $ticket->URI;
$self->{'object'} = $ticket;
- return($ticket->id);
+ return ($ticket->id);
}
else {
$self->{'uri'} = $uri;
@@ -156,9 +156,8 @@
#If it's a local URI, load the ticket object and return its URI
if ( $self->IsLocal ) {
-
my $local_uri_prefix = $self->LocalURIPrefix;
- if ( $self->{'uri'} =~ /^$local_uri_prefix\/(.*?)\/(\d+)$/i ) {
+ if ( $self->{'uri'} =~ /^\Q$local_uri_prefix\E\/(.*?)\/(\d+)$/i ) {
my $type = $1;
my $id = $2;
@@ -192,9 +191,9 @@
sub IsLocal {
my $self = shift;
- my $local_uri_prefix = $self->LocalURIPrefix;
- if ($self->{'uri'} =~ /^$local_uri_prefix/i) {
- return 1;
+ my $local_uri_prefix = $self->LocalURIPrefix;
+ if ( $self->{'uri'} =~ /^\Q$local_uri_prefix/i ) {
+ return 1;
}
else {
return undef;
Modified: rt/branches/3.6-RELEASE/lib/t/regression/06mailgateway.t
==============================================================================
--- rt/branches/3.6-RELEASE/lib/t/regression/06mailgateway.t (original)
+++ rt/branches/3.6-RELEASE/lib/t/regression/06mailgateway.t Tue Jul 18 17:51:35 2006
@@ -52,16 +52,19 @@
=cut
use strict;
-use Test::More tests => 57;
+use Test::More tests => 104;
+
use RT;
RT::LoadConfig();
RT::Init();
use RT::I18N;
+
no warnings 'once';
-my $url = $RT::WebURL;
+my $url = join( ':', grep $_, "http://localhost", $RT::WebPort ) . $RT::WebPath ."/";
# Make sure that when we call the mailgate wrong, it tempfails
+$! = '';
ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url http://this.test.for.non-connection.is.expected.to.generate.an.error"), "Opened the mailgate - The error below is expected - $@");
print MAIL <<EOF;
From: root\@localhost
@@ -78,7 +81,8 @@
# {{{ Test new ticket creation by root who is privileged and superuser
-ok(open(MAIL, "|$RT::BinPath/rt-mailgate --debug --url $url --queue general --action correspond"), "Opened the mailgate - $@");
+$! = '';
+ok(open(MAIL, "|$RT::BinPath/rt-mailgate --debug --url $url --queue general --action correspond"), "Opened the mailgate - $!");
print MAIL <<EOF;
From: root\@localhost
To: rt\@$RT::rtname
@@ -106,7 +110,8 @@
# {{{This is a test of new ticket creation as an unknown user
-ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $url --queue general --action correspond"), "Opened the mailgate - $@");
+$! = '';
+ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $url --queue general --action correspond"), "Opened the mailgate - $!");
print MAIL <<EOF;
From: doesnotexist\@$RT::rtname
To: rt\@$RT::rtname
@@ -142,7 +147,8 @@
ok ($val, "Granted everybody the right to create tickets - $msg");
-ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $url --queue general --action correspond"), "Opened the mailgate - $@");
+$! = '';
+ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $url --queue general --action correspond"), "Opened the mailgate - $!");
print MAIL <<EOF;
From: doesnotexist\@$RT::rtname
To: rt\@$RT::rtname
@@ -175,7 +181,8 @@
#($val,$msg) = $g->PrincipalObj->GrantRight(Right => 'CreateTicket');
#ok ($val, "Granted everybody the right to create tickets - $msg");
-ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $url --queue general --action correspond"), "Opened the mailgate - $@");
+$! = '';
+ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $url --queue general --action correspond"), "Opened the mailgate - $!");
print MAIL <<EOF;
From: doesnotexist-2\@$RT::rtname
To: rt\@$RT::rtname
@@ -200,7 +207,8 @@
($val,$msg) = $g->PrincipalObj->GrantRight(Right => 'ReplyToTicket');
ok ($val, "Granted everybody the right to reply to tickets - $msg");
-ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $url --queue general --action correspond"), "Opened the mailgate - $@");
+$! = '';
+ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $url --queue general --action correspond"), "Opened the mailgate - $!");
print MAIL <<EOF;
From: doesnotexist-2\@$RT::rtname
To: rt\@$RT::rtname
@@ -226,7 +234,8 @@
#($val,$msg) = $g->PrincipalObj->GrantRight(Right => 'CreateTicket');
#ok ($val, "Granted everybody the right to create tickets - $msg");
-ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $url --queue general --action comment"), "Opened the mailgate - $@");
+$! = '';
+ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $url --queue general --action comment"), "Opened the mailgate - $!");
print MAIL <<EOF;
From: doesnotexist-3\@$RT::rtname
To: rt\@$RT::rtname
@@ -251,7 +260,8 @@
($val,$msg) = $g->PrincipalObj->GrantRight(Right => 'CommentOnTicket');
ok ($val, "Granted everybody the right to reply to tickets - $msg");
-ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $url --queue general --action comment"), "Opened the mailgate - $@");
+$! = '';
+ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $url --queue general --action comment"), "Opened the mailgate - $!");
print MAIL <<EOF;
From: doesnotexist-3\@$RT::rtname
To: rt\@$RT::rtname
@@ -292,7 +302,8 @@
Encoding => 'base64');
# Create a ticket with a binary attachment
-ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $url --queue general --action correspond"), "Opened the mailgate - $@");
+$! = '';
+ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $url --queue general --action correspond"), "Opened the mailgate - $!");
$entity->print(\*MAIL);
@@ -350,7 +361,8 @@
# {{{ Simple I18N testing
-ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $url --queue general --action correspond"), "Opened the mailgate - $@");
+$! = '';
+ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $url --queue general --action correspond"), "Opened the mailgate - $!");
print MAIL <<EOF;
From: root\@localhost
@@ -384,7 +396,8 @@
ok($unitick->Transactions->First->Attachments->First->Content =~ /$unistring/i, $unitick->Id." appears to be unicode ". $unitick->Transactions->First->Attachments->First->Id);
# supposedly I18N fails on the second message sent in.
-ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $url --queue general --action correspond"), "Opened the mailgate - $@");
+$! = '';
+ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $url --queue general --action correspond"), "Opened the mailgate - $!");
print MAIL <<EOF;
From: root\@localhost
@@ -423,20 +436,28 @@
($val,$msg) = $g->PrincipalObj->RevokeRight(Right => 'CreateTicket');
ok ($val, $msg);
-=for later
+##=for later
+
+SKIP: {
+skip "Advanced mailgate actions require an unsafe configuration", 47 unless $RT::UnsafeEmailCommands;
-TODO: {
+#create new queue to be shure we don't mess with rights
+use RT::Queue;
+my $queue = RT::Queue->new($RT::SystemUser);
+my ($qid) = $queue->Create( Name => 'ext-mailgate');
+ok( $qid, 'queue created for ext-mailgate tests' );
# {{{ Check take and resolve actions
# create ticket that is owned by nobody
use RT::Ticket;
$tick = RT::Ticket->new($RT::SystemUser);
-my ($id) = $tick->Create( Queue => 'general', Subject => 'test');
+my ($id) = $tick->Create( Queue => 'ext-mailgate', Subject => 'test');
ok( $id, 'new ticket created' );
is( $tick->Owner, $RT::Nobody->Id, 'owner of the new ticket is nobody' );
-ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $url --queue general --action take"), "Opened the mailgate - $@");
+$! = '';
+ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $url --queue ext-mailgate --action take"), "Opened the mailgate - $!");
print MAIL <<EOF;
From: root\@localhost
Subject: [$RT::rtname \#$id] test
@@ -453,14 +474,15 @@
# check that there is no text transactions writen
is( $tick->Transactions->Count, 2, 'no superfluous transactions');
+my $status;
($status, $msg) = $tick->SetOwner( $RT::Nobody->Id, 'Force' );
ok( $status, 'successfuly changed owner: '. ($msg||'') );
is( $tick->Owner, $RT::Nobody->Id, 'set owner back to nobody');
- local $TODO = "Advanced mailgate actions require an unsafe configuration";
-ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $RT::WebURL --queue general --action take-correspond"), "Opened the mailgate - $@");
+$! = '';
+ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $RT::WebURL --queue ext-mailgate --action take-correspond"), "Opened the mailgate - $@");
print MAIL <<EOF;
From: root\@localhost
Subject: [$RT::rtname \#$id] correspondence
@@ -470,17 +492,21 @@
close (MAIL);
is ($? >> 8, 0, "The mail gateway exited normally");
+DBIx::SearchBuilder::Record::Cachable->FlushCache;
+
$tick = RT::Ticket->new($RT::SystemUser);
$tick->Load( $id );
-is( $tick->Id, $id, 'load correct ticket');
+is( $tick->Id, $id, "load correct ticket #$id");
is( $tick->OwnerObj->EmailAddress, 'root at localhost', 'successfuly take ticket via email');
my $txns = $tick->Transactions;
$txns->Limit( FIELD => 'Type', VALUE => 'Correspond');
-is( $txns->Last->Subject, "[$RT::rtname \#$id] correspondence", 'successfuly add correspond within take via email' );
+$txns->OrderBy( FIELD => 'id', ORDER => 'DESC' );
# +1 because of auto open
is( $tick->Transactions->Count, 6, 'no superfluous transactions');
+is( $txns->First->Subject, "[$RT::rtname \#$id] correspondence", 'successfuly add correspond within take via email' );
-ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $url --queue general --action resolve --debug"), "Opened the mailgate - $@");
+$! = '';
+ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $url --queue ext-mailgate --action resolve --debug"), "Opened the mailgate - $!");
print MAIL <<EOF;
From: root\@localhost
Subject: [$RT::rtname \#$id] test
@@ -497,10 +523,115 @@
is( $tick->Status, 'resolved', 'successfuly resolved ticket via email');
is( $tick->Transactions->Count, 7, 'no superfluous transactions');
-};
+use RT::User;
+my $user = RT::User->new( $RT::SystemUser );
+my ($uid) = $user->Create( Name => 'ext-mailgate',
+ EmailAddress => 'ext-mailgate at localhost',
+ Privileged => 1,
+ Password => 'qwe123',
+ );
+ok( $uid, 'user created for ext-mailgate tests' );
+ok( !$user->HasRight( Right => 'OwnTicket', Object => $queue ), "User can't own ticket" );
+
+$tick = RT::Ticket->new($RT::SystemUser);
+($id) = $tick->Create( Queue => $qid, Subject => 'test' );
+ok( $id, 'create new ticket' );
+
+$! = '';
+ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $url --queue ext-mailgate --action take"), "Opened the mailgate - $!");
+print MAIL <<EOF;
+From: ext-mailgate\@localhost
+Subject: [example.com \#$id] test
+
+EOF
+close (MAIL);
+is ( $? >> 8, 0, "mailgate exited normally" );
+DBIx::SearchBuilder::Record::Cachable->FlushCache;
+
+cmp_ok( $tick->Owner, '!=', $user->id, "we didn't change owner" );
+
+($status, $msg) = $user->PrincipalObj->GrantRight( Object => $queue, Right => 'ReplyToTicket' );
+ok( $status, "successfuly granted right: $msg" );
+my $ace_id = $status;
+ok( $user->HasRight( Right => 'ReplyToTicket', Object => $tick ), "User can reply to ticket" );
+
+$! = '';
+ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $url --queue ext-mailgate --action correspond-take"), "Opened the mailgate - $!");
+print MAIL <<EOF;
+From: ext-mailgate\@localhost
+Subject: [example.com \#$id] test
+
+correspond-take
+EOF
+close (MAIL);
+is ( $? >> 8, 0, "mailgate exited normally" );
+DBIx::SearchBuilder::Record::Cachable->FlushCache;
+
+cmp_ok( $tick->Owner, '!=', $user->id, "we didn't change owner" );
+is( $tick->Transactions->Count, 3, "one transactions added" );
+
+$! = '';
+ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $url --queue ext-mailgate --action take-correspond"), "Opened the mailgate - $!");
+print MAIL <<EOF;
+From: ext-mailgate\@localhost
+Subject: [example.com \#$id] test
+
+correspond-take
+EOF
+close (MAIL);
+is ( $? >> 8, 0, "mailgate exited normally" );
+DBIx::SearchBuilder::Record::Cachable->FlushCache;
+
+cmp_ok( $tick->Owner, '!=', $user->id, "we didn't change owner" );
+is( $tick->Transactions->Count, 3, "no transactions added, user can't take ticket first" );
+
+# revoke ReplyToTicket right
+use RT::ACE;
+my $ace = RT::ACE->new($RT::SystemUser);
+$ace->Load( $ace_id );
+$ace->Delete;
+my $acl = RT::ACL->new($RT::SystemUser);
+$acl->Limit( FIELD => 'RightName', VALUE => 'ReplyToTicket' );
+$acl->LimitToObject( $RT::System );
+while( my $ace = $acl->Next ) {
+ $ace->Delete;
+}
+
+ok( !$user->HasRight( Right => 'ReplyToTicket', Object => $tick ), "User can't reply to ticket any more" );
+
+
+my $group = RT::Group->new( $RT::SystemUser );
+ok( $group->LoadQueueRoleGroup( Queue => $qid, Type=> 'Owner' ), "load queue owners role group" );
+$ace = RT::ACE->new( $RT::SystemUser );
+($ace_id, $msg) = $group->PrincipalObj->GrantRight( Right => 'ReplyToTicket', Object => $queue );
+ok( $ace_id, "Granted queue owners role group with ReplyToTicket right" );
+
+($status, $msg) = $user->PrincipalObj->GrantRight( Object => $queue, Right => 'OwnTicket' );
+ok( $status, "successfuly granted right: $msg" );
+($status, $msg) = $user->PrincipalObj->GrantRight( Object => $queue, Right => 'TakeTicket' );
+ok( $status, "successfuly granted right: $msg" );
+
+$! = '';
+ok(open(MAIL, "|$RT::BinPath/rt-mailgate --url $url --queue ext-mailgate --action take-correspond"), "Opened the mailgate - $!");
+print MAIL <<EOF;
+From: ext-mailgate\@localhost
+Subject: [example.com \#$id] test
+
+take-correspond with reply right granted to owner role
+EOF
+close (MAIL);
+is ( $? >> 8, 0, "mailgate exited normally" );
+DBIx::SearchBuilder::Record::Cachable->FlushCache;
+
+$tick->Load( $id );
+is( $tick->Owner, $user->id, "we changed owner" );
+ok( $user->HasRight( Right => 'ReplyToTicket', Object => $tick ), "owner can reply to ticket" );
+is( $tick->Transactions->Count, 5, "transactions added" );
-=cut
# }}}
+};
+
1;
+
Modified: rt/branches/3.6-RELEASE/lib/t/regression/22search_tix_by_txn.t
==============================================================================
--- rt/branches/3.6-RELEASE/lib/t/regression/22search_tix_by_txn.t (original)
+++ rt/branches/3.6-RELEASE/lib/t/regression/22search_tix_by_txn.t Tue Jul 18 17:51:35 2006
@@ -1,6 +1,13 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
#use Test::More tests => 26;
use Test::More qw/no_plan/;
+
$ENV{'TZ'} = 'GMT';
+
use RT;
RT::LoadConfig();
RT::Init();
@@ -29,4 +36,5 @@
$tix->FromSQL(qq{Updated = "2005-08-05" AND Subject = "$SUBJECT"});
is( $tix->Count, 1);
-1;
+
+exit 0;
Added: rt/branches/3.6-RELEASE/lib/t/regression/23-web_attachments.t
==============================================================================
--- (empty file)
+++ rt/branches/3.6-RELEASE/lib/t/regression/23-web_attachments.t Tue Jul 18 17:51:35 2006
@@ -0,0 +1,60 @@
+#!/usr/bin/perl -w
+use strict;
+
+use Test::More tests => 15;
+use RT;
+RT::LoadConfig;
+RT::Init;
+use Test::WWW::Mechanize;
+
+$RT::WebURL ||= 0; # avoid stupid warning
+my $BaseURL = $RT::WebURL;
+use constant LogoFile => $RT::MasonComponentRoot .'/NoAuth/images/bplogo.gif';
+use constant FaviconFile => $RT::MasonComponentRoot .'/NoAuth/images/favicon.png';
+
+my $queue_name = 'General';
+
+my $m = Test::WWW::Mechanize->new;
+isa_ok($m, 'Test::WWW::Mechanize');
+
+$m->get_ok( $BaseURL."?user=root;pass=password" );
+$m->content_like(qr/Logout/, 'we did log in');
+
+my $qid;
+{
+ $m->content =~ /<SELECT\s+NAME\s*="Queue">.*?<OPTION\s+VALUE="(\d+)"\s*\d*>\s*\Q$queue_name\E\s*<\/OPTION>/msi;
+ ok( $qid = $1, "found id of the '$queue_name' queue");
+}
+
+$m->form_number(1);
+$m->field('Queue', $qid);
+$m->submit;
+is($m->status, 200, "request successful");
+$m->content_like(qr/Create a new ticket/, 'ticket create page');
+
+$m->form('TicketCreate');
+$m->field('Subject', 'Attachments test');
+$m->field('Attach', LogoFile);
+$m->field('Content', 'Some content');
+$m->submit;
+is($m->status, 200, "request successful");
+
+$m->content_like(qr/Attachments test/, 'we have subject on the page');
+$m->content_like(qr/Some content/, 'and content');
+$m->content_like(qr/Download bplogo\.gif/, 'page has file name');
+
+$m->follow_link_ok({text => 'Reply'}, "reply to the ticket");
+$m->form('TicketUpdate');
+$m->field('Attach', LogoFile);
+$m->click('AddMoreAttach');
+is($m->status, 200, "request successful");
+
+$m->form('TicketUpdate');
+$m->field('Attach', FaviconFile);
+$m->field('UpdateContent', 'Message');
+$m->click('SubmitTicket');
+is($m->status, 200, "request successful");
+
+$m->content_like(qr/Download bplogo\.gif/, 'page has file name');
+$m->content_like(qr/Download favicon\.png/, 'page has file name');
+
Modified: rt/branches/3.6-RELEASE/sbin/rt-setup-database.in
==============================================================================
--- rt/branches/3.6-RELEASE/sbin/rt-setup-database.in (original)
+++ rt/branches/3.6-RELEASE/sbin/rt-setup-database.in Tue Jul 18 17:51:35 2006
@@ -559,6 +559,10 @@
next;
}
my ( $return, $msg ) = $new_entry->Create(%$item);
+ unless( $return ) {
+ print "(Error: $msg)\n";
+ next;
+ }
foreach my $value ( @{$values} ) {
my ( $eval, $emsg ) = $new_entry->AddValue(%$value);
More information about the Rt-commit
mailing list