summaryrefslogtreecommitdiff
path: root/rt/bin
diff options
context:
space:
mode:
Diffstat (limited to 'rt/bin')
-rw-r--r--rt/bin/initacls.Oracle26
-rwxr-xr-xrt/bin/initacls.Pg28
-rwxr-xr-xrt/bin/initacls.mysql20
-rwxr-xr-xrt/bin/mason_handler.fcgi255
-rwxr-xr-xrt/bin/mason_handler.scgi218
-rwxr-xr-xrt/bin/rt1391
-rwxr-xr-xrt/bin/rt-mailgate842
-rw-r--r--rt/bin/rtadmin1040
-rwxr-xr-xrt/bin/webmux.pl248
9 files changed, 706 insertions, 3362 deletions
diff --git a/rt/bin/initacls.Oracle b/rt/bin/initacls.Oracle
deleted file mode 100644
index 8d05f45e1..000000000
--- a/rt/bin/initacls.Oracle
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/sh
-
-DATABASEHOME=$1
-HOSTNAME=$2
-PORT=$3
-DATABASEADMIN=$4
-DBAPASSWD=$5
-DATABASENAME=$6
-DATABASEACLS=$7
-
-BINDIR=${DATABASEHOME}/bin
-
-echo "DBHOME = $DATABASEHOME"
-echo "HOSTNAME = $HOSTNAME"
-echo "PORT = $PORT"
-echo "DATABASEADMIN = $DATABASEADMIN"
-echo "DBAPASSWD = $DBAPASSWD"
-echo "DATABASENAME = $DATABASENAME"
-
-PATH=$PATH:$BINDIR
-export PATH
-
-echo "Please enter ${DATABASEADMIN}'s password for the SID ${DATABASENAME} to create an rt user";
-
-$BINDIR/sqlplus ${DATABASEADMIN}@${DATABASENAME} @$DATABASEACLS
-
diff --git a/rt/bin/initacls.Pg b/rt/bin/initacls.Pg
deleted file mode 100755
index 82e32de74..000000000
--- a/rt/bin/initacls.Pg
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/sh
-
-DATABASEHOME=$1
-HOSTNAME=$2
-PORT=$3
-DATABASEADMIN=$4
-DBAPASSWD=$5
-DATABASENAME=$6
-DATABASEACLS=$7
-
-BINDIR=${DATABASEHOME}/bin
-
-
-PATH=$PATH:$BINDIR
-export PATH
-
-echo "Enter the postgres administrator's database password to create a new user for rt"
-
-if [ "fnord$PORT" != "fnord" ]; then
- PORT="-p $PORT"
-fi;
-
-if [ "fnord$HOSTNAME" != "fnord" ]; then
- HOSTNAME="-h $HOSTNAME"
-fi;
-
-psql $HOSTNAME $PORT -d $DATABASENAME -f $DATABASEACLS -U $DATABASEADMIN
-
diff --git a/rt/bin/initacls.mysql b/rt/bin/initacls.mysql
deleted file mode 100755
index 17e63f837..000000000
--- a/rt/bin/initacls.mysql
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/sh
-
-DATABASEHOME=$1
-HOSTNAME=$2
-PORT=$3
-DATABASEADMIN=$4
-DBAPASSWD=$5
-DATABASENAME=$6
-DATABASEACLS=$7
-
-BINDIR=${DATABASEHOME}/bin
-
-PATH=$PATH:$BINDIR
-export PATH
-
-echo "Enter the mysql administrator's database password to create a new user for RT"
-$BINDIR/mysql --host=${HOSTNAME} --port=${PORT} --user=${DATABASEADMIN} -p${DBAPASSWD} mysql < $DATABASEACLS
-
-echo "Enter the mysql administrator's database password to nondestructively reload the database"
-$BINDIR/mysqladmin --host=${HOSTNAME} --port=${PORT} --user=${DATABASEADMIN} -p${DBAPASSWD} reload
diff --git a/rt/bin/mason_handler.fcgi b/rt/bin/mason_handler.fcgi
index e8a4e128f..431eccbd3 100755
--- a/rt/bin/mason_handler.fcgi
+++ b/rt/bin/mason_handler.fcgi
@@ -1,221 +1,54 @@
-#!!!PERL!!
-# $Header: /home/cvs/cvsroot/freeside/rt/bin/mason_handler.fcgi,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# RT is (c) 1996-2001 Jesse Vincent (jesse@fsck.com);
+#!/usr/bin/perl
+# BEGIN LICENSE BLOCK
+#
+# Copyright (c) 1996-2003 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
use strict;
-$ENV{'PATH'} = '/bin:/usr/bin'; # or whatever you need
-$ENV{'CDPATH'} = '' if defined $ENV{'CDPATH'};
-$ENV{'SHELL'} = '/bin/sh' if defined $ENV{'SHELL'};
-$ENV{'ENV'} = '' if defined $ENV{'ENV'};
-$ENV{'IFS'} = '' if defined $ENV{'IFS'};
+use File::Basename;
+require ('/opt/rt3/bin/webmux.pl');
+my $h = &RT::Interface::Web::NewCGIHandler();
-# We really don't want apache to try to eat all vm
-# see http://perl.apache.org/guide/control.html#Preventing_mod_perl_Processes_Fr
-
-
-package RT::Mason;
-#use CGI qw(-private_tempfiles); # pull in CGI with the private tempfiles
- #option predefined
-use HTML::Mason; # brings in subpackages: Parser, Interp, etc.
-
-use vars qw($VERSION %session $Nobody $SystemUser $cgi);
-
-# List of modules that you want to use from components (see Admin
-# manual for details)
-
-#Clean up our umask...so that the session files aren't world readable, writable or executable
-umask(0077);
-
-
-
-$VERSION="!!RT_VERSION!!";
-
-use lib "!!RT_LIB_PATH!!";
-use lib "!!RT_ETC_PATH!!";
-
-#This drags in RT's config.pm
-use config;
-use Carp;
-
-{
- package HTML::Mason::Commands;
- use vars qw(%session $ContentType);
-
- use RT;
- use RT::Ticket;
- use RT::Tickets;
- use RT::Transaction;
- use RT::Transactions;
- use RT::User;
- use RT::Users;
- use RT::CurrentUser;
- use RT::Template;
- use RT::Templates;
- use RT::Queue;
- use RT::Queues;
- use RT::ScripAction;
- use RT::ScripActions;
- use RT::ScripCondition;
- use RT::ScripConditions;
- use RT::Scrip;
- use RT::Scrips;
- use RT::Group;
- use RT::Groups;
- use RT::Keyword;
- use RT::Keywords;
- use RT::ObjectKeyword;
- use RT::ObjectKeywords;
- use RT::KeywordSelect;
- use RT::KeywordSelects;
- use RT::GroupMember;
- use RT::GroupMembers;
- use RT::Watcher;
- use RT::Watchers;
- use RT::Handle;
- use RT::Interface::Web;
- use MIME::Entity;
- use CGI::Cookie;
- use Date::Parse;
- use HTML::Entities;
- use Text::Wrapper;
-
- #TODO: make this use DBI
- use Apache::Session::File;
- use CGI::Fast;
-
- # set the page's content type.
- # In this case, just save it to a variable that we can pull later;
- sub SetContentType {
- $ContentType = shift;
- }
- sub CGIObject {
- return $RT::Mason::cgi;
- }
-}
-
-
-my ($output, $parser, $interp);
-if ($HTML::Mason::VERSION < 1.0902) {
- require HTML::Mason::ApacheHandler;
-
- $parser = &RT::Interface::Web::NewParser(allow_globals => [%session]);
-
- $interp = &RT::Interface::Web::NewInterp(parser=>$parser,
- allow_recursive_autohandlers => 1,
- out_method => \$output);
-}
-else {
- $interp = &RT::Interface::Web::NewInterp(
- allow_globals => [%session],
- default_escape_flags => 'h',
-
- out_method => \$output);
-}
-# Die if WebSessionDir doesn't exist or we can't write to it
-
-stat ($RT::MasonSessionDir);
-die "Can't read and write $RT::MasonSessionDir"
- unless (( -d _ ) and ( -r _ ) and ( -w _ ));
-
+# Enter CGI::Fast mode, which should also work as a vanilla CGI script.
+require CGI::Fast;
RT::Init();
# Response loop
-while ($RT::Mason::cgi = new CGI::Fast) {
-
- $HTML::Mason::Commands::ContentType = 'text/html';
-
- # This routine comes from ApacheHandler.pm:
- my (%args, $cookie);
- foreach my $key ( $cgi->param ) {
- foreach my $value ( $cgi->param($key) ) {
- if (exists($args{$key})) {
- if (ref($args{$key})) {
- $args{$key} = [@{$args{$key}}, $value];
- } else {
- $args{$key} = [$args{$key}, $value];
- }
- } else {
- $args{$key} = $value;
- }
-
- }
-
- }
-
-
- my $comp = $ENV{'PATH_INFO'};
-
- if ($comp =~ /^(.*)$/) { # untaint the path info. apache should
- # never hand us a bogus path.
- # We should be more careful here.
- $comp = $1;
- }
-
- if ($comp =~ /\/$/) {
- $comp .= "index.html";
- }
-
- #This is all largely cut and pasted from mason's session_handler.pl
-
- # {{{ Cookies
- my %cookies = fetch CGI::Cookie();
-
- eval {
- my $session_id = undef;
-
- #Get the session id and untaint it
- if ($cookies{'AF_SID'} && $cookies{'AF_SID'}->value() =~ /^(.*)$/) {
- $session_id = $1;
- }
-
- tie %HTML::Mason::Commands::session, 'Apache::Session::File',
- $session_id,
- { Directory => $RT::MasonSessionDir,
- LockDirectory => $RT::MasonSessionDir,
- } ;
- };
-
- if ( $@ ) {
- # If the session is invalid, create a new session.
- if ( $@ =~ m#^Object does not exist in the data store# ) {
- tie %HTML::Mason::Commands::session, 'Apache::Session::File', undef,
- { Directory => $RT::MasonSessionDir,
- LockDirectory => $RT::MasonSessionDir,
- };
- undef $cookies{'AF_SID'};
- }
- else {
- die "$@ \nProbably means that RT Couldn't write to session directory '$RT::MasonSessionDir'. Check that this directory's permissions are correct.";
- }
+while ( my $cgi = CGI::Fast->new ) {
+ # the whole point of fastcgi requires the env to get reset here..
+ # So we must squash it again
+ $ENV{'PATH'} = '/bin:/usr/bin';
+ $ENV{'CDPATH'} = '' if defined $ENV{'CDPATH'};
+ $ENV{'SHELL'} = '/bin/sh' if defined $ENV{'SHELL'};
+ $ENV{'ENV'} = '' if defined $ENV{'ENV'};
+ $ENV{'IFS'} = '' if defined $ENV{'IFS'};
+
+ unless ($h->interp->comp_exists($cgi->path_info)) {
+ $cgi->path_info($cgi->path_info . "/index.html");
}
-
- if ( !$cookies{'AF_SID'} ) {
- $cookie = new CGI::Cookie
- (-name=>'AF_SID',
- -value=>$HTML::Mason::Commands::session{_session_id},
- -path => '/',);
-
- } else {
- $cookie = undef;
- }
-
- # }}}
-
- $output = '';
- eval {
- my $status = $interp->exec($comp, %args);
- };
-
- if ($@) {
- $output = "<PRE>$@</PRE>";
- }
-
- print "Content-Type: $HTML::Mason::Commands::ContentType\r\n";
- print "Set-Cookie: $cookie\r\n" if ($cookie);
- print "\r\n";
- print $output;
- untie %HTML::Mason::Commands::session;
-
+ $h->handle_cgi_object($cgi);
+ # _should_ always be tied
}
+
+1;
diff --git a/rt/bin/mason_handler.scgi b/rt/bin/mason_handler.scgi
index b9846c898..8e1135c2f 100755
--- a/rt/bin/mason_handler.scgi
+++ b/rt/bin/mason_handler.scgi
@@ -1,193 +1,41 @@
-#!!!PERL!! -w
-
-#!/usr/bin/speedy -- -t600 -M8
-# $Header: /home/cvs/cvsroot/freeside/rt/bin/mason_handler.scgi,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# RT is (c) 1996-2001 Jesse Vincent (jesse@fsck.com);
-#
-# Contains code derived from mason.cgi
-# mason.cgi is Copyright December 2000 Joshua Kronengold (mneme@io.com,
-# mneme@cyberspace.org). All Rights Reserved.
+#!/usr/local/bin/speedy
+# BEGIN LICENSE BLOCK
+#
+# Copyright (c) 1996-2003 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
use strict;
-# {{{ Clean out the environment a little bit
-$ENV{'PATH'} = '/bin:/usr/bin'; # or whatever you need
-$ENV{'CDPATH'} = '' if defined $ENV{'CDPATH'};
-$ENV{'SHELL'} = '/bin/sh' if defined $ENV{'SHELL'};
-$ENV{'ENV'} = '' if defined $ENV{'ENV'};
-$ENV{'IFS'} = '' if defined $ENV{'IFS'};
-# }}}
-
-package RT::Mason;
-use HTML::Mason; # brings in subpackages: Parser, Interp, etc.
-use vars qw($VERSION %session $Nobody $SystemUser);
-
-# List of modules that you want to use from components (see Admin
-# manual for details)
-
-$VERSION="!!RT_VERSION!!";
-
-use lib "!!RT_LIB_PATH!!";
-use lib "!!RT_ETC_PATH!!";
-
-
-#This drags in RT's config.pm
-use config;
-use Carp;
-
-use HTML::Mason::FakeApache;
-use CGI;
-
-# {{{ Set up CGI environment and grab CGI params:
+require ('/opt/rt3/bin/webmux.pl');
-my $r=new HTML::Mason::FakeApache;
+my $h = &RT::Interface::Web::NewCGIHandler();
-$|=1; # set output to non-buffered.
+require CGI;
-my %cgi;
-CGI::ReadParse(\%cgi); # %cgi is now a tied hash containing our params.
+RT::Init();
-my $q=$cgi{CGI}; # $q now contains the object tied to %cgi.
-# }}}
-
-# {{{ require what we need
-{
- package HTML::Mason::Commands;
-
- use vars qw(%session);
-
- use RT::Ticket;
- use RT::Tickets;
- use RT::Transaction;
- use RT::Transactions;
- use RT::User;
- use RT::Users;
- use RT::CurrentUser;
- use RT::Template;
- use RT::Templates;
- use RT::Queue;
- use RT::Queues;
- use RT::ScripAction;
- use RT::ScripActions;
- use RT::ScripCondition;
- use RT::ScripConditions;
- use RT::Scrip;
- use RT::Scrips;
- use RT::Group;
- use RT::Groups;
- use RT::Keyword;
- use RT::Keywords;
- use RT::ObjectKeyword;
- use RT::ObjectKeywords;
- use RT::KeywordSelect;
- use RT::KeywordSelects;
- use RT::GroupMember;
- use RT::GroupMembers;
- use RT::Watcher;
- use RT::Watchers;
- use RT::Handle;
- use RT::Interface::Web;
- use MIME::Entity;
- use CGI::Cookie;
- use Date::Parse;
- use HTML::Entities;
-
-
- use Apache::Session::File;
-
-
+my $cgi = CGI->new;
+unless ($h->interp->comp_exists($cgi->path_info)) {
+ $cgi->path_info($cgi->path_info . "/index.html");
}
-# }}}
-
-# {{{ RT Database setup
- $RT::Handle = new RT::Handle;
-
- $RT::Handle->Connect;
-
- use RT::CurrentUser;
-
- #RT's system user is a genuine database user. its id lives here
- $RT::SystemUser = new RT::CurrentUser();
- $RT::SystemUser->LoadByName('RT_System');
-
- #RT's "nobody user" is a genuine database user. its ID lives here.
- $RT::Nobody = new RT::CurrentUser();
- $RT::Nobody->LoadByName('Nobody');
-
-
-# }}}
-
-
-
-
-# {{{ Deal with cookies
-
-my %cookies = fetch CGI::Cookie();
-eval {
- tie %HTML::Mason::Commands::session, 'Apache::Session::File',
- ( $cookies{'AF_SID'} ? $cookies{'AF_SID'}->value() : undef );
-};
-
-if ( $@ ) {
- # If the session is invalid, create a new session.
- if ( $@ =~ m#^Object does not exist in the data store# ) {
- tie %HTML::Mason::Commands::session, 'Apache::Session::File', undef;
- undef $cookies{'AF_SID'};
- }
-}
-
-if ( !$cookies{'AF_SID'} ) {
- my $cookie = new CGI::Cookie(
- -name=>'AF_SID',
- -value=>$HTML::Mason::Commands::session{_session_id},
- -path => '/');
- print 'Set-Cookie: '. $cookie."\r\n";
-}
-
-# }}}
-
-my $path=$ENV{PATH_INFO} || "/"; $path=~s/\'/\\\'/g;
-
-my $type=`/usr/bin/file '$RT::MasonComponentRoot/$path'`;
-
-# {{{ if it's a text file, handle it with mason.
-if($type=~/text|directory/) {
- my ($out, %mason_params);
- my $parser = RT::Interface::Web::NewParser(allow_globals=>[qw($r)]);
- $mason_params{parser}=$parser;
- $r->content_type('text/html');
- # (get cookies line) ...
- $r->access_hash('headers_in','Cookie',$ENV{HTTP_COOKIE});
- $r->{'args@'}=[];
- $mason_params{out_method}=\$out;
-
- my $interp = RT::Interface::Web::NewInterp(%mason_params);
-
- $interp->set_global(r=>$r);
- $interp->exec($path,%cgi);
- $r->send_http_header();
- print $out;
-}
-# }}}
-
-# {{{ if it's not a text file, just stream it out.
-
-else { # file is binary, damn it
- my $mime_type;
- if ( $mime_type=
- eval{ use MIME::Types;
- my($type,$encoding)=MIME::Types::by_suffix($path);
- $type; }) {
- print $q->header($mime_type);
- $path=~s/[\|\>\<\&]//g;
- open F,"$RT::MasonComponentRoot/$path" or
- die "couldn't open $path -- $!";
- print while <F>;
- close F;
- } else {
- die "couldn't resolve type of non-text file (!@; $type) -- install Mime::Types\n";
- }
- }
-
-# }}}
+$h->handle_cgi_object($cgi);
-untie %HTML::Mason::Commands::session;
+1;
diff --git a/rt/bin/rt b/rt/bin/rt
deleted file mode 100755
index 41220bb56..000000000
--- a/rt/bin/rt
+++ /dev/null
@@ -1,1391 +0,0 @@
-#!!!PERL!! -w
-#
-# $Header: /home/cvs/cvsroot/freeside/rt/bin/Attic/rt,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# RT is (c) 1996-2001 Jesse Vincent <jesse@bestpractical.com>
-
-use strict;
-use Carp;
-use Getopt::Long;
-
-use lib "!!RT_LIB_PATH!!";
-use lib "!!RT_ETC_PATH!!";
-
-use RT::Interface::CLI qw(CleanEnv LoadConfig DBConnect
- GetCurrentUser GetMessageContent);
-
-#Clean out all the nasties from the environment
-CleanEnv();
-
-#Load etc/config.pm and drop privs
-LoadConfig();
-
-#Connect to the database and get RT::SystemUser and RT::Nobody loaded
-DBConnect();
-
-#Drop setgid permissions
-RT::DropSetGIDPermissions();
-
-#Get the current user all loaded
-my $CurrentUser = GetCurrentUser();
-
-unless ($CurrentUser->Id) {
- print "No RT user found. Please consult your RT administrator.\n";
- exit(1);
-}
-
-
-# {{{ commandline flags
-
-my ( @id,
- @limit_queue,
- @limit_status,
- @limit_owner,
- @limit_priority,
- @limit_final_priority,
- @limit_requestor,
- @limit_subject,
- @limit_body,
- @limit_created,
- @limit_resolved,
- @limit_lastupdated,
- @limit_dependson,
- @limit_dependedonby,
- @limit_memberof,
- @limit_hasmember,
- @limit_refersto,
- @limit_referredtoby,
- @limit_keyword,
-
- @limit_due,
- @limit_starts,
- @limit_started,
- $limit_first,
- $limit_rows,
- $history,
- $summary,
- $create,
- @requestors,
- @cc,
- @admincc,
- $status,
- $subject,
- $owner,
- $steal,
- $queue,
- $time_left,
- $priority,
- $final_priority,
- $due,
- $starts,
- $started,
- $contacted,
- $comment,
- $reply,
- $source,
- $edit,
- @dependson,
- @memberof,
- @refersto,
- $mergeinto,
- @keywords,
- $time_taken,
- $verbose,
- $debug,
- $help,
- $version);
-
-# }}}
-
-# Set defaults for cli args
-
-$edit = 1; # Assume the user wants to edit replies and comments
- # unless they specify --noedit
-
-# {{{ args
-
-my @args =("id=s" => \@id,
- "limit-queue=s" => \@limit_queue,
- "limit-status=s" => \@limit_status,
- "limit-owner=s" => \@limit_owner,
- "limit-priority=s" => \@limit_priority,
- "limit-final-priority=s" => \@limit_final_priority,
- "limit-requestor=s" => \@limit_requestor,
- "limit-subject=s" => \@limit_subject,
- "limit-body=s", \@limit_body,
- "limit-created=s" => \@limit_created,
- "limit-due=s" => \@limit_due,
- "limit-last-updated=s" => \@limit_lastupdated,
- "limit-keyword=s" => \@limit_keyword,
-
- "limit-member-of=s" => \@limit_memberof,
- "limit-has-member=s" => \@limit_hasmember,
- "limit-depended-on-by=s" => \@limit_dependedonby,
- "limit-depends-on=s" => \@limit_dependson,
- "limit-referred-to-by=s" => \@limit_referredtoby,
- "limit-refers-to=s" => \@limit_refersto,
-
- "limit-starts=s" => \@limit_starts,
- "limit-started=s" => \@limit_started,
- "limit-first=i" => \$limit_first,
- "limit-rows=i" => \$limit_rows,
- "history|show" => \$history,
- "summary:s" => \$summary,
- "create" => \$create,
- "keywords=s" => \@keywords,
- "requestor|requestors=s" => \@requestors,
- "cc=s" => \@cc,
- "admincc=s" => \@admincc,
- "status=s" => \$status,
- "subject=s" => \$subject,
- "owner=s" => \$owner,
- "steal" => \$steal,
- "queue=s" => \$queue,
-
-
- "priority=i" => \$priority,
- "final-priority=i" => \$final_priority,
- "due=s" => \$due,
- "starts=s" => \$starts,
- "started=s" => \$started,
- "contacted=s" => \$contacted,
- "comment", \$comment,
- "reply|respond", \$reply,
- "source=s" => \$source,
- "edit!" => \$edit,
- "depends-on=s" => \@dependson,
- "member-of=s" => \@memberof,
- "merge-into=s" => \$mergeinto,
- "refers-to=s" => \@refersto,
- "time-left=i" => \$time_left,
- "time-taken=i" => \$time_taken,
- "verbose+" => \$verbose,
- "debug" => \$debug,
- "version" => \$version,
- "help|h|usage" => \$help
- );
-
-# }}}
-
-
-
-GetOptions(@args);
-
-print join(':',@keywords);
-# {{{ If they want it, print a usage message and get out
-
-if ($help) {
-
-
-print <<EOUSAGE;
-
-Limit the set of records returned:
-
---id=[first][-][last]
- Specify a single ticket, a range, or to start with (n-) or end with (-n)
-a specific ticket.
-
- --limit-queue=<queue>
- --limit-status=[!](new|open|stalled|resolved)
-
- --limit-owner=[!]<userid>
- --limit-priority=[starts][-][ends]
- --limit-final-priority=[starts][-][ends]
- starts is less than ends
- --limit-requestor=[!]<userid>|<email>
- --limit-subject=[!]<text>
- --limit-body=[!]<text>
- --limit-keyword=[!]<select>/<keyword>
-
- Links
- --limit-member-of=<ticketid>
- --limit-has-member=<ticketid>
- --limit-refers-to=<ticketid>
- --limit-referred-to-by=<ticketid>
- --limit-depends-on=<ticketid>
- --limit-depended-on-by=<ticketid>
-
-
- Dates
- --limit-created=[starts][-][ends]
- --limit-due=[starts][-][ends]
- --limit-starts=[starts][-][ends]
- --limit-started=[starts][-][ends]
- --limit-resolved=[starts][-][ends]
- --limit-last-updated=[starts][-][ends]
- starts and ends are dates. starts can not be less than ends
-
- --limit-first=<first row returned>
- --limit-rows=<row count>
-
- --history | --show
- show a history of the tickets found
-
-
- --summary [format-string]
- show a listing-style summary of the tickets found. If format string
- is ommitted, uses \$RT_SUMMARY_FORMAT or an internal default
-
-
- #TODO: doc summary
- format: <atom>%<format>
- atom: <name><size>
- size: <integer>
- name: (grep for # {{{ attribs for the array of ok values)
-
-
- --create
- create a new ticket. Any attributes that you can modify on an existing ticket
- can also be used for ticket creation.
-
-
-
-Attributes
- Basics
- --status=<new|open|stalled|resolved|dead>
- sets status
- --subject=<subject>
- sets subject
- --owner=<userid>
- set owner to
- --steal
- Become the owner, even if someone else owns the ticket
- --queue=<queueid>
- set queue to
-
- --priority=<int>
-
- --final-priority=<int>
-
- Watchers
- --requestors=[+|-]<userid|email address>
- add or remove this user as a ticket requestor
- --cc=[+|-]<userid|email address>
- add or remove this user as a ticket cc
- --admincc=[+|-]<userid|email address>
- add or remove this user as a ticket admincc
-
- (When creating tickets, just leave off the + or - )
-
- Keywords
- --keywords[+|-]<keyword_select>/<keyword>
- Add or remove a keyword.
-
-
-
- Dates
- --due=<date>
- --starts=<date>
- --started=<date>
- --contacted=<date>
-
- --time-left=<int>
-
- --time-taken=<int>
-
-
- Link related manipulation:
-
- --depends-on=[+|-]<ticketid>
- --member-of=[+|-]<ticketid>
- --refers-to=[+|-]<ticketid>
- --merge-into=<ticketid>
-
-Comments and replies
-
- --comment
- --reply|respond
- --source <path>
- Specify the path to the source file for this ticket update
-
- --noedit
- Don't invoke \$EDITOR to edit the content of this update
-
-
-
-
- Condiments
-
- --verbose
- --debug
- --version
- --help|h|usage
- You're reading it.
-
-EOUSAGE
-
- exit(0);
-}
-
-# Print version, and leave
-if ($version) {
- print "RT $RT::VERSION for $RT::rtname. Copyright 1996-2001 Jesse Vincent <jesse\@fsck.com>\n";
- exit(0);
-}
-
-# }}}
-
-# {{{ Validate any options that were passed in. normalize them.
-
-#if a queue was specified
-if ($queue) {
- # make sure that $queue is a valid queue and load it into $queue_obj
-}
-
-#For each date in: $due, $starts, $started
-
-# load up an RT::Date object and parse it into a normalized form
-# if it can't parse it, log an error and null out the variable
-
-# }}}
-
-# {{{ Check if we're creating, if so, create the ticket and be done
-
-if ($create) {
- $RT::Logger->debug("Creating a new ticket");
-
- #Make sure the current user can create tickets in this queue
-
- #Make sure that the owner specified can own tickets in this queue
-
-
-
- my $linesref = GetMessageContent( Edit => $edit, Source => $source,
- CurrentUser => $CurrentUser
- );
-
- require MIME::Entity;
- my $MIMEObj;
-
- if ($linesref) {
- $MIMEObj = MIME::Entity->build(Data => $linesref);
- }
-
- use RT::Ticket;
- my $Ticket=new RT::Ticket($CurrentUser);
- my ($ticket, $trans, $msg) =
- $Ticket->Create(Queue => $queue,
- Owner => $owner,
- Status => $status || 'new' ,
- Subject => $subject,
- Requestor => \@requestors,
- Cc => \@cc,
- AdminCc => \@admincc,
- Due => $due,
- Starts => $starts,
- Started => $started,
- TimeLeft => $time_left,
- InitialPriority => $priority,
- FinalPriority => $final_priority,
- MIMEObj => $MIMEObj
- );
- print $msg . "\n";
-}
-
-# }}}
-
-else {
- #Apply restrictions
- use RT::Tickets;
- my $Tickets = new RT::Tickets($CurrentUser);
-
- # {{{ Limit our search
- my $value; #to use when iterating through restrictions
- my $queue_id; #to use when limiting by keyword
-
- # {{{ limit on id
-
- foreach $value (@id) {
- if ($value =~ /^(\d+)$/) {
- $Tickets->LimitId ( VALUE => $1,
- OPERATOR => '=');
- }
- elsif ($value =~ /^(\d*)\D?(\d*)$/) {
- my $start = $1;
- my $end = $2;
- $Tickets->LimitId(
- VALUE => "$start",
- OPERATOR => '>=') if ($start);
- $Tickets->LimitId(
- VALUE => "$end",
- OPERATOR => '<=') if ($end);
- }
- }
-
-
- # }}}
-
- # {{{ limit on status
-
- foreach $value (@limit_status) {
- if ($value =~ /^(=|!=|!|)(.*)$/) {
- my $op = $1;
- my $val = $2;
-
-
- $op = ParseBooleanOp($op);
- $Tickets->LimitStatus(VALUE => "$val",
- OPERATOR => "$op");
- }
- }
-
- # }}}
-
-
-
- # {{{ limit on queue
- foreach $value (@limit_queue) {
- if ($value =~ /^(\W?)(.*?)$/i) {
- my $op = $1;
- my $val = $2;
-
- $op = ParseBooleanOp($op);
-
- my $queue_obj = new RT::Queue($RT::SystemUser);
-
- unless ($queue_obj->Load($val)) {
- $RT::Logger->debug("Queue '$val' not found");
- print STDERR "Queue '$val' not found\n";
- exit(-1);
- }
- $RT::Logger->debug ("Limiting queue to $op ".$queue_obj->Name);
- $Tickets->LimitQueue(VALUE => $queue_obj->Name,
- OPERATOR => $op);
- $queue_id=$queue_obj->id;
- }
- }
-
- # {{{ limit on keyword
- foreach $value (@limit_keyword) {
- if ($value =~ /^(\W?)(.*?)\/(.*)$/i) {
- my $op = $1;
- my $select = $2;
- my $keyword = $3;
-
- $op = ParseBooleanOp($op);
-
- # load the keyword select
- my $keyselect = RT::KeywordSelect->new($RT::SystemUser);
- unless ($keyselect->LoadByName(Name=>$select, Queue=>$queue_id)) {
- $RT::Logger->debug("KeywordSelect '$select' not found");
- print STDERR "KeywordSelect '$select' not fount\n";
- exit(-1);
- }
-
- # load the keyword
- my $k = RT::Keyword->new($RT::SystemUser);
- unless ($k->LoadByNameAndParentId($keyword, $keyselect->Keyword)) {
- $RT::Logger->debug("Keyword '$keyword' not found");
- print STDERR "Keyword '$keyword' not found\n";
- exit(-1);
- }
- $Tickets->LimitKeyword(OPERATOR => $op,
- KEYWORDSELECT => $keyselect->id,
- KEYWORD => $k->id);
- $RT::Logger->debug ("Limiting keyword to $op ".$k->Path);
- }
- }
- # }}}
- # {{{ limit on owner
- foreach $value (@limit_owner) {
- if ($value =~ /^(\W?)(.*?)$/i) {
- my $op = $1;
- my $val = $2;
-
- $op = ParseBooleanOp($op);
-
- my $user_obj = new RT::User($RT::SystemUser);
-
- unless ($user_obj->Load($val)) {
- $RT::Logger->debug("User '$val' not found");
- print STDERR "User '$val' not found\n";
- exit(-1);
- }
- $val = $user_obj->id();
-
- $RT::Logger->debug ("Limiting owner to $op $val");
- $Tickets->LimitOwner(VALUE => "$val",
- OPERATOR => "$op");
- }
- }
- # }}}
- # {{{ limt on priority
-
- foreach $value (@limit_priority) {
- my ($start, $end) = ParseRange($value);
- if ($start == $end) {
- $Tickets->LimitPriority( VALUE => $start,
- OPERATOR => '=');
- } elsif ($start) {
- $Tickets->LimitPriority( VALUE => $start,
- OPERATOR => '>=');
- } elsif ($end) {
- $Tickets->LimitPriority( VALUE => $end,
- OPERATOR => '<=');
- }
-
- }
- foreach $value (@limit_final_priority) {
- my ($start, $end) = ParseRange($value);
- if ($start == $end) {
- $Tickets->LimitFinalPriority( VALUE => $start,
- OPERATOR => '=');
- } elsif ($start) {
- $Tickets->LimitFinalPriority( VALUE => $start,
- OPERATOR => '>=');
- } elsif ($end) {
- $Tickets->LimitFinalPriority( VALUE => $end,
- OPERATOR => '<=');
- }
- }
- # }}}
-
- foreach $value (@limit_requestor) {
- if ($value =~ /^(\W?)(.*?)$/i) {
- my $op = $1;
- my $val = $2;
-
- $op = ParseBooleanOp($op);
- $Tickets->LimitRequestor(VALUE => $val,
- OPERATOR => $op );
- }
-
- }
- foreach $value (@limit_subject) {
-
- if ($value =~ /^(\W?)(.*?)$/i) {
- my $op = $1;
- my $val = $2;
-
- $op = ParseLikeOp($op);
-
- $Tickets->LimitSubject(VALUE => $val,
- OPERATOR => $op );
- }
- }
-
- foreach $value (@limit_body) {
- if ($value =~ /^(\W?)(.*?)$/i) {
- my $op = $1;
- my $val = $2;
-
- $op = ParseLikeOp($op);
-
- $Tickets->LimitBody(VALUE => $val,
- OPERATOR => $op );
- }
-
- }
-
-
-
- # Dates
- foreach my $date (@limit_created) {
- my ($start, $end) = ParseDateRange($date);
- $Tickets->LimitCreated ( VALUE => $start,
- OPERATOR => '>=' ) if ($start);
- $Tickets->LimitCreated ( VALUE => $end,
- OPERATOR => '<=' ) if ($end);
- }
-
- foreach my $date (@limit_due) {
- my ($start, $end) = ParseDateRange($date);
- $Tickets->LimitDue ( VALUE => $start,
- OPERATOR => '>=' ) if ($start);
- $Tickets->LimitDue ( VALUE => $end,
- OPERATOR => '<=' ) if ($end);
- }
-
- foreach my $date (@limit_starts) {
- my ($start, $end) = ParseDateRange($date);
- $Tickets->LimitStarts ( VALUE => $start,
- OPERATOR => '>=' ) if ($start);
- $Tickets->LimitStarts ( VALUE => $end,
- OPERATOR => '<=' ) if ($end);
- }
-
- foreach my $date (@limit_started) {
- my ($start, $end) = ParseDateRange($date);
- $Tickets->LimitStarted ( VALUE => $start,
- OPERATOR => '>=' ) if ($start);
- $Tickets->LimitStarted ( VALUE => $end,
- OPERATOR => '<=' ) if ($end);
- }
-
- foreach my $date (@limit_resolved) {
- my ($start, $end) = ParseDateRange($date);
- $Tickets->LimitResolved ( VALUE => $start,
- OPERATOR => '>=' ) if ($start);
- $Tickets->LimitResolved ( VALUE => $end,
- OPERATOR => '<=' ) if ($end);
- }
-
- foreach my $date (@limit_lastupdated) {
- my ($start, $end) = ParseDateRange($date);
- $Tickets->LimitLastUpdated( VALUE => $start,
- OPERATOR => '>=' ) if ($start);
- $Tickets->LimitLastUpdated ( VALUE => $end,
- OPERATOR => '<=' ) if ($end);
- }
-
- foreach my $link (@limit_memberof) {
- $Tickets->LimitMemberOf($link);
- }
-
- foreach my $link (@limit_hasmember) {
- $Tickets->LimitHasMember($link);
- }
-
- foreach my $link (@limit_dependson) {
- $Tickets->LimitDependsOn($link);
- }
-
- foreach my $link (@limit_dependedonby) {
- $Tickets->LimitDependedOnBy($link);
- }
- foreach my $link (@limit_refersto) {
- $Tickets->LimitRefersTo($link);
- }
-
- foreach my $link (@limit_referredtoby) {
- $Tickets->LimitReferredToBy($link);
- }
-
-
- if ($limit_first){
- }
- if ($limit_rows){
- }
-
-# }}}
-
- # {{{ Iterate through all tickets we found
-
-
- my ($format, $titles, $code);
-
- #Set up the summary format if we need to
- if (defined $summary) {
- my $format_string = $summary || $ENV{'RT_SUMMARY_FORMAT'} || "%id4%status4%queue7%subject40%requestor16";
-
- ($format, $titles, $code) = BuildListingFormat($format_string);
- printf "$format\n", eval "$titles";
- }
-
-
-
- while (my $Ticket = $Tickets->Next()) {
- $RT::Logger->debug ("Now working on ticket ". $Ticket->id);
-
- #Run through all the ticket modifications we might want to do
- #TODO: these are all insufficiently lazy and should be replaced with some
- # nice foreaches.
-
-
- # {{{ deal with watchers
-
- # add / delete requestors
- foreach $value (@requestors) {
- if ($value =~ /^(\W?)(.*)$/) {
- my $op = $1;
- my $addr = $2;
-
- $Ticket->AddRequestor(Email => $addr) if ($op eq '+');
- $Ticket->DeleteRequestor( $addr) if ($op eq '-');
- }
- }
-
- # add / delete ccs
- foreach $value (@cc) {
- if ($value =~ /^(\W?)(.*)$/) {
- my $op = $1;
- my $addr = $2;
- $Ticket->AddCc(Email => $addr) if ($op eq '+');
- $Ticket->DeleteCc($addr) if ($op eq '-');
- }
- }
-
- # add / delete adminccs
- $RT::Logger->debug("Looking at admin ccs");
- foreach $value (@admincc) {
- if ($value =~ /^(\W?)(.*)$/) {
- my $op = $1;
- my $addr = $2;
- $Ticket->AddAdminCc(Email => $addr) if ($op eq '+');
- $Ticket->DeleteAdminCc($addr) if ($op eq '-');
- }
- }
-
- # }}}
-
- # {{{ Deal with ticket keywords
-
- my $KeywordSelects = $Ticket->QueueObj->KeywordSelects();
- $RT::Logger->debug ("Looking at keywords");
- foreach $value (@keywords) {
- $RT::Logger->debug("Looking at --keyword=$value");
- if ($value =~ /^(\W?)(.*?)\/(.*)$/) {
- my $op = $1;
- my $select = $2;
- my $keyword = $3;
-
- $RT::Logger->debug("Going to $op Keyword $select / $keyword");
- while (my $ks = $KeywordSelects->Next) {
- $RT::Logger->debug("$select is select ".$ks->Name." is found");
- next unless ($ks->Name =~ /$select/i);
- $RT::Logger->debug ("Found a match for $select\n");
- my $kids = $ks->KeywordObj->Descendents;
-
- my ($kid);
- foreach $kid (keys %{$kids}) {
- $RT::Logger->debug("Now comparing $keyword with ".$kids->{$kid}. "\n");
- next unless ($kids->{$kid} =~ /^$keyword$/i);
- $RT::Logger->debug("Going to $op $select / $keyword (".$kids->{$kid} .")");
- $Ticket->DeleteKeyword(KeywordSelect => $ks->id,
- Keyword => $kid) if ($op eq '-');
-
- $Ticket->AddKeyword(KeywordSelect => $ks->id,
- Keyword => $kid) if ($op eq '+');
- }
-
- }
- }
- }
- # }}}
-
- # {{{ deal with links
-
- # Deal with merging {
- if ($mergeinto) {
- my ($trans, $msg) =$Ticket->MergeInto($mergeinto);
- print $msg."\n";
- }
- # add /delete depends-ons
-
- foreach my $value (@dependson) {
- if ($value =~ /^(\W?)(.*)$/) {
- my $op = $1;
- my $ticket = $2;
- if (!$op or ($op eq '+')) {
- my ($trans, $msg) =
- $Ticket->AddLink(Type => 'DependsOn', Target => $ticket);
- print $msg."\n";
- }
- elsif ($op eq '-') {
- my ($trans, $msg) =
- $Ticket->DeleteLink(Type => 'DependsOn', Target => $ticket);
- print $msg."\n";
- }
-
- }
- }
- # add /delete member-of
- foreach my $value (@memberof) {
- if ($value =~ /^(\W?)(.*)$/) {
- my $op = $1;
- my $ticket = $2;
- if ($op eq '+') {
- my ($trans, $msg) =
- $Ticket->AddLink(Type => 'MemberOf', Target => $ticket);
- print $msg;
- }
- elsif ($op eq '-') {
- my ($trans, $msg) =
- $Ticket->DeleteLink(Type => 'MemberOf', Target => $ticket);
- print $msg;
- }
-
- }
- }
- # add / delete refers-to
- foreach my $value (@refersto) {
- if ($value =~ /^(\W?)(.*)$/) {
- my $op = $1;
- my $ticket = $2;
- if ($op eq '+') {
- my ($trans, $msg) =
- $Ticket->AddLink(Type => 'RefersTo', Target => $ticket);
- print $msg;
- }
- elsif ($op eq '-') {
- my ($trans, $msg) =
- $Ticket->DeleteLink(Type => 'RefersTo', Target => $ticket);
- print $msg;
- }
-
- }
- }
-
- # }}}
-
- # {{{ deal with dates
-
- #set due
- if ($due) {
- my $iso = ParseDateToISO($due);
- if ($iso) {
- $RT::Logger->debug("Setting due date to $iso ($due)");
- my ($trans, $msg) =
- $Ticket->SetDue($iso);
- print $msg;
- }
- else {
- print "Due date '$due' could not be parsed";
- }
- }
-
- #set starts
- if ($starts) {
- my $iso = ParseDateToISO($due);
- if ($iso) {
- my ($trans, $msg) =
- $Ticket->SetStarts($iso);
- print $msg."\n";
- }
- else {
- print "Starts date '$starts' could not be parsed";
- }
- }
- #set started
- if ($started) {
- my $iso = ParseDateToISO($started);
- if ($iso) {
- my ($trans, $msg) =
- $Ticket->SetStarted($iso);
- print $msg."\n";
- }
- else {
- print "Started date '$started' could not be parsed";
- }
- }
- #set contacted
- if ($contacted) {
- my $iso = ParseDateToISO($contacted);
- if ($iso) {
- my ($trans, $msg) =
- $Ticket->SetContacted($iso);
- print $msg."\n";
- }
- else {
- print "Contacted date '$contacted' could not be parsed";
- }
- }
-
- # }}}
-
- # {{{ set other attributes
-
- #Set subject
- if ($subject) {
- my ($trans, $msg) = $Ticket->SetSubject($subject);
- print $msg."\n";
- }
-
- #Set priority
- if ($priority) {
- my ($trans, $msg) =
- $Ticket->SetPriority($priority);
- print $msg."\n";
- }
-
- #Set final priority
- if ($final_priority) {
- my ($trans, $msg) =
- $Ticket->SetFinalPriority($final_priority);
- print $msg."\n";
- }
-
- #Set status
- if ($status) {
- my ($trans, $msg) =
- $Ticket->SetStatus($status);
- print $msg."\n";
- }
-
- #Set time left
- if ($time_left) {
- my ($trans, $msg) =
- $Ticket->SetTimeLeft($time_left);
- print $msg."\n";
- }
-
- #Set time_taken
- if ($time_taken) {
- my ($trans, $msg) =
- $Ticket->SetTimeTaken($time_taken);
- print $msg."\n";
- }
-
- #Set owner
- if ($owner) {
- my ($trans, $msg) =
- $Ticket->SetOwner($owner);
- print $msg."\n";
- }
-
- # Steal
- if ($steal) {
- my ($trans, $msg) =
- $Ticket->Steal();
- print $msg . "\n";
- }
- #Set queue
- if ($queue) {
- my ($trans, $msg) =
- $Ticket->SetQueue($queue);
- print $msg."\n";
- }
-
- # }}}
-
-
-
- # {{{ Perform ticket comments/replies
- if ($reply) {
- $RT::Logger->debug("Replying to ticket ".$Ticket->Id);
-
- my $linesref = GetMessageContent( Edit => $edit, Source => $source,
- CurrentUser => $CurrentUser
- );
-
- #TODO build this entity
- require MIME::Entity;
- my $MIMEObj = MIME::Entity->build(Data => $linesref);
-
- $Ticket->Correspond( MIMEObj => $MIMEObj ,
- TimeTaken => $time_taken);
- }
-
- elsif ($comment) {
- $RT::Logger->debug("Commenting on ticket ".$Ticket->Id);
-
- my $linesref =GetMessageContent(Edit => $edit, Source => $source,
- CurrentUser => $CurrentUser);
- #TODO build this entity
- require MIME::Entity;
- my $MIMEObj = MIME::Entity->build(Data => $linesref);
-
- $Ticket->Comment( MIMEObj => $MIMEObj,
- TimeTaken => $time_taken);
- }
-
- # }}}
-
- # {{{ Display whatever we need to display
-
- # {{{ Display a full ticket listing and history
- if ($history) {
- #Display the history
- $RT::Logger->debug("Show history for ".$Ticket->id);
-
- if ($Ticket->CurrentUserHasRight("ShowTicket")) {
- &ShowSummary($Ticket);
- print "\n";
- &ShowHistory($Ticket);
- }
- else {
- print "You don't have permission to view that ticket.\n";
- }
- }
-
- # }}}
-
- # {{{ Display a summary if we need to
- if (defined $summary) {
- $RT::Logger->debug ("Show ticket summary with format $format");
-
- printf $format."\n", eval $code;
-
- }
- # }}}
-
- # }}}
-
- }
-
- # }}}
-
-}
-
-
-$RT::Handle->Disconnect();
-
-
-
-
-
-
-
-# {{{ sub ParseBooleanOp
-
-=head2 ParseBooleanOp
-
- Takes an option modifier. returns the apropriate SQL operator.
- If it's handed ! or -, returns !=. Otherwise returns =.
-
-=cut
-
-sub ParseBooleanOp {
-
- my $op = shift;
-
- #so that !new limits to not new, etc
- if ($op =~ /^(\!|-)/) {
- $op = "!=";
- }
- else {
- $op = "=";
- }
-
- return($op);
-}
-
-# }}}
-
-# {{{ sub ParseLikeOp
-=head2 ParseLikeOp
-
- Takes an option modifier. returns the apropriate SQL operator.
- If it's handed ! or -, returns NOT LIKE. Otherwise returns LIKE
-
-=cut
-
-sub ParseLikeOp {
-
- my $op = shift;
-
- #so that !new limits to not new, etc
- if ($op =~ /^(\!|-)/) {
- $op = "NOT LIKE";
- }
- else {
- $op = "LIKE";
- }
-
- return($op);
-}
-# }}}
-
-# {{{ sub ParseDateToISO
-
-=head2 ParseDateToISO
-
-Takes a date in an arbitrary format.
-Returns an ISO date and time in GMT
-
-=cut
-
-sub ParseDateToISO {
- my $date = shift;
-
- my $date_obj = new RT::Date($CurrentUser);
- $date_obj->Set( Format => 'unknown',
- Value => $date
- );
- return ($date_obj->ISO);
-}
-
-# }}}
-
-# {{{ sub ParseDateRange
-
-=head2 ParseDateRange [RANGE]
-
-Takes a range of dates of the form [<date>][-][<date>] and returns
-starting and ending dates (as ISOs) If a date is specified as neither a starting nor ending
-date, we parse it it as "midnight tonight to midnight tomorrow"
-
-=cut
-
-sub ParseDateRange {
- my $in = shift;
- my ($start, $end);
-
-
- use RT::Date;
- my $start_obj = new RT::Date($CurrentUser);
- my $end_obj = new RT::Date($CurrentUser);
-
- if ($in =~ /^(.*?)-(.*?)$/) {
- $start = $1;
- $end = $2;
-
- if ($start) {
- $start_obj->Set(Format => 'unknown',
- Value => $start);
- }
- if ($end) {
- $end_obj->Set(Format => 'unknown',
- Value => $end);
- }
- }
- else {
- $start = $in;
- $end = $in;
-
- $start_obj->Set(Format => 'unknown',
- Value => $start);
-
- $end_obj->Set(Format => 'unknown',
- Value => $end);
-
- $start_obj->SetToMidnight();
- $end_obj->SetToMidnight();
- $end_obj->AddDay();
- }
-
- if ($start) {
- $start = $start_obj->ISO;
- }
- if ($end) {
- $end = $end_obj->ISO;
- }
-
- return ($start, $end);
-}
-
-# }}}
-
-# {{{ ParseRange
-=head2 ParseRange [RANGE]
-
-Takes a range of the form [<int>][-][<int>] and returns
-a first and a last value. If the - is omitted, both $start and $end are the same.
-=cut
-
-sub ParseRange {
- my $in = shift;
- my ($start, $end);
-
- if ($in =~ /(.*?)-(.*?)/) {
- $start = $1;
- $end = $2;
- }
- else {
- $start = $in;
- $end = $in;
- }
-
- return ($start, $end);
-
-
-
-}
-
-# }}}
-
-# {{{ sub ShowSummary
-
-sub ShowSummary {
- my $Ticket = shift;
-
-
- print <<EOFORM;
-Serial Number: @{[$Ticket->Id]} Status:@{[$Ticket->Status]} Worked: @{[$Ticket->TimeWorked]} minutes Queue:@{[$Ticket->QueueObj->Name]}
- Subject: @{[$Ticket->Subject]}
- Requestors: @{[$Ticket->RequestorsAsString]}
- Cc: @{[$Ticket->CcAsString]}
- Admin Cc: @{[$Ticket->AdminCcAsString]}
- Owner: @{[$Ticket->OwnerObj->Name]}
- Priority: @{[$Ticket->Priority]} / @{[$Ticket->FinalPriority]}
- Due: @{[$Ticket->DueAsString]}
- Created: @{[$Ticket->CreatedAsString]} (@{[$Ticket->AgeAsString]})
- Last Contact: @{[$Ticket->ToldAsString]} (@{[$Ticket->LongSinceToldAsString]})
- Last Update: @{[$Ticket->LastUpdatedAsString]} by @{[$Ticket->LastUpdatedByObj->Name]}
-
-EOFORM
-
-my $selects = $Ticket->QueueObj->KeywordSelects();
- #get the keyword selects
- print "Keywords:\n";
- while (my $select = $selects->Next) {
- print "\t" .$select->Name .": ";
- my $keys = $Ticket->KeywordsObj($select->id);
- while (my $key = $keys->Next) {
- print $key->KeywordObj->RelativePath($select->KeywordObj) . " ";
-
- }
- print "\n";
- }
-
-#iterate through the keyword selects.
-#print the keyword select and all the related keywords
-
-
-
-#TODO: finish link descriptions
-print "Dependencies: \n";
- while (my $l=$Ticket->DependedOnBy->Next) {
- print $l->BaseObj->id," (",$l->BaseObj->Subject,") ",$l->Type," this ticket\n";
- }
- while (my $l=$Ticket->DependsOn->Next) {
- print "This ticket ",$l->Type," ",$l->TargetObj->Id," (",$l->TargetObj->Subject,")\n";
- }
-}
-
-# }}}
-
-# {{{ sub ShowHistory
-sub ShowHistory {
- my $Ticket = shift;
- my $Transaction;
- my $Transactions = $Ticket->Transactions;
-
- while ($Transaction = $Transactions->Next) {
- &ShowTransaction($Transaction);
- }
- }
-# }}}
-
-# {{{ sub ShowTransaction
-sub ShowTransaction {
- my $transaction = shift;
-
-print <<EOFORM;
-==========================================================================
-Date: @{[$transaction->CreatedAsString]} (@{[$transaction->TimeTaken]} minutes)
-@{[$transaction->Description]}
-EOFORM
- ;
- my $attachments=$transaction->Attachments();
- while (my $message=$attachments->Next) {
- print <<EOFORM;
---------------------------------------------------------------------------
-@{[$message->Headers]}
-EOFORM
-
- if ($message->ContentType =~ m{^(text/plain|message|text$)}) {
- print $message->Content;
- } else {
- print $message->ContentType, " not shown";
- }
- }
- print "\n";
- return();
-}
-# }}}
-
-
-# {{{ sub BuildListingFormat
-
-sub BuildListingFormat {
- my $format_string = shift;
-
- my ($id, @format, @code, @titles);
- my ($field,$titles,$length, $format);
-
- my $code = "";
-
- # {{{ attribs
- my $attribs = { id => { chars => '4',
- justify => 'r',
- title => 'id',
- value => '$Ticket->id',
- },
-
- queue => { chars => '8',
- justify => 'l',
- title => 'Queue',
- value => '$Ticket->QueueObj->Name'
- },
- subject => { chars => '30',
- justify => 'l',
- title => 'Subject',
- value => '$Ticket->Subject',
- },
- priority => { chars => '2',
- justify => 'r',
- title => 'Pri',
- value => '$Ticket->Priority',
- },
- final_priority => { chars => '2',
- justify => 'r',
- title => 'Fin',
- value => '$Ticket->FinalPriority',
- },
- time_worked => { chars => '6',
- justify => 'r',
- title => 'Worked',
- value => '$Ticket->TimeWorked',
- },
- time_left => { chars => '5',
- justify => 'r',
- title => 'Left',
- value => '$Ticket->TimeLeft',
-
- },
-
- status => { chars => '6',
- justify => 'r',
- title => 'Status',
- value => '$Ticket->Status',
- },
- owner => { chars => '10',
- justify => 'r',
- title => 'Owner',
- value => '$Ticket->OwnerObj->Name'
- },
- requestor => { chars => '10',
- justify => 'r',
- title => 'Requestor',
- value => '$Ticket->RequestorsAsString'
- },
- created => { chars => '12',
- justify => 'r',
- title => 'Created',
- value => '$Ticket->CreatedAsString'
- },
- updated => { chars => '12',
- justify => 'r',
- title => 'Updated',
- value => '$Ticket->LastUpdatedAsString'
- },
- due => { chars => '12',
- justify => 'r',
- title => 'Due',
- value => '$Ticket->DueAsString'
- },
- told => { chars => '12',
- justify => 'r',
- title => 'Told',
- value => '$Ticket->ToldAsString'
- },
-
-
-
- };
-
- # }}}
-
-
- foreach $field (split ('%',$format_string)) {
-
- if ($field =~ /^(\D*?)(\d*?)$/) {
- $id = $1;
- $length = $2;
- }
- else {
- $RT::Logger->debug ("Error parsing $field\n");
- }
- if ($length) {
- push (@format, "%".$length.".".$length."s ");
-
- push (@code, $attribs->{"$id"}->{'value'});
-
- push (@titles, "'". $attribs->{"$id"}->{title}. "'");
- }
-
-
- }
- $code = join (',', @code);
- $format = join (" ", @format);
- $titles = join (', ', @titles);
-
-
- return ($format, $titles, $code);
-}
-
-# }}}
-
-
-
-1;
diff --git a/rt/bin/rt-mailgate b/rt/bin/rt-mailgate
index e6f0d95c5..b30443638 100755
--- a/rt/bin/rt-mailgate
+++ b/rt/bin/rt-mailgate
@@ -1,367 +1,587 @@
-#!!!PERL!! -w
+#!/usr/bin/perl -w
+# BEGIN LICENSE BLOCK
+#
+# Copyright (c) 1996-2003 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
+
+=head1 NAME
+
+rt-mailgate - Mail interface to RT3.
+
+=begin testing
+
+use RT::I18N;
+
+
+# {{{ Test new ticket creation by root who is privileged and superuser
+
+ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@");
+print MAIL <<EOF;
+From: root\@localhost
+To: rt\@example.com
+Subject: This is a test of new ticket creation
+
+Blah!
+Foob!
+EOF
+close (MAIL);
+
+use RT::Tickets;
+my $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id', OPERATOR => '>', VALUE => '0');
+my $tick = $tickets->First();
+ok (UNIVERSAL::isa($tick,'RT::Ticket'));
+ok ($tick->Id, "found ticket ".$tick->Id);
+ok ($tick->Subject eq 'This is a test of new ticket creation', "Created the ticket");
-# $Header: /home/cvs/cvsroot/freeside/rt/bin/rt-mailgate,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# (c) 1996-2001 Jesse Vincent <jesse@fsck.com>
-# This software is redistributable under the terms of the GNU GPL
+# }}}
-package RT;
-use strict;
-use vars qw($VERSION $Handle $Nobody $SystemUser);
-
-$VERSION="!!RT_VERSION!!";
-
-
-use lib "!!RT_LIB_PATH!!";
-use lib "!!RT_ETC_PATH!!";
-
-use RT::Interface::Email qw(CleanEnv LoadConfig DBConnect
- GetCurrentUser
- GetMessageContent
- CheckForLoops
- CheckForSuspiciousSender
- CheckForAutoGenerated
- ParseMIMEEntityFromSTDIN
- ParseTicketId
- MailError
- ParseCcAddressesFromHead
- ParseSenderAddressFromHead
- ParseErrorsToAddressFromHead
- );
-
-#Clean out all the nasties from the environment
-CleanEnv();
-
-#Load etc/config.pm and drop privs
-LoadConfig();
-
-#Connect to the database and get RT::SystemUser and RT::Nobody loaded
-DBConnect();
-
-#Drop setgid permissions
-RT::DropSetGIDPermissions();
-
-use RT::Ticket;
-use RT::Queue;
-use MIME::Parser;
-use File::Temp;
-use Mail::Address;
-
-
-#Set some sensible defaults
-my $Queue = 1;
-my $time = time;
-my $Action = "correspond";
-
-my ($Verbose, $ReturnTid, $Debug);
-my ($From, $TicketId, $Subject,$SquelchReplies);
-
-# using --owner-from-extension, this will let you set ticket owner on create
-my $AssignTicketTo = undef;
-my ($status, $msg);
-
-# {{{ 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 '--ticket-id-from-extension') {
- $TicketId = $ENV{'EXTENSION'};
- }
- if ($flag eq '--queue-from-extension') {
- $Queue = $ENV{'EXTENSION'};
- }
- if ($flag eq '--owner-from-extension') {
- $AssignTicketTo = $ENV{'EXTENSION'};
- }
-
- if (($flag eq '-a') or ($flag eq '--action')) {
- $Action = shift @ARGV;
- }
-
-
-}
+# {{{This is a test of new ticket creation as an unknown user
+
+ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@");
+print MAIL <<EOF;
+From: doesnotexist\@example.com
+To: rt\@example.com
+Subject: This is a test of new ticket creation as an unknown user
+
+Blah!
+Foob!
+EOF
+close (MAIL);
+
+$tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+$tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+ok ($tick->Subject ne 'This is a test of new ticket creation as an unknown user', "failed to create the new ticket from an unprivileged account");
+my $u = RT::User->new($RT::SystemUser);
+$u->Load('doesnotexist@example.com');
+ok( $u->Id == 0, " user does not exist and was not created by failed ticket submission");
+
# }}}
-# get the current mime entity from stdin
-my ($entity, $head) = ParseMIMEEntityFromSTDIN();
+# {{{ now everybody can create tickets. can a random unkown user create tickets?
-#Get someone to send runtime errors to;
-my $ErrorsTo = ParseErrorsToAddressFromHead($head);
+my $g = RT::Group->new($RT::SystemUser);
+$g->LoadSystemInternalGroup('Everyone');
+ok( $g->Id, "Found 'everybody'");
-#Get us a current user object.
-my $CurrentUser = GetCurrentUser($head, $entity, $ErrorsTo);
+my ($val,$msg) = $g->PrincipalObj->GrantRight(Right => 'CreateTicket');
+ok ($val, "Granted everybody the right to create tickets - $msg");
-# We've already performed a warning and sent the mail off to somewhere safe ($RTOwner).
-# this is _exceedingly_ unlikely but we don't want to keep going if we don't have a current user
+sleep(60); # gotta sleep so the remote process' ACL cache times out
-unless ($CurrentUser->Id) {
- exit(1);
-}
+ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@");
+print MAIL <<EOF;
+From: doesnotexist\@example.com
+To: rt\@example.com
+Subject: This is a test of new ticket creation as an unknown user
-my $MessageId = $head->get('Message-Id') ||
- "<no-message-id-".time.rand(2000)."\@.$RT::Organization>";
+Blah!
+Foob!
+EOF
+close (MAIL);
-#Pull apart the subject line
-$Subject = $head->get('Subject') || "[no subject]";
-chomp $Subject;
-# Get the ticket ID unless it's already set
-$TicketId = ParseTicketId($Subject) unless ($TicketId);
+$tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id' ,OPERATOR => '>', VALUE => '0');
+$tick = $tickets->First();
+ok ($tick->Id, "found ticket ".$tick->Id);
+ok ($tick->Subject eq 'This is a test of new ticket creation as an unknown user', "failed to create the new ticket from an unprivileged account");
+my $u = RT::User->new($RT::SystemUser);
+$u->Load('doesnotexist@example.com');
+ok( $u->Id != 0, " user does not exist and was created by ticket submission");
-#Set up a queue object
-my $QueueObj = RT::Queue->new($CurrentUser);
-$QueueObj->Load($Queue);
-unless ($QueueObj->id ) {
+# }}}
- MailError(To => $RT::OwnerEmail,
- Subject => "RT Bounce: $Subject",
- Explanation => "RT couldn't find the queue: $Queue",
- MIMEObj => $entity);
-}
+# {{{ can another random reply to a ticket without being granted privs? answer should be no.
-# {{{ Lets check for mail loops of various sorts.
-my $IsAutoGenerated = CheckForAutoGenerated($head);
+#($val,$msg) = $g->PrincipalObj->GrantRight(Right => 'CreateTicket');
+#ok ($val, "Granted everybody the right to create tickets - $msg");
+#sleep(60); # gotta sleep so the remote process' ACL cache times out
-my $IsSuspiciousSender = CheckForSuspiciousSender($head);
+ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@");
+print MAIL <<EOF;
+From: doesnotexist-2\@example.com
+To: rt\@example.com
+Subject: [example.com #@{[$tick->Id]}] This is a test of a reply as an unknown user
-my $IsALoop = CheckForLoops($head);
+Blah!
+Foob!
+EOF
+close (MAIL);
+$u = RT::User->new($RT::SystemUser);
+$u->Load('doesnotexist-2@example.com');
+ok( $u->Id == 0, " user does not exist and was not created by ticket correspondence submission");
+# }}}
+# {{{ can another random reply to a ticket after being granted privs? answer should be yes
-#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;
-
- #TODO: Is what we want to do here really
- # "Make the requestor cease to get mail from RT"?
- # This might wreak havoc with vacation-mailing users.
- # Maybe have a "disabled for bouncing" state that gets
- # turned off when we get a legit incoming message
+($val,$msg) = $g->PrincipalObj->GrantRight(Right => 'ReplyToTicket');
+ok ($val, "Granted everybody the right to reply to tickets - $msg");
+sleep(60); # gotta sleep so the remote process' ACL cache times out
-}
+ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@");
+print MAIL <<EOF;
+From: doesnotexist-2\@example.com
+To: rt\@example.com
+Subject: [example.com #@{[$tick->Id]}] This is a test of a reply as an unknown user
+Blah!
+Foob!
+EOF
+close (MAIL);
-# {{{ 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 Received 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 => $entity);
-
- #Do we actually want to store it?
- exit unless ($RT::StoreLoops);
- }
-}
+
+$u = RT::User->new($RT::SystemUser);
+$u->Load('doesnotexist-2@example.com');
+ok( $u->Id != 0, " user exists and was created by ticket correspondence submission");
# }}}
+# {{{ can another random comment on a ticket without being granted privs? answer should be no.
- #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')
- }
+#($val,$msg) = $g->PrincipalObj->GrantRight(Right => 'CreateTicket');
+#ok ($val, "Granted everybody the right to create tickets - $msg");
+#sleep(60); # gotta sleep so the remote process' ACL cache times out
-if ($SquelchReplies) {
- ## TODO: This is a hack. It should be some other way to
- ## indicate that the transaction should be "silent".
+ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action comment"), "Opened the mailgate - $@");
+print MAIL <<EOF;
+From: doesnotexist-3\@example.com
+To: rt\@example.com
+Subject: [example.com #@{[$tick->Id]}] This is a test of a comment as an unknown user
- my ($Sender, $junk) = ParseSenderAddressFromHead($head);
- $head->add('RT-Squelch-Replies-To', $Sender);
-}
+Blah!
+Foob!
+EOF
+close (MAIL);
+
+$u = RT::User->new($RT::SystemUser);
+$u->Load('doesnotexist-3@example.com');
+ok( $u->Id == 0, " user does not exist and was not created by ticket comment submission");
# }}}
+# {{{ can another random reply to a ticket after being granted privs? answer should be yes
-# {{{ If we require that the sender be found in an external DB and they're not
-# forward this message to RTOwner
+($val,$msg) = $g->PrincipalObj->GrantRight(Right => 'CommentOnTicket');
+ok ($val, "Granted everybody the right to reply to tickets - $msg");
+sleep(60); # gotta sleep so the remote process' ACL cache times out
+ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action comment"), "Opened the mailgate - $@");
+print MAIL <<EOF;
+From: doesnotexist-3\@example.com
+To: rt\@example.com
+Subject: [example.com #@{[$tick->Id]}] This is a test of a comment as an unknown user
+Blah!
+Foob!
+EOF
+close (MAIL);
-if ($RT::LookupSenderInExternalDatabase &&
- $RT::SenderMustExistInExternalDatabase ) {
- MailError(To => $RT::OwnerEmail,
- Subject => "RT Bounce: $Subject",
- Explanation => "RT couldn't find requestor via its external database lookup",
- MIMEObj => $entity);
-
-}
+$u = RT::User->new($RT::SystemUser);
+$u->Load('doesnotexist-3@example.com');
+ok( $u->Id != 0, " user exists and was created by ticket comment submission");
# }}}
-# {{{ elsif we don't have a ticket Id, we're creating a new ticket
-
-
-
-elsif (!defined($TicketId)) {
-
- # {{{ Create a new ticket
- if ($Action =~ /correspond/) {
-
- # open a new ticket
- my @Requestors = ($CurrentUser->id);
-
- my @Cc;
- if ($RT::ParseNewMessageForTicketCcs) {
- @Cc = ParseCcAddressesFromHead(Head => $head,
- CurrentUser => $CurrentUser,
- QueueObj => $QueueObj );
- }
-
- my $Ticket = new RT::Ticket($CurrentUser);
- my ($id, $Transaction, $ErrStr) =
- $Ticket->Create ( Queue => $Queue,
- Subject => $Subject,
- Owner => $AssignTicketTo,
- Requestor => \@Requestors,
- Cc => \@Cc,
- MIMEObj => $entity
- );
- if ($id == 0 ) {
- MailError( To => $ErrorsTo,
- Subject => "Ticket creation failed",
- Explanation => $ErrStr,
- MIMEObj => $entity
- );
- $RT::Logger->error("Create failed: $id / $Transaction / $ErrStr ");
- }
- }
-
- # }}}
-
- else {
- #TODO Return an error message
- MailError( To => $ErrorsTo,
- Subject => "No ticket id specified",
- Explanation => "$Action aliases require a TicketId to work on",
- MIMEObj => $entity
- );
-
- $RT::Logger->crit("$Action aliases require a TicketId to work on ".
- "(from ".$CurrentUser->UserObj->EmailAddress.") ".
- $MessageId);
- }
-}
+# {{{ Testing preservation of binary attachments
+
+# Get a binary blob (Best Practical logo)
+
+# Create a mime entity with an attachment
+
+use MIME::Entity;
+my $entity = MIME::Entity->build( From => 'root@localhost',
+ To => 'rt@localhost',
+ Subject => 'binary attachment test',
+ Data => ['This is a test of a binary attachment']);
+
+# currently in lib/t/autogen
+$entity->attach(Path => '../../../html/NoAuth/images/spacer.gif',
+ Type => 'image/gif',
+ Encoding => 'base64');
+
+# Create a ticket with a binary attachment
+ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@");
+
+$entity->print(\*MAIL);
+
+close (MAIL);
+
+my $tickets = RT::Tickets->new($RT::SystemUser);
+$tickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets->Limit(FIELD => 'id', OPERATOR => '>', VALUE => '0');
+ $tick = $tickets->First();
+ok (UNIVERSAL::isa($tick,'RT::Ticket'));
+ok ($tick->Id, "found ticket ".$tick->Id);
+ok ($tick->Subject eq 'binary attachment test', "Created the ticket - ".$tick->Id);
+
+my $file = `cat ../../../html/NoAuth/images/spacer.gif`;
+ok ($file, "Read in the logo image");
+
+
+ use Digest::MD5;
+warn "for the raw file the content is ".Digest::MD5::md5_base64($file);
+
+
+
+# Verify that the binary attachment is valid in the database
+my $attachments = RT::Attachments->new($RT::SystemUser);
+$attachments->Limit(FIELD => 'ContentType', VALUE => 'image/gif');
+ok ($attachments->Count == 1, 'Found only one gif in the database');
+my $attachment = $attachments->First;
+my $acontent = $attachment->Content;
+
+ warn "coming from the database, the content is ".Digest::MD5::md5_base64($acontent);
+
+is( $acontent, $file, 'The attachment isn\'t screwed up in the database.');
+# Log in as root
+use Getopt::Long;
+use LWP::UserAgent;
+
+
+# Grab the binary attachment via the web ui
+my $ua = LWP::UserAgent->new();
+
+my $full_url = "http://localhost/Ticket/Attachment/".$attachment->TransactionId."/".$attachment->id."/spacer.gif?&user=root&pass=password";
+my $r = $ua->get( $full_url);
+
+
+# Verify that the downloaded attachment is the same as what we uploaded.
+is($file, $r->content, 'The attachment isn\'t screwed up in download');
+
+
# }}}
-# {{{ 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 => "Comment not recorded",
- Explanation => "Could not find a ticket with id $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 => "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);
-
- #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 => "Correspondence not recorded",
- Explanation => $msg,
- MIMEObj => $entity
- );
- }
- }
-
- else {
- #Return mail to the sender with an error
- MailError( To => $ErrorsTo,
- Subject => "RT Configuration error",
- Explanation => "'$Action' not a recognized action.".
- " Your RT administrator has misconfigured ".
- "the mail aliases which invoke RT" ,
- MIMEObj => $entity
- );
-
- $RT::Logger->crit("$Action type unknown for $MessageId");
-
- }
-
-}
+# {{{ Simple I18N testing
+
+ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@");
+
+print MAIL <<EOF;
+From: root\@localhost
+To: rtemail\@example.com
+Subject: This is a test of I18N ticket creation
+Content-Type: text/plain; charset="utf-8"
+
+2 accented lines
+\303\242\303\252\303\256\303\264\303\273
+\303\241\303\251\303\255\303\263\303\272
+bye
+EOF
+close (MAIL);
+
+my $unitickets = RT::Tickets->new($RT::SystemUser);
+$unitickets->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$unitickets->Limit(FIELD => 'id', OPERATOR => '>', VALUE => '0');
+my $unitick = $unitickets->First();
+ok (UNIVERSAL::isa($unitick,'RT::Ticket'));
+ok ($unitick->Id, "found ticket ".$unitick->Id);
+ok ($unitick->Subject eq 'This is a test of I18N ticket creation', "Created the ticket - ". $unitick->Subject);
+
+
+
+my $unistring = "\303\241\303\251\303\255\303\263\303\272";
+Encode::_utf8_on($unistring);
+is ($unitick->Transactions->First->Content, $unitick->Transactions->First->Attachments->First->Content, "Content is ". $unitick->Transactions->First->Attachments->First->Content);
+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, "|/opt/rt3/bin/rt-mailgate --url http://localhost/ --queue general --action correspond"), "Opened the mailgate - $@");
+
+print MAIL <<EOF;
+From: root\@localhost
+To: rtemail\@example.com
+Subject: This is a test of I18N ticket creation
+Content-Type: text/plain; charset="utf-8"
+
+2 accented lines
+\303\242\303\252\303\256\303\264\303\273
+\303\241\303\251\303\255\303\263\303\272
+bye
+EOF
+close (MAIL);
+
+my $tickets2 = RT::Tickets->new($RT::SystemUser);
+$tickets2->OrderBy(FIELD => 'id', ORDER => 'DESC');
+$tickets2->Limit(FIELD => 'id', OPERATOR => '>', VALUE => '0');
+my $tick2 = $tickets2->First();
+ok (UNIVERSAL::isa($tick2,'RT::Ticket'));
+ok ($tick2->Id, "found ticket ".$tick2->Id);
+ok ($tick2->Subject eq 'This is a test of I18N ticket creation', "Created the ticket");
+
+
+
+my $unistring = "\303\241\303\251\303\255\303\263\303\272";
+Encode::_utf8_on($unistring);
+
+ok ($tick2->Transactions->First->Content =~ $unistring, "It appears to be unicode - ".$tick2->Transactions->First->Content);
# }}}
-$RT::Handle->Disconnect();
+($val,$msg) = $g->PrincipalObj->RevokeRight(Right => 'CreateTicket');
+ok ($val, $msg);
+
+
+
+=end testing
+
+=cut
+
+
+use strict;
+use Getopt::Long;
+use LWP::UserAgent;
+
+use constant EX_TEMPFAIL => 75;
+
+my %opts;
+GetOptions( \%opts, "queue=s", "action=s", "url=s", "jar=s", "help", "debug", "extension=s" );
+
+if ( $opts{help} ) {
+ require Pod::Usage;
+ import Pod::Usage;
+ pod2usage("RT Mail Gateway\n");
+ exit 1; # Don't want to succeed if this is really an email!
+}
+
+for (qw(url)) {
+ die "$0 invoked improperly\n\nNo $_ provided to mail gateway!\n" unless $opts{$_};
+}
+
+undef $/;
+my $message = <>;
+my $ua = LWP::UserAgent->new();
+$ua->cookie_jar( { file => $opts{jar} } );
+
+my %args = (
+ queue => $opts{queue},
+ action => $opts{action},
+ message => $message,
+ SessionType => 'REST', # Surpress login box
+);
+
+
+if ($opts{'extension'}) {
+ $args{$opts{'extension'}} = $ENV{'EXTENSION'};
+}
+
+# Set up cookie here.
+
+my $full_url = $opts{'url'}. "/REST/1.0/NoAuth/mail-gateway";
+warn "Connecting to $full_url" if $opts{'debug'};
+
+
+
+my $r = $ua->post( $full_url, {%args} );
+check_failure($r);
+
+my $content = $r->content;
+warn $content if ($opts{debug});
+
+if ( $content !~ /^(ok|not ok)/ ) {
+
+ # It's not the server's fault if the mail is bogus. We just want to know that
+ # *something* came out of the server.
+ die <<EOF
+RT server error.
+
+The RT server which handled your email did not behave as expected. It
+said:
+
+$content
+EOF
+
+}
+
+sub check_failure {
+ my $r = shift;
+ return if $r->is_success();
+
+ # This ordinarily oughtn't to be able to happen, suggests a bug in RT.
+ # So only load these heavy modules when they're needed.
+ require HTML::TreeBuilder;
+ require HTML::FormatText;
+
+ my $error = $r->error_as_HTML;
+ my $tree = HTML::TreeBuilder->new->parse($error);
+ $tree->eof;
+
+ # It'll be a cold day in hell before RT sends out bounces in HTML
+ my $formatter = HTML::FormatText->new( leftmargin => 0,
+ rightmargin => 50 );
+ warn $formatter->format($tree);
+ warn "This is $0 exiting because of an undefined server error" if ($opts{debug});
+ exit EX_TEMPFAIL;
+}
+
+
+=head1 SYNOPSIS
+
+ rt-mailgate --help : this text
+
+Usual invocation (from MTA):
+
+ rt-mailgate --action (correspond|comment) --queue queuename
+ --url http://your.rt.server/
+ [ --extension (queue|action|ticket)
+
+See C<man rt-mailgate> for more.
+
+=head1 OPTIONS
+
+=over 3
+
+=item C<--action>
+
+Specifies whether this is a correspondence or comment address.
+
+=item C<--queue>
+
+Reflects which queue this address handles.
+
+=item C<--url>
+
+The location of the web server for your RT instance.
+
+
+=item C<--extension> OPTIONAL
+
+Some MTAs will route mail sent to user-foo@host or user+foo@host to user@host
+and present "foo" in the environment variable $EXTENSION. By specifying
+the value "queue" for this parameter, the queue this message should be
+submitted to will be set to the value of $EXTENSION. By specifying
+"ticket", $EXTENSION will be interpreted as the id of the ticket this message
+is related to. "action" will allow the user to specify either "comment" or
+"correspond" in the address extension.
+
+
+=head1 DESCRIPTION
+
+The RT mail gateway is the primary mechanism for communicating with RT
+via email. This program simply directs the email to the RT web server,
+which handles filing correspondence and sending out any required mail.
+It is designed to be run as part of the mail delivery process, either
+called directly by the MTA or C<procmail>, or in a F<.forward> or
+equivalent.
+
+=head1 SETUP
+
+Much of the set up of the mail gateway depends on your MTA and mail
+routing configuration. However, you will need first of all to create an
+RT user for the mail gateway and assign it a password; this helps to
+ensure that mail coming into the web server did originate from the
+gateway.
+
+Next, you need to route mail to C<rt-mailgate> for the queues you're
+monitoring. For instance, if you're using F</etc/aliases> and you have a
+"bugs" queue, you will want something like this:
+
+ bugs: "|/opt/rt3/bin/rt-mailgate --queue bugs --action correspond
+ --url http://rt.mycorp.com/"
+
+ bugs-comment: "|/opt/rt3/bin/rt-mailgate --queue bugs --action comment
+ --url http://rt.mycorp.com/"
+
+Note that you don't have to run your RT server on your mail server, as
+the mail gateway will happily relay to a different machine.
+
+=head1 CUSTOMIZATION
+
+By default, the mail gateway will accept mail from anyone. However,
+there are situations in which you will want to authenticate users
+before allowing them to communicate with the system. You can do this
+via a plug-in mechanism in the RT configuration.
+
+You can set the array C<@RT::MailPlugins> to be a list of plugins. The
+default plugin, if this is not given, is C<Auth::MailFrom> - that is,
+authentication of the person is done based on the C<From> header of the
+email. If you have additional filters or authentication mechanisms, you
+can list them here and they will be called in order:
+
+ @RT::MailPlugins = (
+ "Filter::SpamAssassin",
+ "Auth::LDAP",
+ # ...
+ );
+
+See the documentation for any additional plugins you have.
+
+You may also put Perl subroutines into the C<@RT::MailPlugins> array, if
+they behave as described below.
+
+=head1 WRITING PLUGINS
+
+What's actually going on in the above is that C<@RT::MailPlugins> is a
+list of Perl modules; RT prepends C<RT::Interface::Email::> to the name,
+to form a package name, and then C<use>'s this module. The module is
+expected to provide a C<GetCurrentUser> subroutine, which takes a hash of
+several parameters:
+
+=over 4
+
+=item Message
+
+A C<MIME::Entity> object representing the email
+=item CurrentUser
+
+An C<RT::CurrentUser> object
+
+=item AuthStat
+
+The authentication level returned from the previous plugin.
+
+=item Ticket [OPTIONAL]
+
+The ticket under discussion
+
+=item Queue [OPTIONAL]
+
+If we don't already have a ticket id, we need to know which queue we're talking about
+
+=item Action
-# Everything below this line is a helper sub. most of them will eventually
-# move to Interface::Email
+The action being performed. At the moment, it's one of "comment" or "correspond"
-#When we call die, trap it and log->crit with the value of the die.
-$SIG{__DIE__} = sub {
- unless ($^S || !defined $^S ) {
- $RT::Logger->crit("$_[0]");
- MailError( To => $ErrorsTo,
- Bcc => $RT::OwnerEmail,
- Subject => "RT Critical error. Message not recorded!",
- Explanation => "$_[0]",
- MIMEObj => $entity
- );
- exit(-1);
- }
- else {
- #Get out of here if we're in an eval
- die $_[0];
- }
-};
+=back 4
+It returns two values, the new C<RT::CurrentUser> object, and the new
+authentication level. The authentication level can be zero, not allowed
+to communicate with RT at all, (a "permission denied" error is mailed to
+the correspondent) or one, which is the normal mode of operation.
+Additionally, if C<-1> is returned, then the processing of the plug-ins
+stops immediately and the message is ignored.
+=cut
-1;
diff --git a/rt/bin/rtadmin b/rt/bin/rtadmin
deleted file mode 100644
index 25ba1b06a..000000000
--- a/rt/bin/rtadmin
+++ /dev/null
@@ -1,1040 +0,0 @@
-#!!!PERL!! -w
-#
-# $Header: /home/cvs/cvsroot/freeside/rt/bin/Attic/rtadmin,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# RT is (c) 1996-2001 Jesse Vincent <jesse@fsck.com>
-
-use strict;
-use Carp;
-use Getopt::Long qw(:config pass_through);
-
-use lib "!!RT_LIB_PATH!!";
-use lib "!!RT_ETC_PATH!!";
-
-use RT::Interface::CLI qw(CleanEnv LoadConfig DBConnect
- GetCurrentUser GetMessageContent);
-
-#Clean out all the nasties from the environment
-CleanEnv();
-
-#Load etc/config.pm and drop privs
-LoadConfig();
-
-#Connect to the database and get RT::SystemUser and RT::Nobody loaded
-DBConnect();
-
-#Drop setgid permissions
-RT::DropSetGIDPermissions();
-
-#Get the current user all loaded
-my $CurrentUser = GetCurrentUser();
-
-unless ($CurrentUser->Id) {
- print "No RT user found. Please consult your RT administrator.\n";
- exit(1);
-}
-
-
-
-
-PickMode();
-
-
-# {{{ Help
-
-sub Help {
-
- # {{{ help_acl
-my $help_acl ="
- Access control
- --grant-right <right>
- --revoke-right <right>
- --userid <user>
- --groupid <group>
- --list-rights";
-
-# }}}
-
- # {{{ help_keyword_sel
-my $help_keyword_sel = "
- Keyword Selections
- --add-keyword-select
- --modify-keyword-select <name>
- --ks-name <name>
- --ks-keyword <keyword>
- --ks-single
- --ks-multiple
- --ks-depth <int>
-
- --disable-keyword-select <name>";
-# }}}
-
- # {{{ help_scrip
-my $help_scrip = "
- Scrips
- --create-scrip
- --scrip-condition <condition name or id>
- --scrip-action <action name or id>
- --scrip-template <template name or id>
-
- --delete-scrip <id>
- --list-scrips";
-
-# }}}
-
- # {{{ help_template
-my $help_template = "
- Templates
- --delete-template [<id>|<name>]
- --display-template [<id>|<name>]
-
- --create-template
- --modify-template [<id>|<name>]
- Flags for --create-template and --modify-template
- --template-name
- --template-description
- --template-edit-content
-
- --list-templates";
-
-# }}}
-
-
-print <<EOF;
-
-USAGE: rtadmin --user <userid> [Userflags]
- rtadmin --list-users
- rtadmin --queue <queueid> [Queueflags]
- rtadmin --list-queues
- rtadmin --group [groupflags]
- rtadmin --list-groups
- rtadmin --system [SystemFlags]
- rtadmin --keyword [keywordflags]
-
-User configuration for --user <userid>
-
- --disable
- --create
- --display
-
- Core Attributes
- --userid
- --gecos
- --password
- --emailaddress
- --privileged
- --comments
- --signature
- --organization
-
- Names
- --realname
- --nickname
-
- Auth and external info
- --externalcontactinfoid
- --contactinfosystem
- --externalauthid
- --authsystem
-
- Phone numbers
- --pagerphone
- --workphone
- --mobilemphone
- --homephone
-
- Paper address
- --address1
- --address2
- --city
- --state
- --zip
- --country
- --freeformcontactqinfo
-
-
-Group Configuration for --group <groupid>
- --create
- --delete
- --display
-
- --name <new name>
- --description <new description>
-
-
-
- --add-member <userid>
- --delete-member <userid>
- --list-members
-
-Queue Configuration for --queue <queueid>
- --create
- --disable
- --display
-
- --name <name>
- --correspondaddress <email address>
- --commentaddress <email address>
- --initialpriority <int>
- --finalpriority <int>
- --defaultduein <days>
-
- --add-cc <email address>
- --delete-cc <email address>
- --add-admincc <email address>
- --delete-admincc <email address>
- --list-watchers
-
-
-
-$help_acl
-
-$help_keyword_sel
-
-$help_template
-
-$help_scrip
-
-
-System configuration for --system
-
-$help_acl
-
-$help_keyword_sel
-
-$help_template
-
-$help_scrip
-
-
-Keyword configuration for --keyword <fully qualified name>
- --list-children
- --create-child <name>
- --disable
- --name <new name>
- --description <new description>
-
-EOF
-
-
-
-}
-
-# }}}
-
-# {{{ PickMode
-
-sub PickMode {
- my ($user,$group, $queue, $system, $keyword, $listusers,
- $listgroups, $listqueues, $help);
-
-
- GetOptions ('help|h|usage' => \$help,
- 'user=s' => \$user,
- 'queue=s' => \$queue,
- 'group=s' => \$group,
- 'system' => \$system,
- 'keyword=s', => \$keyword,
- 'list-users' => \$listusers,
- 'list-queues' => \$listqueues,
- 'list-groups' => \$listgroups,
- );
-
-
-
- if ($user) { AdminUser($user) }
- elsif ($group) { AdminGroup($group) }
- elsif ($queue) { AdminQueue($queue) }
- elsif ($system) { AdminSystem($system) }
- elsif ($keyword) { AdminKeywords($keyword) }
- elsif ($listusers) { ListUsers() }
- elsif ($listgroups) { ListGroups() }
- elsif ($listqueues) { ListQueues() }
- elsif ($help) { Help()}
- else {
- print "No command found\n";
- }
- exit(0);
-}
-
-# }}}
-
-# {{{ AdminUser
-
-sub AdminUser {
- my $user=shift;
- my %args;
-
- GetOptions(\%args,
- 'create', 'disable|delete', 'display',
- 'Name=s', 'Gecos=s', 'Password=s',
- 'EmailAddress=s', 'Privileged=s', 'Comments=s', 'Signature=s',
- 'Organization=s', 'RealName=s', 'NickName=s',
- 'ExternalContactInfoId=s', 'ContactInfoSystem=s',
- 'ExternalAuthId=s', 'AuthSystem=s',
- 'HomePhone=s', 'WorkPhone=s', 'MobilePhone=s', 'PagerPhone=s',
- 'Address1=s', 'Address2=s', 'City=s', 'State=s', 'Zip=s',
- 'Country=s', 'FreeformContactInfo=s');
-
- my $user_obj = new RT::User($CurrentUser);
-
-
- #Create the user if we need to
- if ($args{'create'}) {
- my ($status, $msg) =
- $user_obj->Create( Name => ($args{'Name'} || $user),
- Gecos => $args{'Gecos'},
- Password => $args{'Password'},
- EmailAddress => $args{'EmailAddress'},
- Privileged => $args{'Privileged'},
- Comments => $args{'Comments'},
- Signature => $args{'Signature'},
- Organization => $args{'Organization'},
- RealName => $args{'RealName'},
- NickName => $args{'NickName'},
- ExternalContactInfoId => $args{'ExternalContactInfoId'},
- ContactInfoSystem => $args{'ContactInfoSystem'},
- ExternalAuthId => $args{'ExternalAuthId'},
- AuthSystem => $args{'AuthSystem'},
- HomePhone => $args{'HomePhone'},
- WorkPhone => $args{'WorkPhone'},
- MobilePhone => $args{'MobilePhone'},
- PagerPhone => $args{'PagerPhone'},
- Address1 => $args{'Address1'},
- Address2 => $args{'Address2'},
- City => $args{'City'},
- State => $args{'State'},
- Zip => $args{'Zip'},
- FreeformContactInfo => $args{'FreeformContactInfo'}
- );
-
- print "$msg\n";
- return();
-
- }
- else {
-
-
- #Load the user
- $user_obj->Load($user);
-
- unless ($user_obj->id) {
- print "User '$user' not found\n";
- return();
- }
-
-
-
- #modify the user if we need to
- my @attributes = ('Name', 'Gecos',
- 'EmailAddress', 'Privileged', 'Comments', 'Signature',
- 'Organization', 'RealName', 'NickName',
- 'ExternalContactInfoId', 'ContactInfoSystem',
- 'ExternalAuthId', 'AuthSystem',
- 'HomePhone', 'WorkPhone', 'MobilePhone', 'PagerPhone',
- 'Address1', 'Address2', 'City', 'State', 'Zip',
- 'Country', 'FreeformContactInfo');
- foreach my $attrib (@attributes) {
- if ( (exists ($args{"$attrib"})) and
- ($user_obj->$attrib() ne $args{"$attrib"})) {
-
- my $method = "Set$attrib";
- my ($val, $msg) = $user_obj->$method($args{"$attrib"});
- print "User ".$user_obj->Name. " $attrib: $msg\n";
-
- }
- }
-
- if (exists ($args{'Password'})) {
- my ($code, $msg);
- ($code, $msg) = $user_obj->SetPassword($args{'Password'});
- print "User ". $user_obj->Name. ' Password: '. $msg . "\n";
- }
-
- #Check if we need to display the user
- if ($args{'display'}) {
- foreach my $attrib (@attributes) {
- next if ($attrib eq 'Password'); #Can't see the password
- printf("%22.22s %-64s\n",$attrib, ($user_obj->$attrib()||'(undefined)'));
-
- }
- }
-
- #Check if we need to delete the user
- if ($args{'disable'}) {
- my ($val, $msg) = $user_obj->SetDisabled(1);
- print "$msg\n";
- }
-
- }
-}
-
-# }}}
-
-# {{{ AdminQueue
-
-sub AdminQueue {
- my $queue=shift;
- my %args;
-
- GetOptions(\%args,
- 'create', 'disable|delete', 'display',
- 'Name=s', 'CorrespondAddress=s', 'Description=s',
- 'CommentAddress=s', 'InitialPriority=n', 'FinalPriority=n',
- 'DefaultDueIn=n',
-
- 'add-cc=s@', 'add-admincc=s@',
- 'delete-cc=s@', 'delete-admincc=s@',
- 'list-watchers', 'create-template'
- );
-
- use RT::Queue;
- my $queue_obj = new RT::Queue($CurrentUser);
-
- #Create the queue if we need to
- if ($args{'create'}) {
- my ($status, $msg) =
- $queue_obj->Create(
- Name => ($args{'Name'} || $queue) ,
- CorrespondAddress => $args{'CorrespondAddress'},
- Description => $args{'Description'},
- CommentAddress => $args{'CommentAddress'},
- InitialPriority => $args{'InitialPriority'},
- FinalPriority => $args{'FinalPriority'},
- DefaultDueIn => $args{'DefaultDueIn'}
- );
-
- print "$msg\n";
- }
- else {
- #Load the queue
- $queue_obj->Load($queue);
-
- unless ($queue_obj->id) {
- print "Queue '$queue' not found\n";
- return();
- }
-
- #modify if we need to
- my @attributes = qw(Name CorrespondAddress Description
- CommentAddress InitialPriority FinalPriority
- DefaultDueIn
- );
- foreach my $attrib (@attributes) {
- if ( (exists ($args{"$attrib"})) and
- ($queue_obj->$attrib() ne $args{"$attrib"})) {
-
- my $method = "Set$attrib";
- my ($val, $msg) = $queue_obj->$method($args{"$attrib"});
- print "Queue ".$queue_obj->Name. " $attrib: $msg\n";
-
- }
- }
-
-
- #Check if we need to display the queue
- if ($args{'display'}) {
- foreach my $attrib (@attributes) {
- printf("%22.22s %-64s\n",$attrib, ($queue_obj->$attrib()||'(undefined)'));
-
- }
- }
-
- foreach my $person (@{$args{'add-cc'}}) {
- my ($val, $msg) = $queue_obj->AddCc(Email => $person);
- print "$msg\n";
- }
- foreach my $person (@{$args{'add-admincc'}}) {
- my ($val, $msg) = $queue_obj->AddAdminCc(Email => $person);
- print "$msg\n";
- }
-
- foreach my $person (@{$args{'delete-cc'}}) {
- my ($val, $msg) = $queue_obj->DeleteCc($person);
- print "$msg\n";
- }
- foreach my $person (@{$args{'delete-admincc'}}) {
- my ($val, $msg) = $queue_obj->DeleteAdminCc($person);
- print "$msg\n";
- }
-
- if ($args{'list-watchers'}) {
- require RT::Watchers;
- my $watchers = new RT::Watchers($CurrentUser);
- $watchers->LimitToQueue($queue_obj->id);
- while (my $watcher = $watchers->Next()) {
- printf("%10s %-60s\n",
- $watcher->Type, $watcher->Email );
- }
- }
-
- AdminTemplates($queue_obj->Id());
- AdminScrips($queue_obj->Id());
- AdminRights($queue_obj->Id());
- AdminKeywordSelects($queue_obj->Id());
-
- #Check if we need to delete the queue
- if ($args{'disable'}) {
- my ($val, $msg) = $queue_obj->SetDisabled(1);
- print "$msg\n";
- }
-
- }
-}
-
-# }}}
-
-# {{{ AdminKeywords
-
-sub AdminKeywords {
- my $keyword = shift;
-
- my %args;
- GetOptions(\%args, 'list-children', 'create-child=s', 'disable|delete', 'Name=s', 'Description=s');
-
- use RT::Keyword;
-
- my $key_obj = new RT::Keyword($CurrentUser);
- my $key_id;
-
- #If we're dealing with the root of the keyword list
- if ($keyword eq '/') {
- $key_id=0;
- }
- else {
- my ($val, $msg) = $key_obj->LoadByPath( $keyword );
- unless ($val) {
- print $msg ."\n";
- }
- $key_id = $key_obj->Id();
- }
-
- if ($args{'create-child'}) {
- my $child = new RT::Keyword($CurrentUser);
-
- my ($val, $msg) = $child->Create( Parent => $key_id,
- Name => $args{'create-child'},
- );
- print $msg ."\n";
- }
-
- elsif ($args{'list-children'}) {
- my $keywords;
- if ($key_obj->id) {
- $keywords = $key_obj->Children();
- }
- #If we didn't actually have a keyword object, we need to create our own Keywords object.
- else {
- $keywords = new RT::Keywords($CurrentUser);
- $keywords->LimitToParent(0);
- }
-
- while (my $key=$keywords->Next) {
- print $key->Name;
- if ($key->Description) {
- print " (" . $key->Description .")";
- }
- print "\n";
- }
-
-
- }
-
- #Else we wanna do some modification.
- else {
-
- #If we didn't load a keyword, get out
- return(undef) unless ($key_obj->Id);
-
-
- my @attributes = qw( Name Description );
- foreach my $attrib (@attributes) {
- if ( (exists ($args{"$attrib"})) and
- ($key_obj->$attrib() ne $args{"$attrib"})) {
-
- my $method = "Set$attrib";
- my ($val, $msg) = $key_obj->$method($args{"$attrib"});
-
- print "Keyword ".$key_obj->Name. " $attrib: $msg\n"; }
- }
-
- if ($args{'disable'}) {
- $key_obj->SetDisabled(1);
-
- }
-
- }
-}
-
-# }}}
-
-# {{{ AdminKeywordSelects
-
-sub AdminKeywordSelects {
- my $queue = shift;
- # O for queue means global
-
- my %args;
- GetOptions(\%args, 'add-keyword-select','disable-keyword-select|delete-keyword-select=s',
- 'modify-keyword-select=s',
- 'keyword-select-Keyword|ks-keyword=s',
- 'keyword-select-Single|ks-single',
- 'keyword-select-Multiple|ks-multiple',
- 'keyword-select-Depth|ks-depth=i',
- 'keyword-select-Name|ks-name=s'
- );
-
- # sanitize single vs multiple.
- if ($args{'keyword-select-Multiple'}) {
- $args{'keyword-select-Single'} = 0;
- }
-
- use RT::KeywordSelect;
- my $keysel_obj = new RT::KeywordSelect($CurrentUser);
- if ($args{'add-keyword-select'}) {
-
- my ($val, $msg) = $keysel_obj->Create( Keyword => $args{'keyword-select-Keyword'},
- Depth => $args{'keyword-select-Depth'},
- Single => $args{'keyword-select-Single'},
- Name => $args{'keyword-select-Name'},
- ObjectType => 'Ticket',
- ObjectField => 'Queue',
- ObjectValue => $queue);
- print $msg ."\n";
- }
- elsif ($args{'modify-keyword-select'}) {
- $keysel_obj->LoadByName(Name => $args{'modify-keyword-select'},
- Queue => $queue
- );
-
- unless ($keysel_obj->Id()) {
- print "Keyword select not found\n";
- return();
- }
- my @attributes = qw( Name Keyword Single Depth );
- foreach my $attrib (@attributes) {
- if ( (exists ($args{"keyword-select-$attrib"})) and
- ($keysel_obj->$attrib() ne $args{"keyword-select-$attrib"})) {
-
- my $method = "Set$attrib";
- my ($val, $msg) = $keysel_obj->$method($args{"keyword-select-$attrib"});
-
- print "Keyword select ".$keysel_obj->Name. " $attrib: $msg\n"; }
- }
-
-
- }
-
-
- elsif ($args{'disable-keyword-select'}) {
- $keysel_obj->LoadByName(Name => $args{'disable-keyword-select'},
- Queue => $queue);
-
- $keysel_obj->SetDisabled(1);
-
- }
-}
-
-# }}}
-
-# {{{ AdminGroup
-
-sub AdminGroup {
- my $group = shift;
-
- my (%args);
-
- GetOptions(\%args,
- 'create', 'delete', 'display',
- 'Name=s', 'Description=s',
-
- 'add-member=s@', 'delete-member=s@',
- 'list-members'
- );
-
-
- use RT::Group;
- my $group_obj = new RT::Group($CurrentUser);
- unless ($group) {
- print "Group not specified.\n";
- return();
- }
-
-
- #Create the group if we need to
- if ($args{'create'}) {
- my ($val, $msg) = $group_obj->Create( Name => ($args{'Name'} || $group),
- Description => $args{'Description'} );
- print $msg ."\n";
- }
- #otherwise we load it
- else {
- $group_obj->Load($group);
- }
-
- #If we have no group object, get the hell out
- unless ($group_obj->Id) {
- print "Group not found.\n";
- }
-
- if ($args{'delete'}) {
- my ($val, $msg) = $group_obj->Delete();
- print $msg ."\n";
- return();
- }
-
-
-
- #modify if we need to
- my @attributes = qw(Name Description
-
- );
- foreach my $attrib (@attributes) {
- if ( (exists ($args{"$attrib"})) and
- ($group_obj->$attrib() ne $args{"$attrib"})) {
-
- my $method = "Set$attrib";
- my ($val, $msg) = $group_obj->$method($args{"$attrib"});
- print "Group ".$group_obj->Name. " $attrib: $msg\n";
-
- }
- }
-
- foreach my $user (@{$args{'add-member'}}) {
- my ($val, $msg) = $group_obj->AddMember($user);
- print $msg. "\n";
- }
- foreach my $user (@{$args{'delete-member'}}) {
- my ($val, $msg) = $group_obj->DeleteMember($user);
- print $msg ."\n";
- }
-
- if ($args{'list-members'}) {
- my $members = $group_obj->MembersObj();
- while (my $member = $members->Next()) {
- print $member->UserObj->Name() ."\n";
- }
- }
-
-}
-
-# }}}
-
-# {{{ AdminSystem
-sub AdminSystem {
- print "In AdminSystem\n";
-
- AdminTemplates(0);
- AdminScrips(0);
- AdminRights(0);
- AdminKeywordSelects(0);
-}
-# }}}
-
-# {{{ sub AdminTemplates
-
-sub AdminTemplates {
- my $queue = shift;
- #Queue = 0 means 'global';
-
- my %args;
-
-
- GetOptions(\%args, 'list-templates', 'create-template','modify-template=s',
- 'delete-template=s', 'display-template=s',
- 'template-Name=s', 'template-Description=s',
- 'template-edit-content!');
-
- # {{{ List templates
- if ($args{'list-templates'}) {
- print "Templates for $queue\n";
- require RT::Templates;
- my $templates = new RT::Templates($CurrentUser);
- if ($queue != 0) {
- $templates->LimitToQueue($queue);
- }
- else {
- $templates->LimitToGlobal();
- }
- while (my $template = $templates->Next) {
- print $template->Id.": ".$template->Name." - " . $template->Description ."\n";
- }
- }
-
- # }}}
-
- require RT::Template;
- my $template = new RT::Template($CurrentUser);
- if ($args{'delete-template'}) {
- $template->Load($args{'delete-template'});
- unless ($template->id) {
- print "Couldn't load template";
- return(undef);
- }
- my ($val, $msg) = $template->Delete();
- print "$msg\n";
- }
- elsif ($args{'create-template'}) {
- #TODO edit the template content
- my $content;
-
- my $linesref = GetMessageContent(CurrentUser => $CurrentUser,
- Edit => 1);
-
- $content = join("\n", @{$linesref});
-
-
- my ($val, $msg) = $template->Create(Name => $args{'template-Name'},
- Description => $args{'template-Description'},
- Content => $content,
- Queue => $queue);
- print "$msg\n";
- }
- elsif ($args{'modify-template'}) {
-
- $template->Load($args{'modify-template'});
- unless ($template->Id()) {
- print "Template not found\n";
- return();
- }
- my @attributes = qw( Name Description );
- foreach my $attrib (@attributes) {
- if ( (exists ($args{"template-$attrib"})) and
- ($template->$attrib() ne $args{"template-$attrib"})) {
-
- my $method = "Set$attrib";
- my $val = $template->$method($args{"template-$attrib"});
-
- }
- }
- if ($args{'template-edit-content'}) {
-
- my $linesref = GetMessageContent(CurrentUser => $CurrentUser,
- Content => $template->Content,
- Edit => 1);
-
- my $content = join("\n", @{$linesref});
- my ($val) = $template->SetContent($content);
- print $val."\n";
- }
-
- }
- if ($args{'display-template'}) {
- $template->Load($args{'display-template'});
- print $template->Name . "\n". $template->Description ."\n". $template->Content."\n";
- }
-}
-
-# }}}
-
-# {{{ sub AdminScrips
-
-sub AdminScrips {
- my $queue = shift;
- #Queue = 0 means 'global';
-
- my %args;
-
-
- GetOptions(\%args, 'list-scrips', 'create-scrip','modify-scrip=s',
- 'scrip-action=s', 'scrip-template=s', 'scrip-condition=s',
- 'delete-scrip=s');
-
-
- # {{{ List entries
- if ($args{'list-scrips'}) {
- print "Scrips for $queue\n";
- require RT::Scrips;
- my $scrips = new RT::Scrips($CurrentUser);
- if ($queue != 0) {
- $scrips->LimitToQueue($queue);
- }
- else {
- $scrips->LimitToGlobal();
- }
- while (my $scrip = $scrips->Next) {
- print $scrip->Id.": If ".
- $scrip->ConditionObj->Name." then " .
- $scrip->ActionObj->Name." with template " .
- $scrip->TemplateObj->Name."\n";
- }
- }
-
- # }}}
-
- require RT::Scrip;
- my $scrip = new RT::Scrip($CurrentUser);
- if ($args{'delete-scrip'}) {
- $scrip->Load($args{'delete-scrip'});
- unless ($scrip->id) {
- print "Couldn't load scrip";
- return(undef);
- }
- my ($val, $msg) = $scrip->Delete();
- print "$msg\n";
- }
- elsif ($args{'create-scrip'}) {
- my ($val, $msg) = $scrip->Create( ScripAction => $args{'scrip-action'},
- ScripCondition => $args{'scrip-condition'},
- Template => $args{'scrip-template'},
- Queue => $queue);
-
- print "$msg\n";
- }
-}
-
-# }}}
-
-# {{{ sub AdminRights
-
-sub AdminRights {
- my $queue = shift;
- #Queue = 0 means 'global';
-
- my ($scope, $appliesto);
- if ($queue == 0) {
- $scope = 'System';
- $appliesto = 0;
- }
- else {
- $scope = 'Queue';
- $appliesto = $queue;
- }
-
- my %args;
- GetOptions(\%args,
- 'grant-right|add-right|new-right|create-right=s@',
- 'revoke-right|del-right|delete-right=s@',
- 'list-rights', 'userid=s@', 'groupid=s@',
- );
-
-
- # {{{ List entries
- if ($args{'list-rights'}) {
- require RT::ACL;
- my $acl = new RT::ACL($CurrentUser);
- if ($queue != 0) {
- $acl->LimitToQueue($queue);
- }
- else {
- $acl->LimitToSystem();
- }
- while (my $ace = $acl->Next) {
- print $ace->RightScope;
-
- #Print the queue name if we have it.
- print " " . $ace->AppliesToObj->Name if (defined $ace->AppliesToObj);
-
- print ": ". $ace->PrincipalType . " " .$ace->PrincipalObj->Name .
- " has right " . $ace->RightName ."\n";
-
- }
- }
-
- # }}}
-
- require RT::ACE;
-
- # {{{ Build up an array of principals
- my (@principals);
- my $i = 0;
- foreach my $group (@{$args{'groupid'}}) {
-
-
- my $princ = new RT::Group($CurrentUser);
- $princ->Load("$group");
- if ($princ->id) {
- $principals[$i]->{'type'} = 'Group';
- $principals[$i]->{'id'} = $princ->id();
- $i++;
- }
- else {
- print "Could not find group $group\n";
- }
- }
-
-
- foreach my $user (@{$args{'userid'}}) {
- my $princ = new RT::User($CurrentUser);
- $princ->Load("$user");
- if ($princ->id) {
- $principals[$i]->{'type'} = 'User';
- $principals[$i]->{'id'} = $princ->id();
- $i++;
- }
- else {
- print "Could not find user $user.\n";
- }
- }
- # }}}
-
-
- foreach my $principal (@principals) {
-
- # {{{ Delete rights that need deleting
- foreach my $right (@{$args{'revoke-right'}}) {
- my $ace = new RT::ACE($CurrentUser);
- $RT::Logger->debug("Trying to delete a right: $right \n");
- my ($val, $msg) = $ace->LoadByValues( RightName => $right,
- RightScope => $scope,
- PrincipalType => $principal->{'type'},
- PrincipalId => $principal->{'id'},
- RightAppliesTo => $appliesto);
-
- unless ($val) {
- print "Right $right not found for" . $principal->{'type'} . " " .
- $principal->{'id'} . " in scope $scope ($appliesto)\n";
- next;
- }
- my ($delval, $delmsg) =$ace->Delete;
- print "$delmsg\n";
-
-
- }
-
- # }}}
-
- # {{{ grant rights that need granting
- foreach my $right (@{$args{'grant-right'}}) {
- my $ace = new RT::ACE($CurrentUser);
- my ($val, $msg) = $ace->Create(RightName => $right,
- PrincipalType => $principal->{'type'},
- PrincipalId => $principal->{'id'},
- RightScope => $scope,
- RightAppliesTo => $appliesto);
-
- print $msg . "\n";
- }
-
- # }}}
- }
-
-}
-
-# }}}
-
-
-sub ListUsers {
- require RT::Users;
- my $users = new RT::Users($CurrentUser);
- $users->UnLimit();
- while (my $user = $users->Next()) {
- printf ("%16s %-16s\n",$user->Name(), $user->EmailAddress());
- }
-}
-sub ListQueues {
- require RT::Queues;
- my $queues = new RT::Queues($CurrentUser);
- $queues->UnLimit();
- while (my $queue = $queues->Next()) {
- printf ("%16s %-16s\n",$queue->Name(), $queue->Description());
- }
-}
-
-sub ListGroups {
- require RT::Groups;
- my $groups = new RT::Groups($CurrentUser);
- $groups->UnLimit();
- while (my $group = $groups->Next()) {
- printf ("%16s %-16s\n",$group->Name(), $group->Description());
- }
-}
diff --git a/rt/bin/webmux.pl b/rt/bin/webmux.pl
index 6e1ae06de..21cb83f5e 100755
--- a/rt/bin/webmux.pl
+++ b/rt/bin/webmux.pl
@@ -1,177 +1,125 @@
-# $Header: /home/cvs/cvsroot/freeside/rt/bin/Attic/webmux.pl,v 1.1 2002-08-12 06:17:07 ivan Exp $
-# RT is (c) 1996-2000 Jesse Vincent (jesse@fsck.com);
+#!/usr/bin/perl
+# BEGIN LICENSE BLOCK
+#
+# Copyright (c) 1996-2003 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
use strict;
-$ENV{'PATH'} = '/bin:/usr/bin'; # or whatever you need
-$ENV{'CDPATH'} = '' if defined $ENV{'CDPATH'};
-$ENV{'SHELL'} = '/bin/sh' if defined $ENV{'SHELL'};
-$ENV{'ENV'} = '' if defined $ENV{'ENV'};
-$ENV{'IFS'} = '' if defined $ENV{'IFS'};
+BEGIN {
+ $ENV{'PATH'} = '/bin:/usr/bin'; # or whatever you need
+ $ENV{'CDPATH'} = '' if defined $ENV{'CDPATH'};
+ $ENV{'SHELL'} = '/bin/sh' if defined $ENV{'SHELL'};
+ $ENV{'ENV'} = '' if defined $ENV{'ENV'};
+ $ENV{'IFS'} = '' if defined $ENV{'IFS'};
+}
-# We really don't want apache to try to eat all vm
-# see http://perl.apache.org/guide/control.html#Preventing_mod_perl_Processes_Fr
-
+use lib ("/opt/rt3/local/lib", "/opt/rt3/lib");
+use RT;
package RT::Mason;
-use CGI qw(-private_tempfiles); #bring this in before mason, to make sure we
- #set private_tempfiles
-use HTML::Mason::ApacheHandler (args_method => 'CGI');
-use HTML::Mason; # brings in subpackages: Parser, Interp, etc.
-
-use vars qw($VERSION %session $Nobody $SystemUser $r $m);
+use CGI qw(-private_tempfiles); #bring this in before mason, to make sure we
+ #set private_tempfiles
-# List of modules that you want to use from components (see Admin
-# manual for details)
-
-#Clean up our umask...so that the session files aren't world readable, writable or executable
-umask(0077);
+BEGIN {
+ if ($CGI::MOD_PERL) {
+ require HTML::Mason::ApacheHandler;
+ }
+ else {
+ require HTML::Mason::CGIHandler;
+ }
+}
+use HTML::Mason; # brings in subpackages: Parser, Interp, etc.
-
-$VERSION="!!RT_VERSION!!";
+use vars qw($Nobody $SystemUser $r);
-use lib "!!RT_LIB_PATH!!";
-use lib "!!RT_ETC_PATH!!";
+#This drags in RT's config.pm
+RT::LoadConfig();
-#This drags in RT's config.pm
-use config;
use Carp;
-{
- package HTML::Mason::Commands;
- use vars qw(%session $m);
-
- use RT;
- use RT::Ticket;
- use RT::Tickets;
- use RT::Transaction;
- use RT::Transactions;
- use RT::User;
- use RT::Users;
- use RT::CurrentUser;
- use RT::Template;
- use RT::Templates;
- use RT::Queue;
- use RT::Queues;
- use RT::ScripAction;
- use RT::ScripActions;
- use RT::ScripCondition;
- use RT::ScripConditions;
- use RT::Scrip;
- use RT::Scrips;
- use RT::Group;
- use RT::Groups;
- use RT::Keyword;
- use RT::Keywords;
- use RT::ObjectKeyword;
- use RT::ObjectKeywords;
- use RT::KeywordSelect;
- use RT::KeywordSelects;
- use RT::GroupMember;
- use RT::GroupMembers;
- use RT::Watcher;
- use RT::Watchers;
- use RT::Handle;
- use RT::Interface::Web;
- use MIME::Entity;
- use Text::Wrapper;
- use Apache::Cookie;
- use Date::Parse;
- use HTML::Entities;
-
- #TODO: make this use DBI
- use Apache::Session::File;
-
- # Set this page's content type to whatever we are called with
- sub SetContentType {
- my $type = shift;
- $RT::Mason::r->content_type($type);
- }
-
- sub CGIObject {
- $m->cgi_object();
- }
-
- }
-my ($parser, $interp, $ah);
-if ($HTML::Mason::VERSION < 1.0902) {
- $parser = &RT::Interface::Web::NewParser(allow_globals => [%session]);
-
- $interp = &RT::Interface::Web::NewInterp(parser=>$parser,
- allow_recursive_autohandlers => 1,
- );
-
- $ah = &RT::Interface::Web::NewApacheHandler($interp);
-} else {
- $ah = &RT::Interface::Web::NewMason11ApacheHandler();
+{
+ package HTML::Mason::Commands;
+ use vars qw(%session);
+
+ use RT::Tickets;
+ use RT::Transactions;
+ use RT::Users;
+ use RT::CurrentUser;
+ use RT::Templates;
+ use RT::Queues;
+ use RT::ScripActions;
+ use RT::ScripConditions;
+ use RT::Scrips;
+ use RT::Groups;
+ use RT::GroupMembers;
+ use RT::CustomFields;
+ use RT::CustomFieldValues;
+ use RT::TicketCustomFieldValues;
+
+ use RT::Interface::Web;
+ use MIME::Entity;
+ use Text::Wrapper;
+ use CGI::Cookie;
+ use Time::ParseDate;
+ use HTML::Entities;
}
-# Activate the following if running httpd as root (the normal case).
-# Resets ownership of all files created by Mason at startup.
-#
-chown (Apache->server->uid, Apache->server->gid,
- [$RT::MasonSessionDir]);
-
-
-chown (Apache->server->uid, Apache->server->gid,
- $ah->interp->files_written);
-# Die if WebSessionDir doesn't exist or we can't write to it
-stat ($RT::MasonSessionDir);
-die "Can't read and write $RT::MasonSessionDir"
- unless (( -d _ ) and ( -r _ ) and ( -w _ ));
+# Activate the following if running httpd as root (the normal case).
+# Resets ownership of all files created by Mason at startup.
+# Note that mysql uses DB for sessions, so there's no need to do this.
+unless ($RT::DatabaseType =~ /(mysql|Pg)/) {
+ # Clean up our umask to protect session files
+ umask(0077);
+
+if ( $CGI::MOD_PERL) {
+ chown( Apache->server->uid, Apache->server->gid, [$RT::MasonSessionDir] )
+ if Apache->server->can('uid');
+ }
+ # Die if WebSessionDir doesn't exist or we can't write to it
+ stat($RT::MasonSessionDir);
+ die "Can't read and write $RT::MasonSessionDir"
+ unless ( ( -d _ ) and ( -r _ ) and ( -w _ ) );
+}
+my $ah = &RT::Interface::Web::NewApacheHandler() if $CGI::MOD_PERL;
sub handler {
($r) = @_;
-
+
RT::Init();
-
+
# We don't need to handle non-text items
- return -1 if defined($r->content_type) && $r->content_type !~ m|^text/|io;
-
- #This is all largely cut and pasted from mason's session_handler.pl
-
- my %cookies = Apache::Cookie::parse($r->header_in('Cookie'));
-
- eval {
- tie %HTML::Mason::Commands::session, 'Apache::Session::File',
- ( $cookies{'AF_SID'} ? $cookies{'AF_SID'}->value() : undef ),
- { Directory => $RT::MasonSessionDir,
- LockDirectory => $RT::MasonSessionDir,
- } ;
- };
-
- if ( $@ ) {
- # If the session is invalid, create a new session.
- if ( $@ =~ m#^Object does not exist in the data store# ) {
- tie %HTML::Mason::Commands::session, 'Apache::Session::File', undef,
- { Directory => $RT::MasonSessionDir,
- LockDirectory => $RT::MasonSessionDir,
- };
- undef $cookies{'AF_SID'};
- }
- else {
- die "RT Couldn't write to session directory '$RT::MasonSessionDir'. Check that this directory's permissions are correct.";
- }
- }
-
- if ( !$cookies{'AF_SID'} ) {
- my $cookie = new Apache::Cookie
- ($r,
- -name=>'AF_SID',
- -value=>$HTML::Mason::Commands::session{_session_id},
- -path => '/',);
- $cookie->bake;
+ return -1 if defined( $r->content_type ) && $r->content_type !~ m|^text/|io;
- }
+ my %session;
my $status = $ah->handle_request($r);
- untie %HTML::Mason::Commands::session;
-
+ undef (%session);
+
+ $RT::Logger->crit("Transaction not committed. Usually indicates a software fault. Data loss may have occurred") if $RT::Handle->TransactionDepth;
return $status;
-
- }
-1;
+}
+1;