From 6587f6ba7d047ddc1686c080090afe7d53365bd4 Mon Sep 17 00:00:00 2001 From: Ivan Kohler Date: Tue, 24 Apr 2012 11:35:56 -0700 Subject: first pass RT4 merge, RT#13852 --- rt/docs/UPGRADING-2.0 | 7 + rt/docs/UPGRADING-3.0 | 18 + rt/docs/UPGRADING-3.2 | 11 + rt/docs/UPGRADING-3.4 | 12 + rt/docs/UPGRADING-3.6 | 49 + rt/docs/UPGRADING-3.8 | 192 + rt/docs/UPGRADING-4.0 | 108 + rt/docs/UPGRADING.mysql | 85 + rt/docs/customizing/articles_introduction.pod | 155 + rt/docs/customizing/templates.pod | 132 + rt/docs/customizing/timezones_in_charts.pod | 88 + rt/docs/extending/clickable_links.pod | 184 + rt/docs/extending/external_custom_fields.pod | 90 + rt/docs/extending/using_forms_widgets.pod | 113 + rt/docs/full_text_indexing.pod | 174 + rt/docs/glossary.pod | 30 + rt/docs/hacking.pod | 301 ++ rt/docs/network-diagram.svg | 6095 +++++++++++++++++++++++++ rt/docs/schema.dot | 99 + rt/docs/security.pod | 77 + rt/docs/web_deployment.pod | 233 + 21 files changed, 8253 insertions(+) create mode 100644 rt/docs/UPGRADING-2.0 create mode 100644 rt/docs/UPGRADING-3.0 create mode 100644 rt/docs/UPGRADING-3.2 create mode 100644 rt/docs/UPGRADING-3.4 create mode 100644 rt/docs/UPGRADING-3.6 create mode 100644 rt/docs/UPGRADING-3.8 create mode 100644 rt/docs/UPGRADING-4.0 create mode 100644 rt/docs/UPGRADING.mysql create mode 100644 rt/docs/customizing/articles_introduction.pod create mode 100644 rt/docs/customizing/templates.pod create mode 100644 rt/docs/customizing/timezones_in_charts.pod create mode 100644 rt/docs/extending/clickable_links.pod create mode 100644 rt/docs/extending/external_custom_fields.pod create mode 100644 rt/docs/extending/using_forms_widgets.pod create mode 100644 rt/docs/full_text_indexing.pod create mode 100644 rt/docs/glossary.pod create mode 100644 rt/docs/hacking.pod create mode 100644 rt/docs/network-diagram.svg create mode 100644 rt/docs/schema.dot create mode 100644 rt/docs/security.pod create mode 100644 rt/docs/web_deployment.pod (limited to 'rt/docs') diff --git a/rt/docs/UPGRADING-2.0 b/rt/docs/UPGRADING-2.0 new file mode 100644 index 000000000..a935552b5 --- /dev/null +++ b/rt/docs/UPGRADING-2.0 @@ -0,0 +1,7 @@ +UPGRADING FROM 2.x: + +The core RT distribution does not contain the tool to upgrade RT from +version 2.0; the tool, can be downloaded from CPAN at +http://search.cpan.org/dist/RT-Extension-RT2toRT3/ + +Further instructions may be found in that distribution's README file. diff --git a/rt/docs/UPGRADING-3.0 b/rt/docs/UPGRADING-3.0 new file mode 100644 index 000000000..625ca4baf --- /dev/null +++ b/rt/docs/UPGRADING-3.0 @@ -0,0 +1,18 @@ +UPGRADING FROM 3.0.x - Changes: + += Installation = + +We recommend you move your existing /opt/rt3 tree completely out +of the way before installing the new version of RT, to make sure +that you don't inadvertently leave old files hanging around. + += Rights changes = + +Now, if you want RT to automatically create new users upon ticket +submission, you MUST grant 'Everyone' the right to create tickets. +Granting this right only to "Unprivileged Users" is now insufficient. + += Web server configuration + +The configuration for RT's web interface has changed. Please refer to +docs/web_deployment.pod for instructions. diff --git a/rt/docs/UPGRADING-3.2 b/rt/docs/UPGRADING-3.2 new file mode 100644 index 000000000..c0b8cebae --- /dev/null +++ b/rt/docs/UPGRADING-3.2 @@ -0,0 +1,11 @@ +UPGRADING FROM 3.2 and earlier - Changes: + += Rights changes = + +Now, if you want any user to be able to access the Admin tools (a.k.a. +the Configuration tab), you must grant that user the "ShowConfigTab" +right. Making the user a privileged user is no longer sufficient. + +"SuperUser" users are no longer automatically added to the list of users +who can own tickets in a queue. You now need to explicitly give them the +"OwnTicket" right. diff --git a/rt/docs/UPGRADING-3.4 b/rt/docs/UPGRADING-3.4 new file mode 100644 index 000000000..4dca0451f --- /dev/null +++ b/rt/docs/UPGRADING-3.4 @@ -0,0 +1,12 @@ +UPGRADING FROM 3.3.14 and earlier - Changes: + +The "ModifyObjectCustomFieldValues" right name was too long. It has been +changed to "ModifyCustomField" + + +UPGRADING FROM 3.3.11 and earlier - Changes: + +Custom Fields now have an additional right, "ModifyCustomField". This +right governs whether a user can modify an object's custom field values +for a particular custom field. This includes adding, deleting and +changing values. diff --git a/rt/docs/UPGRADING-3.6 b/rt/docs/UPGRADING-3.6 new file mode 100644 index 000000000..3c27709cb --- /dev/null +++ b/rt/docs/UPGRADING-3.6 @@ -0,0 +1,49 @@ +UPGRADING FROM 3.6.X and earlier - Changes: + +As there are a large number of code changes, it is highly recommended +that you install RT into a fresh directory, and then reinstall your +customizations. + +The database schema has changed significantly for mysql 4.1 and above; +please read UPGRADING.mysql for more details. + +The configuration format has been made stricter. All options MUST be set +using the Set function; the historical "@XXX = (...) unless @XXX;" is no +longer allowed. + +The RTx::Shredder extension has been integrated into core, and several +features have been added, so you MUST uninstall it before upgrading. + +A new interface for making links in text clickable, and doing other +arbitrary text replacements, has been integrated into RT. You can read +more in `perldoc docs/extending/clickable_links.pod`. + +A new feature has been added that allows users to forward +messages. There is a new option in the config ($ForwardFromUser), new +rights, and a new template. + +New global templates have been added with "Error: " prefixed to the name +to make it possible to configure error messages sent to users. + +You can read about the new GnuPG integration in `perldoc +lib/RT/Crypt/GnuPG.pm`. + +New scrip conditions 'On Close' and 'On Reopen' have been added. + + +UPGRADING FROM 3.5.7 and earlier - Changes: + +Scrips are now prepared and committed in order alphanumerically by +description. This means that you can prepend a number (00, 07, 15, 24) +to the beginning of each scrip's description, and they will run in that +order. Depending on your database, the old ordering may have been by +scrip id number -- if that is the case, simply prepend the scrip id +number to the beginning of its description. + + +UPGRADING FROM 3.5.1 and earlier - Changes: + +The default for $RedistributeAutoGeneratedMessages has changed to +'privileged', to make out-of-the-box installations more resistant to +mail loops. If you rely on the old default of redistributing to all +watchers, you'll need to set it explicitly now. diff --git a/rt/docs/UPGRADING-3.8 b/rt/docs/UPGRADING-3.8 new file mode 100644 index 000000000..cb53030e4 --- /dev/null +++ b/rt/docs/UPGRADING-3.8 @@ -0,0 +1,192 @@ +UPGRADING FROM 3.8.8 and earlier - Changes: + +Previous versions of RT used a password hashing scheme which was too +easy to reverse, which could allow attackers with read access to the RT +database to possibly compromise users' passwords. Even if RT does no +password authentication itself, it may still store these weak password +hashes -- using ExternalAuth does not guarantee that you are not +vulnerable! To upgrade stored passwords to a stronger hash, run: + + perl etc/upgrade/vulnerable-passwords + +We have also proved that it's possible to delete a notable set of +records from Transactions table without losing functionality. To delete +these records, run the following script: + + perl -I /opt/rt4/local/lib -I /opt/rt4/lib etc/upgrade/shrink_transactions_table.pl + +If you chose not to run the shrink_cgm_table.pl script when you upgraded +to 3.8, you should read more about it below and run it at this point. + +The default for $MessageBoxWrap is now SOFT and $MessageBoxWidth is now +unset by default. This means the message box will expand to fill all +the available width. $MessageBoxWrap is also overridable by the user +now. These changes accommodate the new default two column layout for +ticket create and update pages. You may turn this layout off by setting +$UseSideBySideLayout to 0. To retain the original behavior, set +$MessageBoxWrap to HARD and $MessageBoxWidth to 72. + + +UPGRADING FROM 3.8.7 and earlier - Changes: + +RT's ChartFont option has been changed from a string to a hash which +lets you specify per-language fonts. RT now comes with a better default +font for charts, too. You should either update your 'ChartFont' option +to match the new format, or consider trying the new default. + +RT now gives you more precise control over the order in which custom +fields are displayed. This change requires some small changes to your +currently saved custom field orders. RT will automatically clean up +your existing custom fields when you run the standard database upgrade +steps. After that cleanup, you should make sure that custom fields are +ordered in a way that you and your users find pleasing. + + +UPGRADING FROM 3.8.6 and earlier - Changes: + +For MySQL and Oracle users: +If you upgraded from a version of RT earlier than 3.7.81, you should +already have a CachedGroupMembers3 index on your CachedGroupMembers +table. If you did a clean install of RT somewhere in the 3.8 release +series, you most likely don't have this index. You can add it manually +with: + + CREATE INDEX CachedGroupMembers3 on CachedGroupMembers (MemberId, ImmediateParentId); + + +UPGRADING FROM 3.8.5 and earlier - Changes: + +You can now forward an entire Ticket history (in addition to specific +transactions) but this requires a new Template called "Forward Ticket". +This template will be added as part of the standard database upgrade +step. + +Custom fields with categories can optionally be split out into +hierarchical custom fields. If you wish to convert your old +category-based custom fields, run: + + perl etc/upgrade/split-out-cf-categories + +It will prompt you for each custom field with categories that it finds, +and the name of the custom field to create to store the categories. + +If you were using the LocalizedDateTime RT::Date formatter from custom +code, and passing a DateFormat or TimeFormat argument, you need to +switch from the strftime methods to the cldr methods; that is, +'full_date_format' becomes 'date_format_full'. + +You may also have done this from your RT_SiteConfig.pm, using: + Set($DateTimeFormat, { + Format => 'LocalizedDateTime', + DateFormat => 'medium_date_format', + ); +Which would need to be changed to: + Set($DateTimeFormat, { + Format => 'LocalizedDateTime', + DateFormat => 'date_format_medium', + ); + + +UPGRADING FROM 3.8.3 and earlier - Changes: + +Arguments to the NotifyGroup Scrip Action will be updated as part of the +standard database upgrade process. + + +UPGRADING FROM 3.8.2 and earlier - Changes: + +A new scrip condition, 'On Reject', has been added. + + +UPGRADING FROM 3.8.1 and earlier - Changes: + +When using Oracle, $DatabaseName is now used as SID, so RT can connect +without environment variables or tnsnames.ora file. Because of this +change, your RT instance may loose its ability to connect to your DB; to +resolve this, you will need to update RT's configuration and restart +your web server. Example configuration: + + Set($DatabaseType, 'Oracle'); + Set($DatabaseHost, '192.168.0.1'); + # undefined port => will try both 1526 and 1521 + Set($DatabasePort, undef); + # ORACLE SID + Set($DatabaseName, 'XE'); + # user for RT in Oracle, RT's tables in his schema + Set($DatabaseUser, 'test'); + # above user's password + Set($DatabasePassword, 'test'); + +If you want a user to be able to access the Approvals tools (a.k.a. the +Approvals tab), you must grant that user the "ShowApprovalsTab" right. + + +UPGRADING FROM 3.8.0 and earlier - Changes: + +The TicketSQL syntax for bookmarked tickets has been changed. +Specifically, the new phrasing is "id = '__Bookmarked__'", rather than +the old "__Bookmarks__". The old form will remain, for backwards +compatibility. The standard database upgrade process will only +automatically change the global 'Bookmarked Tickets' search + + +UPGRADING FROM 3.7.85 and earlier - Changes: + +We have proved that it is possible to delete a large set of records from +the CachedGroupMembers table without losing functionality; in fact, +failing to do so may result in occasional problems where RT miscounts +users, particularly in the chart functionality. To delete these records +run the following script: + + perl -I /opt/rt4/local/lib -I /opt/rt4/lib etc/upgrade/shrink_cgm_table.pl + +After you run this, you will have significantly reduced the number of +records in your CachedGroupMembers table, and may need to tell your +database to refresh indexes/statistics. Please consult your DBA for +specific instructions for your database. + + +UPGRADING FROM 3.7.81 and earlier - Changes: + +RT::Extension::BrandedQueues has been integrated into core, and the +handling of subject tags has changed as a consequence. You will need to +modify any of your email templates which use the $rtname variable, in +order to make them respect the per-queue subject tags. To edit your +templates, log into RT as your administrative user, then click: + + Configuration -> Global -> Templates -> Select -> + +The only template which ships with RT which needs updating is the +"Autoreply" template, which includes this line: + + "There is no need to reply to this message right now. Your ticket + has been assigned an ID of [{$rtname} #{$Ticket->id()}]." + +Change this line to read: + + "There is no need to reply to this message right now. Your ticket + has been assigned an ID of { $Ticket->SubjectTag }." + +If you were previously using RT::Extension::BrandedQueues, you MUST +uninstall it before upgrading. In addition, you must run the +'etc/upgrade/3.8-branded-queues-extension' perl script. This will +convert the extension's configuration into the new format. Finally, in +templates where you were using the Tag method ($Ticket->QueueObj->Tag), +you will need to replace it with $Ticket->SubjectTag + +RT::Action::LinearEscalate extension has been integrated into core, +so you MUST uninstall it before upgrading. + +RT::Extension::iCal has been integrated into core, so you MUST uninstall +it before upgrading. In addition, you must run etc/upgrade/3.8-ical-extension +script to convert old data. + + +UPGRADING FROM 3.7.80 and earlier - Changes: + +Added indexes to CachedGroupMembers for MySQL and Oracle. +If you have previously installed RTx-Shredder, you may already +have these indexes. You can see the indexes by looking at +etc/upgrade/3.7.81/schema.* + +These indexes may take a very long time to create. diff --git a/rt/docs/UPGRADING-4.0 b/rt/docs/UPGRADING-4.0 new file mode 100644 index 000000000..a9301348e --- /dev/null +++ b/rt/docs/UPGRADING-4.0 @@ -0,0 +1,108 @@ +Common Issues + +RT now defaults to a database name of rt4 and an installation root of /opt/rt4. + +If you are upgrading, you will likely want to specify that your database +is still named rt3 (or import a backup of your database as rt4 so that +you can feel more confident making the upgrade). + +You really shouldn't install RT4 into your RT3 source tree (/opt/rt3) +and instead should be using make install to set up a clean environment. +This will allow you to evaluate your local modifications and configuration +changes as you migrate to 4.0. + +If you choose to force RT to install into /opt/rt3, or another existing RT 3.x +install location, you will encounter issues because we removed the _Overlay +files (such as Ticket_Overlay.pm) and relocated other files. You will +need to manually remove these files after the upgrade or RT will fail. +After making a complete backup of your /opt/rt3 install, you might use a +command like the following to remove the _Overlay files: + + find /opt/rt3/lib/ -type f -name '*_Overlay*' -delete + +RT has also changed how web deployment works; you will need to review +docs/web_deployment.pod for current instructions. The old +`fastcgi_server`, `webmux.pl`, and `mason_handler.*` files will not +work with RT 4.0, and should be removed to reduce confusion. + +******* +RT_SiteConfig.pm + +You will need to carefully review your local settings when moving from +3.8 to 4.0. + +If you were adding your own custom statuses in earlier versions of RT, +using ActiveStatus or InactiveStatus you will need to port these to use +the new Lifecycles functionality. You can read more about it in +RT_Config.pm. In most cases, you can do this by extending the default +active and inactive lists. + +******* +Upgrading sessions on MySQL + +In 4.0.0rc2, RT began shipping an updated schema for the sesions table +that specificies a character set as well as making the table InnoDB. As +part of the upgrade process, your sessions table will be dropped and +recreated with the new schema. + +******* +UPGRADING FROM RT 3.8.x and RTFM 2.1 or greater + +RT4 now includes an Articles functionality, merged from RTFM. +You should not install and enable the RT::FM plugin separately on RT 4. +If you have existing data in RTFM, you can use the etc/upgrade/upgrade-articles +script to upgrade that data. + +When running normal upgrade scripts, RT will warn if it finds existing +RTFM tables that contain data and point you to the upgrade-articles script. + +This script should be run from your RT tarball. It will immediately +begin populating your new RT4 tables with data from RTFM. If you have +browsed in the RT4 UI and created new classes and articles, this script +will fail spectacularly. Do *not* run this except on a fresh upgrade of +RT. + +You can run this as + + etc/upgrade/upgrade-articles + +It will ouput a lot of data about what it is changing. You should +review this for errors. + +If you are running RTFM 2.0 with a release of RT, there isn't currently an upgrade +script that can port RTFM's internal CustomField and Transaction data to RT4. + +You must also remove RT::FM from your @Plugins line in RT_SiteConfig.pm. + +******* +The deprecated classes RT::Action::Generic, RT::Condition::Generic and RT::Search::Generic +have been removed, but you shouldn't have been using them anyway. You should have been using +RT::Action, RT::Condition and RT::Search, respectively. + +* The "Rights Delegation" and "Personal Groups" features have been removed. + +* Replace the following code in templates: + + [{$Ticket->QueueObj->SubjectTag || $rtname} #{$Ticket->id}] + +with + + { $Ticket->SubjectTag } + +* Unique names are now enforced for user defined groups. New groups cannot be + created with a duplicate name and existing groups cannot be renamed to an + in-use name. The admin interface will warn about existing groups with + duplicate names. Although the groups will still function, some parts of the + interface (rights management, subgroup membership) may not work as expected + with duplicate names. Running + + /opt/rt4/sbin/rt-validator --check + + will report duplicate group names, and running it with --resolve will fix + duplicates by appending the group id to the name. + + Nota Bene: As a result of differing indexes in the schema files, Postgres and + SQLite RT databases have enforced group name uniqueness for many years at the + database level. + +******* diff --git a/rt/docs/UPGRADING.mysql b/rt/docs/UPGRADING.mysql new file mode 100644 index 000000000..77a6b389f --- /dev/null +++ b/rt/docs/UPGRADING.mysql @@ -0,0 +1,85 @@ +If you did not start by reading the README file, please start there; +these steps do not list the full upgrading process, merely a part which +is sometimes necessary. + +This file applies if either: + + 1) You are upgrading RT from a version prior to 3.8.0, on any version + of MySQL +............. OR ............. + 2) You are migrating from MySQL 4.0 to MySQL 4.1 or above + +If neither of the above cases apply, your should upgrade as per the +instructions in the README. + +These changes are necessary because MySQL 4.1 and greater changed some +aspects of character set handling that may result in RT failures; this +will manifest as multiple login requests, corrupted binary attachments, +and corrupted image custom fields, among others. In order to resolve +this issue, the upgrade process will need to modify the schema. + + 1) If you are moving the database and/or upgrading MySQL + 1a) Dump the database; with MySQL 4.1 and greater be sure to pass + the mysqldump command the --default-character-set=binary option. + This is necessary because the data was originally encoded in + Latin1. + + 1b) Configure the new MySQL to use Latin1 as the default character + set everywhere, not UTF-8. This is necessary so the import in + the next step assumes the data is Latin1. + + 1c) Import the dump made in step 1a into the new MySQL server, using + the --default-character-set=binary option on restore. This will + ensure that the data is imported as bytes, which will be + interpreted as Latin1 thanks to step 1b above. + + 1d) Test that your RT works as expected on this new database. + + 2) Backup RT's database using --default-character-set=binary + Furthermore, test that you can restore from this backup. + + 3) Follow instructions in the README file to step 6b. + + 4) Apply changes described in the README's step 6b, but only up to + version 3.7.87. + + 5) Apply the RT 3.8 schema upgrades. Included in RT is the script + etc/upgrade/upgrade-mysql-schema.pl that will generate the + appropriate SQL queries: + + perl etc/upgrade/upgrade-mysql-schema.pl db user pass > queries.sql + + If your mysql database is on a remote host, you can run the script + like this instead: + + perl etc/upgrade/upgrade-mysql-schema.pl db:host user pass > queries.sql + + 6) Check the sanity of the SQL queries in the queries.sql file + yourself, or consult with your DBA. + + 7) Apply the queries. Note that this step can take a while; it may also + require additional space on your hard drive comparable with size of + your tables. + + mysql -u root -p rt3 < queries.sql + + NOTE that 'rt3' is the default name of the RT database, change it in + the command above if your database is named differently. + + This step should not produce any errors or warnings. If you see any, + restore your database from the backup you made at step 1, and send a + report to the rt-users@lists.bestpractical.com mailing list. + + 8) Re-run the `make upgrade-database` command from step 6b of the + README, applying the rest of the upgrades, starting with 3.7.87, and + follow the README's remaining steps. + + 9) Test everything. The most important parts you have to test: + * binary attachments, like docs, PDFs, and images + * binary custom fields + * everything that may contain characters other than ASCII + +10) If you were upgrading from MySQL 4.0, you may now, if you wish, + reconfigure your newer MySQL instance to use UTF-8 as the default + character set, as step 7 above adjusted the character sets on all + existing tables to contain UTF-8 encoded data, rather than Latin1. diff --git a/rt/docs/customizing/articles_introduction.pod b/rt/docs/customizing/articles_introduction.pod new file mode 100644 index 000000000..ea49b05de --- /dev/null +++ b/rt/docs/customizing/articles_introduction.pod @@ -0,0 +1,155 @@ + +=head1 Articles + +Articles are a way of managing stock answers or frequently asked +questions. Articles are a collection of custom fields whose values can +be easily inserted into ticket replies or searched and browsed within +RT. They are organized into classes and topics. + +=head2 UI + +The user interface to Articles is available from the Tools -> Articles +menu. Admin functionality can be found under Tools -> Configuration -> +Articles. Once configured, articles will become available for searching +on the Reply/Comment page on tickets. There are configuration variables +to make Articles available on ticket creation. + +=head2 Basics + +You will need to make some decisions about how to organize your +articles. Articles will be organized into one Class and multiple +Topics. They will use Custom Fields to store their article data. +These Custom Fields can be configured on a Class by Class basis. +Classes can be made available globally or on a per-Queue basis. + +=head2 Organization + +=head3 Classes + +Classes are equivalent to RT's queues. They can be created by going +to Tools -> Configuration -> Articles -> Classes -> New Class. Articles +are assigned to one Class. When you create Custom Fields for use with +Articles, they will be applied Globally or to a Class, like Custom +Fields are applied to a Queue in RT. Each class also controls what +information is included into a reply (such as the Class header and +footer) and the Article. + +Classes need to be Applied, just like a Custom Field by using the +Applied To link. You can apply them globally or on a queue-by-queue +basis. + +hotlist. + +=head3 Topics + +You can also use Topics to organize your Articles. While editing a +Class, there is a Topic tab for Class specific Topics. You can create +global Topics from the Global tab under Tools -> Configuration. + +When editing Topics, type the name (and optionally description) of the +Topic, and then click the button at the appropriate location in the +Topic hierarchy. This should allow you to build a tree of Topics. This +tree of Topics should show up when creating or modifying articles in +the class. These can be arbitrarily nested. + +Global Topics will be available for all Articles, regardless of their +Class. Articles can belong to both global and class-specific Topics. + +Articles topics can be set from the 'Modify' screen for the article -- +simply select as many topics as you desire from the list at the bottom +of the screen. + +=head2 Custom Fields + +Articles don't have a single "body" section for each +article. Everything is a custom field (except for name, summary and +some other basic metadata). So, you need to create some custom +fields to hold the Article body and other data. These Custom Fields +should have "Applies To" be "RTFM Articles". + +Once you've created your custom fields, go into your classes and click +on "Custom Fields" and add the Custom Fields you want to each class. +Alternatively, use the Applies To link from each Custom Field. + +=head2 Creating Articles + +You can create an article from scratch by going to Tools -> Articles -> +New Article and then picking which Class to create the Article under. +The Summary, Description and Custom Fields will all be searchable when +including an Article and you can control what Custom Fields end up in +your Ticket from the Class configuration page. + +=head3 Extracting an Article + +You can extract the body of a ticket into an article. Within RT, you +should now see an "Extract to article" button in the upper right hand +corner of RT's UI when working with tickets. When you click that +button, RT will ask you which Class to create your new article in. +Once you click on a class name, the Ticket's transactions will be +displayed, along with a set of select boxes. For each transaction, you +can pick which Custom Field that transaction should be extracted to. +From there on in, it's just regular article creation. + +=head2 Including an Article + +When replying to or commenting on tickets or creating tickets, there +is a UI widget that lets you search for and include Articles in +your reply. (They're editable, of course). + +Articles can be included by searching for them, knowing the Id of the +article, using the Article Hotlist and using the Queue specific +dropdown. + +=head2 Queue Specific List of Articles + +You can use Topics to organize a set of Queue specific Articles. +Simply create a global Topic called 'Queues' and then create Topics +under Queues named after each of your Queues. Within each Queue named +Topic, create some Topics and then assign Articles to those +sub-topics. This creates a hierarchy like this: + +Queues +\-> General + \-> Topic 1 + \-> Topic 2 + +If you are replying to a Ticket in the General Queue you will be +offered a choice of Topic 1 and Topic 2 along with the searching. +After choosing Topic 1 or Topic 2, you will be given a list of +relevant articles to choose. + +Alternately, you can now implement this by applying a single class to +your queue and using the L
feature described below. + +=head2 Article Hotlist + +If you enable "All articles in this class are on dropdown on ticket +reply page" option, there will be a dropdown on the Create or Update +page which allows users to quickly include Articles. + +=head2 SelfService Interface + +If you grant the Unprivileged user group the right ShowArticle, they +will get a Search box at the top of their interface. This allows users +to look for answer to questions before creating a Ticket. + +=head1 Configuration options + +=head2 ArticleOnTicketCreate + +Set this to a true value to display the Article include interface on the +Ticket Create page in addition to the Reply/Comment page (Create.html +in addition to Update.html) + +=head2 HideArticleSearchOnReplyCreate + +On Ticket Reply (and Create if you set the above config var) +RTFM normally displays a search box and an include box (for +inputting an article id) and configurable dropdowns +of articles. These can be configured using Global Topics or +on the Class page. + +If you set this to a true value, RTFM will only display +dropdowns and hide the search boxes + +=cut diff --git a/rt/docs/customizing/templates.pod b/rt/docs/customizing/templates.pod new file mode 100644 index 000000000..5733f606c --- /dev/null +++ b/rt/docs/customizing/templates.pod @@ -0,0 +1,132 @@ +=head1 Templates + +Each template is split into two sections. A block of headers and a body. These +sections are separated by a blank line. + +Templates are processed by the L module. This module +allows you to embed arbitrary Perl code into your templates. Text wrapped +in curly braces, C<{...}> is interpreted as Perl. See L +for more information. + +=head2 Headers + +Your template may specify arbitrary email headers. Each header is a name, a +colon, then a value. So, for example, to specify a subject, you can use: + + Subject: Thanks for your bug report. + +=head3 Special Headers + +=over + +=item Content-Type: text/html + +The special header "Content-Type: text/html" tells RT that the template should +be parsed as HTML. RT will automatically make the outgoing message multipart. +That way, recipients who can read only plaintext email will receive something +readable, while users with clients which can display HTML will receive the full +experience. Please be aware that HTML support in mail clients varies greatly, +much more so than different web browsers. + +We welcome contributions of HTML-ization of builtin templates. + +=back + +=head2 Template Types + +Templates have a Type which dictates which level of code execution is +allowed. + +Templates of type C are evaluated using L +which allows arbitrary code execution. Only users which have the global +C privilege may write templates of type C. Prior to +RT 4.0, this was the only type of Template available. + +Templates of type C permit only simple variable interpolation. +No special privilege beyond C is needed to write C +templates. + +For both types of templates, text between curly braces C<{ ... }> is +interpolated. For C templates, this text can be any code (see +L). For C templates, only simple variables +are permitted; for example C<{ $TicketSubject }>. + +=head2 Variables + +=head3 Perl templates + +The variables that your templates may use include: + +=over 4 + +=item C<$Transaction> + +The transaction object. + +=item C<$rtname> + +The value of the "rtname" config variable. + +=item C<$Ticket> + +The ticket object. This is only set during a ticket transaction. + +=item C<$Requestor> + +This is not an object, but the name of the first requestor on the ticket. +If this is not what you need, inspect C<< $Ticket->Requestors >>. + +=item C + +A localization function. See L. + +=back + +=head3 Selected Simple template variables + +Since method calls are not allowed in simple templates, many common +method results have been placed into scalar variables for the template's +use. Among them: + +=over 4 + +=item $TicketId + +=item $TicketSubject + +=item $TicketStatus + +=item $TicketQueueName + +=item $TicketOwnerName + +=item $TicketOwnerEmailAddress + +=item $TicketCF(Name) + +For example, C<$TicketCFDepartment>. + +=item $TransactionType + +=item $TransactionField + +=item $TransactionOldValue + +=item $TransactionNewValue + +=item $TransactionData + +=item $TransactionContent + +=item $TransactionDescription + +=item $TransactionBriefDescription + +=item $TransactionCF(Name) + +For example, C<$TransactionCFLocation>. + +=back + +=cut + diff --git a/rt/docs/customizing/timezones_in_charts.pod b/rt/docs/customizing/timezones_in_charts.pod new file mode 100644 index 000000000..47c3a096f --- /dev/null +++ b/rt/docs/customizing/timezones_in_charts.pod @@ -0,0 +1,88 @@ +=head1 INTRODUCTION + +Every date in RT's DB is stored in UTC format. This affects charts +grouped by time periods (Annually, Monthly, etc.), in that they are by +default shown in UTC. To produce charts that are in a specific timezone, +we have to use database-specific functions to convert between timezones; +unsurprisingly, each DB has very different requirements. + +=head1 CONFIGURATION + +This code is experimental; you can enable it using the +C<$ChartsTimezonesInDB> configuration option. + +=head1 DATABASE SPECIFIC NOTES + +=head2 mysql + +The time adjustment cannot simply be converted using a numeric time +shift, as this shift value depends on the daylight saving time +properties of the time zone. + +mysql since 4.1.3 supports named timezones, but you have to fill special +tables with up-to-date timezone data. On modern systems, this is usually +a simple case of: + + mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root mysql + +mysql's doc recommends you restart server after running this; you can +read more about mysql's timezone support at +L + +=head2 PostgreSQL + +PostgreSQL uses your operating system's functions to convert timezones. +Thus, you don't need to do anything in particular except to make sure +that the data in F is up to date. On some systems +this may mean upgrading a system package. + +=head3 Note for users of Pg 7.2 and older or users upgraded from those + +You should be sure that timestamps in RT DB have no TZ set. The +TIMESTAMP column type in PostgreSQL prior to Pg 7.3 had timezone info by +default; this has been removed in more recent versions. If your RT +database has this embedded timezone info, you will need to alter the +columns to remove them before enabling this feature. + +=head2 Other databases + +There is no implementation for Oracle or SQLite at current. + +=head1 FOR DEVELOPERS + +=head2 PostgreSQL + +We use the timestamp type for all datetime fields. It either has +timezone info or not, since by default Pg 7.3 and above have no +timezone. Conversion is kinda tricky: + + timezone('Europe/Moscow', timezone('UTC', column_without_tz_info)) + timezone('to_tz', timezone('from_tz', column_without_tz_info)) + +This function flips the HAS_TZ flag on the argument, and moves the +timestamp to UTC. The first call makes no conversion, but flips the +HAS_TZ flag; the second call flips it back and does actual conversion. + +For more information, See +L +and +L + +=head2 mysql + +Once timezone information is loaded into tables on the server, +we have all the same set of named timezones in the system +and DateTime (DateTime project has copy of the TZ data in a module). + +CONVERT_TZ(TS, from, to) exists since mysql 4.1.3. Note that it takes a +timestamp, so it only supports limitted date range (usuall 1970-2038). + +=head2 Oracle + +Look at FROM_TZ function. + +=head2 SQLite + +Has no apparent timezone support. + +=cut diff --git a/rt/docs/extending/clickable_links.pod b/rt/docs/extending/clickable_links.pod new file mode 100644 index 000000000..91e9eec22 --- /dev/null +++ b/rt/docs/extending/clickable_links.pod @@ -0,0 +1,184 @@ +=head1 MakeClicky extension + +=head2 Description + +I detects various formats of data in headers and email +messages, and makes them into links in RT's web UI. + +=head2 Configuration + +You can configure which actions are enabled from RT config with the +@Active_MakeClicky option, which should contain an ordered list of the +actions you want to apply. + +By default, RT provides two actions: + +=over 4 + +=item C + +Detects C and C URLs and adds an C<[Open URL]> link +after the URL. + +=item C + +Detects URLs as C format, but replaces the URL with a link. + +=back + +RTIR, an RT extension for CERT teams (not installed with core RT), +shipps with several additional actions you can use: C, C, +C, C and C. + +=head2 Order of actions + +The order of the actions is important in situations when you use +multiple actions that could match the same block of text; only the first +matching action from the list is applied. For example, it makes no sense +to use C and C at the same time, as both +actions always match the same pieces of text. + +=head2 How it works + +Each action consists of regular expression and function that does text +replacement. When you open the history of a ticket, RT searches in the +text with the given regular expresion for matches. If it finds a match, +it calls the function with the match as the argument, then replaces the +matched text with the string returned by the function. + +While RT only searches plaintext content, the actions can generate +arbitrary HTML. + +=head2 Writing custom MakeClicky actions + +To extend the list of actions with your own types of data, use the +provided callback. Specifically, create the file +F. + +It will be called with the following arguments: + +=over 4 + +=item types + +An array reference of hash references. Modify this array +reference to add your own types; the first matching type will be +used. Each hashref should contain: + +=over 4 + +=item name + +The name of the data format; this is used in the configuration file to +enable the format. + +=item regex + +A regular expression to match against. + +=item action + +The name of the action to run (see "actions", below) + +=back + +=item actions + +A hash reference of 'actions'. Modify this hash reference to change or +add action types. Values are subroutine references which will get +called when needed. They should return the modified string. Note that +subroutine B HTML. + +=item handler + +A subroutine reference; modify it only if you have to. This can be used +to add pre- or post-processing around all actions. + +=back + +=head2 Actions' arguments + +A hash is passed to the action with two keys that always exist: + +=over 4 + +=item value + +The full match of the regular expression; this is the block of text that +will be replaced with action's result. + +=item all_matches + +And arrayref with all of the match's capturing groups; for example if +your regexp is C, then the first element will be +full match ("ticket #XXX"), the same as in 'value' key, but the second +element of the array will be the id of a ticket (XXX). Using this, you +can avoid reparsing the value in the action. Only the first eight +groups of your regexps are passed to action. + +=back + +=head2 Custom MakeClicky action example + +Create a new file F +with the content: + + <%ARGS> + $types => [] + $actions => {} + + <%INIT> + my $web_path = RT->Config->Get('WebPath'); + + # action that takes ticket ID as argument and returns link to the ticket + $actions->{'link_ticket'} = sub { + my %args = @_; + my $id = $args{'all_matches'}[1]; + return qq{$args{value}}; + }; + + # add action to the list + push @$types, { + # name, that should be used in config to activate action + name => 'short_ticket_link', + # regular expression that matches text 'ticket #xxx' + regex => qr{ticket\s+#(\d+)}i, + # name of the action that should be applied + action => 'link_ticket', + }; + + +That's all; add C to the C<@Active_MakeClicky> option +in your C, and restart your server. Creating a ticket +with "ticket #1" in the body should cause that text to be automatically +linked to the ticket in question. + +=head2 Notes for custom clicky actions writers + +=over + +=item * + +Note that an action B illegal HTML characters with entities +and/or arguments in URLs. + +=item * + +Complex regular expressions could slow down RT, as the conversion is run +each time a user opens a ticket, for every transaction. For long +tickets and complex regular expressions, this can slow down ticket +display notably. + +=item * + +Try to match the shortest expression you need with your regular +expression; otherwise another action may miss its chance to match. + +=item * + +Whenever possible, precalculate values using closures around the +functions. + +=back + +=cut diff --git a/rt/docs/extending/external_custom_fields.pod b/rt/docs/extending/external_custom_fields.pod new file mode 100644 index 000000000..c6730ae4e --- /dev/null +++ b/rt/docs/extending/external_custom_fields.pod @@ -0,0 +1,90 @@ +=head1 External custom fields + +=head2 Description + +C is an extension to custom fields that allow +you to define CFs with dynamic lists of values. Loading values into +these custom fields requires writing a little Perl code to fetch the +data from the external source. + +=head2 Introduction into writing source of values + +For each type of data source that you want, you'll need to put a file in +F (or equivalent if you +installed RT into someplace other than F). To get a sense of +the code that you'll need to write, take a look at the code in +L for a simple example +which just uses RT's API to pull in a list of RT's groups. + +Running C will +show you the documentation for the API that needs to be fulfilled; +copying and editing the C example is probably a fine place to +start. + +Later in this doc we'll describe the example a little bit more. + +=head2 Configuration + +After the custom code is written, you need to tell RT about its +existence by adding something like following to your RT_SiteConfig.pm: + + Set(@CustomFieldValuesSources, "RT::CustomFieldValues::MySource"); + +The value in quotes should be the name of the class that you created. + +Stop and start your web server to enable any config changes. Open the +web interface as an administrative user (such as root), and create new +custom field. Set its type to be a Select or Autocomplete field, and +save the changes. You should now you have ability to select a "source" +for values. Choose the class you wrote from the list and the save +changes. + +=head2 How to write custom source + +You have to implement a subclass of L. +There are two main methods you want to override: + +=over 4 + +=item SourceDescription + +This method should return a string describing the data source; this is +the identifier which the administrator will see in the dropdown in the +web interface. See L. + +=item ExternalValues + +This method should return an array reference of hash references. The +hash references should contain keys for C, C, and +C. C is most important one; the others are optional. + +=back + +Here's a simple static example: + + package RT::CustomFieldValues::MySource; + + # define class inheritance + use base qw(RT::CustomFieldValues::External); + + # admin friendly description, the default valuse is the name of the class + sub SourceDescription { + return 'My Source'; + } + + # actual values provider method + sub ExternalValues { + # return reference to array ([]) + return [ + # each element of the array is a reference to hash that describe a value + # possible keys are name, description and sortorder + { name => 'value1', description => 'external value', sortorder => 1 }, + { name => 'value2', description => 'another external value', sortorder => 2 }, + # values without description are also valid, the default description is empty string + { name => 'value3', sortorder => 3 }, + # you can skip sortorder too, but note that the default sortorder is 0 (zero) + { name => 'value3' }, + ]; + } + + 1; # don't forget to return some true value diff --git a/rt/docs/extending/using_forms_widgets.pod b/rt/docs/extending/using_forms_widgets.pod new file mode 100644 index 000000000..8deb91362 --- /dev/null +++ b/rt/docs/extending/using_forms_widgets.pod @@ -0,0 +1,113 @@ +=head1 Using widgets F + +This widgets was implemented to address several common issues in handling +request arguments and allow developers to avoid reinventing the wheel. + +=head2 General info + +Each component shows widget by default and has two methods: Process and +InputOnly. The first one method process arguments and return new value +of a parametr. The second one is helper that shows only form elements +with minimum of required text labels. + +So you show a widget with: + <& /Widgets/Form/Integer, + Name => 'NameOfInputElement', + Description => 'Input integer', + &> + +You can show only C box using: + <& /Widgets/Form/Integer:InputOnly, + Name => 'NameOfInputElement', + &> + +In such a simple case you even can avoid processing. Yeah, most probably +you want to check if value is really integer, but these widgets don't +do validation for you, but they are more about fetching values from +hash of arguments, showing these values to user and preserving state +of value between form reloads (see below). + +=head2 Processing + +Processing is required when you use L, +such as Default, Multiple or Alternative. + +To process arguments of a request you have to do the following: + $ARGS{'NameOfInputElement'} = $m->comp( + '/Widgets/Form/Integer:Process', + Arguments => \%ARGS, + Name => 'NameOfInputElement', + ); + +The method returns processed value in canonical form. For different widgets +a canonical form is different and depends on activated features, so you must +always activate the same features during showing a widget and processing +results. + +=head2 Extendent features + +=head3 Default value + +If C argument is true then widgets expect that there is some +default value for argument if user fills nothing. 'Nothing' in each +widget is different, for example in select box it's special option +which is always the first one, in integer box string '' means empty +value, but boolean box uses radio buttons in this case with three +options: Yes, No and Default. + +Each widget that supports C feature as well has C and +C arguments. + +=head4 Processing and showing with activated Default feature + +When this option is activated then C method returns undef +value if user selected default value. So for integer box it's empty +string and so on. + +As well when you show a widget you should pass undef as C +to inform widget that the current value is default one. + +As all methods of a widget are consistent in this behaviour so you +shouldn't care much about that, but this allows you to implement +custom actions if processing returned undef, for example delete user's +preference record instead of updating it (default value may change later to). + +=head4 C when C is not active + +DefaultValue argument is still actual in the Process method even if +C is not true. This argument defines intial value. If value +of a key in Arguments is not defined then it's treated as intial state +and the method returns default value. + +=head3 Multiple and Alternative + +These options are only supported by the select widget. + +TODO: Add more info + +=head2 Implementation details + +=head3 Boolean widget + +This widget a little bit tricky. When you use Default option then +things are simple and you see three radio buttons, but in other +case we use a checkbox. But as you know browsers don't pass unchecked +boxes to server, so arguments of a request has no entry for them. + +In the latter case it's hard to figure out case when user unselected +value. Imagine form with a checkbox, you want show it checked by +default and as well form is reloadable (like Reply forms that have +"Add Another File" buttons). User uncheck the box and then upload +file, in this case you want to show user's choice instead of default, +but browser doesn't send any value and you can not figure out if +it's initial state or page reload. To solve this problem we use magic +hidden input field with the same name as the box and value equal to +zero (0). Mason folds arguments with the same name into array refs, so +we get 0 if box is unchecked and [0, 1] if box is checked. An array +reference is true value and 0 is defined value so we know that it's +not initial state and avoid switching back to default. As well this +trick works good in a case when you want show a link to a page and +define default choice for some boolean argument, you don't need +to set argument twice, you just set it to true value (for ex. 1) and +things just work. + diff --git a/rt/docs/full_text_indexing.pod b/rt/docs/full_text_indexing.pod new file mode 100644 index 000000000..0952b4eb9 --- /dev/null +++ b/rt/docs/full_text_indexing.pod @@ -0,0 +1,174 @@ +=head1 NAME + +Full text indexing in RT + +=head1 LIMITATIONS + +While all of the below solutions can search for Unicode characters, they +are not otherwise Unicode aware, and do no case folding, normalization, +or the like. That is, a string that contains C followed by C will not match a +search for C. They also only +know how to tokenize C-ish languages where words are separated +by whitespace or similar characters; as such, support for searching for +Japanese and Chinese content is extremely limited. + +=head1 POSTGRES + +=head2 Creating and configuring the index + +Postgres 8.3 and above support full-text searching natively; to set up +the required C column, and create either a C or C +index on it, run: + + sbin/rt-setup-fulltext-index + +If you have a non-standard database administrator username or password, +you may need to pass the C<--dba> or C<--dba-password> options: + + sbin/rt-setup-fulltext-index --dba postgres --dba-password secret + +This will also output an appropriate C<%FullTextSearch> configuration to +add to your F; you will need to restart your webserver +after making these changes. However, the index will also need to be +filled before it can be used. To update the index initially, run: + + sbin/rt-fulltext-indexer --all + +This will tokenize and index all existing attachments in your database; +it may take quite a while if your database already has a large number of +tickets in it. + +=head2 Updating the index + +To keep the index up-to-date, you will need to run: + + sbin/rt-fulltext-indexer + +...at regular intervals. By default, this will only tokenize up to 100 +tickets at a time; you can adjust this upwards by passing +C<--limit 500>. Larger batch sizes will take longer and +consume more memory. Care should be taken to ensure that multiple +instances of C are not run at the same time. + +=head1 MYSQL + +MySQL does not support full-text indexing natively. However, it does +integrate with the external Sphinx engine, available from +L. Unfortunately, Sphinx integration (using +SphinxSE) does require that you recompile MySQL from source. Most +distribution-provided packages for MySQL do not include SphinxSE +integration, merely the external Sphinx tools; these are not sufficient +for RT's needs. + +=head2 Compiling MySQL and SphinxSE + +SphinxSE requires MySQL 5.0 or 5.1; later versions of MySQL have not +been tested at this time. Sphinx version 2.0.1 has been tested to work, +but version 0.9.9 may work as well. Compilation and installation +instructions for MySQL with SphinxSE can be found at +L. + +=head2 Creating and configuring the index + +Once MySQL has been recompiled with SphinxSE, and Sphinx itself is +installed, you may create the required SphinxSE communication table via: + + sbin/rt-setup-fulltext-index + +If you have a non-standard database administrator username or password, +you may need to pass the C<--dba> or C<--dba-password> options: + + sbin/rt-setup-fulltext-index --dba root --dba-password secret + +This will also provide you with the appropriate C<%FullTextSearch> +configuration to add to your F; you will need to +restart your webserver after making these changes. It will also print a +sample Sphinx configuration, which should be placed in +F, or equivalent. + +To fill the index, you will need to run the C command-line tool +provided by Sphinx: + + indexer rt + +Finally, start the Sphinx search daemon: + + searchd + +=head2 Updating the index + +To keep the index up-to-date, you will need to run: + + indexer rt --rotate + +...at regular intervals in order to pick up new and updated attachments +from RT's database. Failure to do so will result in stale data. + +=head2 Caveats + +Sphinx only returns a finite number of matches to any query; this number +is controlled by C in F and +C<%FullTextSearch>'s C in C, which must be +kept in sync. The default, set during C, is +10000. This limit may lead to false negatives in search results if the +maximum number of matches is reached but the results returned do not +match RT's other criteria. + +Take, for example, the instance where Sphinx is configured to return a +maximum of three results, and tickets 1, 2, 3, 4, and 5 contain the +string "target", but only ticket 5 is in status "Open". A search for +C may return no results, +despite ticket 5 matching those criteria, as Sphinx will only return +tickets 1, 2, and 3 as possible matches. + +After index creation, altering C in C is +insufficient to adjust this limit; both C in +F and C<%FullTextSearch>'s C in +C must be updated. + +=head1 ORACLE + +=head2 Creating and configuring the index + +Oracle supports full-text indexing natively using the Oracle Text +package. Once Oracle Text is installed and configured, run: + + sbin/rt-setup-fulltext-index + +If you have a non-standard database administrator username or password, +you may need to pass the C<--dba> or C<--dba-password> options: + + sbin/rt-setup-fulltext-index --dba sysdba --dba-password secret + +This will create an Oracle CONTEXT index on the Content column in the +Attachments table, as well as several preferences, functions and +triggers to support this index. The script will also output an +appropriate C<%FullTextSearch> configuration to add to your +F. + +=head2 Updating the index + +To update the index, you will need to run the following at regular +intervals: + + sbin/rt-fulltext-indexer + +This, in effect, simply runs: + + begin + ctx_ddl.sync_index('rt_fts_index', '2M'); + end; + +The amount of memory used for the sync can be controlled with the +C<--memory> option: + + rt-fulltext-indexer --memory 10M + +Instead of being run via C, this may instead be run via a +DBMS_JOB; read the B +chapter of Oracle's B for details +how to keep the index optimized, perform garbage collection, and other +tasks. + +=cut diff --git a/rt/docs/glossary.pod b/rt/docs/glossary.pod new file mode 100644 index 000000000..0e058ba02 --- /dev/null +++ b/rt/docs/glossary.pod @@ -0,0 +1,30 @@ +=head1 RT Glossary + +This document is intended to be a glossary of terms used in RT. Currently it +doesn't even scratch the surface, but with time it should be expanded. + +=head2 Right names + +RT uses a handful of (mostly) standard prefixes to create right names of the +form "". The prefixes and their meanings (if not apparent) +are explained here. + +=over 4 + +=item Admin - Create, modify, and delete + +=item Create + +=item Delete + +=item Edit - Create, modify, and delete + +=item Load - See/show + +=item Modify - Change the content, details and/or metadata + +=item See - Allow viewing of + +=item Show - Allow viewing of, or display in the interface + +=back diff --git a/rt/docs/hacking.pod b/rt/docs/hacking.pod new file mode 100644 index 000000000..8aa84fd01 --- /dev/null +++ b/rt/docs/hacking.pod @@ -0,0 +1,301 @@ +=head1 Development of RT + +RT's source code is stored in a C repository. If you are not +familiar with git, see L, below, for a short tutorial +which will give you enough information to get started submitting patches +to RT. + +The rest of this document details conventions and tips surrounding the +organization of RT's version control, source code conventions, and how +to submit patches. + + + +=head1 Organization of rt.git + +The RT source repository is available via git from GitHub; you can +browse it at L or obtain a local +copy via: + + git clone git://github.com/bestpractical/rt.git + +The bleeding-edge development happens in the C branch. When a +major release is anticipated, a "trunk" branch will be branched from +this -- for example, C<4.0-trunk>. This will allow the trunk to +stabilize while feature development continues on C. +Additionally, as a release is impending for a particular series, a +release engineering branch will be created, named, for example +C<4.0.0-releng>. + +New feature development should always be based off of the C +branch. Branches to fix bugs should be based off of whichever trunk the +bug was first found in. If you found the bug in your RT 4.0.0 install, +you'd branch from 4.0-trunk. + +Branches should be named based on the trunk they are branched +from -- which is to say, the earliest branch they might be merged into. +For example, a bugfix branched from C<4.0-trunk> might be named +C<4.0/fail-taint-mode-early>. A feature branched from C when +there exists a C<4.0-trunk> but no C<4.2-trunk> might be named +C<4.2/rename-LogToScreen>. For consistency, branches should use dashes, +not underscores, to separate words. + +Branches should be reviewed by another developer before being merged. +Reviewers should make sure that the branch accomplishes what it claims +to, and does not introduce any unwanted behavior in doing so. Commit +messages explain the B as much as the B of each commit, and +not include extranous changes. + + +=head1 Code conventions + +The RT codebase is more than ten years old; as such, there are sections +which do not (yet) conform to the guidelines below. Please attempt to +follow the guidelines, even if the code surrounding your changes does +not yet. + +RT also includes a F<.perltidyrc> in its top-level which encodes many of +the conventions. + +=over + +=item Indentation + +Each level of indentation should be four spaces; tabs should never be +used for indentation. + +=back + +=head1 Internationalization + +RT has been translated into several dozen languages. We use Launchpad +( https://translations.launchpad.net/rt ) to crowdsource our +translations into C files. RT uses L to +localize its user interface. + +Your first stop on this magical journey of internationalization +is L, which explains the whys of +L. RT uses most of the features developed in that +article. + +Strings that are displayed to users should be passed through the +C function or the C<< <&|/l&>... >> Mason template. +C and C both take parameters, which are used in place of +string interpolation (much like C). It's acceptable to use +HTML in C calls, especially for bold and emphasis. However, you +should limit the amount of HTML that translators must keep exactly +correct, which means avoid including tags that wrap the entire +translatable string, especially C<<

