Commit 6ea5aea3 authored by Jesse Vincent's avatar Jesse Vincent
Browse files

Merging changes from ourinternet

parent 4f03449a
......@@ -89,8 +89,6 @@ RT_READABLE_DIR_MODE = 0755
# RT_MODPERL_HANDLER is the mason handler script for mod_perl
RT_MODPERL_HANDLER = $(RT_BIN_PATH)/webmux.pl
# RT_MODPERL2_HANDLER is the mason handler script for mod_perl2
RT_MODPERL2_HANDLER = $(RT_BIN_PATH)/modperl2.pl
# RT_FASTCGI_HANDLER is the mason handler script for FastCGI
RT_FASTCGI_HANDLER = $(RT_BIN_PATH)/mason_handler.fcgi
# RT_WIN32_FASTCGI_HANDLER is the mason handler script for FastCGI
......@@ -109,7 +107,6 @@ SETGID_BINARIES = $(DESTDIR)/$(RT_MAILGATE_BIN) \
$(DESTDIR)/$(RT_CLI_ADMIN_BIN)
BINARIES = $(DESTDIR)/$(RT_MODPERL_HANDLER) \
$(DESTDIR)/$(RT_MODPERL2_HANDLER) \
$(DESTDIR)/$(RT_CRON_BIN) \
$(SETGID_BINARIES)
SYSTEM_BINARIES = $(DESTDIR)/$(RT_SBIN_PATH)/
......@@ -304,7 +301,8 @@ initialize-database:
dropdb:
$(PERL) $(DESTDIR)/$(RT_SBIN_PATH)/initdb --action drop --dba root --prompt-for-dba-password
insert-approval-data:
$(PERL) $(DESTDIR)/$(RT_SBIN_PATH)/insert_approval_scrips
# }}}
# {{{ libs-install
......@@ -314,12 +312,6 @@ libs-install:
chgrp -R $(LIBS_GROUP) $(DESTDIR)/$(RT_LIB_PATH)
chmod -R $(RT_READABLE_DIR_MODE) $(DESTDIR)/$(RT_LIB_PATH)
cp -rp lib/* $(DESTDIR)/$(RT_LIB_PATH)
$(PERL) -p -i -e " s'!!RT_VERSION!!'$(RT_VERSION)'g;\
s'!!RT_CONFIG!!'$(CONFIG_FILE)'g; \
s'!!RT_SITE_CONFIG!!'$(SITE_CONFIG_FILE)'g; \
s'!!RT_VENDOR_CONFIG!!'$(VENDOR_CONFIG_FILE)'g;" \
$(DESTDIR)/$(RT_LIB_PATH)/RT.pm ; \
# }}}
# {{{ html-install
......@@ -346,10 +338,6 @@ sbin-install:
sbin/testdeps \
sbin/insert_approval_scrips \
$(DESTDIR)/$(RT_SBIN_PATH)
$(PERL) -p -i -e " s'!!PERL!!'"$(PERL)"'g;\
s'!!RT_LIB_PATH!!'"$(RT_LIB_PATH)"'g;"\
$(DESTDIR)/$(RT_SBIN_PATH)/*
# }}}
# {{{ bin-install
......@@ -362,20 +350,10 @@ bin-install:
bin/enhanced-mailgate \
bin/mason_handler.fcgi \
bin/mason_handler.svc \
bin/modperl2.pl \
bin/webmux.pl \
bin/rt-crontool \
bin/rt-commit-handler \
$(DESTDIR)/$(RT_BIN_PATH)
$(PERL) -p -i -e " s'!!PERL!!'"$(PERL)"'g;\
s'!!RT_LIB_PATH!!'"$(RT_LIB_PATH)"'g;"\
$(BINARIES)
# }}}
# {{{ Best Practical Build targets -- no user servicable parts inside
......@@ -385,8 +363,8 @@ POD2TEST_EXE = sbin/extract_pod_tests
testify-pods:
[ -d lib/t/autogen ] || mkdir lib/t/autogen
find lib -name \*pm |xargs -n 1 $(PERL) $(POD2TEST_EXE)
find bin -type f |grep -v \~| xargs -n 1 $(PERL) $(POD2TEST_EXE)
find lib -name \*pm |grep -v\*.in |xargs -n 1 $(PERL) $(POD2TEST_EXE)
find bin -type f |grep -v \~| grep -v \*.in | xargs -n 1 $(PERL) $(POD2TEST_EXE)
......
......@@ -89,8 +89,6 @@ RT_READABLE_DIR_MODE = 0755
# RT_MODPERL_HANDLER is the mason handler script for mod_perl
RT_MODPERL_HANDLER = $(RT_BIN_PATH)/webmux.pl
# RT_MODPERL2_HANDLER is the mason handler script for mod_perl2
RT_MODPERL2_HANDLER = $(RT_BIN_PATH)/modperl2.pl
# RT_FASTCGI_HANDLER is the mason handler script for FastCGI
RT_FASTCGI_HANDLER = $(RT_BIN_PATH)/mason_handler.fcgi
# RT_WIN32_FASTCGI_HANDLER is the mason handler script for FastCGI
......@@ -109,7 +107,6 @@ SETGID_BINARIES = $(DESTDIR)/$(RT_MAILGATE_BIN) \
$(DESTDIR)/$(RT_CLI_ADMIN_BIN)
BINARIES = $(DESTDIR)/$(RT_MODPERL_HANDLER) \
$(DESTDIR)/$(RT_MODPERL2_HANDLER) \
$(DESTDIR)/$(RT_CRON_BIN) \
$(SETGID_BINARIES)
SYSTEM_BINARIES = $(DESTDIR)/$(RT_SBIN_PATH)/
......@@ -304,7 +301,8 @@ initialize-database:
dropdb:
$(PERL) $(DESTDIR)/$(RT_SBIN_PATH)/initdb --action drop --dba @DB_DBA@ --prompt-for-dba-password
insert-approval-data:
$(PERL) $(DESTDIR)/$(RT_SBIN_PATH)/insert_approval_scrips
# }}}
# {{{ libs-install
......@@ -314,12 +312,6 @@ libs-install:
chgrp -R $(LIBS_GROUP) $(DESTDIR)/$(RT_LIB_PATH)
chmod -R $(RT_READABLE_DIR_MODE) $(DESTDIR)/$(RT_LIB_PATH)
cp -rp lib/* $(DESTDIR)/$(RT_LIB_PATH)
$(PERL) -p -i -e " s'!!RT_VERSION!!'$(RT_VERSION)'g;\
s'!!RT_CONFIG!!'$(CONFIG_FILE)'g; \
s'!!RT_SITE_CONFIG!!'$(SITE_CONFIG_FILE)'g; \
s'!!RT_VENDOR_CONFIG!!'$(VENDOR_CONFIG_FILE)'g;" \
$(DESTDIR)/$(RT_LIB_PATH)/RT.pm ; \
# }}}
# {{{ html-install
......@@ -346,10 +338,6 @@ sbin-install:
sbin/testdeps \
sbin/insert_approval_scrips \
$(DESTDIR)/$(RT_SBIN_PATH)
$(PERL) -p -i -e " s'!!PERL!!'"$(PERL)"'g;\
s'!!RT_LIB_PATH!!'"$(RT_LIB_PATH)"'g;"\
$(DESTDIR)/$(RT_SBIN_PATH)/*
# }}}
# {{{ bin-install
......@@ -362,20 +350,10 @@ bin-install:
bin/enhanced-mailgate \
bin/mason_handler.fcgi \
bin/mason_handler.svc \
bin/modperl2.pl \
bin/webmux.pl \
bin/rt-crontool \
bin/rt-commit-handler \
$(DESTDIR)/$(RT_BIN_PATH)
$(PERL) -p -i -e " s'!!PERL!!'"$(PERL)"'g;\
s'!!RT_LIB_PATH!!'"$(RT_LIB_PATH)"'g;"\
$(BINARIES)
# }}}
# {{{ Best Practical Build targets -- no user servicable parts inside
......@@ -385,8 +363,8 @@ POD2TEST_EXE = sbin/extract_pod_tests
testify-pods:
[ -d lib/t/autogen ] || mkdir lib/t/autogen
find lib -name \*pm |xargs -n 1 $(PERL) $(POD2TEST_EXE)
find bin -type f |grep -v \~| xargs -n 1 $(PERL) $(POD2TEST_EXE)
find lib -name \*pm |grep -v\*.in |xargs -n 1 $(PERL) $(POD2TEST_EXE)
find bin -type f |grep -v \~| grep -v \*.in | xargs -n 1 $(PERL) $(POD2TEST_EXE)
......
......@@ -45,12 +45,13 @@ o A DB backend; MySQL is recommended ( http://www.mysql.com )
(Some older releases had crippling SQL bugs)
Postgres 7.2 or later
o Apache + mod_perl -- ( http://perl.apache.org)
o Apache (1.3.x or 2.x) with mod_perl -- ( http://perl.apache.org )
or A webserver with FastCGI support (www.fastcgi.com)
If you compile mod_perl as a DSO, you're on your own. It's known
to have massive stability problems.
mod_perl must be build with EVERYTHING=1
If you compile mod_perl on Apache 1.3.x as a DSO, you're on your own;
It's known to have massive stability problems.
mod_perl 1.x must be build with EVERYTHING=1
o Various and sundry perl modules
RT takes care of the installation of most of these automatically
......@@ -153,8 +154,8 @@ THE WEB UI
----------
RT's web ui is based around HTML::Mason, which works best with the mod_perl
perl interpreter within Apache httpd. We're working on a FastCGI version as
well, but for now, apache's your best bet.
perl interpreter within Apache httpd. Alternatively, support for the FastCGI
(and plain CGI) interface is also provided as 'bin/mason_handler.fcgi'.
Apache
RT Uses HTML::Mason. You'll need to add a few lines to your
......@@ -162,20 +163,30 @@ Apache
(you should, the perl scripts will go quite a bit faster around with
it), you can do something like this:
<VirtualHost your.ip.address>
DocumentRoot /path/to/rt3/html
ServerName your.rt.server.hostname
PerlModule Apache::DBI
PerlFreshRestart On
PerlRequire /path/to/rt3/bin/webmux.pl
<Location />
SetHandler perl-script
PerlHandler RT::Mason
</Location>
ServerName your.rt.server.hostname
DocumentRoot /path/to/rt3/share/html
AddDefaultCharset UTF-8
PerlFreshRestart On # only for Apache/mod_perl 1.x
PerlModule Apache2 Apache::compat # only for Apache/mod_perl 2.x
PerlModule Apache::DBI
PerlRequire /path/to/rt3/bin/webmux.pl
<FilesMatch "\.html$">
SetHandler perl-script
PerlHandler RT::Mason
</FilesMatch>
<LocationMatch "/Attachment/">
SetHandler perl-script
PerlHandler RT::Mason
</LocationMatch>
</VirtualHost>
Additionally, you should set up a cron job to remove stale session data.
Additionally, if you are using a database engine other than MySQL, you should
set up a cron job to remove stale session locks. (MySQL uses the database
itself for that.)
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
WARNING: Don't install this cron job or run this find command if your
......
......@@ -39,7 +39,7 @@ $VERSION='0.3';
# KEYIDIR should point to the directory containing a pubring.gpg
# for gpg to use as its authentication database
$KEYDIR = "/opt/rt2/etc/gnupg";
$KEYDIR = "/opt/rt3/etc/gnupg";
# If you turn on the $PermitReplayAttacks flag in enhanced-mailgate, RT will
# treat
......@@ -49,7 +49,7 @@ $KEYDIR = "/opt/rt2/etc/gnupg";
$PermitReplayAttacks = 0;
use lib "!!RT_LIB_PATH!!";
use lib "/opt/rt3/lib";
use RT::Interface::Email qw(CleanEnv
......
#!@PERL@ -w
# BEGIN LICENSE BLOCK
#
# Copyright (c) 1996-2002 Jesse Vincent <jesse@bestpractical.com>
#
# (Except where explictly superceded by other copyright notices)
#
# 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.
#
#
# Unless otherwise specified, all modifications, corrections or
# extensions to this work which alter its source code become the
# property of Best Practical Solutions, LLC when submitted for
# inclusion in the work.
#
#
# END LICENSE BLOCK
# This software is redistributable under the terms of version 2 of the GNU GPL
# This product works with RT 2.0, but is
# not part of the RT distribution and IS NOT A FREELY SUPPORTED PRODUCT.
# Patches are, of course, appreciated.
package RT;
use strict;
use vars qw($VERSION $KEYDIR $Handle $Nobody $SystemUser $PermitReplayAttacks);
$VERSION='0.3';
# KEYIDIR should point to the directory containing a pubring.gpg
# for gpg to use as its authentication database
$KEYDIR = "@RT_ETC_PATH@/gnupg";
# If you turn on the $PermitReplayAttacks flag in enhanced-mailgate, RT will
# treat
# the [tag #<int>] in the message's subject as an initial RT-Ticket: header.
# This leaves you open to the possibility of a hostile user applying your
# updates to another ticket.
$PermitReplayAttacks = 0;
use lib "@RT_LIB_PATH@";
use RT::Interface::Email qw(CleanEnv
GetCurrentUser
GetMessageContent
CheckForLoops
CheckForSuspiciousSender
CheckForAutoGenerated
ParseMIMEEntityFromSTDIN
ParseTicketId
MailError
ParseCcAddressesFromHead
ParseSenderAddressFromHead
ParseErrorsToAddressFromHead
loc
);
#Clean out all the nasties from the environment
CleanEnv();
#Load etc/config.pm and drop privs
RT::LoadConfig();
#Connect to the database and get RT::SystemUser and RT::Nobody loaded
RT::Init();
use RT::Ticket;
use RT::Queue;
use MIME::Parser;
use File::Temp;
use Mail::Address;
#Set some sensible defaults
my $Queue = 1;
my $Action = "correspond";
my ($Verbose, $ReturnTid, $Debug);
my ($From, $TicketId, $Subject,$SquelchReplies);
my ($status, $msg, $CurrentUser, $CurrentUserAuth);
# {{{ parse commandline
while (my $flag = shift @ARGV) {
if (($flag eq '-v') or ($flag eq '--verbose')) {
$Verbose = 1;
}
if (($flag eq '-t') or ($flag eq '--ticketid')) {
$ReturnTid = 1;
}
if (($flag eq '-d') or ($flag eq '--debug')) {
$RT::Logger->debug("Debug mode enabled\n");
$Debug = 1;
}
if (($flag eq '-q') or ($flag eq '--queue')) {
$Queue = shift @ARGV;
}
if (($flag eq '-a') or ($flag eq '--action')) {
$Action = shift @ARGV;
}
}
# }}}
# get the current mime entity from stdin
my ($entity, $head) = ParseMIMEEntityFromSTDIN();
#Get someone to send runtime errors to;
my $ErrorsTo = ParseErrorsToAddressFromHead($head);
# If there's a gpg signature, try to validate it.
if ( ($head->mime_type =~ /multipart\/signed/i) and
( $entity->parts(1)->head->mime_type =~ /application\/pgp-signature/i) ) {
($CurrentUser, $CurrentUserAuth) =
GetCurrentUserFromPGPSignature($entity, $ErrorsTo);
}
# Get us a current user object, if we couldn't validate the sig
# or there was no sig
unless ($CurrentUser) {
$CurrentUser = GetCurrentUser($head);
$CurrentUserAuth = 'mailfrom';
}
my $MessageId = $head->get('Message-Id') ||
"<no-message-id-".time.rand(2000)."\@.$RT::rtname>";
#Pull apart the subject line
$Subject = $head->get('Subject') || "";
chomp $Subject;
# Get the ticket ID
$TicketId = ParseTicketId($Subject);
#Set up a queue object
my $QueueObj = RT::Queue->new($CurrentUser);
$QueueObj->Load($Queue);
unless ($QueueObj->id ) {
MailError(To => $RT::OwnerEmail,
Subject => loc("RT Bounce: [_1]", $Subject),
Explanation => loc("RT couldn't find the queue: [_1]", $Queue),
MIMEObj => $entity);
}
# {{{ Lets check for mail loops of various sorts.
my $IsAutoGenerated = CheckForAutoGenerated($head);
my $IsSuspiciousSender = CheckForSuspiciousSender($head);
my $IsALoop = CheckForLoops($head);
#If the message is autogenerated, we need to know, so we can not
# send mail to the sender
if ($IsSuspiciousSender || $IsAutoGenerated || $IsALoop) {
$SquelchReplies = 1;
$ErrorsTo = $RT::OwnerEmail;
}
# {{{ 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(loc("RT Received mail ([_1]) from itself.", $MessageId));
#Should we mail it to RTOwner?
if ($RT::LoopsToRTOwner) {
MailError(To => $RT::OwnerEmail,
Subject => loc("RT Bounce: [_1]", $Subject),
Explanation => loc("RT thinks this message may be a bounce"),
MIMEObj => $entity);
#Do we actually want to store it?
exit unless ($RT::StoreLoops);
}
}
# }}}
#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) {
## TODO: This is a hack. It should be some other way to
## indicate that the transaction should be "silent".
my ($Sender, $junk) = ParseSenderAddressFromHead($head);
$head->add('RT-Squelch-Replies-To', $Sender);
}
# }}}
# {{{ If we don't have a ticket Id, we're creating a new ticket
# {{{ if we're processing an action
if ($Action =~ /action/i) {
#Get pseudo headers out of the message body before we go there.
my $PseudoHeaders = ParseMessageForCommands($entity);
if ($CurrentUserAuth eq 'pgp-signature') {
my $ResultsMessage = ActOnPseudoHeaders($TicketId, $PseudoHeaders);
MailError( To => $ErrorsTo,
Subject => loc("RT has proccessed your commands"),
Explanation => $ResultsMessage,
MIMEObj => $entity->parts(0)
);
}
else {
MailError( To => $ErrorsTo,
Subject => loc("RT couldn't authenticate you"),
MIMEObj => $entity->parts(0),
Explanation =>
loc("RT's email command mode requires PGP authentication. Either you didn't sign your message, or your signature could not be verified.")
);
}
}
# }}}
elsif (!defined($TicketId)) {
#If the message doesn't reference a ticket #, create a new ticket
# {{{ Create a new ticket
if ($Action =~ /correspond/) {
# open a new ticket
my @Requestors = ($CurrentUser->id);
my @Cc;
if ($RT::ParseNewMessageForTicketCcs) {
@Cc = ParseCcAddressesFromHead(Head => $head, QueueObj => $QueueObj );
}
# Pull commands out of $entity.
my $Commands = ParseMessageForCommands($entity);
# Pull values out of commands, setting some defaults.
my $values = ParsePseudoHeadersForNewTicket($Commands,
status => 'new',
queue => $Queue,
subject => $Subject,
requestor => \@Requestors,
cc => \@Cc,
admincc => undef,
);
my $Ticket = new RT::Ticket($CurrentUser);
my ($id, $Transaction, $ErrStr) =
$Ticket->Create ( MIMEObj => $entity,
Status => $values->{'status'},
Queue => $values->{'queue'},
Subject => $values->{'subject'},
Requestor => \@{$values->{'requestor'}},
Cc => \@{$values->{'cc'}},
AdminCc => \@{$values->{'admincc'}},
Owner => $values->{'owner'},
TimeWorked => $values->{'timeworked'},
TimeLeft => $values->{'timeleft'},
Priority => $values->{'priority'},
FinalPriority => $values->{'finalpriority'},
Due => $values->{'due'},
);
if ($id == 0 ) {
MailError( To => $ErrorsTo,
Subject => loc("Ticket creation failed"),
Explanation => $ErrStr,
MIMEObj => $entity
);
$RT::Logger->error("Create failed: [_1]/[_2]/[_3]", $id, $Transaction, $ErrStr );
}
}
# }}}
else {
#TODO Return an error message
MailError( To => $ErrorsTo,
Subject => loc("No ticket id specified"),
Explanation => loc("[_1] aliases require a TicketId to work on", $Action),
MIMEObj => $entity
);
$RT::Logger->crit(loc("[_1] aliases require a TicketId to work on (from [_2]) [_3]" , $Action, $CurrentUser->UserObj->EmailAddress, $MessageId);
return();
}
}
# }}}
# {{{ If we've got a ticket ID, update the ticket
else {
# If the action is comment, add a comment.
if ($Action =~ /comment/i){
my $Ticket = new RT::Ticket($CurrentUser);
$Ticket->Load($TicketId);
unless ($Ticket->Id) {
MailError( To => $ErrorsTo,
Subject => loc("Comment not recorded"),
Explanation => loc("Could not find a ticket with id [_1]", $TicketId),
MIMEObj => $entity
);
#Return an error message saying that Ticket "#foo" wasn't found.
}
($status, $msg) = $Ticket->Comment(MIMEObj=>$entity);
unless ($status) {
#Warn the sender that we couldn't actually submit the comment.
MailError( To => $ErrorsTo,
Subject => loc("Comment not recorded"),
Explanation => $msg,
MIMEObj => $entity
);
}
}
# If the message is correspondence, add it to the ticket
elsif ($Action =~ /correspond/i) {
my $Ticket = RT::Ticket->new($CurrentUser);
$Ticket->Load($TicketId);
$Ticket->Open; #TODO: Don't open if it's alreadyopen
#TODO: Check for error conditions
($status, $msg) = $Ticket->Correspond(MIMEObj => $entity);
unless ($status) {
#Return mail to the sender with an error
MailError( To => $ErrorsTo,
Subject => loc("Correspondence not recorded"),
Explanation => $msg,
MIMEObj => $entity
);
}
}
else {
#Return mail to the sender with an error
MailError( To => $ErrorsTo,
Subject => loc("RT Configuration error"),
Explanation => loc("'[_1]' not a recognized action. ", $Action).
loc("Your RT administrator has misconfigured the mail aliases which invoke RT"),
MIMEObj => $entity);
$RT::Logger->crit(loc("[_1] type unknown for [_2]", $Action, $MessageId);
}
}
# }}}
$RT::Handle->Disconnect();