diff options
-rw-r--r-- | ChangeLog | 348 | ||||
-rw-r--r-- | Makefile | 6 | ||||
-rw-r--r-- | debian/changelog | 6 | ||||
-rwxr-xr-x | httemplate/browse/cust_main_county.cgi | 47 | ||||
-rw-r--r-- | httemplate/docs/license.html | 2 | ||||
-rw-r--r-- | install/rpm/freeside.spec | 2 | ||||
-rw-r--r-- | rt/Makefile | 193 | ||||
-rwxr-xr-x | rt/bin/mason_handler.fcgi | 58 | ||||
-rwxr-xr-x | rt/bin/mason_handler.scgi | 50 | ||||
-rw-r--r-- | rt/bin/mason_handler.svc | 45 | ||||
-rw-r--r-- | rt/bin/rt-crontool | 164 | ||||
-rwxr-xr-x | rt/bin/rt-mailgate | 440 | ||||
-rw-r--r-- | rt/etc/RT_Config.pm | 184 | ||||
-rw-r--r-- | rt/html/Elements/Header | 8 | ||||
-rw-r--r-- | rt/lib/RT.pm | 176 |
15 files changed, 1048 insertions, 681 deletions
@@ -1,3 +1,351 @@ +2009-07-23 13:49 ivan + + * rt/: Makefile, bin/mason_handler.fcgi, bin/mason_handler.scgi, + bin/mason_handler.svc, bin/rt-crontool, bin/rt-mailgate, + etc/RT_Config.pm, lib/RT.pm: run make configure-rt to normalize + tempalated .in files + +2009-07-23 13:33 ivan + + * rt/html/Elements/Header: new domain + +2009-07-23 13:30 ivan + + * rt/Makefile: lost changes from 3.4.6 update, doh + +2009-07-23 13:16 ivan + + * rt/Makefile: lost changes from 3.4.6 update, doh + +2009-07-23 13:13 ivan + + * rt/Makefile: lost changes from 3.4.6 update, doh + +2009-07-23 12:46 ivan + + * FS/FS/cust_pay.pm: avoid harmless warning: Use of uninitialized + value in string ne + +2009-07-23 12:40 ivan + + * FS/bin/freeside-void-payments: fix -r option, RT#5675 + +2009-07-23 07:27 ivan + + * httemplate/docs/license.html: its 2009 + +2009-07-23 07:00 ivan + + * Makefile: 1.7.4rc1 + +2009-07-23 06:53 ivan + + * ChangeLog: 1.7.4rc1 + +2009-07-23 06:36 ivan + + * httemplate/browse/cust_main_county.cgi: add back collapse county + links to tax config (backport) + +2009-07-23 01:07 ivan + + * FS/bin/freeside-void-payments: adding this to 1.7 + +2009-07-13 02:19 ivan + + * FS/FS/ClientAPI/MyAccount.pm, + fs_selfservice/FS-SelfService/cgi/cust_bill-logo.cgi: fix + self-service agent-specific logos + +2009-07-13 00:21 ivan + + * conf/invoice_html: thank you IE8 + +2009-07-12 06:27 jeff + + * FS/FS/Record.pm: stop gratuitous hash manipulatoin during enum + untaint + +2009-07-07 00:32 mark + + * FS/bin/freeside-void-payments: Add freeside-void-payments script + for returned check processing + +2009-07-07 00:32 ivan + + * FS/bin/freeside-void-payments: file freeside-void-payments was + added on branch FREESIDE_1_7_BRANCH on 2009-07-23 08:07:13 +0000 + +2009-07-01 18:30 jeff + + * FS/FS/: cust_pkg.pm, ClientAPI/MyAccount.pm, part_pkg/flat.pm, + part_pkg/flat_introrate.pm: update flat_introrate plan to better + fit current codebase RT#4912 + +2009-06-26 11:53 ivan + + * FS/FS/cust_main.pm: in smart_search, move duplicate elimination + bits so that they're used even when doing an exact search on a + browser-remembered result + +2009-06-12 19:52 rsiddall + + * install/rpm/freeside.spec: Fix up permissions of default + configuration files and ownership of the data source + configuration folder. + +2009-06-12 16:35 rsiddall + + * install/rpm/freeside.spec: Since Freeside uses the absence of + configuration files to turn off config options, don't reinstall + the data source-dependent config directory every time the RPM is + installed or upgraded. Instead, keep the configuration in a + default folder and copy that to the data source-dependent folder + only if that folder does not exist. + +2009-06-12 03:20 mark + + * FS/FS/: Conf.pm, cust_main.pm: backported option for no postal + fee on one-time charges + +2009-06-09 20:06 ivan + + * FS/bin/freeside-upgrade: doh, semicolon + +2009-06-09 20:00 ivan + + * FS/bin/freeside-upgrade: don't attempt to create h_queue indices, + for SG upgradability + +2009-06-09 19:08 ivan + + * httemplate/edit/payment_gateway.html: update gateway list in + order to add WesternACH, RT#5409 + +2009-06-04 07:27 ivan + + * httemplate/docs/credits.html: fix scrolling + +2009-06-04 07:08 ivan + + * httemplate/docs/credits.html: $core->add("jeremyd"); + +2009-06-03 12:52 ivan + + * FS/FS/UID.pm: add a hack to set default schema, cf. + http://www.freeside.biz/mediawiki/index.php/Freeside:1.7:Documentation:Administration:PostgreSQL_Schema + +2009-05-29 20:40 ivan + + * FS/FS/part_pkg/prepaid.pm: and enable overlimit_action, RT#4995 + +2009-05-29 20:14 ivan + + * FS/FS/: svc_acct.pm, part_pkg/flat.pm, part_pkg/prepaid.pm: add + ability for prepaid packages to have usage limits and cancel if + they're hit, RT#4995 + +2009-05-29 19:31 ivan + + * FS/FS/: Conf.pm, svc_acct.pm: require svc_acct-usage_threshold to + be set explicitly, don't default to 80% + +2009-05-21 20:22 ivan + + * FS/bin/freeside-upgrade: commit before sqlradius upgrade so + sqlradius upgrade errors from permissions can be ignored for now + +2009-05-20 08:27 ivan + + * FS/FS/Conf.pm, httemplate/view/cust_main/packages.html: add + "manage device" link & config, RT#5438 + +2009-05-16 13:07 rsiddall + + * FS/FS/part_export/domreg_opensrs.pm: Added information on common + failure causes to the perldoc. + +2009-05-16 12:29 rsiddall + + * FS/FS/part_export/domreg_opensrs.pm: Defer loading Net::OpenSRS + so that failure to install this module doesn't stop Apache from + starting. This will cause attempts to register domains to fail + instead. + +2009-05-15 19:31 rsiddall + + * FS/FS/part_export/domreg_opensrs.pm: Provide better diagnostics + when the cust_main owning this domain lacks fields required for + use as a contact handle in the domain registration record. Also + temporarily disable the ability to use the export for only + registration or only transfers. + +2009-05-15 12:43 rsiddall + + * FS/FS/svc_domain.pm, FS/FS/part_export/domreg_opensrs.pm, + httemplate/edit/part_export.cgi, httemplate/edit/svc_domain.cgi, + httemplate/edit/process/part_export.cgi, + httemplate/edit/process/svc_domain.cgi: Simple domain + registration at Tucows OpenSRS using an export based on + Net::OpenSRS. When a domain is added and the export runs, it + will register the domain or initiate a transfer. You can also + choose no action. There's currently no provision for revoking + domains or renewing registrations. Depending on the settings at + OpenSRS, orders may look like they've succeeded in Freeside but + actually be queued pending input by the reseller at OpenSRS. The + part_export CGIs were modified to allow a multi-valued select to + be used to control which TLDs are enabled for registration. + +2009-05-15 12:41 rsiddall + + * FS/FS/part_export/domreg_opensrs.pm: Simple domain registration + at Tucows OpenSRS using an export based on Net::OpenSRS. When a + domain is added and the export runs, it will register the domain + or initiate a transfer. You can also choose no action. There's + currently no provision for revoking domains or renewing + registrations. Depending on the settings at OpenSRS, orders may + look like they've succeeded in Freeside but actually be queued + pending input by the reseller at OpenSRS. The part_export CGIs + were modified to allow a multi-valued select to be used to + control which TLDs are enabled for registration. + +2009-05-15 12:41 rsiddall + + * FS/FS/part_export/domreg_opensrs.pm: file domreg_opensrs.pm was + added on branch FREESIDE_1_7_BRANCH on 2009-05-15 19:43:06 +0000 + +2009-05-03 18:17 ivan + + * FS/FS/svc_acct.pm: eliminate Argument "" isn't numeric in + addition (+) warning + +2009-04-29 11:25 ivan + + * httemplate/edit/svc_www.cgi: fix inadvertant select box, RT#5277 + +2009-04-28 15:38 ivan + + * fs_selfservice/FS-SelfService/cgi/bill.html: UI + +2009-04-27 21:36 ivan + + * FS/FS/cust_main.pm: add cancelled_cust-noevents flag to emulate + SG billing-daily -r behavior, RT#4412 + +2009-04-27 21:13 ivan + + * FS/FS/: Conf.pm, cust_main.pm: add cancelled_cust-noevents flag + to emulate SG billing-daily -r behavior + +2009-04-27 16:06 ivan + + * htetc/handler.pl: typo + +2009-04-27 16:01 ivan + + * htetc/handler.pl: refuse to run w/CGI.pm 3.38. all lenny + upgrades will need libcgi-pm-perl removed, suck + +2009-04-26 16:43 ivan + + * FS/FS/Schema.pm: would help to have an index on priority if we're + going to order based on it + +2009-04-26 16:19 ivan + + * FS/bin/freeside-queued: start small jobs more efficiently, + RT#4412 + +2009-04-26 16:09 ivan + + * FS/FS/Conf.pm: add a config option for max # of queued kids, + RT#4412 + +2009-04-25 15:50 ivan + + * FS/: FS/Cron/bill.pm, bin/freeside-daily: add dry run to + multi-process mode for testing, RT#4412 + +2009-04-25 10:02 ivan + + * FS/FS/Cron/bill.pm: well. that never returned any results at + all. reverting. RT#4412 + +2009-04-24 12:06 ivan + + * FS/FS/Cron/bill.pm: tune 1.7 query for better performance, + hopefully. RT#4412 + +2009-04-22 21:57 ivan + + * FS/FS/Cron/bill.pm: we don't actually need the results ordered, + and i'm sure it doesn't help the planner get us results sooner. + last chance to try and get cursor approach working? RT#4412 + +2009-04-22 21:14 ivan + + * FS/FS/Cron/bill.pm: does pg try to finish the query when the job + addition is committed? well, if this works, that answers that. + RT#4412 + +2009-04-22 13:24 ivan + + * FS/FS/Cron/bill.pm: hopefully better performance running the big + query once and then fetching results with a cursor, rather than + running it multiple times with an OFFSET and LIMIT, RT#4412 + +2009-04-21 23:52 ivan + + * FS/FS/Cron/bill.pm: perhaps a happier medium, RT#4412 + +2009-04-21 17:54 ivan + + * FS/FS/Cron/bill.pm: have the big query find customers in batches. + this should be way more efficient in multi-process mode, can + start billing before the big query completes. RT#4412 + +2009-04-21 09:42 ivan + + * FS/FS/Cron/bill.pm: yow. fix fallout from cust_main.archived + stuff causing nothing to bill. RT#4412 + +2009-04-20 13:55 rsiddall + + * install/rpm/freeside.spec: Acceptance testing of the RPM build + system flushed out a place where /bin/rm stops for input if + you're running /bin/su as another user to do the build. Adding a + -f flag to stop it asking for input. + +2009-04-20 09:57 ivan + + * FS/FS/: Schema.pm, cust_main.pm, Cron/bill.pm: add + cust_main.archived field, skip billing if Y, RT#4412 + +2009-04-19 17:20 ivan + + * httemplate/elements/header.html: fix botched backport from 1.9 + +2009-04-17 12:50 ivan + + * FS/: FS/Schema.pm, FS/Cron/bill.pm, bin/freeside-queued: add + priority to job queue so billing jobs don't don't drown out + provisioning jobs + +2009-04-17 05:08 ivan + + * FS/: FS/Cron/bill.pm, bin/freeside-daily, FS/cust_main.pm: + backport freeside-daily -m and cust_main::bill_and_collect to + 1.7, RT#4412 + +2009-04-17 03:17 ivan + + * FS/FS/cust_main.pm: backport paycvv upgrade from 1.9: "orders of + magnitude faster" + +2009-04-17 01:33 ivan + + * ChangeLog: 1.7.4? + 2009-04-17 01:25 ivan * httemplate/docs/about.html: when you're waiting for a miracle @@ -115,10 +115,10 @@ RT_PATH = /opt/rt3 #only used for dev kludge now, not a big deal FREESIDE_PATH = `pwd` -PERL_INC_DEV_KLUDGE = /usr/local/share/perl/5.8.8/ +PERL_INC_DEV_KLUDGE = /usr/local/share/perl/5.10.0/ -VERSION=1.7.3 -TAG=freeside_1_7_3 +VERSION=1.7.4rc1 +TAG=freeside_1_7_4rc1 DEBVERSION = `echo ${VERSION} | perl -pe 's/(\d)([a-z])/\1~\2/'`-1 diff --git a/debian/changelog b/debian/changelog index e83e749..e017613 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +freeside (1.7.4~rc1-1) unstable; urgency=low + + * New upstream release + + -- Ivan Kohler <ivan-debian@420.am> Thu, 23 Jul 2009 14:01:10 -0700 + freeside (1.7.3-1) unstable; urgency=low * New upstream release diff --git a/httemplate/browse/cust_main_county.cgi b/httemplate/browse/cust_main_county.cgi index 736d7fd..232e688 100755 --- a/httemplate/browse/cust_main_county.cgi +++ b/httemplate/browse/cust_main_county.cgi @@ -23,10 +23,6 @@ 'link_onclicks' => \@link_onclicks, ) %> -% -% # <FONT SIZE=-1><A HREF="<% $p %>edit/process/cust_main_county-collapse.cgi?<% $hashref->{taxnum} %>">collapse state</A></FONT> -% # % } -% <%once> my $conf = new FS::Conf; @@ -102,6 +98,17 @@ sub expand_link { '</FONT>'; } +sub collapse_link { + my %param = @_; + + my $taxnum = $param{'row'}->taxnum; + my $url = "${p}edit/process/cust_main_county-collapse.cgi?$taxnum"; + $url = "javascript:collapse_areyousure('$url')"; + + qq(<FONT SIZE="-1"><A HREF="$url">$param{'label'}</A></FONT>); +} + + sub separate_taxclasses_link { my( $row ) = @_; my $taxnum = $row->taxnum; @@ -110,6 +117,8 @@ sub separate_taxclasses_link { qq!<FONT SIZE="-1"><A HREF="$url">!; } +#un-separate taxclasses too + </%once> <%init> @@ -122,9 +131,18 @@ my $enable_taxclasses = $conf->exists('enable_taxclasses'); my @menubar; -my $html_init = - "Click on <u>add states</u> to specify a country's tax rates by state or province. - <BR>Click on <u>add counties</u> to specify a state's tax rates by county."; +my $html_init = <<END; + <SCRIPT> + function collapse_areyousure(href) { + if (confirm("Are you sure you want to remove all county tax rates for this state?") == true) + window.location.href = href; + } + </SCRIPT> + + Click on <u>add states</u> to specify a country's tax rates by state or province. + <BR>Click on <u>add counties</u> to specify a state's tax rates by county, or <u>remove counties</u> to remove per-county tax rates. +END + $html_init .= "<BR>Click on <u>separate taxclasses</u> to specify taxes per taxclass." if $enable_taxclasses; $html_init .= '<BR><BR>'; @@ -360,11 +378,16 @@ my @fields = ( ) ) }, - sub { $_[0]->county || '(all) '. - expand_link( desc => 'Add Counties', - row => $_[0], - label => 'add counties', - ) + sub { $_[0]->county + ? $_[0]->county. ' '. + collapse_link( label=> 'remove counties', + row => $_[0], + ) + : '(all) '. + expand_link( desc => 'Add Counties', + row => $_[0], + label => 'add counties', + ); }, ); diff --git a/httemplate/docs/license.html b/httemplate/docs/license.html index fa75878..dab47d6 100644 --- a/httemplate/docs/license.html +++ b/httemplate/docs/license.html @@ -6,7 +6,7 @@ <P> -Copyright © 2005-2008 Freeside Internet Services, Inc.<BR> +Copyright © 2005-2009 Freeside Internet Services, Inc.<BR> Copyright © 2000-2005 Ivan Kohler<BR> Copyright © 1999 Silicon Interactive Software Design<BR> All rights reserved<BR> diff --git a/install/rpm/freeside.spec b/install/rpm/freeside.spec index c36d918..1270645 100644 --- a/install/rpm/freeside.spec +++ b/install/rpm/freeside.spec @@ -1,5 +1,5 @@ %{!?_initrddir:%define _initrddir /etc/rc.d/init.d} -%{!?version:%define version 1.7.3} +%{!?version:%define version 1.7.4rc1} %{!?release:%define release 6} Summary: Freeside ISP Billing System diff --git a/rt/Makefile b/rt/Makefile index 0895874..b5f7e79 100644 --- a/rt/Makefile +++ b/rt/Makefile @@ -1,8 +1,14 @@ -# BEGIN LICENSE BLOCK +# BEGIN BPS TAGGED BLOCK {{{ # -# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +# COPYRIGHT: +# +# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC +# <jesse@bestpractical.com> # -# (Except where explictly superceded by other copyright notices) +# (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 @@ -14,13 +20,29 @@ # 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. +# 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.) # -# END LICENSE BLOCK +# 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 }}} # # DO NOT HAND-EDIT the file named 'Makefile'. This file is autogenerated. # Have a look at "configure" and "Makefile.in" instead @@ -35,15 +57,15 @@ SITE_CONFIG_FILE = $(CONFIG_FILE_PATH)/RT_SiteConfig.pm RT_VERSION_MAJOR = 3 -RT_VERSION_MINOR = 0 -RT_VERSION_PATCH = 9 +RT_VERSION_MINOR = 4 +RT_VERSION_PATCH = 6 RT_VERSION = $(RT_VERSION_MAJOR).$(RT_VERSION_MINOR).$(RT_VERSION_PATCH) TAG = rt-$(RT_VERSION_MAJOR)-$(RT_VERSION_MINOR)-$(RT_VERSION_PATCH) # This is the group that all of the installed files will be chgrp'ed to. -RTGROUP = rt +RTGROUP = freeside # User which should own rt binaries. @@ -55,8 +77,11 @@ LIBS_OWNER = root # Group that should own all of RT's libraries, generally root. LIBS_GROUP = bin -WEB_USER = www -WEB_GROUP = www +WEB_USER = freeside +WEB_GROUP = freeside + + +APACHECTL = # {{{ Files and directories @@ -76,10 +101,11 @@ RT_VAR_PATH = /opt/rt3/var RT_DOC_PATH = /opt/rt3/share/doc RT_LOCAL_PATH = /opt/rt3/local LOCAL_ETC_PATH = /opt/rt3/local/etc +LOCAL_LIB_PATH = /opt/rt3/local/lib LOCAL_LEXICON_PATH = /opt/rt3/local/po -MASON_HTML_PATH = /opt/rt3/share/html +MASON_HTML_PATH = /var/www/freeside/rt MASON_LOCAL_HTML_PATH = /opt/rt3/local/html -MASON_DATA_PATH = /opt/rt3/var/mason_data +MASON_DATA_PATH = /usr/local/etc/freeside/masondata MASON_SESSION_PATH = /opt/rt3/var/session_data RT_LOG_PATH = /opt/rt3/var/log @@ -94,6 +120,10 @@ RT_READABLE_DIR_MODE = 0755 # RT_MODPERL_HANDLER is the mason handler script for mod_perl RT_MODPERL_HANDLER = $(RT_BIN_PATH)/webmux.pl +# RT_STANDALONE_SERVER is a stand-alone HTTP server +RT_STANDALONE_SERVER = $(RT_BIN_PATH)/standalone_httpd +# RT_SPEEDYCGI_HANDLER is the mason handler script for SpeedyCGI +RT_SPEEDYCGI_HANDLER = $(RT_BIN_PATH)/mason_handler.scgi # RT_FASTCGI_HANDLER is the mason handler script for FastCGI RT_FASTCGI_HANDLER = $(RT_BIN_PATH)/mason_handler.fcgi # RT_WIN32_FASTCGI_HANDLER is the mason handler script for FastCGI @@ -107,14 +137,15 @@ RT_CRON_BIN = $(RT_BIN_PATH)/rt-crontool # }}} -SETGID_BINARIES = $(DESTDIR)/$(RT_FASTCGI_HANDLER) \ - $(DESTDIR)/$(RT_WIN32_FASTCGI_HANDLER) BINARIES = $(DESTDIR)/$(RT_MODPERL_HANDLER) \ $(DESTDIR)/$(RT_MAILGATE_BIN) \ $(DESTDIR)/$(RT_CLI_BIN) \ $(DESTDIR)/$(RT_CRON_BIN) \ - $(SETGID_BINARIES) + $(DESTDIR)/$(RT_STANDALONE_SERVER) \ + $(DESTDIR)/$(RT_SPEEDYCGI_HANDLER) \ + $(DESTDIR)/$(RT_FASTCGI_HANDLER) \ + $(DESTDIR)/$(RT_WIN32_FASTCGI_HANDLER) SYSTEM_BINARIES = $(DESTDIR)/$(RT_SBIN_PATH)/ @@ -128,7 +159,7 @@ SYSTEM_BINARIES = $(DESTDIR)/$(RT_SBIN_PATH)/ # "Pg" is known to work # "Informix" is known to work -DB_TYPE = mysql +DB_TYPE = Pg # Set DBA to the name of a unix account with the proper permissions and # environment to run your commandline SQL sbin @@ -140,7 +171,7 @@ DB_TYPE = mysql # For Oracle, you want 'system' # For Informix, you want 'informix' -DB_DBA = root +DB_DBA = freeside DB_HOST = localhost @@ -166,9 +197,9 @@ DB_RT_HOST = localhost # set this to the name you want to give to the RT database in # your database server. For Oracle, this should be the name of your sid -DB_DATABASE = rt3 -DB_RT_USER = rt_user -DB_RT_PASS = rt_pass +DB_DATABASE = freeside +DB_RT_USER = freeside +DB_RT_PASS = # }}} @@ -189,8 +220,11 @@ instruct: @echo "" @echo "You must now configure RT by editing $(SITE_CONFIG_FILE)." @echo "" - @echo "(You will definitely need to set RT's database password before continuing." - @echo " Not doing so could be very dangerous)" + @echo "(You will definitely need to set RT's database password in " + @echo "$(SITE_CONFIG_FILE) before continuing. Not doing so could be " + @echo "very dangerous. Note that you do not have to manually add a " + @echo "database user or set up a database for RT. These actions will be " + @echo "taken care of in the next step.)" @echo "" @echo "After that, you need to initialize RT's database by running" @echo " 'make initialize-database'" @@ -206,9 +240,12 @@ upgrade-instruct: @echo "$(CONFIG_FILE) for any necessary site customization. Additionally," @echo "you should update RT's system database objects by running " @echo " ls etc/upgrade" - @echo "For each file in that directory whose name is greater than" + @echo "" + @echo "For each item in that directory whose name is greater than" @echo "your previously installed RT version, run:" - @echo " $(RT_SBIN_PATH)/rt-setup-database --action insert --datafile etc/upgrade/<version>" + @echo " $(RT_SBIN_PATH)/rt-setup-database --dba $(DB_DBA) --prompt-for-dba-password --action schema --datadir etc/upgrade/<version>" + @echo " $(RT_SBIN_PATH)/rt-setup-database --dba $(DB_DBA) --prompt-for-dba-password --action acl --datadir etc/upgrade/<version>" + @echo " $(RT_SBIN_PATH)/rt-setup-database --dba $(DB_DBA) --prompt-for-dba-password --action insert --datadir etc/upgrade/<version>" upgrade: config-install dirs files-install fixperms upgrade-instruct @@ -218,10 +255,12 @@ upgrade-noclobber: config-install libs-install html-install bin-install local-in # {{{ dependencies testdeps: - $(PERL) ./sbin/rt-test-dependencies --with-$(DB_TYPE) + $(PERL) ./sbin/rt-test-dependencies --verbose --with-$(DB_TYPE) + +depends: fixdeps fixdeps: - $(PERL) ./sbin/rt-test-dependencies --install --with-$(DB_TYPE) + $(PERL) ./sbin/rt-test-dependencies --verbose --install --with-$(DB_TYPE) #}}} @@ -241,18 +280,17 @@ fixperms: chmod 0500 $(DESTDIR)/$(RT_ETC_PATH)/* #TODO: the config file should probably be able to have its - # owner set seperately from the binaries. + # owner set separately from the binaries. chown -R $(BIN_OWNER) $(DESTDIR)/$(RT_ETC_PATH) chgrp -R $(RTGROUP) $(DESTDIR)/$(RT_ETC_PATH) chmod 0550 $(DESTDIR)/$(CONFIG_FILE) chmod 0550 $(DESTDIR)/$(SITE_CONFIG_FILE) - # Make the interfaces executable and setgid rt + # Make the interfaces executable chown $(BIN_OWNER) $(BINARIES) chgrp $(RTGROUP) $(BINARIES) chmod 0755 $(BINARIES) - chmod g+s $(SETGID_BINARIES) # Make the web ui readable by all. chmod -R u+rwX,go-w,go+rX $(DESTDIR)/$(MASON_HTML_PATH) \ @@ -272,12 +310,6 @@ fixperms: $(DESTDIR)/$(MASON_SESSION_PATH) # }}} -fixperms-nosetgid: fixperms - @echo "You should never be running RT this way. it's unsafe" - chmod 0555 $(SETGID_BINARIES) - chmod 0555 $(DESTDIR)/$(CONFIG_FILE) - chmod 0555 $(DESTDIR)/$(SITE_CONFIG_FILE) - # {{{ dirs dirs: mkdir -p $(DESTDIR)/$(RT_LOG_PATH) @@ -289,6 +321,7 @@ dirs: mkdir -p $(DESTDIR)/$(MASON_HTML_PATH) mkdir -p $(DESTDIR)/$(MASON_LOCAL_HTML_PATH) mkdir -p $(DESTDIR)/$(LOCAL_ETC_PATH) + mkdir -p $(DESTDIR)/$(LOCAL_LIB_PATH) mkdir -p $(DESTDIR)/$(LOCAL_LEXICON_PATH) # }}} @@ -298,7 +331,7 @@ files-install: libs-install etc-install bin-install sbin-install html-install lo config-install: mkdir -p $(DESTDIR)/$(CONFIG_FILE_PATH) - cp etc/RT_Config.pm $(DESTDIR)/$(CONFIG_FILE) + -cp etc/RT_Config.pm $(DESTDIR)/$(CONFIG_FILE) [ -f $(DESTDIR)/$(SITE_CONFIG_FILE) ] || cp etc/RT_SiteConfig.pm $(DESTDIR)/$(SITE_CONFIG_FILE) chgrp $(RTGROUP) $(DESTDIR)/$(CONFIG_FILE) @@ -315,14 +348,13 @@ test: regression-install: config-install $(PERL) -pi -e 's/Set\(\$$DatabaseName.*\);/Set\(\$$DatabaseName, "rt3regression"\);/' $(DESTDIR)/$(CONFIG_FILE) -regression-nosetgid-quiet: regression-install dirs files-install libs-install sbin-install bin-install regression-instruct regression-reset-db testify-pods fixperms-nosetgid apachectl - $(PERL) sbin/regression_harness +regression: regression-install dirs files-install libs-install sbin-install bin-install regression-instruct regression-reset-db testify-pods fixperms apachectl run-regression -regression-nosetgid: regression-install dirs files-install libs-install sbin-install bin-install regression-instruct regression-reset-db testify-pods fixperms-nosetgid apachectl - $(PERL) lib/t/02regression.t +run-regression: + prove -Ilib lib/t/setup_regression.t lib/t/autogen/ lib/t/regression/ -regression: regression-install dirs files-install libs-install sbin-install bin-install regression-instruct regression-reset-db testify-pods fixperms apachectl - $(PERL) lib/t/02regression.t + +regression-noapache: regression-install dirs files-install libs-install sbin-install bin-install regression-instruct regression-reset-db testify-pods fixperms start-httpd run-regression regression-quiet: $(PERL) sbin/regression_harness @@ -334,9 +366,11 @@ regression-instruct: # {{{ database-installation regression-reset-db: - $(PERL) $(DESTDIR)/$(RT_SBIN_PATH)/rt-setup-database --action drop --dba $(DB_DBA) --dba-password '' + $(PERL) $(DESTDIR)/$(RT_SBIN_PATH)/rt-setup-database --action drop --dba $(DB_DBA) --dba-password '' --force $(PERL) $(DESTDIR)/$(RT_SBIN_PATH)/rt-setup-database --action init --dba $(DB_DBA) --dba-password '' +initdb :: initialize-database + initialize-database: $(PERL) $(DESTDIR)/$(RT_SBIN_PATH)/rt-setup-database --action init --dba $(DB_DBA) --prompt-for-dba-password @@ -349,13 +383,13 @@ insert-approval-data: # {{{ libs-install libs-install: - [ -d $(DESTDIR)/$(RT_LIB_PATH) ] || mkdir $(DESTDIR)/$(RT_LIB_PATH) + [ -d $(DESTDIR)/$(RT_LIB_PATH) ] || mkdir -p $(DESTDIR)/$(RT_LIB_PATH) -cp -rp lib/* $(DESTDIR)/$(RT_LIB_PATH) # }}} # {{{ html-install html-install: - [ -d $(DESTDIR)/$(MASON_HTML_PATH) ] || mkdir $(DESTDIR)/$(MASON_HTML_PATH) + [ -d $(DESTDIR)/$(MASON_HTML_PATH) ] || mkdir -p $(DESTDIR)/$(MASON_HTML_PATH) -cp -rp ./html/* $(DESTDIR)/$(MASON_HTML_PATH) # }}} @@ -363,7 +397,7 @@ html-install: doc-install: # RT 3.0.0 - RT 3.0.2 would accidentally create a file instead of a dir -[ -f $(DESTDIR)/$(RT_DOC_PATH) ] && rm $(DESTDIR)/$(RT_DOC_PATH) - [ -d $(DESTDIR)/$(RT_DOC_PATH) ] || mkdir $(DESTDIR)/$(RT_DOC_PATH) + [ -d $(DESTDIR)/$(RT_DOC_PATH) ] || mkdir -p $(DESTDIR)/$(RT_DOC_PATH) -cp -rp ./README $(DESTDIR)/$(RT_DOC_PATH) # }}} @@ -382,9 +416,12 @@ etc-install: sbin-install: mkdir -p $(DESTDIR)/$(RT_SBIN_PATH) - chmod +x sbin/rt-setup-database \ + chmod +x \ + sbin/rt-dump-database \ + sbin/rt-setup-database \ sbin/rt-test-dependencies -cp -rp \ + sbin/rt-dump-database \ sbin/rt-setup-database \ sbin/rt-test-dependencies \ $(DESTDIR)/$(RT_SBIN_PATH) @@ -401,6 +438,7 @@ bin-install: bin/rt-mailgate \ bin/mason_handler.fcgi \ bin/mason_handler.scgi \ + bin/standalone_httpd \ bin/mason_handler.svc \ bin/rt \ bin/webmux.pl \ @@ -422,8 +460,10 @@ POD2TEST_EXE = sbin/extract_pod_tests testify-pods: [ -d lib/t/autogen ] || mkdir lib/t/autogen - find lib -name \*pm |grep -v \*.in |xargs -n 1 $(PERL) $(POD2TEST_EXE) - find bin -type f |grep -v \~ | grep -v "\.in" | xargs -n 1 $(PERL) $(POD2TEST_EXE) + find lib -name \*pm |grep -v .svn | grep -v \*.in |xargs -n 1 $(PERL) $(POD2TEST_EXE) + find bin -type f |grep -v .svn | grep -v \~ | grep -v "\.in" | xargs -n 1 $(PERL) $(POD2TEST_EXE) + find lib -name \*pm |grep -v .svn | grep -v \*.in |xargs -n 1 $(PERL) $(POD2TEST_EXE) + find bin -type f |grep -v .svn | grep -v \~ | grep -v "\.in" | xargs -n 1 $(PERL) $(POD2TEST_EXE) @@ -436,55 +476,18 @@ license-tag: factory: initialize-database cd lib; $(PERL) ../sbin/factory $(DB_DATABASE) RT -commit: - aegis -build ; aegis -diff ; aegis -test; aegis -develop_end - -integrate: - aegis -integrate_begin; aegis -build; aegis -diff; aegis -test ; aegis -integrate_pass - -predist: commit tag-and-tar - -tag-and-release-baseline: - aegis -cp -ind Makefile -output /tmp/Makefile.tagandrelease; \ - $(MAKE) -f /tmp/Makefile.tagandrelease tag-and-release-never-by-hand - - -# Running this target in a working directory is -# WRONG WRONG WRONG. -# it will tag the current baseline with the version of RT defined -# in the currently-being-worked-on makefile. which is wrong. -# you want tag-and-release-baseline - -tag-and-release-never-by-hand: - aegis --delta-name $(TAG) - rm -rf /tmp/$(TAG) - mkdir /tmp/$(TAG) - cd /tmp/$(TAG); \ - aegis -cp -ind -delta $(TAG) . ;\ - make reconfigure;\ - chmod 600 Makefile;\ - aegis --report --project rt.$(RT_VERSION_MAJOR) \ - --page_width 80 \ - --page_length 9999 \ - --change $(RT_VERSION_MINOR) --output Changelog Change_Log - - cd /tmp; tar czvf /home/ftp/pub/rt/devel/$(TAG).tar.gz $(TAG)/ - chmod 644 /home/ftp/pub/rt/devel/$(TAG).tar.gz - - reconfigure: aclocal -I m4 autoconf chmod 755 ./configure ./configure -rpm: - (cd ..; tar czvf /usr/src/redhat/SOURCES/rt.tar.gz rt) - rpm -ba etc/rt.spec - +start-httpd: + $(PERL) bin/standalone_httpd 80 & apachectl: - apachectl stop - sleep 3 - apachectl start + $(APACHECTL) stop + sleep 10 + $(APACHECTL) start + sleep 5 # }}} diff --git a/rt/bin/mason_handler.fcgi b/rt/bin/mason_handler.fcgi index 93d1f88..4ce6c00 100755 --- a/rt/bin/mason_handler.fcgi +++ b/rt/bin/mason_handler.fcgi @@ -1,9 +1,15 @@ #!/usr/bin/perl -# BEGIN LICENSE BLOCK +# BEGIN BPS TAGGED BLOCK {{{ # -# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +# COPYRIGHT: +# +# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC +# <jesse@bestpractical.com> # -# (Except where explictly superceded by other copyright notices) +# (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 @@ -15,26 +21,41 @@ # 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. +# 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 LICENSE BLOCK +# END BPS TAGGED BLOCK }}} +package RT::Mason; use strict; +use vars '$Handler'; use File::Basename; require ('/opt/rt3/bin/webmux.pl'); -my $h = &RT::Interface::Web::NewCGIHandler(@RT::MasonParameters); - # Enter CGI::Fast mode, which should also work as a vanilla CGI script. require CGI::Fast; RT::Init(); -# Response loop while ( my $cgi = CGI::Fast->new ) { # the whole point of fastcgi requires the env to get reset here.. # So we must squash it again @@ -44,24 +65,19 @@ while ( my $cgi = CGI::Fast->new ) { $ENV{'ENV'} = '' if defined $ENV{'ENV'}; $ENV{'IFS'} = '' if defined $ENV{'IFS'}; + Module::Refresh->refresh if $RT::DevelMode; RT::ConnectToDatabase(); - if ( ( !$h->interp->comp_exists( $cgi->path_info ) ) - && ( $h->interp->comp_exists( $cgi->path_info . "/index.html" ) ) ) { + if ( ( !$Handler->interp->comp_exists( $cgi->path_info ) ) + && ( $Handler->interp->comp_exists( $cgi->path_info . "/index.html" ) ) ) { $cgi->path_info( $cgi->path_info . "/index.html" ); } - eval { $h->handle_cgi_object($cgi); }; + eval { $Handler->handle_cgi_object($cgi); }; if ($@) { $RT::Logger->crit($@); } - - - if ($RT::Handle->TransactionDepth) { - $RT::Handle->ForceRollback; - $RT::Logger->crit("Transaction not committed. Usually indicates a software fault. Data loss may have occurred") ; - } - + RT::Interface::Web::Handler->CleanupRequest(); } diff --git a/rt/bin/mason_handler.scgi b/rt/bin/mason_handler.scgi index 7774189..bc6bd76 100755 --- a/rt/bin/mason_handler.scgi +++ b/rt/bin/mason_handler.scgi @@ -1,9 +1,15 @@ #!/usr/local/bin/speedy -# BEGIN LICENSE BLOCK +# BEGIN BPS TAGGED BLOCK {{{ # -# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +# COPYRIGHT: +# +# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC +# <jesse@bestpractical.com> # -# (Except where explictly superceded by other copyright notices) +# (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 @@ -15,29 +21,45 @@ # 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. +# 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.) # -# END LICENSE BLOCK +# 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::Mason; use strict; +use vars '$Handler'; require ('/opt/rt3/bin/webmux.pl'); -my $h = &RT::Interface::Web::NewCGIHandler(@RT::MasonParameters); - require CGI; RT::Init(); my $cgi = CGI->new; -if ( ( !$h->interp->comp_exists( $cgi->path_info ) ) - && ( $h->interp->comp_exists( $cgi->path_info . "/index.html" ) ) ) { +if ( ( !$Handler->interp->comp_exists( $cgi->path_info ) ) + && ( $Handler->interp->comp_exists( $cgi->path_info . "/index.html" ) ) ) { $cgi->path_info( $cgi->path_info . "/index.html" ); } -$h->handle_cgi_object($cgi); - +$Handler->handle_cgi_object($cgi); +RT::Interface::Web::Handler->CleanupRequest(); 1; diff --git a/rt/bin/mason_handler.svc b/rt/bin/mason_handler.svc index c05d21e..6065fa5 100644 --- a/rt/bin/mason_handler.svc +++ b/rt/bin/mason_handler.svc @@ -1,9 +1,15 @@ #!/usr/bin/perl -# BEGIN LICENSE BLOCK +# BEGIN BPS TAGGED BLOCK {{{ # -# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +# COPYRIGHT: +# +# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC +# <jesse@bestpractical.com> # -# (Except where explictly superceded by other copyright notices) +# (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 @@ -15,13 +21,29 @@ # 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. +# 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: # -# END LICENSE BLOCK +# (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 }}} =head1 NAME @@ -55,8 +77,11 @@ registry setting will also be automatically populated. =cut +package RT::Mason; + use strict; use File::Basename; +use vars '$Handler'; require (dirname(__FILE__) . '/webmux.pl'); use Cwd; @@ -197,7 +222,6 @@ BEGIN { warn "Begin listening on $ENV{'FCGI_SOCKET_PATH'}\n"; require CGI::Fast; -my $h = &RT::Interface::Web::NewCGIHandler(@RT::MasonParameters); RT::Init(); @@ -212,7 +236,8 @@ while( my $cgi = CGI::Fast->new ) { warn "Serving $comp\n"; - $h->handle_cgi($comp); + $Handler->handle_cgi($comp); + RT::Interface::Web::Handler->CleanupRequest(); # _should_ always be tied } diff --git a/rt/bin/rt-crontool b/rt/bin/rt-crontool index cdbc3cb..3375b8c 100644 --- a/rt/bin/rt-crontool +++ b/rt/bin/rt-crontool @@ -1,9 +1,15 @@ #!/usr/bin/perl -# BEGIN LICENSE BLOCK +# BEGIN BPS TAGGED BLOCK {{{ # -# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +# COPYRIGHT: +# +# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC +# <jesse@bestpractical.com> # -# (Except where explictly superceded by other copyright notices) +# (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 @@ -15,18 +21,33 @@ # 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. +# 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. # # -# END LICENSE BLOCK - +# 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 }}} use strict; use Carp; -use lib ("/opt/rt3/lib", "/opt/rt3/local/lib"); +use lib ("/opt/rt3/local/lib", "/opt/rt3/lib"); package RT; @@ -45,9 +66,6 @@ RT::LoadConfig(); #Connect to the database and get RT::SystemUser and RT::Nobody loaded RT::Init(); -#Drop setgid permissions -RT::DropSetGIDPermissions(); - #Get the current user all loaded my $CurrentUser = GetCurrentUser(); @@ -57,18 +75,27 @@ unless ( $CurrentUser->Id ) { } my ( $search, $condition, $action, $search_arg, $condition_arg, $action_arg, - $template_id, $help, $verbose ); -GetOptions( "search=s" => \$search, - "search-arg=s" => \$search_arg, - "condition=s" => \$condition, - "condition-arg=s" => \$condition_arg, - "action-arg=s" => \$action_arg, - "action=s" => \$action, - "template-id=s" => \$template_id, - "help" => \$help, - "verbose|v" => \$verbose ); - -help() if $help; + $template_id, $transaction, $transaction_type, $help, $verbose ); +GetOptions( "search=s" => \$search, + "search-arg=s" => \$search_arg, + "condition=s" => \$condition, + "condition-arg=s" => \$condition_arg, + "action-arg=s" => \$action_arg, + "action=s" => \$action, + "template-id=s" => \$template_id, + "transaction=s" => \$transaction, + "transaction-type=s" => \$transaction_type, + "help" => \$help, + "verbose|v" => \$verbose ); + +help() if $help or not $search or not $action; + +$transaction ||= 'first'; +unless ( $transaction =~ /^(first|last)$/i ) { + print STDERR loc("--transaction argument could be only 'first' or 'last'"); + exit 1; +} +$transaction = lc($transaction) eq 'first'? 'ASC': 'DESC'; # We _must_ have a search object load_module($search); @@ -78,15 +105,21 @@ load_module($condition) if ($condition); # load template if specified my $template_obj; if ($template_id) { - $template_obj = RT::Template->new($RT::Nobody); - $template_obj->LoadById($template_id); + $template_obj = RT::Template->new($CurrentUser); + $template_obj->Load($template_id); } +my $void_scrip = RT::Scrip->new( $CurrentUser ); +my $void_scrip_action = RT::ScripAction->new( $CurrentUser ); #At the appointed time: #find a bunch of tickets my $tickets = RT::Tickets->new($CurrentUser); -my $search = $search->new( TicketsObj => $tickets, Argument => $search_arg ); +my $search = $search->new( + TicketsObj => $tickets, + Argument => $search_arg, + CurrentUser => $CurrentUser +); $search->Prepare(); @@ -95,12 +128,22 @@ my $tickets = $search->TicketsObj; #for each ticket we've found while ( my $ticket = $tickets->Next() ) { - print "\n" . $ticket->Id() . ": " if ($verbose); + print $ticket->Id() . ": " if ($verbose); + + my $transaction = get_transaction($ticket); + print loc("Using transaction #[_1]...", $transaction->id) + if $verbose && $transaction; # perform some more advanced check if ($condition) { - my $condition_obj = $condition->new( TicketObj => $ticket, - Argument => $condition_arg ); + my $condition_obj = $condition->new( + TransactionObj => $transaction, + TicketObj => $ticket, + ScripObj => $void_scrip, + TemplateObj => $template_obj, + Argument => $condition_arg, + CurrentUser => $CurrentUser, + ); # if the condition doesn't apply, get out of here @@ -109,9 +152,15 @@ while ( my $ticket = $tickets->Next() ) { } #prepare our action - my $action_obj = $action->new( TicketObj => $ticket, - TemplateObj => $template_obj, - Argument => $action_arg ); + my $action_obj = $action->new( + TicketObj => $ticket, + TransactionObj => $transaction, + TemplateObj => $template_obj, + Argument => $action_arg, + ScripObj => $void_scrip, + ScripActionObj => $void_scrip_action, + CurrentUser => $CurrentUser, + ); #if our preparation, move onto the next ticket next unless ( $action_obj->Prepare ); @@ -119,7 +168,27 @@ while ( my $ticket = $tickets->Next() ) { #commit our action. next unless ( $action_obj->Commit ); - print loc("Action committed.") if ($verbose); + print loc("Action committed.\n") if ($verbose); +} + +=head2 get_transaction + +Takes ticket and returns its transaction acording to command +line arguments C<--transaction> and <--transaction-type>. + +=cut + +sub get_transaction { + my $ticket = shift; + my $txns = $ticket->Transactions; + $txns->OrderByCols( + { FIELD => 'Created', ORDER => $transaction }, + { FIELD => 'id', ORDER => $transaction }, + ); + $txns->Limit( FIELD => 'Type', VALUE => $transaction_type ) + if $transaction_type; + $txns->RowsPerPage(1); + return $txns->First; } # {{{ load_module @@ -181,6 +250,15 @@ sub help { . loc( "[_1] - An argument to pass to [_2]", "--action-argument", "--action" ) . "\n"; print " " + . loc( "[_1] - Specify id of the template you want to use", "--template-id" ) + . "\n"; + print " " + . loc( "[_1] - Specify if you want to use either 'first' or 'last' tarnsaction", "--transaction" ) + . "\n"; + print " " + . loc( "[_1] - Specify the type of a transaction you want to use", "--transaction-type" ) + . "\n"; + print " " . loc( "[_1] - Output status updates to STDOUT", "--verbose" ) . "\n"; print "\n"; print "\n"; @@ -197,19 +275,17 @@ sub help { ) . "\n\n"; - print " bin/rt-cron-tool \\\n"; - print - " --search RT::Search::ActiveTicketsInQueue --search-arg general \\\n"; - print - " --condition RT::Condition::UntouchedInHours --condition-arg 4 \\\n"; + print " bin/rt-crontool \\\n"; + print " --search RT::Search::ActiveTicketsInQueue --search-arg general \\\n"; + print " --condition RT::Condition::UntouchedInHours --condition-arg 4 \\\n"; print " --action RT::Action::SetPriority --action-arg 99 \\\n"; print " --verbose\n"; print "\n"; - print loc("Escalate tickets"); - print "rt-crontool \\\n"; - print " --search RT::Search::ActiveTicketsInQueue --search-arg thequeuename \\\n"; - print " --action RT::Action::EscalatePriority \\\n"; + print loc("Escalate tickets"). "\n"; + print " bin/rt-crontool \\\n"; + print " --search RT::Search::ActiveTicketsInQueue --search-arg general \\\n"; + print " --action RT::Action::EscalatePriority\n"; diff --git a/rt/bin/rt-mailgate b/rt/bin/rt-mailgate index 8af8002..5663d68 100755 --- a/rt/bin/rt-mailgate +++ b/rt/bin/rt-mailgate @@ -1,9 +1,15 @@ #!/usr/bin/perl -w -# BEGIN LICENSE BLOCK +# BEGIN BPS TAGGED BLOCK {{{ # -# Copyright (c) 1996-2003 Jesse Vincent <jesse@bestpractical.com> +# COPYRIGHT: +# +# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC +# <jesse@bestpractical.com> # -# (Except where explictly superceded by other copyright notices) +# (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 @@ -15,388 +21,34 @@ # 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. +# 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.) # -# END LICENSE BLOCK +# 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 }}} =head1 NAME rt-mailgate - Mail interface to RT3. -=begin testing - -use RT::I18N; - -# Make sure that when we call the mailgate wrong, it tempfails - -ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://bad.address"), "Opened the mailgate - The error below is expected - $@"); -print MAIL <<EOF; -From: root\@localhost -To: rt\@example.com -Subject: This is a test of new ticket creation - -Foob! -EOF -close (MAIL); - -# Check the return value -is ( $? >> 8, 75, "The error message above is expected The mail gateway exited with a failure. yay"); - - -# {{{ Test new ticket creation by root who is privileged and superuser - -ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost".$RT::WebPath."/ --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); - -#Check the return value -is ($? >> 8, 0, "The mail gateway exited normally. yay"); - -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"); - -# }}} - - -# {{{This is a test of new ticket creation as an unknown user - -ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost".$RT::WebPath."/ --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); -#Check the return value -is ($? >> 8, 0, "The mail gateway exited normally. yay"); - -$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"); - - -# }}} - -# {{{ now everybody can create tickets. can a random unkown user create tickets? - -my $g = RT::Group->new($RT::SystemUser); -$g->LoadSystemInternalGroup('Everyone'); -ok( $g->Id, "Found 'everybody'"); - -my ($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 - -ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost".$RT::WebPath."/ --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); -#Check the return value -is ($? >> 8, 0, "The mail gateway exited normally. yay"); - - -$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"); - -# }}} - - -# {{{ can another random reply to a ticket without being granted privs? answer should be no. - - -#($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 - -ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost".$RT::WebPath."/ --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); -#Check the return value -is ($? >> 8, 0, "The mail gateway exited normally. yay"); - -$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 - - -($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".$RT::WebPath."/ --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); -#Check the return value -is ($? >> 8, 0, "The mail gateway exited normally. yay"); - - -$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. - - -#($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 - -ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost".$RT::WebPath."/ --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); - -#Check the return value -is ($? >> 8, 0, "The mail gateway exited normally. yay"); - -$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 - - -($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".$RT::WebPath."/ --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); - -#Check the return value -is ($? >> 8, 0, "The mail gateway exited normally. yay"); - -$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"); - -# }}} - -# {{{ 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 => '/opt/rt3/share/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".$RT::WebPath."/ --queue general --action correspond"), "Opened the mailgate - $@"); - -$entity->print(\*MAIL); - -close (MAIL); - -#Check the return value -is ($? >> 8, 0, "The mail gateway exited normally. yay"); - -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".$RT::WebPath."/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'); - - - -# }}} - -# {{{ Simple I18N testing - -ok(open(MAIL, "|/opt/rt3/bin/rt-mailgate --url http://localhost".$RT::WebPath."/ --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); - -#Check the return value -is ($? >> 8, 0, "The mail gateway exited normally. yay"); - -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".$RT::WebPath."/ --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); - -#Check the return value -is ($? >> 8, 0, "The mail gateway exited normally. yay"); - -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); - -# }}} - - -($val,$msg) = $g->PrincipalObj->RevokeRight(Right => 'CreateTicket'); -ok ($val, $msg); - - - -=end testing - =cut @@ -420,7 +72,6 @@ for (qw(url)) { die "$0 invoked improperly\n\nNo $_ provided to mail gateway!\n" unless $opts{$_}; } -undef $/; my $ua = LWP::UserAgent->new(); $ua->cookie_jar( { file => $opts{jar} } ); @@ -431,8 +82,12 @@ my %args = ( ); # Read the message in from STDIN -$args{'message'} = <>; +$args{'message'} = do { local (@ARGV, $/); <> }; +unless ( $args{message} =~ /\S/ ) { + print STDERR "$0: no message passed on STDIN!\n"; + exit 0; +} if ($opts{'extension'}) { $args{$opts{'extension'}} = $ENV{'EXTENSION'}; @@ -500,7 +155,7 @@ sub check_failure { Usual invocation (from MTA): - rt-mailgate --action (correspond|comment) --queue queuename + rt-mailgate --action (correspond|comment|...) --queue queuename --url http://your.rt.server/ [ --debug ] [ --extension (queue|action|ticket) ] @@ -516,15 +171,31 @@ See C<man rt-mailgate> for more. =item C<--action> -Specifies whether this is a correspondence or comment address. +Specifies what happens to email sent to this alias. The avaliable +basic actions are: C<correspond>, C<comment>. + + +If you've set the RT configuration variable B<$RT::UnsafeEmailCommands>, +C<take> and C<resolve> are also available. You can execute two or more +actions on a single message using a C<-> separated list. RT will execute +the actions in the listed order. For example you can use C<take-comment>, +C<correspond-resolve> or C<take-comment-resolve> as actions. + +Note that C<take> and C<resolve> actions ignore message text if used +alone. Include a C<comment> or C<correspond> action if you want RT +to record the incoming message. + +The default action is C<correspond>. =item C<--queue> -Reflects which queue this address handles. +This flag determines which queue this alias should create a ticket in if no ticket identifier +is found. =item C<--url> -The location of the web server for your RT instance. +This flag tells the mail gateway where it can find your RT server. You should +probably use the same URL that users use to log into RT. =item C<--extension> OPTIONAL @@ -615,6 +286,7 @@ several parameters: =item Message A C<MIME::Entity> object representing the email + =item CurrentUser An C<RT::CurrentUser> object diff --git a/rt/etc/RT_Config.pm b/rt/etc/RT_Config.pm index 5386a8e..edb3659 100644 --- a/rt/etc/RT_Config.pm +++ b/rt/etc/RT_Config.pm @@ -17,7 +17,7 @@ use RT::Config; # {{{ Base Configuration -# $rtname the string that RT will look for in mail messages to +# $rtname is the string that RT will look for in mail messages to # figure out what ticket a new piece of mail belongs to # Your domain name is recommended, so as not to pollute the namespace. @@ -26,6 +26,28 @@ use RT::Config; Set($rtname , "example.com"); + +# This regexp controls what subject tags RT recognizes as its own. +# If you're not dealing with historical $rtname values, you'll likely +# never have to enable this feature. +# +# Be VERY CAREFUL with it. Note that it overrides $rtname for subject +# token matching and that you should use only "non-capturing" parenthesis +# grouping. For example: +# +# Set($EmailSubjectTagRegex, qr/(?:example.com|example.org)/i ); +# +# and NOT +# +# Set($EmailSubjectTagRegex, qr/(example.com|example.org)/i ); +# +# This setting would make RT behave exactly as it does without the +# setting enabled. +# +# Set($EmailSubjectTagRegex, qr/\Q$rtname\E/i ); + + + # You should set this to your organization's DNS domain. For example, # fsck.com or asylum.arkham.ma.us. It's used by the linking interface to # guarantee that ticket URIs are unique and easy to construct. @@ -42,14 +64,12 @@ Set($Timezone , 'US/Eastern'); # }}} -# }}} - # {{{ Database Configuration # Database driver beeing used. Case matters # Valid types are "mysql", "Oracle" and "Pg" -Set($DatabaseType , 'mysql'); +Set($DatabaseType , 'Pg'); # The domain name of your database server # If you're running mysql and it's on localhost, @@ -62,13 +82,13 @@ Set($DatabaseRTHost , 'localhost'); Set($DatabasePort , ''); #The name of the database user (inside the database) -Set($DatabaseUser , 'rt_user'); +Set($DatabaseUser , 'freeside'); # Password the DatabaseUser should use to access the database -Set($DatabasePassword , 'rt_pass'); +Set($DatabasePassword , ''); # The name of the RT's database on your database server -Set($DatabaseName , 'rt3'); +Set($DatabaseName , 'freeside'); # If you're using Postgres and have compiled in SSL support, # set DatabaseRequireSSL to 1 to turn on SSL communication @@ -89,7 +109,7 @@ Set($OwnerEmail , 'root'); Set($LoopsToRTOwner , 1); -# If $StoreLoopss is defined, RT will record messages that it believes +# If $StoreLoops is defined, RT will record messages that it believes # to be part of mail loops. # As it does this, it will try to be careful not to send mail to the # sender of these messages @@ -106,12 +126,12 @@ Set($StoreLoops , undef); Set($MaxAttachmentSize , 10000000); # $TruncateLongAttachments: if this is set to a non-undef value, -# RT will truncate attachments longer than MaxAttachmentLength. +# RT will truncate attachments longer than MaxAttachmentSize. Set($TruncateLongAttachments , undef); # $DropLongAttachments: if this is set to a non-undef value, -# RT will silently drop attachments longer than MaxAttachmentLength. +# RT will silently drop attachments longer than MaxAttachmentSize. Set($DropLongAttachments , undef); @@ -135,8 +155,12 @@ Set($RTAddressRegexp , '^rt\@example.com$'); # (These values are passed to the CanonicalizeEmailAddress subroutine in RT/User.pm) # By default, that routine performs a s/$Match/$Replace/gi on any address passed to it -Set($CanonicalizeEmailAddressMatch , 'subdomain.example.com$'); -Set($CanonicalizeEmailAddressReplace , 'example.com'); +#Set($CanonicalizeEmailAddressMatch , '@subdomain\.example\.com$'); +#Set($CanonicalizeEmailAddressReplace , '@example.com'); + +# set this to true and the create new user page will use the values that you +# enter in the form but use the function CanonicalizeUserInfo in User_Local.pm +Set($CanonicalizeOnCreate , 0); # If $SenderMustExistInExternalDatabase is true, RT will refuse to # create non-privileged accounts for unknown users if you are using @@ -175,7 +199,7 @@ Set($CommentAddress , 'RT_CommentAddressNotSet'); # If 'sendmailpipe' doesn't work well for you, try 'sendmail' # # Note that you should remove the '-t' from $SendmailArguments -# if you use 'sendmail rather than 'sendmailpipe' +# if you use 'sendmail' rather than 'sendmailpipe' Set($MailCommand , 'sendmailpipe'); @@ -186,6 +210,11 @@ Set($MailCommand , 'sendmailpipe'); # These options are good for most sendmail wrappers and workalikes Set($SendmailArguments , "-oi -t"); +# $SendmailBounceArguments defines what flags to pass to $Sendmail +# assuming RT needs to send an error (ie. bounce). + +Set($SendmailBounceArguments , '-f "<>"'); + # These arguments are good for sendmail brand sendmail 8 and newer #Set($SendmailArguments,"-oi -t -ODeliveryMode=b -OErrorMode=m"); @@ -216,12 +245,15 @@ Set($UseFriendlyToLine , 0); # are WatcherType and TicketId. Set($FriendlyToLineFormat, "\"%s of $RT::rtname Ticket #%s\":;"); -# By default RT doesn't notify the person who performs an update, as they +# By default, RT doesn't notify the person who performs an update, as they # already know what they've done. If you'd like to change this behaviour, # Set $NotifyActor to 1 Set($NotifyActor, 0); +# By default, RT records each message it sends out to its own internal database.# To change this behaviour, set $RecordOutgoingEmail to 0 + +Set($RecordOutgoingEmail, 1); # }}} @@ -247,6 +279,14 @@ Set($LogToFile , undef); Set($LogDir, '/opt/rt3/var/log'); Set($LogToFileNamed , "rt.log"); #log to rt.log +# On Solaris or UnixWare, set to ( socket => 'inet' ). Options here +# override any other options RT passes to Log::Dispatch::Syslog. +# Other interesting flags include facility and logopt. (See the +# Log::Dispatch::Syslog documentation for more information.) (Maybe +# ident too, if you have multiple RT installations.) + +@LogToSyslogConf = () unless (@LogToSyslogConf); + # }}} # {{{ Web interface configuration @@ -263,17 +303,22 @@ Set($WebPath , ""); # This is the Scheme, server and port for constructing urls to webrt # $WebBaseURL doesn't need a trailing / -Set($WebBaseURL , "http://RT::WebBaseURL.not.configured:80"); +Set($WebBaseURL , "http://localhost"); Set($WebURL , $WebBaseURL . $WebPath . "/"); # $WebImagesURL points to the base URL where RT can find its images. -Set($WebImagesURL , $WebURL . "NoAuth/images/"); +Set($WebImagesURL , $WebPath . "/NoAuth/images/"); + +# $LogoURL points to the URL of the RT logo displayed in the web UI -# $RTLogoURL points to the URL of the RT logo displayed in the web UI +Set($LogoURL , $WebImagesURL . "bplogo.gif"); -Set($LogoURL , $WebImagesURL . "rt.jpg"); +# WebNoAuthRegex - What portion of RT's URLspace should not require +# authentication. +Set($WebNoAuthRegex, qr!^(?:/+NoAuth/| + /+REST/\d+\.\d+/NoAuth/)!x ); # For message boxes, set the entry box width and what type of wrapping # to use. @@ -289,6 +334,20 @@ Set($MessageBoxWrap, "HARD"); # sent in a request (although there is probably more to it than that) Set($TrustHTMLAttachments , undef); +# Should RT redistribute correspondence that it identifies as +# machine generated? A true value (the default) will do so, setting +# this to '0' will cause no such messages to be redistributed. +# You can also use 'privileged', which will redistribute only to +# privileged users. This is seful if you get malformed bounces caused by +# autocreated requestors with bogus addresses. +Set($RedistributeAutoGeneratedMessages, 1); + +# If PreferRichText is set to a true value, RT will show HTML/Rich text +# messages in preference to their plaintext alternatives. RT "scrubs" the +# html to show only a minimal subset of HTML to avoid possible contamination +# by cross-site-scripting attacks. +Set($PreferRichText, undef); + # If $WebExternalAuth is defined, RT will defer to the environment's # REMOTE_USER variable. @@ -316,32 +375,71 @@ Set($WebExternalAuto , undef); # Set($WebSessionClass , 'Apache::Session::File'); +# By default, RT clears its database cache after every page view. +# This ensures that you've always got the most current information +# when working in a multi-process (mod_perl or FastCGI) Environment +# Setting $WebFlushDbCacheEveryRequest to '0' will turn this off, +# which will speed RT up a bit, at the expense of a tiny bit of data +# accuracy + +Set($WebFlushDbCacheEveryRequest, '1'); + + # $MaxInlineBody is the maximum attachment size that we want to see # inline when viewing a transaction. 13456 is a random sane-sounding # default. Set($MaxInlineBody, 13456); -# $MyTicketsLength is the length of the table on the front page. -# For some people, the default of 10 isn't big enough to get a feel for -# how much work needs to be done before you get some time off. +# By default, RT shows newest transactions at the bottom of the ticket +# history page, if you want see them at the top set this to '0'. + +Set($OldestTransactionsFirst, '1'); + +# $MyTicketsLength is the length of the owned tickets table on the +# front page. For some people, the default of 10 isn't big enough +# to get a feel for how much work needs to be done before you get +# some time off. Set($MyTicketsLength, 10); +# $MyRequestsLength is the length of the requested tickets table +# on the front page. + +Set($MyRequestsLength, 10); + # @MasonParameters is the list of parameters for the constructor of # HTML::Mason's Apache or CGI Handler. This is normally only useful -# for debugging, eg. profiling individual components with -# (preamble => 'my $p = MasonX::Profiler->new($m, $r);'); +# for debugging, eg. profiling individual components with: +# use MasonX::Profiler; # available on CPAN +# @MasonParameters = (preamble => 'my $p = MasonX::Profiler->new($m, $r);'); @MasonParameters = () unless (@MasonParameters); +# $DefaultSearchResultFormat is the default format for RT search results +Set ($DefaultSearchResultFormat, qq{ + '<B><A HREF="$RT::WebPath/Ticket/Display.html?id=__id__">__id__</a></B>/TITLE:#', + '<B><A HREF="$RT::WebPath/Ticket/Display.html?id=__id__">__Subject__</a></B>/TITLE:Subject', + Status, + QueueName, + OwnerName, + Priority, + '__NEWLINE__', + '', + '<small>__Requestors__</small>', + '<small>__CreatedRelative__</small>', + '<small>__ToldRelative__</small>', + '<small>__LastUpdatedRelative__</small>', + '<small>__TimeLeft__</small>'}); + + # }}} # {{{ RT UTF-8 Settings # An array that contains languages supported by RT's internationalization -# interface. Defaults to all *.po lexicons; set it to qw(en ja) will make -# RT bilingual instead of multilingual, but will save same memory. +# interface. Defaults to all *.po lexicons; setting it to qw(en ja) will make +# RT bilingual instead of multilingual, but will save some memory. @LexiconLanguages = qw(*) unless (@LexiconLanguages); @@ -371,4 +469,40 @@ Set($AmbiguousDayInPast , 1); # }}} +# {{{ Miscellaneous RT Settings + +# You can define new statuses and even reorder existing statuses here. +# WARNING. DO NOT DELETE ANY OF THE DEFAULT STATUSES. If you do, RT +# will break horribly. + +@ActiveStatus = qw(new open stalled) unless @ActiveStatus; +@InactiveStatus = qw(resolved rejected deleted) unless @InactiveStatus; + +# Backward compatability setting. Add/Delete Link used to record one +# transaction and run one scrip. Set this value to 0 if you want +# both link transactions to have a scrip run. +Set($LinkTransactionsRun1Scrip , 1); + +# }}} + + +# {{{ Development Mode +# +# RT comes with a "Development mode" setting. +# This setting, as a convenience for developers, turns on +# all sorts of development options that you most likely don't want in +# production: +# +# * Turns off Mason's 'static_source' directive. By default, you can't +# edit RT's web ui components on the fly and have RT magically pick up +# your changes. (It's a big performance hit) +# +# * More to come +# + +Set($DevelMode, '0'); + +# }}} + + 1; diff --git a/rt/html/Elements/Header b/rt/html/Elements/Header index b5512aa..d88d880 100644 --- a/rt/html/Elements/Header +++ b/rt/html/Elements/Header @@ -106,15 +106,15 @@ ONLOAD=" <tr> <td align=right> <FONT SIZE="-3"> - <A HREF="http://www.sisd.com/freeside">Freeside</A> v<% &RT::URI::freeside::FreesideVersion() %><BR> - <A HREF="<% FS::Conf->new->config('support-key') ? "http://www.sisd.com/mediawiki/index.php/Supported:Documentation" : "http://www.sisd.com/mediawiki/index.php/Freeside:1.7:Documentation" %>">Documentation</A><BR> + <A HREF="http://www.freeside.biz/freeside" TARGET="_blank">Freeside</A> v<% &RT::URI::freeside::FreesideVersion() %><BR> + <A HREF="<% FS::Conf->new->config('support-key') ? "http://www.freeside.biz/mediawiki/index.php/Supported:Documentation" : "http://www.freeside.biz/mediawiki/index.php/Freeside:1.7:Documentation" %>" TARGET="_blank">Documentation</A><BR> </FONT> </td> <td bgcolor=#000000></td> <td align=left> <FONT SIZE="-3"> - <A HREF="http://www.bestpractical.com/rt">RT</A> v<% $RT::VERSION %><BR> - <A HREF="http://wiki.bestpractical.com/">Documentation</A><BR> + <A HREF="http://www.bestpractical.com/rt" TARGET="_blank">RT</A> v<% $RT::VERSION %><BR> + <A HREF="http://wiki.bestpractical.com/" TARGET="_blank">Documentation</A><BR> </FONT> </td> diff --git a/rt/lib/RT.pm b/rt/lib/RT.pm index 7e941a2..ec461b7 100644 --- a/rt/lib/RT.pm +++ b/rt/lib/RT.pm @@ -1,29 +1,48 @@ -# BEGIN LICENSE BLOCK +# BEGIN BPS TAGGED BLOCK {{{ # -# Copyright (c) 1996-2002 Jesse Vincent <jesse@bestpractical.com> +# COPYRIGHT: +# +# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC +# <jesse@bestpractical.com> # -# (Except where explictly superceded by other copyright notices) +# (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 +# 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. # -# 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. # +# CONTRIBUTION SUBMISSION POLICY: # -# END LICENSE BLOCK - - +# (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; use strict; use RT::I18N; @@ -33,7 +52,6 @@ use RT::System; use vars qw($VERSION $System $SystemUser $Nobody $Handle $Logger $CORE_CONFIG_FILE $SITE_CONFIG_FILE - $VENDOR_CONFIG_FILE $BasePath $EtcPath $VarPath @@ -41,19 +59,23 @@ use vars qw($VERSION $System $SystemUser $Nobody $Handle $Logger $LocalEtcPath $LocalLexiconPath $LogDir + $BinPath $MasonComponentRoot $MasonLocalComponentRoot $MasonDataDir $MasonSessionDir ); -$VERSION = '3.0.9'; +$VERSION = '3.4.6'; $CORE_CONFIG_FILE = "/opt/rt3/etc/RT_Config.pm"; $SITE_CONFIG_FILE = "/opt/rt3/etc/RT_SiteConfig.pm"; + + $BasePath = '/opt/rt3'; $EtcPath = '/opt/rt3/etc'; +$BinPath = '/opt/rt3/bin'; $VarPath = '/opt/rt3/var'; $LocalPath = '/opt/rt3/local'; $LocalEtcPath = '/opt/rt3/local/etc'; @@ -61,7 +83,7 @@ $LocalLexiconPath = '/opt/rt3/local/po'; # $MasonComponentRoot is where your rt instance keeps its mason html files -$MasonComponentRoot = '/opt/rt3/share/html'; +$MasonComponentRoot = '/var/www/freeside/rt'; # $MasonLocalComponentRoot is where your rt instance keeps its site-local # mason html files. @@ -70,7 +92,7 @@ $MasonLocalComponentRoot = '/opt/rt3/local/html'; # $MasonDataDir Where mason keeps its datafiles -$MasonDataDir = '/opt/rt3/var/mason_data'; +$MasonDataDir = '/usr/local/etc/freeside/masondata'; # RT needs to put session data (for preserving state between connections # via the web interface) @@ -80,22 +102,26 @@ $MasonSessionDir = '/opt/rt3/var/session_data'; =head1 NAME - RT - Request Tracker +RT - Request Tracker =head1 SYNOPSIS - A fully featured request tracker package +A fully featured request tracker package =head1 DESCRIPTION +=head2 LoadConfig -=cut - -=item LoadConfig +Load RT's config file. First, the site configuration file +(C<RT_SiteConfig.pm>) is loaded, in order to establish overall site +settings like hostname and name of RT instance. Then, the core +configuration file (C<RT_Config.pm>) is loaded to set fallback values +for all settings; it bases some values on settings from the site +configuration file. -Load RT's config file. First, go after the core config file. -After that, try to load the vendor config. -After that, go after the site config. +In order for the core configuration to not override the site's +settings, the function C<Set> is used; it only sets values if they +have not been set already. =cut @@ -110,10 +136,10 @@ sub LoadConfig { RT::I18N->Init; } -=item Init +=head2 Init + +Conenct to the database, set up logging. - Conenct to the database, set up logging. - =cut sub Init { @@ -131,7 +157,8 @@ sub Init { $System = RT::System->new(); - InitLogging(); + InitClasses(); + InitLogging(); } @@ -140,7 +167,7 @@ sub Init { Get a database connection =cut - + sub ConnectToDatabase { require RT::Handle; unless ($Handle && $Handle->dbh && $Handle->dbh->ping) { @@ -154,9 +181,10 @@ sub ConnectToDatabase { Create the RT::Logger object. =cut + sub InitLogging { - # We have to set the record seperator ($, man perlvar) + # We have to set the record separator ($, man perlvar) # or Log::Dispatch starts getting # really pissy, as some other module we use unsets it. @@ -168,21 +196,24 @@ sub InitLogging { $RT::Logger=Log::Dispatch->new(); if ($RT::LogToFile) { - - unless (-d $RT::LogDir && -w $RT::LogDir) { - # localizing here would be hard when we don't have a current user yet - # die $self->loc("Log directory [_1] not found or couldn't be written.\n RT can't run.", $RT::LogDir); - die ("Log directory $RT::LogDir not found or couldn't be written.\n RT can't run."); - } - - my $filename; + my ($filename, $logdir); if ($RT::LogToFileNamed =~ m![/\\]!) { # looks like an absolute path. $filename = $RT::LogToFileNamed; + ($logdir) = $RT::LogToFileNamed =~ m!^(.*[/\\])!; } else { $filename = "$RT::LogDir/$RT::LogToFileNamed"; + $logdir = $RT::LogDir; } + + unless ( -d $logdir && ( ( -f $filename && -w $filename ) || -w $logdir ) ) { + # localizing here would be hard when we don't have a current user yet + # die $self->loc("Log directory [_1] not found or couldn't be written.\n RT can't run.", $RT::LogDir); + die ("Log file $filename couldn't be written or created.\n RT can't run."); + } + + package Log::Dispatch::File; require Log::Dispatch::File; @@ -200,6 +231,7 @@ sub InitLogging { )); } if ($RT::LogToScreen) { + package Log::Dispatch::Screen; require Log::Dispatch::Screen; $RT::Logger->add(Log::Dispatch::Screen->new ( name => 'screen', @@ -213,6 +245,7 @@ sub InitLogging { )); } if ($RT::LogToSyslog) { + package Log::Dispatch::Syslog; require Log::Dispatch::Syslog; $RT::Logger->add(Log::Dispatch::Syslog->new ( name => 'syslog', @@ -231,7 +264,8 @@ sub InitLogging { return "$p{message} ($filename:$line)\n"} }, - stderr => 1 + stderr => 1, + @RT::LogToSyslogConf )); } @@ -244,7 +278,14 @@ sub InitLogging { ## Mason). It will log all problems through the standard logging ## mechanism (see above). -$SIG{__WARN__} = sub {$RT::Logger->warning($_[0])}; +$SIG{__WARN__} = sub { + my $w = shift; + $w =~ s/(?:\r*\n)+$//; + # The 'wide character' warnings has to be silenced for now, at least + # until HTML::Mason offers a sane way to process both raw output and + # unicode strings. + $RT::Logger->warning($w) if index($w, 'Wide character in ') != 0; +}; #When we call die, trap it and log->crit with the value of the die. @@ -252,18 +293,38 @@ $SIG{__DIE__} = sub { unless ($^S || !defined $^S ) { $RT::Handle->Rollback(); $RT::Logger->crit("$_[0]"); - exit(-1); - } - else { - #Get out of here if we're in an eval - die $_[0]; } + die $_[0]; }; # }}} } +=head2 InitClasses + +Load all modules that define base classes + +=cut + +sub InitClasses { + require RT::Tickets; + require RT::Transactions; + require RT::Users; + require RT::CurrentUser; + require RT::Templates; + require RT::Queues; + require RT::ScripActions; + require RT::ScripConditions; + require RT::Scrips; + require RT::Groups; + require RT::GroupMembers; + require RT::CustomFields; + require RT::CustomFieldValues; + require RT::ObjectCustomFields; + require RT::ObjectCustomFieldValues; +} + # }}} @@ -275,44 +336,25 @@ sub Nobody { return ($Nobody); } - -=head2 DropSetGIDPermissions - -Drops setgid permissions. - -=cut - -sub DropSetGIDPermissions { - # Now that we got the config read in, we have the database - # password and don't need to be setgid - # make the effective group the real group - $) = $(; -} - - -=head1 SYNOPSIS - =head1 BUGS -Please report them to rt-3.0-bugs@fsck.com, if you know what's broken and have at least some idea of what needs to be fixed. -If you're not sure what's going on, report them rt-devel@lists.fsck.com. +Please report them to rt-bugs@fsck.com, if you know what's broken and have at least +some idea of what needs to be fixed. + +If you're not sure what's going on, report them rt-devel@lists.bestpractical.com. =head1 SEE ALSO L<RT::StyleGuide> L<DBIx::SearchBuilder> - - =begin testing - ok ($RT::Nobody->Name() eq 'Nobody', "Nobody is nobody"); ok ($RT::Nobody->Name() ne 'root', "Nobody isn't named root"); ok ($RT::SystemUser->Name() eq 'RT_System', "The system user is RT_System"); ok ($RT::SystemUser->Name() ne 'noname', "The system user isn't noname"); - =end testing =cut |