>>. + +

<&|/l, $button &>Do not click [_1]

# ok + + <&|/l, $button &>

Do not click [_1]

# not ok + +In a few places in RT we also pass HTML as parameters to C +so that translators do not have to reproduce it exactly, and we can +also change it more freely. For example: + + <&|/l, + '', + '', + &>Distributed under [_1]version 2 of the GNU GPL[_2]. + +F looks for C and +C<< <&|/l&>... >> in our source code to pick out translatable +strings, clean them up, and put them into F files. We use +our C<.po> files not only to populate L's lexicons, +but also to sync new translatable strings and translations with +Launchpad. This Launchpad sync is typically done early during the +freeze of RC releases to give our volunteer translators time to +translate all the new strings which, because of the RC freeze, won't +continue changing. + +Because C and C are used to generate strings for human +eyes, they generally must be used "close to the browser". These are +directly in Mason templates, or in functions that return text that +will be passed through Mason. However, in many places in RT we have +hardcoded strings which need translations. For example, the C<$RIGHTS> +hash in F maps rights' names (which must be +translatable) to their descriptions (which also must be translatable). +However, when we're declaring such structures, we do not want to +translate them straight away. RT uses English internally, including +in its web forms, so we do not want to localize rights' names except +for display, otherwise things might break weirdly when you check +if a user has the "Superusuario" right. Furthermore, when we're +declaring such data structures at compile time, there is no current +user to select which language to use for localization. Thus, we +cannot call C when declaring C<$RIGHTS> and other similar +places. + +For this reason, F lets you +denote translatable strings with comments. That's what the C<#loc_pair> +comments in the C<$RIGHTS> hash in F indicate. +Since we have those comments, our toolchain will put the rights' +names and descriptions into F files, which enables +translation by our lovely volunteers. Later on, when RT displays +information about rights in the web UI, we'll pass the right's name +through C, and L will then be able to find +our "Superusuario". So although we never used a literal +C, we still get its effects thanks to the +C<#loc_pair> comments and using C. + +C<#loc_pair> is used for declaring that the both the key and value +of a particular C<< key => value >> pair are translatable. There +are other markers that you can use. + +C<#loc> is used for declaring that a particular string is translatable. +Its parsing is pretty strict so you can use it to declare that only +the value of a particular C<< key => value >> pair is translatable. + +C<#loc_left_pair> is used for declaring that the I of a +particular C<< key => value >> pair is translatable. This is of +very limited usefulness. + +C<#loc_right_pair> does NOT exist. C<#loc> works in such cases since +its parser does not extend beyond the string at the end of a line. + +=head1 Development tips + +=head2 Setting up a development environment + +=head2 Test suite + +RT also comes with a fairly complete test suite. To run it, you will +need to set environment variables to a database user and password which +can create and drop databases: + + export RT_DBA_USER=root + export RT_DBA_PASSWORD= + +You'll need to configure RT and make sure you have all the dependencies +before running tests. To do this in place without installing: + + ./configure.ac --with-my-user-group --enable-layout=inplace --with-devel-mode + make testdeps + make fixdeps + +Adjust the relevant database options as necessary if you want to test on +Postgres, Oracle, or SQLite. The default is MySQL. + +To run the test suite: + + make test + +If you have multiple processors, you can run the test suite in parallel, +which will be significantly faster: + + make test-parallel + +The C<*-trunk> and C branches are expected to be passing always +be passing all tests. While it is acceptable to break tests in an +intermediate commit, a branch which does not pass tests will not be +merged. Ideally, commits which fix a bug should also include a testcase +which fails before the fix and succeeds after. + + + +=head1 git quickstart + +=over + +=item 1. + +You will first need to obtain a copy of git; this is accomplished via +C in RedHat and derivatives, or C for Debian or Ubuntu. + +=item 2. + +Next, obtain a copy of the RT source from git: + + git clone git://github.com/bestpractical/rt.git + cd rt + +=item 3. + +Configure git to know your name and email address; git uses these when +it makes commits. + + git config user.email your.email@example.com + git config user.name Examp L. Name + +=item 4. + +Switch to the appropriate point to base your work on; this is generally +C followed by the major version, followed by C<-trunk>. For +example, if your bug was observed in version 3.8.9, you would choose +C; if it was in 4.0.0, you would choose +C. New features should be based on C. + + git checkout --track origin/4.0-trunk + +=item 5. + +Give your branch a name based on what you are attempting to accomplish. +We suggest that branch names be lower-case and separate words with +dashes, but this branch name is purely for your own reference. + + git branch -m gnupg-encryption + +=item 6. + +Edit the source tree to make your changes. A few commands you may find +useful in doing so are listed below. + +To see what files you have changed: + + git status + +To see a line-by-line list of changes: + + git diff + +To revert a file to the original version: + + git checkout path/to/file + +To revert only individual parts of a file: + + git checkout -p path/to/file + +See L for more tips for working with the RT codebase. + +=item 7. + +Check that you have no extraneous changes using C, then commit +your changes: + + git commit -a + +You will be prompted to type your commit message. The first line should +be a short (E 80 character) summary of the changes, followed by a +blank line, followed by a longer description, if necessary. The commit +message should not simply restate the diff of which lines were added and +subtracted, but should rather explain B those changes accomplish, +and B they are desired. + +If your changes are easily split into multiple components, you may wish +to split your changes into more than one commit; simply return to step 6 +and repeat the with the next related change. If your changes are B +related to each other, you should submit them separately; finish step 9, +then start over from step 4. + +=item 8. + +Save your commits to patch files: + + git format-patch @{u} + +This will print out the names of the files as it creates them. + +=item 9. + +Attach these files to an email using your standard email client, and +send it to C. + +=back + +If you have another bug or feature to implement, simply restart the +process at step 4. + +=cut diff --git a/rt/docs/network-diagram.svg b/rt/docs/network-diagram.svg new file mode 100644 index 000000000..cbd3fe1d1 --- /dev/null +++ b/rt/docs/network-diagram.svg @@ -0,0 +1,6095 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Users + + + + + + + + + + + + + + + + + + + + + + + + + + + + Mail server + + + + + + + + + + + + + + + + + + + + + + + + + + + Database server + PostgreSQL, MySQL, Oracle + postfix, exim, qmail,sendmail, Exchange, etc. + + RT webserver + Apache, lighttpd, nginx, etc. + + + + + + + + + + + + + + + + + + + + + + + + + + + External authentication + LDAP, Active Directory, externaldatabase, webauth + New tickets and replies via email to RT + Notification emails from RT + Web interface + Optional authentication source + For small installations, the database server can be on the same server as RT. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Example Request Trackernetwork setup + + + + diff --git a/rt/docs/schema.dot b/rt/docs/schema.dot new file mode 100644 index 000000000..d81ceee12 --- /dev/null +++ b/rt/docs/schema.dot @@ -0,0 +1,99 @@ +digraph g { +graph [ +rankdir = "RL", + concentrate = true, +ratio = auto +]; +node [ +fontsize = "18", +shape = record, fontsize = 18 +]; +edge [ +]; + +"Records" [shape = record, fontsize = 18, label = "(Any RT::Record)" ]; +"Records" -> "Principals" [label = "Creator → id"]; +"ACL" [shape = record, fontsize = 18, label = " \N " ]; +"ACL" -> "Principals" [label="PrincipalId → id"]; +"ACL" -> "Records" [label="ObjectId → id"]; + +"Attachments" [shape = record, fontsize = 18, label = " \N " ]; +"Attachments" -> "Transactions" [label="TransactionId → id"]; +"Attachments" -> "Attachments" [label="Parent → id"]; + +"CachedGroupMembers" [shape = record, fontsize = 18, label = " \N " ]; +"CachedGroupMembers" -> "Groups" [label="GroupId → id", weight=2]; +"CachedGroupMembers" -> "Principals" [label="MemberId → id"]; +"CachedGroupMembers" -> "CachedGroupMembers" [label="Via → id"]; +"CachedGroupMembers" -> "Groups" [label="ImmediateParentId → id"]; + +"CustomFields" [shape = record, fontsize = 18, label = " \N " ]; + +"CustomFieldValues" [shape = record, fontsize = 18, label = " \N " ]; +"CustomFieldValues" -> "CustomFields" [label="CustomField → id"]; + +"GroupMembers" [shape = record, fontsize = 18, label = " \N " ]; +"GroupMembers" -> "Groups" [label="GroupId → id", weight=2]; +"GroupMembers" -> "Principals" [label="MemberId → id", weight = 2]; + +"Groups" [shape = record, fontsize = 18, label = " \N " ]; +"Groups" -> "Principals" [label="id → id"]; + +"Links" [shape = record, fontsize = 18, label = " \N " ]; +"Links" -> "Tickets" [label="LocalBase ⇢ id (usually)", style="dotted"]; +"Links" -> "Tickets" [label="LocalTarget ⇢ id (usually)", style="dotted"]; + +"Principals" [shape = record, fontsize = 18, label = " \N " ]; + +"Attributes" [shape = record, fontsize = 18, label = " \N " ]; +"Attributes" -> "Records" [label="ObjectId → id"]; + +"Queues" [shape = record, fontsize = 18, label = " \N " ]; + +"ScripActions" [shape = record, fontsize = 18, label = " \N " ]; + +"ScripConditions" [shape = record, fontsize = 18, label = " \N " ]; + +"Scrips" [shape = record, fontsize = 18, label = " \N " ]; +"Scrips" -> "ScripConditions" [label="ScripCondition → id"]; +"Scrips" -> "ScripActions" [label="ScripAction → id"]; +"Scrips" -> "Templates" [label="Template → id"]; +"Scrips" -> "Queues" [label="Queue → id"]; + +"Templates" [shape = record, fontsize = 18, label = " \N " ]; +"Templates" -> "Queues" [label ="Queue → id" ]; + +"ObjectCustomFields" [shape = record, fontsize = 18, label = " \N " ]; +"ObjectCustomFields" -> "CustomFields" [label="CustomField → id"]; +"ObjectCustomFields" -> "Records" [label="ObjectId → id"]; + +"ObjectCustomFieldValues" [shape = record, fontsize = 18, label = " \N " ]; +"ObjectCustomFieldValues" -> "CustomFields" [label="CustomField → id"]; +"ObjectCustomFieldValues" -> "Records" [label="ObjectId → id"]; + +"Tickets" [shape = record, fontsize = 18, label = " \N " ]; +"Tickets" -> "Tickets" [label="EffectiveId → id"]; +"Tickets" -> "Principals" [label="Owner → id"]; +"Queues" -> "Tickets" [style="invis"]; +"Tickets" -> "Queues" [label="Queue → id"]; + +"Transactions" [shape = record, fontsize = 18, label = " \N " ]; +"Transactions" -> "Records" [label="ObjectId → id"]; + +"Users" [shape = record, fontsize = 18, label = " \N " ]; + +"Users" -> "Principals" [label="id → id"]; + +// "Classes" [shape = record, fontsize = 18 label = " \N " ]; +// "Articles" [shape = record, fontsize = 18 label = " \N " ]; +// "Articles" -> "Classes" [ label="Class → id"]; +// "Articles" -> "Articles" [ label="Parent → id"]; +// "ObjectClasses" [shape = record, fontsize = 18 label = " \N " ]; +// "ObjectClasses" -> "Records" [label="ObjectId → id"]; +// "ObjectClasses" -> "Classes" [label="Class → id"]; +// "Topics" [shape = record, fontsize = 18 label = " \N " ]; +// "ObjectTopics" [shape = record, fontsize = 18 label = " \N " ]; +// "ObjectTopics" -> "Records" [label="ObjectId → id"]; +// "ObjectTopics" -> "Topics" [label="Topic → id"]; + +} diff --git a/rt/docs/security.pod b/rt/docs/security.pod new file mode 100644 index 000000000..b8650e05d --- /dev/null +++ b/rt/docs/security.pod @@ -0,0 +1,77 @@ +=head1 RT Security + +=head2 Reporting security vulnerabilities in RT + +If you believe you've discovered a security issue in RT, please send an +email to with a detailed description of the +issue, and a secure means to respond to you (such as your PGP public +key). + +More information is available at L. + +=head2 Security tips for running RT + +=over + +=item * + +Protect your RT installation by making it only accessible via SSL. This +will protect against users' passwords being sniffed as they go over the +wire, as well as helping prevent phishing attacks. If you use SSL, you +will need to install some additional Perl libraries so that C +can connect. You can use the C<--enable-ssl-mailgate> command to +configure to automate the installation of these dependencies. This is +documented further in step 10 of the README. + +You should use a certificate signed by a reputable authority, or at very +least a certificate signed by a consistent local CA, which you configure +your local systems to trust. If your SSL certificate is self-signed, it +does little to prevent phishing, as users are trained to accept the +unauthorized certificate. See also the C<--no-verify-ssl> flag to +C. + +=item * + +Be sure to change the password for the C user of RT. The default +password is C. This can be changed via the RT web interface +at: Preferences > About me + + +=item * + +Be sure to protect your F file if it contains database +credentials or other sensitive information. This file only needs to be +readable by RT and your web server. One way to accomplish this is to +make the file readable only by root and the group that RT runs as, and +then make sure your web server is a member of that group. Advanced +configuration may be required if other users have the ability to run +CGIs or access the server where RT is running. + + +=item * + +Be sure to protect your database. If it does not need to talk to the +world, then don't allow it to listen for remote connections. With MySQL +this can be accomplished via C. If you use your +database for other things and must allow remote connections, be sure to +use a strong, hard to guess password for RT. + + +=item * + +Apache, lighttpd, and most other web servers support name based virtual +hosts. When possible, configure RT as a name based virtual host to +raise the bar against DNS rebinding attacks. If you see RT when you +visit http://your.servers.ipaddress.here, it means you are likely not +getting this additional protection. + + +=item * + +Use groups to organize RT permissions. Granting permissions per-user +makes them, in general, more easily over-granted and forgotten, and more +likely to diverge from each other, forming a maintenance hassle. + +=back + +=cut diff --git a/rt/docs/web_deployment.pod b/rt/docs/web_deployment.pod new file mode 100644 index 000000000..65065c5cd --- /dev/null +++ b/rt/docs/web_deployment.pod @@ -0,0 +1,233 @@ +=head1 Setting up the web interface + +As of RT 3.9, RT's web interface speaks PSGI +(L) which lets you use RT with any PSGI-supported web +server (which includes Apache, nginx, lighttpd, etc). + +=head2 Standalone + +The standalone RT web server is backed by a pure-Perl server engine +(L). This standalone server is appropriate for development +and testing, but is not appropriate for production use. + +You should not run this server against port 80 (which is the default port) +because that requires root-level privileges and may conflict with any existing +listeners. So choose a high port (for example 8080) and start the standalone +server with: + + /opt/rt4/sbin/rt-server --port 8080 + +You can also run C with any other PSGI server, for example, +to use L, a high performance preforking server: + + /opt/rt4/sbin/rt-server --server Starman --port 8080 + +B: After you run the standalone server as root, you will need to +remove your C directory, or the non-standalone servers +(Apache, etc), which run as a non-privileged user, will not be able to +write to it and will not work. + + +=head2 Apache + +B: Both C and C are known to break RT. +C will cause RT's CSS and JS to not be loaded, making RT +appear unstyled. C will cache cookies, making users be +spontaneously logged in as other users in the system. + +=head3 mod_fastcgi + + # Tell FastCGI to put its temporary files somewhere sane; this may + # be necessary if your distribution doesn't already set it + #FastCgiIpcDir /tmp + + FastCgiServer /opt/rt4/sbin/rt-server.fcgi -processes 5 -idle-timeout 300 + + + ### Optional apache logs for RT + # Ensure that your log rotation scripts know about these files + # ErrorLog /opt/rt4/var/log/apache2.error + # TransferLog /opt/rt4/var/log/apache2.access + # LogLevel debug + + AddDefaultCharset UTF-8 + + Alias /NoAuth/images/ /opt/rt4/share/html/NoAuth/images/ + ScriptAlias / /opt/rt4/sbin/rt-server.fcgi/ + + DocumentRoot "/opt/rt4/share/html" + + Order allow,deny + Allow from all + + Options +ExecCGI + AddHandler fastcgi-script fcgi + + + +=head3 mod_fcgid + + + ### Optional apache logs for RT + # Ensure that your log rotation scripts know about these files + # ErrorLog /opt/rt4/var/log/apache2.error + # TransferLog /opt/rt4/var/log/apache2.access + # LogLevel debug + + AddDefaultCharset UTF-8 + + Alias /NoAuth/images/ /opt/rt4/share/html/NoAuth/images/ + ScriptAlias / /opt/rt4/sbin/rt-server.fcgi/ + + DocumentRoot "/opt/rt4/share/html" + + Order allow,deny + Allow from all + + Options +ExecCGI + AddHandler fcgid-script fcgi + + + +=head3 mod_perl 2.xx + +B + +B: Due to thread-safety limitations, all timestamps will be +presented in the webserver's default time zone when using the C +and C MPMs; the C<$Timezone> setting and the user's timezone +preference are ignored. We suggest the C MPM or FastCGI +deployment if your privileged users are in a different timezone than the +one the server is configured for. + + + ### Optional apache logs for RT + # ErrorLog /opt/rt4/var/log/apache2.error + # TransferLog /opt/rt4/var/log/apache2.access + # LogLevel debug + + AddDefaultCharset UTF-8 + + DocumentRoot "/opt/rt4/share/html" + + Order allow,deny + Allow from all + + SetHandler modperl + PerlResponseHandler Plack::Handler::Apache2 + PerlSetVar psgi_app /opt/rt4/sbin/rt-server + + + use Plack::Handler::Apache2; + Plack::Handler::Apache2->preload("/opt/rt4/sbin/rt-server"); + + + +=head3 mod_perl 1.xx + +B + +To run RT using mod_perl 1.xx please see L for +configuration examples. + + +=head2 nginx + +C requires that you start RT's fastcgi process externally, for +example using C: + + spawn-fcgi -u www-data -g www-data -a 127.0.0.1 -p 9000 \ + -- /opt/rt4/sbin/rt-server.fcgi + +With the nginx configuration: + + server { + listen 80; + server_name rt.example.com; + access_log /var/log/nginx/access.log; + + location / { + fastcgi_param QUERY_STRING $query_string; + fastcgi_param REQUEST_METHOD $request_method; + fastcgi_param CONTENT_TYPE $content_type; + fastcgi_param CONTENT_LENGTH $content_length; + + fastcgi_param SCRIPT_NAME ""; + fastcgi_param PATH_INFO $uri; + fastcgi_param REQUEST_URI $request_uri; + fastcgi_param DOCUMENT_URI $document_uri; + fastcgi_param DOCUMENT_ROOT $document_root; + fastcgi_param SERVER_PROTOCOL $server_protocol; + + fastcgi_param GATEWAY_INTERFACE CGI/1.1; + fastcgi_param SERVER_SOFTWARE nginx/$nginx_version; + + fastcgi_param REMOTE_ADDR $remote_addr; + fastcgi_param REMOTE_PORT $remote_port; + fastcgi_param SERVER_ADDR $server_addr; + fastcgi_param SERVER_PORT $server_port; + fastcgi_param SERVER_NAME $server_name; + fastcgi_pass 127.0.0.1:9000; + } + + location /NoAuth/images { + root /opt/rt4/share/html; + } + } + + +=head2 lighttpd + + server.modules += ( "mod_fastcgi" ) + $HTTP["host"] =~ "^rt.example.com" { + alias.url = ( + "/NoAuth/images/" => "/opt/rt4/share/html/NoAuth/images/", + ) + $HTTP["url"] !~ "^/NoAuth/images/" { + fastcgi.server = ( + "/" => ( + "rt" => ( + "port" => "9000", + "bin-path" => "/opt/rt4/sbin/rt-server.fcgi", + "check-local" => "disable", + "fix-root-scriptname" => "enable", + ) + ) + ) + } + } + + +=head1 Running RT at /rt rather than / + +First you need to tell RT where it's located by setting C<$WebPath> in your +F: + + # Important: don't include a trailing slash here. Read `perldoc + # etc/RT_Config.pm` for more information. + Set($WebPath, "/rt"); + +Then you need to update your Apache configuration to match. Prefix any RT +related C, C and C directives with C. You +should also make sure C is B set to +C, otherwise RT's source will be served from C. + +For example: if you're using the sample FastCGI config above, you might change +the relevant directives to: + + Alias /rt/NoAuth/images/ /opt/rt4/share/html/NoAuth/images/ + ScriptAlias /rt /opt/rt4/sbin/rt-server.fcgi/ + + # Set DocumentRoot as appropriate for the other content you want to serve + DocumentRoot /var/www + + + ... + + +If you're using the sample mod_perl configuration, you only need to change the +C directive. + +If you're not using Apache, please see L or the web +server's own documentation for configuration examples. + -- cgit v1.2.1