summaryrefslogtreecommitdiff
path: root/rt/lib/RT/Interface
diff options
context:
space:
mode:
authorivan <ivan>2005-10-15 09:11:20 +0000
committerivan <ivan>2005-10-15 09:11:20 +0000
commit673b9a458d9138523026963df6fa3b4683e09bae (patch)
tree42acc524ff5fd53e4fdb2f5b6dac4a42ce8057f6 /rt/lib/RT/Interface
parent591613cf1c861505335646fff3ffb4a705e011bf (diff)
parentd4d0590bef31071e8809ec046717444b95b3f30a (diff)
This commit was generated by cvs2svn to compensate for changes in r4407,
which included commits to RCS files with non-trunk default branches.
Diffstat (limited to 'rt/lib/RT/Interface')
-rwxr-xr-xrt/lib/RT/Interface/Email/Auth/GnuPG.pm6
-rw-r--r--rt/lib/RT/Interface/Email/Auth/MailFrom.pm36
-rw-r--r--rt/lib/RT/Interface/Email/Filter/SpamAssassin.pm27
-rw-r--r--rt/lib/RT/Interface/REST.pm8
-rw-r--r--rt/lib/RT/Interface/Web/Handler.pm81
-rwxr-xr-xrt/lib/RT/Interface/Web/QueryBuilder.pm56
-rwxr-xr-xrt/lib/RT/Interface/Web/QueryBuilder/Tree.pm245
-rwxr-xr-xrt/lib/RT/Interface/Web/Standalone.pm37
8 files changed, 458 insertions, 38 deletions
diff --git a/rt/lib/RT/Interface/Email/Auth/GnuPG.pm b/rt/lib/RT/Interface/Email/Auth/GnuPG.pm
index 724b1b3fc..2dfada755 100755
--- a/rt/lib/RT/Interface/Email/Auth/GnuPG.pm
+++ b/rt/lib/RT/Interface/Email/Auth/GnuPG.pm
@@ -1,8 +1,8 @@
-# {{{ BEGIN BPS TAGGED BLOCK
+# BEGIN BPS TAGGED BLOCK {{{
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2004 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
# <jesse@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -42,7 +42,7 @@
# works based on those contributions, and sublicense and distribute
# those contributions and any derivatives thereof.
#
-# }}} END BPS TAGGED BLOCK
+# END BPS TAGGED BLOCK }}}
#
package RT::Interface::Email::Auth::GnuPG;
use Mail::GnuPG;
diff --git a/rt/lib/RT/Interface/Email/Auth/MailFrom.pm b/rt/lib/RT/Interface/Email/Auth/MailFrom.pm
index 0efadb1cd..ef315dd53 100644
--- a/rt/lib/RT/Interface/Email/Auth/MailFrom.pm
+++ b/rt/lib/RT/Interface/Email/Auth/MailFrom.pm
@@ -1,8 +1,8 @@
-# {{{ BEGIN BPS TAGGED BLOCK
+# BEGIN BPS TAGGED BLOCK {{{
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2004 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
# <jesse@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -42,7 +42,7 @@
# works based on those contributions, and sublicense and distribute
# those contributions and any derivatives thereof.
#
-# }}} END BPS TAGGED BLOCK
+# END BPS TAGGED BLOCK }}}
package RT::Interface::Email::Auth::MailFrom;
use RT::Interface::Email qw(ParseSenderAddressFromHead CreateUser);
@@ -122,6 +122,36 @@ sub GetCurrentUser {
}
}
+ elsif ( $args{'Action'} =~ /^take$/i ) {
+
+ # check to see whether "Everybody" or "Unprivileged users" can correspond on tickets
+ unless ( $everyone->PrincipalObj->HasRight(Object => $args{'Queue'},
+ Right => 'OwnTicket'
+ )
+ || $unpriv->PrincipalObj->HasRight(
+ Object => $args{'Queue'},
+ Right => 'OwnTicket'
+ )
+ ) {
+ return ( $args{'CurrentUser'}, 0 );
+ }
+
+ }
+ elsif ( $args{'Action'} =~ /^resolve$/i ) {
+
+ # check to see whether "Everybody" or "Unprivileged users" can correspond on tickets
+ unless ( $everyone->PrincipalObj->HasRight(Object => $args{'Queue'},
+ Right => 'ModifyTicket'
+ )
+ || $unpriv->PrincipalObj->HasRight(
+ Object => $args{'Queue'},
+ Right => 'ModifyTicket'
+ )
+ ) {
+ return ( $args{'CurrentUser'}, 0 );
+ }
+
+ }
else {
return ( $args{'CurrentUser'}, 0 );
}
diff --git a/rt/lib/RT/Interface/Email/Filter/SpamAssassin.pm b/rt/lib/RT/Interface/Email/Filter/SpamAssassin.pm
index 8c9eae88c..c552d76e6 100644
--- a/rt/lib/RT/Interface/Email/Filter/SpamAssassin.pm
+++ b/rt/lib/RT/Interface/Email/Filter/SpamAssassin.pm
@@ -1,8 +1,8 @@
-# {{{ BEGIN BPS TAGGED BLOCK
+# BEGIN BPS TAGGED BLOCK {{{
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2004 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
# <jesse@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -42,22 +42,31 @@
# works based on those contributions, and sublicense and distribute
# those contributions and any derivatives thereof.
#
-# }}} END BPS TAGGED BLOCK
+# END BPS TAGGED BLOCK }}}
package RT::Interface::Email::Filter::SpamAssassin;
use Mail::SpamAssassin;
my $spamtest = Mail::SpamAssassin->new();
sub GetCurrentUser {
- my $item = shift;
- my $status = $spamtest->check ($item);
- return (undef, 0) unless $status->is_spam();
+ my %args = (
+ Message => undef,
+ CurrentUser => undef,
+ AuthLevel => undef,
+ @_
+ );
+ my $status = $spamtest->check( $args{'Message'} );
+ return ( $args{'CurrentUser'}, $args{'AuthLevel'} )
+ unless $status->is_spam();
+
eval { $status->rewrite_mail() };
- if ($status->get_hits > $status->get_required_hits()*1.5) {
+ if ( $status->get_hits > $status->get_required_hits() * 1.5 ) {
+
# Spammy indeed
- return (undef, -1);
+ return ( $args{'CurrentUser'}, -1 );
}
- return (undef, 0);
+ return ( $args{'CurrentUser'}, $args{'AuthLevel'} );
+
}
=head1 NAME
diff --git a/rt/lib/RT/Interface/REST.pm b/rt/lib/RT/Interface/REST.pm
index 8c8baa1e7..279ddf4b3 100644
--- a/rt/lib/RT/Interface/REST.pm
+++ b/rt/lib/RT/Interface/REST.pm
@@ -1,8 +1,8 @@
-# {{{ BEGIN BPS TAGGED BLOCK
+# BEGIN BPS TAGGED BLOCK {{{
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2004 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
# <jesse@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -42,7 +42,7 @@
# works based on those contributions, and sublicense and distribute
# those contributions and any derivatives thereof.
#
-# }}} END BPS TAGGED BLOCK
+# END BPS TAGGED BLOCK }}}
# lib/RT/Interface/REST.pm
#
@@ -54,7 +54,7 @@ BEGIN {
use Exporter ();
use vars qw($VERSION @ISA @EXPORT);
- $VERSION = do { my @r = (q$Revision: 1.1.1.2 $ =~ /\d+/g); sprintf "%d."."%02d"x$#r, @r };
+ $VERSION = do { my @r = (q$Revision: 1.1.1.3 $ =~ /\d+/g); sprintf "%d."."%02d"x$#r, @r };
@ISA = qw(Exporter);
@EXPORT = qw(expand_list form_parse form_compose vpush vsplit);
diff --git a/rt/lib/RT/Interface/Web/Handler.pm b/rt/lib/RT/Interface/Web/Handler.pm
index 7ee654e7c..ce9222586 100644
--- a/rt/lib/RT/Interface/Web/Handler.pm
+++ b/rt/lib/RT/Interface/Web/Handler.pm
@@ -1,8 +1,8 @@
-# {{{ BEGIN BPS TAGGED BLOCK
+# BEGIN BPS TAGGED BLOCK {{{
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2004 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
# <jesse@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -42,9 +42,24 @@
# works based on those contributions, and sublicense and distribute
# those contributions and any derivatives thereof.
#
-# }}} END BPS TAGGED BLOCK
+# END BPS TAGGED BLOCK }}}
+
package RT::Interface::Web::Handler;
+use CGI qw/-private_tempfiles/;
+use MIME::Entity;
+use Text::Wrapper;
+use CGI::Cookie;
+use Time::ParseDate;
+use Time::HiRes;
+use HTML::Entities;
+use HTML::Scrubber;
+use Text::Quoted;
+use RT::Interface::Web::Handler;
+use File::Path qw( rmtree );
+use File::Glob qw( bsd_glob );
+use File::Spec::Unix;
+
sub DefaultHandlerArgs { (
comp_root => [
[ local => $RT::MasonLocalComponentRoot ],
@@ -53,7 +68,10 @@ sub DefaultHandlerArgs { (
default_escape_flags => 'h',
data_dir => "$RT::MasonDataDir",
allow_globals => [qw(%session)],
- autoflush => 1
+ # Turn off static source if we're in developer mode.
+ static_source => ($RT::DevelMode ? '0' : '1'),
+ use_object_files => ($RT::DevelMode ? '0' : '1'),
+ autoflush => 0
) };
# {{{ sub new
@@ -69,19 +87,17 @@ sub new {
my $class = shift;
$class->InitSessionDir;
- if ($MasonX::Apache2Handler::VERSION) {
- goto &NewApache2Handler;
- }
- elsif ($mod_perl::VERSION and $mod_perl::VERSION >= 1.9908) {
- require Apache::RequestUtil;
- no warnings 'redefine';
- my $sub = *Apache::request{CODE};
- *Apache::request = sub {
- my $r;
- eval { $r = $sub->('Apache'); };
- # warn $@ if $@;
- return $r;
- };
+ if ( $mod_perl::VERSION && $mod_perl::VERSION >= 1.9908 ) {
+# require Apache::RequestUtil;
+# no warnings 'redefine';
+# my $sub = *Apache::request{CODE};
+# *Apache::request = sub {
+# my $r;
+# eval { $r = $sub->('Apache'); };
+#
+# # warn $@ if $@;
+# return $r;
+# };
goto &NewApacheHandler;
}
elsif ($CGI::MOD_PERL) {
@@ -96,14 +112,14 @@ sub InitSessionDir {
# 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)/ ) {
+ 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] )
+ $RT::MasonSessionDir )
if Apache->server->can('uid');
}
@@ -170,9 +186,36 @@ sub NewHandler {
);
$handler->interp->set_escape( h => \&RT::Interface::Web::EscapeUTF8 );
+ $handler->interp->set_escape( u => \&RT::Interface::Web::EscapeURI );
return($handler);
}
+=head2 CleanupRequest
+
+Rollback any uncommitted transaction.
+Flush the ACL cache
+Flush the searchbuilder query cache
+
+=cut
+
+sub CleanupRequest {
+
+ if ( $RT::Handle->TransactionDepth ) {
+ $RT::Handle->ForceRollback;
+ $RT::Logger->crit(
+ "Transaction not committed. Usually indicates a software fault."
+ . "Data loss may have occurred" );
+ }
+
+ # Clean out the ACL cache. the performance impact should be marginal.
+ # Consistency is imprived, too.
+ RT::Principal->InvalidateACLCache();
+ DBIx::SearchBuilder::Record::Cachable->FlushCache
+ if ( $RT::WebFlushDbCacheEveryRequest
+ and UNIVERSAL::can(
+ 'DBIx::SearchBuilder::Record::Cachable' => 'FlushCache' ) );
+
+}
# }}}
1;
diff --git a/rt/lib/RT/Interface/Web/QueryBuilder.pm b/rt/lib/RT/Interface/Web/QueryBuilder.pm
new file mode 100755
index 000000000..b7526b30a
--- /dev/null
+++ b/rt/lib/RT/Interface/Web/QueryBuilder.pm
@@ -0,0 +1,56 @@
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+# <jesse@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
+# This work is made available to you under the terms of Version 2 of
+# the GNU General Public License. A copy of that license should have
+# been provided with this software, but in any event can be snarfed
+# from www.gnu.org.
+#
+# This work is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+package RT::Interface::Web::QueryBuilder;
+
+use strict;
+use warnings;
+
+eval "require RT::Interface::Web::QueryBuilder_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Web/QueryBuilder_Vendor.pm});
+eval "require RT::Interface::Web::QueryBuilder_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Web/QueryBuilder_Local.pm});
+
+1;
diff --git a/rt/lib/RT/Interface/Web/QueryBuilder/Tree.pm b/rt/lib/RT/Interface/Web/QueryBuilder/Tree.pm
new file mode 100755
index 000000000..67b728339
--- /dev/null
+++ b/rt/lib/RT/Interface/Web/QueryBuilder/Tree.pm
@@ -0,0 +1,245 @@
+# BEGIN BPS TAGGED BLOCK {{{
+#
+# COPYRIGHT:
+#
+# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
+# <jesse@bestpractical.com>
+#
+# (Except where explicitly superseded by other copyright notices)
+#
+#
+# LICENSE:
+#
+# This work is made available to you under the terms of Version 2 of
+# the GNU General Public License. A copy of that license should have
+# been provided with this software, but in any event can be snarfed
+# from www.gnu.org.
+#
+# This work is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#
+# CONTRIBUTION SUBMISSION POLICY:
+#
+# (The following paragraph is not intended to limit the rights granted
+# to you to modify and distribute this software under the terms of
+# the GNU General Public License and is only of importance to you if
+# you choose to contribute your changes and enhancements to the
+# community by submitting them to Best Practical Solutions, LLC.)
+#
+# By intentionally submitting any modifications, corrections or
+# derivatives to this work, or any other work intended for use with
+# Request Tracker, to Best Practical Solutions, LLC, you confirm that
+# you are the copyright holder for those contributions and you grant
+# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
+# royalty-free, perpetual, license to use, copy, create derivative
+# works based on those contributions, and sublicense and distribute
+# those contributions and any derivatives thereof.
+#
+# END BPS TAGGED BLOCK }}}
+package RT::Interface::Web::QueryBuilder::Tree;
+
+use strict;
+use warnings;
+
+use base qw/Tree::Simple/;
+
+=head1 NAME
+
+ RT::Interface::Web::QueryBuilder::Tree - subclass of Tree::Simple used in Query Builder
+
+=head1 DESCRIPTION
+
+This class provides support functionality for the Query Builder (Search/Build.html).
+It is a subclass of L<Tree::Simple>.
+
+=head1 METHODS
+
+=head2 TraversePrePost PREFUNC POSTFUNC
+
+Traverses the tree depth-first. Before processing the node's children,
+calls PREFUNC with the node as its argument; after processing all of the
+children, calls POSTFUNC with the node as its argument.
+
+(Note that unlike Tree::Simple's C<traverse>, it actually calls its functions
+on the root node passed to it.)
+
+=cut
+
+sub TraversePrePost {
+ my ($self, $prefunc, $postfunc) = @_;
+
+ $prefunc->($self);
+
+ foreach my $child ($self->getAllChildren()) {
+ $child->TraversePrePost($prefunc, $postfunc);
+ }
+
+ $postfunc->($self);
+}
+
+=head2 GetReferencedQueues
+
+Returns a hash reference with keys each queue name referenced in a clause in
+the key (even if it's "Queue != 'Foo'"), and values all 1.
+
+=cut
+
+sub GetReferencedQueues {
+ my $self = shift;
+
+ my $queues = {};
+
+ $self->traverse(
+ sub {
+ my $node = shift;
+
+ return if $node->isRoot;
+
+ my $clause = $node->getNodeValue();
+
+ if ( ref($clause) and $clause->{Key} eq 'Queue' ) {
+ $queues->{ $clause->{Value} } = 1;
+ };
+ }
+ );
+
+ return $queues;
+}
+
+=head2 GetQueryAndOptionList SELECTED_NODES
+
+Given an array reference of tree nodes that have been selected by the user,
+traverses the tree and returns the equivalent SQL query and a list of hashes
+representing the "clauses" select option list. Each has contains the keys
+TEXT, INDEX, SELECTED, and DEPTH. TEXT is the displayed text of the option
+(including parentheses, not including indentation); INDEX is the 0-based
+index of the option in the list (also used as its CGI parameter); SELECTED
+is either 'SELECTED' or '', depending on whether the node corresponding
+to the select option was in the SELECTED_NODES list; and DEPTH is the
+level of indentation for the option.
+
+=cut
+
+sub GetQueryAndOptionList {
+ my $self = shift;
+ my $selected_nodes = shift;
+
+ my $optionlist = [];
+
+ my $i = 0;
+
+ $self->TraversePrePost(
+ sub { # This is called before recursing to the node's children.
+ my $node = shift;
+
+ return if $node->isRoot or $node->getParent->isRoot;
+
+ my $clause = $node->getNodeValue();
+ my $str = ' ';
+ my $aggregator_context = $node->getParent()->getNodeValue();
+ $str = $aggregator_context . " " if $node->getIndex() > 0;
+
+ if ( ref($clause) ) { # ie, it's a leaf
+ $str .=
+ $clause->{Key} . " " . $clause->{Op} . " " . $clause->{Value};
+ }
+
+ unless ($node->getParent->getParent->isRoot) {
+ # used to check !ref( $parent->getNodeValue() ) )
+ if ( $node->getIndex() == 0 ) {
+ $str = '( ' . $str;
+ }
+ }
+
+ push @$optionlist, {
+ TEXT => $str,
+ INDEX => $i,
+ SELECTED => (grep { $_ == $node } @$selected_nodes) ? 'SELECTED' : '',
+ DEPTH => $node->getDepth() - 1,
+ };
+
+ $i++;
+ }, sub {
+ # This is called after recursing to the node's children.
+ my $node = shift;
+
+ return if $node->isRoot or $node->getParent->isRoot or $node->getParent->getParent->isRoot;
+
+ # Only do this for the rightmost child.
+ return unless $node->getIndex == $node->getParent->getChildCount - 1;
+
+ $optionlist->[-1]{TEXT} .= ' )';
+ }
+ );
+
+ return (join ' ', map { $_->{TEXT} } @$optionlist), $optionlist;
+}
+
+=head2 PruneChildLessAggregators
+
+If tree manipulation has left it in a state where there are ANDs, ORs,
+or parenthesizations with no children, get rid of them.
+
+=cut
+
+sub PruneChildlessAggregators {
+ my $self = shift;
+
+ $self->TraversePrePost(
+ sub {
+ },
+ sub {
+ my $node = shift;
+
+ return if $node->isRoot or $node->getParent->isRoot;
+
+ # We're only looking for aggregators (AND/OR)
+ return if ref $node->getNodeValue;
+
+ return if $node->getChildCount != 0;
+
+ # OK, this is a childless aggregator. Remove self.
+
+ $node->getParent->removeChild($node);
+
+ # Deal with circular refs
+ $node->DESTROY;
+ }
+ );
+}
+
+=head2 GetDisplayedNodes
+
+This function returns a list of the nodes of the tree in depth-first
+order which correspond to options in the "clauses" multi-select box.
+In fact, it's all of them but the root and its child.
+
+=cut
+
+sub GetDisplayedNodes {
+ my $self = shift;
+ my @lines;
+
+ $self->traverse(sub {
+ my $node = shift;
+
+ push @lines, $node unless $node->isRoot or $node->getParent->isRoot;
+ });
+
+ return @lines;
+}
+
+
+eval "require RT::Interface::Web::QueryBuilder::Tree_Vendor";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Web/QueryBuilder/Tree_Vendor.pm});
+eval "require RT::Interface::Web::QueryBuilder::Tree_Local";
+die $@ if ($@ && $@ !~ qr{^Can't locate RT/Interface/Web/QueryBuilder/Tree_Local.pm});
+
+1;
diff --git a/rt/lib/RT/Interface/Web/Standalone.pm b/rt/lib/RT/Interface/Web/Standalone.pm
new file mode 100755
index 000000000..bc2423e6d
--- /dev/null
+++ b/rt/lib/RT/Interface/Web/Standalone.pm
@@ -0,0 +1,37 @@
+package RT::Interface::Web::Standalone;
+
+use strict;
+use base 'HTTP::Server::Simple::Mason';
+use RT::Interface::Web::Handler;
+use RT::Interface::Web;
+
+sub handler_class { "RT::Interface::Web::Handler" }
+
+sub setup_escapes {
+ my $self = shift;
+ my $handler = shift;
+
+ # Override HTTP::Server::Simple::Mason's version of this method to do
+ # nothing. (RT::Interface::Web::Handler does this already for us in
+ # NewHandler.)
+}
+
+sub default_mason_config {
+ return @RT::MasonParameters;
+}
+
+sub handle_request {
+
+ my $self = shift;
+ my $cgi = shift;
+
+ Module::Refresh->refresh if $RT::DevelMode;
+
+ $self->SUPER::handle_request($cgi);
+ $RT::Logger->crit($@) if ($@);
+
+ RT::Interface::Web::Handler->CleanupRequest();
+
+}
+
+1;