diff options
author | Ivan Kohler <ivan@freeside.biz> | 2015-07-09 22:18:55 -0700 |
---|---|---|
committer | Ivan Kohler <ivan@freeside.biz> | 2015-07-09 22:18:55 -0700 |
commit | 1c538bfabc2cd31f27067505f0c3d1a46cba6ef0 (patch) | |
tree | 96922ad4459eda1e649327fd391d60c58d454c53 /rt/etc | |
parent | 4f5619288413a185e9933088d9dd8c5afbc55dfa (diff) |
RT 4.2.11, ticket#13852
Diffstat (limited to 'rt/etc')
136 files changed, 3338 insertions, 970 deletions
diff --git a/rt/etc/RT_Config.pm.in b/rt/etc/RT_Config.pm.in index 498e53c71..fd976de1f 100644 --- a/rt/etc/RT_Config.pm.in +++ b/rt/etc/RT_Config.pm.in @@ -115,19 +115,40 @@ Set($Timezone, "US/Eastern"); =item C<@Plugins> -Set C<@Plugins> to a list of external RT plugins that should be -enabled (those plugins have to be previously downloaded and -installed). +Once a plugin has been downloaded and installed, use C<Plugin()> to add +to the enabled C<@Plugins> list: -Example: + Plugin( "RT::Extension::SLA" ); + Plugin( "RT::Authen::ExternalAuth" ); -C<Set(@Plugins, (qw(RT::Extension::SLA RT::Authen::ExternalAuth)));> +RT will also accept the distribution name (i.e. C<RT-Extension-SLA>) +instead of the package name (C<RT::Extension::SLA>). =cut Set(@Plugins, (qw(RTx::Calendar RT::Extension::MobileUI))); #RTx::Checklist )); +=item C<@StaticRoots> + +Set C<@StaticRoots> to serve extra paths with a static handler. The +contents of each hashref should be the the same arguments as +L<Plack::Middleware::Static> takes. These paths will be checked before +any plugin or core static paths. + +Example: + + Set( @StaticRoots, + { + path => qr{^/static/}, + root => '/local/path/to/static/parent', + }, + ); + +=cut + +Set( @StaticRoots, () ); + =back @@ -140,7 +161,7 @@ Set(@Plugins, (qw(RTx::Calendar =item C<$DatabaseType> Database driver being used; case matters. Valid types are "mysql", -"Oracle" and "Pg". +"Oracle", and "Pg". "SQLite" is also available for non-production use. =cut @@ -194,15 +215,39 @@ SID and database objects are created in C<$DatabaseUser>'s schema. Set($DatabaseName, q{@DB_DATABASE@}); -=item C<$DatabaseRequireSSL> +=item C<%DatabaseExtraDSN> + +Allows additional properties to be passed to the database connection +step. Possible properties are specific to the database-type; see +https://metacpan.org/pod/DBI#connect + +For PostgreSQL, for instance, the following enables SSL (but does no +certificate checking, providing data hiding but no MITM protection): + + # See https://metacpan.org/pod/DBD::Pg#connect + # and http://www.postgresql.org/docs/8.4/static/libpq-ssl.html + Set( %DatabaseExtraDSN, sslmode => 'require' ); + +For MySQL, the following acts similarly if the server has enabled SSL. +Otherwise, it provides no protection; MySQL provides no way to I<force> +SSL connections: + + # See https://metacpan.org/pod/DBD::mysql#connect + # and http://dev.mysql.com/doc/refman/5.1/en/ssl-options.html + Set( %DatabaseExtraDSN, mysql_ssl => 1 ); + +=cut + +Set(%DatabaseExtraDSN, ()); + +=item C<$DatabaseAdmin> -If you're using PostgreSQL and have compiled in SSL support, set -C<$DatabaseRequireSSL> to 1 to turn on SSL communication with the -database. +The name of the database administrator to connect to the database as +during upgrades. =cut -Set($DatabaseRequireSSL, undef); +Set($DatabaseAdmin, "@DB_DBA@"); =back @@ -222,7 +267,7 @@ message. =over 4 -=item C<$LogToSyslog>, C<$LogToScreen> +=item C<$LogToSyslog>, C<$LogToSTDERR> The minimum level error that will be logged to the specific device. From lowest to highest priority, the levels are: @@ -240,7 +285,7 @@ in your web server's error logs). =cut Set($LogToSyslog, "info"); -Set($LogToScreen, "info"); +Set($LogToSTDERR, "info"); =item C<$LogToFile>, C<$LogDir>, C<$LogToFileNamed> @@ -275,11 +320,9 @@ Set($LogStackTraces, ""); =item C<@LogToSyslogConf> -On Solaris or UnixWare, set to ( socket => 'inet' ). Options here -override any other options RT passes to L<Log::Dispatch::Syslog>. -Other interesting flags include facility and logopt. (See the -L<Log::Dispatch::Syslog> documentation for more information.) (Maybe -ident too, if you have multiple RT installations.) +Additional options to pass to L<Log::Dispatch::Syslog>; the most +interesting flags include C<facility>, C<logopt>, and possibly C<ident>. +See the L<Log::Dispatch::Syslog> documentation for more information. =cut @@ -301,14 +344,7 @@ queue-specific subject tags, you'll likely never have to change this configuration. Be B<very careful> with it. Note that it overrides C<$rtname> for -subject token matching and that you should use only "non-capturing" -parenthesis grouping. For example: - -C<Set($EmailSubjectTagRegex, qr/(?:example.com|example.org)/i );> - -and NOT - -C<Set($EmailSubjectTagRegex, qr/(example.com|example.org)/i );> +subject token matching. The setting below would make RT behave exactly as it does without the setting enabled. @@ -320,8 +356,10 @@ setting enabled. =item C<$OwnerEmail> C<$OwnerEmail> is the address of a human who manages RT. RT will send -errors generated by the mail gateway to this address. This address -should I<not> be an address that's managed by your RT instance. +errors generated by the mail gateway to this address; it will also be +displayed as the contact person on the RT's login page. Because RT +sends errors to this address, it should I<not> be an address that's +managed by your RT instance, to avoid mail loops. =cut @@ -350,11 +388,14 @@ Set($StoreLoops, undef); C<$MaxAttachmentSize> sets the maximum size (in bytes) of attachments stored in the database. This setting is irrelevant unless one of -$TruncateLongAttachments or $DropLongAttachments (below) are set. +$TruncateLongAttachments or $DropLongAttachments (below) are set, B<OR> +the database is stored in Oracle. On Oracle, attachments larger than +this can be fully stored, but will be truncated to this length when +read. =cut -Set($MaxAttachmentSize, 10_000_000); +Set($MaxAttachmentSize, 10_000_000); # 10M =item C<$TruncateLongAttachments> @@ -412,38 +453,31 @@ Set($IgnoreCcRegexp, undef); =item C<$CanonicalizeEmailAddressMatch>, C<$CanonicalizeEmailAddressReplace> RT provides functionality which allows the system to rewrite incoming -email addresses. In its simplest form, you can substitute the value -in C<CanonicalizeEmailAddressReplace> for the value in -C<CanonicalizeEmailAddressMatch> (These values are passed to the -C<CanonicalizeEmailAddress> subroutine in F<RT/User.pm>) - -By default, that routine performs a C<s/$Match/$Replace/gi> on any -address passed to it. +email addresses, using L<RT::User/CanonicalizeEmailAddress>. The +default implementation replaces all occurrences of the regular +expression in C<CanonicalizeEmailAddressMatch> with +C<CanonicalizeEmailAddressReplace>, via C<s/$Match/$Replace/gi>. The +most common use of this is to replace C<@something.example.com> with +C<@example.com>. If more complex noramlization is required, +L<RT::User/CanonicalizeEmailAddress> can be overridden to provide it. =cut # Set($CanonicalizeEmailAddressMatch, '@subdomain\.example\.com$'); # Set($CanonicalizeEmailAddressReplace, '@example.com'); -=item C<$CanonicalizeOnCreate> - -Set this to 1 and the create new user page will use the values that -you enter in the form but use the function CanonicalizeUserInfo in -F<RT/User_Local.pm> - -=cut - -Set($CanonicalizeOnCreate, 0); - =item C<$ValidateUserEmailAddresses> -If C<$ValidateUserEmailAddresses> is 1, RT will refuse to create +By default C<$ValidateUserEmailAddresses> is 1, and RT will refuse to create users with an invalid email address (as specified in RFC 2822) or with an email address made of multiple email addresses. +Set this to 0 to skip any email address validation. Doing so may open up +vulnerabilities. + =cut -Set($ValidateUserEmailAddresses, undef); +Set($ValidateUserEmailAddresses, 1); =item C<$NonCustomerEmailRegexp> @@ -515,25 +549,15 @@ Set( $CheckMoreMSMailHeaders, 0); C<$MailCommand> defines which method RT will use to try to send mail. We know that 'sendmailpipe' works fairly well. If 'sendmailpipe' -doesn't work well for you, try 'sendmail'. Other options are 'smtp' -or 'qmail'. - -Note that you should remove the '-t' from C<$SendmailArguments> if you -use 'sendmail' rather than 'sendmailpipe' +doesn't work well for you, try 'sendmail'. 'qmail' is also a supported +value. For testing purposes, or to simply disable sending mail out into the -world, you can set C<$MailCommand> to 'testfile' which writes all mail -to a temporary file. RT will log the location of the temporary file -so you can extract mail from it afterward. - -On shutdown, RT will clean up the temporary file created when using -the 'testfile' option. If testing while the RT server is still running, -you can find the files in the location noted in the log file. If you run -a tool like C<rt-crontool> however, or if you look after stopping the server, -the files will have been deleted when the process completed. If you need to -keep the files for development or debugging, you can manually set -C<< UNLINK => 0 >> where the testfile config is processed in -F<lib/RT/Interface/Email.pm>. +world, you can set C<$MailCommand> to 'mbox' which logs all mail, in +mbox format, to files in F</opt/rt4/var/> based in the process start +time. The 'testfile' option is similar, but the files that it creates +(under /tmp) are temporary, and removed upon process completion; the +format is also not mbox-compatable. =cut @@ -567,7 +591,7 @@ address of the queue as it is handed to sendmail -f. This helps force the From_ header away from www-data or other email addresses that show up in the "Sent by" line in Outlook. -The option is a hash reference of queue name to email address. If +The option is a hash reference of queue id/name to email address. If there is no ticket involved, then the value of the C<Default> key will be used. @@ -715,6 +739,29 @@ will use the address of the current user and remove RT's subject tag. Set($ForwardFromUser, 0); +=item C<$HTMLFormatter> + +RT's default pure-perl formatter may fail to successfully convert even +on some relatively simple HTML; this will result in blank C<text/plain> +parts, which is particuarly unfortunate if HTML templates are not in +use. + +If the optional dependency L<HTML::FormatExternal> is installed, RT will +use external programs to render HTML to plain text. The default is to +try, in order, C<w3m>, C<elinks>, C<html2text>, C<links>, C<lynx>, and +then fall back to the C<core> pure-perl formatter if none are installed. + +Set C<$HTMLFormatter> to one of the above programs (or the full path to +such) to use a different program than the above would choose by default. +Setting this requires that L<HTML::FormatExternal> be installed. + +If the chosen formatter is not in the webserver's $PATH, you may set +this option the full path to one of the aforementioned executables. + +=cut + +Set($HTMLFormatter, undef); + =back =head2 Email dashboards @@ -762,16 +809,13 @@ These options only take effect if C<$MailCommand> is 'sendmail' or =item C<$SendmailArguments> C<$SendmailArguments> defines what flags to pass to C<$SendmailPath> -If you picked 'sendmailpipe', you MUST add a -t flag to -C<$SendmailArguments> These options are good for most sendmail -wrappers and work-a-likes. +These options are good for most sendmail wrappers and work-a-likes. These arguments are good for sendmail brand sendmail 8 and newer: -C<Set($SendmailArguments,"-oi -t -ODeliveryMode=b -OErrorMode=m");> +C<Set($SendmailArguments,"-oi -ODeliveryMode=b -OErrorMode=m");> =cut -#Set($SendmailArguments, "-oi -t"); Set($SendmailArguments, "-oi"); @@ -796,39 +840,6 @@ Set($SendmailPath, "/usr/sbin/sendmail"); =back -=head2 SMTP configuration - -These options only take effect if C<$MailCommand> is 'smtp' - -=over 4 - -=item C<$SMTPServer> - -C<$SMTPServer> should be set to the hostname of the SMTP server to use - -=cut - -Set($SMTPServer, undef); - -=item C<$SMTPFrom> - -C<$SMTPFrom> should be set to the 'From' address to use, if not the -email's 'From' - -=cut - -Set($SMTPFrom, undef); - -=item C<$SMTPDebug> - -C<$SMTPDebug> should be set to 1 to debug SMTP mail sending - -=cut - -Set($SMTPDebug, 0); - -=back - =head2 Other mailers =over 4 @@ -836,7 +847,7 @@ Set($SMTPDebug, 0); =item C<@MailParams> C<@MailParams> defines a list of options passed to $MailCommand if it -is not 'sendmailpipe', 'sendmail', or 'smtp' +is not 'sendmailpipe' or 'sendmail'; =cut @@ -854,15 +865,16 @@ Set(@MailParams, ()); This determines the default stylesheet the RT web interface will use. RT ships with several themes by default: - web2 The default layout for RT 3.8 + rudder The default theme for RT 4.2 aileron The default layout for RT 4.0 + web2 The default layout for RT 3.8 ballard Theme which doesn't rely on JavaScript for menuing This bundled distibution of RT also includes: - freeside3 Integration with Freeside (enabled by default) - freeside2.1 Previous Freeside theme + freeside4 Integration with Freeside (enabled by default) + freeside3 Previous Freeside theme -This value actually specifies a directory in F<share/html/NoAuth/css/> +This value actually specifies a directory in F<share/static/css/> from which RT will try to load the file main.css (which should @import any other files the stylesheet needs). This allows you to easily and cleanly create your own stylesheets to apply to RT. This option can @@ -870,7 +882,7 @@ be overridden by users in their preferences. =cut -Set($WebDefaultStylesheet, "freeside3"); +Set($WebDefaultStylesheet, "freeside4"); =item C<$DefaultQueue> @@ -909,6 +921,48 @@ custom field values from external sources at runtime. Set(@CustomFieldValuesSources, ('RT::CustomFieldValues::Queues')); +=item C<%CustomFieldGroupings> + +This option affects the display of ticket and user custom fields in the +web interface. It does not address the sorting of custom fields within +the groupings; which is controlled by the Ticket Custom Fields tab in +Queue Configuration in the Admin UI. + +A nested datastructure defines how to group together custom fields +under a mix of built-in and arbitrary headings ("groupings"). + +Set C<%CustomFieldGroupings> to a nested structure similar to the following: + + Set(%CustomFieldGroupings, + 'RT::Ticket' => [ + 'Grouping Name' => ['CF Name', 'Another CF'], + 'Another Grouping' => ['Some CF'], + 'Dates' => ['Shipped date'], + ], + 'RT::User' => [ + 'Phones' => ['Fax number'], + ], + ); + +The first level keys are record types for which CFs may be used, and the +values are either hashrefs or arrayrefs -- if arrayrefs, then the +ordering is preserved during display, otherwise groupings are displayed +alphabetically. The second level keys are the grouping names and the +values are array refs containing a list of CF names. + +There are several special built-in groupings which RT displays in +specific places (usually the collapsible box of the same title). The +ordering of these standard groupings cannot be modified. You may also +only append Custom Fields to the list in these boxes, not reorder or +remove core fields. + +For C<RT::Ticket>, these groupings are: C<Basics>, C<Dates>, C<Links>, C<People> + +For C<RT::User>: C<Identity>, C<Access control>, C<Location>, C<Phones> + +Extensions may also add their own built-in groupings, refer to the individual +extension documentation for those. + =item C<$CanonicalizeRedirectURLs> Set C<$CanonicalizeRedirectURLs> to 1 to use C<$WebURL> when @@ -925,32 +979,25 @@ enable this option. Set($CanonicalizeRedirectURLs, 0); -=item C<@JSFiles> +=item C<$CanonicalizeURLsInFeeds> + +Set C<$CanonicalizeURLsInFeeds> to 1 to use C<$WebURL> in feeds +rather than the one we get from request. + +If you use RT behind a reverse proxy, you almost certainly want to +enable this option. -A list of JavaScript files to be included in head. Removing any of -the default entries is not suggested. +=cut + +Set($CanonicalizeURLsInFeeds, 0); -If you're a plugin author, refer to RT->AddJavaScript. +=item C<@JSFiles> + +A list of additional JavaScript files to be included in head. =cut -Set(@JSFiles, qw/ - jquery-1.4.2.min.js - jquery_noconflict.js - jquery-ui-1.8.4.custom.min.js - jquery-ui-timepicker-addon.js - jquery-ui-patch-datepicker.js - jquery.cookie.js - titlebox-state.js - util.js - userautocomplete.js - jquery.event.hover-1.0.js - superfish.js - supersubs.js - jquery.supposition.js - history-folding.js - late.js -/); +Set(@JSFiles, qw//); =item C<$JSMinPath> @@ -977,14 +1024,75 @@ Set(@CSSFiles, qw//); =item C<$UsernameFormat> -This determines how user info is displayed. 'concise' will show one of -either NickName, RealName, Name or EmailAddress, depending on what -exists and whether the user is privileged or not. 'verbose' will show -RealName and EmailAddress. +This determines how user info is displayed. 'concise' will show the +first of RealName, Name or EmailAddress that has a value. 'verbose' will +show EmailAddress, and the first of RealName or Name which is defined. +The default, 'role', uses 'verbose' for unprivileged users, and the Name +followed by the RealName for privileged users. =cut -Set($UsernameFormat, "verbose"); +Set($UsernameFormat, "concise"); + +=item C<$UserSearchResultFormat> + +This controls the display of lists of users returned from the User +Summary Search. The display of users in the Admin interface is +controlled by C<%AdminSearchResultFormat>. + +=cut + +Set($UserSearchResultFormat, + q{ '<a href="__WebPath__/User/Summary.html?id=__id__">__id__</a>/TITLE:#'} + .q{,'<a href="__WebPath__/User/Summary.html?id=__id__">__Name__</a>/TITLE:Name'} + .q{,__RealName__, __EmailAddress__} +); + +=item C<@UserSummaryPortlets> + +A list of portlets to be displayed on the User Summary page. +By default, we show all of the available portlets. +Extensions may provide their own portlets for this page. + +=cut + +Set(@UserSummaryPortlets, (qw/ExtraInfo CreateTicket ActiveTickets InactiveTickets/)); + +=item C<$UserSummaryExtraInfo> + +This controls what information is displayed on the User Summary +portal. By default the user's Real Name, Email Address and Username +are displayed. You can remove these or add more as needed. This +expects a Format string of user attributes. Please note that not all +the attributes are supported in this display because we're not +building a table. + +=cut + +Set($UserSummaryExtraInfo, "RealName, EmailAddress, Name"); + +=item C<$UserSummaryTicketListFormat> + +Control the appearance of the Active and Inactive ticket lists in the +User Summary. + +=cut + +Set($UserSummaryTicketListFormat, q{ + '<B><A HREF="__WebPath__/Ticket/Display.html?id=__id__">__id__</a></B>/TITLE:#', + '<B><A HREF="__WebPath__/Ticket/Display.html?id=__id__">__Subject__</a></B>/TITLE:Subject', + Status, + QueueName, + Owner, + Priority, + '__NEWLINE__', + '', + '<small>__Requestors__</small>', + '<small>__CreatedRelative__</small>', + '<small>__ToldRelative__</small>', + '<small>__LastUpdatedRelative__</small>', + '<small>__TimeLeft__</small>' +}); =item C<$WebBaseURL>, C<$WebURL> @@ -1018,7 +1126,7 @@ Define the directory name to be used for images in RT web documents. =cut -Set($WebImagesURL, RT->Config->Get('WebPath') . "/NoAuth/images/"); +Set($WebImagesURL, RT->Config->Get('WebPath') . "/static/images/"); =item C<$LogoURL> @@ -1046,24 +1154,6 @@ will be passed through C<loc> for localization. Set($LogoAltText, "Best Practical Solutions, LLC corporate logo"); -=item C<$LogoImageHeight> - -C<$LogoImageHeight> is the value of the C<height> attribute of the logo -C<img> tag. - -=cut - -Set($LogoImageHeight, 38); - -=item C<$LogoImageWidth> - -C<$LogoImageWidth> is the value of the C<width> attribute of the logo -C<img> tag. - -=cut - -Set($LogoImageWidth, 181); - =item C<$WebNoAuthRegex> What portion of RT's URL space should not require authentication. The @@ -1112,10 +1202,10 @@ RT comes with two TrueType fonts covering most available languages. Set( %ChartFont, - 'zh-cn' => "$RT::BasePath/share/fonts/DroidSansFallback.ttf", - 'zh-tw' => "$RT::BasePath/share/fonts/DroidSansFallback.ttf", - 'ja' => "$RT::BasePath/share/fonts/DroidSansFallback.ttf", - 'others' => "$RT::BasePath/share/fonts/DroidSans.ttf", + 'zh-cn' => "$RT::FontPath/DroidSansFallback.ttf", + 'zh-tw' => "$RT::FontPath/DroidSansFallback.ttf", + 'ja' => "$RT::FontPath/DroidSansFallback.ttf", + 'others' => "$RT::FontPath/DroidSans.ttf", ); =item C<$ChartsTimezonesInDB> @@ -1132,6 +1222,19 @@ At this time, this feature only applies to MySQL and PostgreSQL. Set($ChartsTimezonesInDB, 0); +=item C<@ChartColors> + +An array of 6-digit hexadecimal RGB color values used for chart series. By +default there are 12 distinct colors. + +=cut + +Set(@ChartColors, qw( + 66cc66 ff6666 ffcc66 663399 + 3333cc 339933 993333 996633 + 33cc33 cc3333 cc9933 6633cc +)); + =back @@ -1168,7 +1271,7 @@ user's customized homepage ("RT at a glance"). Set( $HomepageComponents, [ - qw(QuickCreate Quicksearch MyCalendar MyAdminQueues MySupportQueues MyReminders RefreshHomepage Dashboards SavedSearches ) # loc_qw + qw(QuickCreate Quicksearch MyCalendar MyAdminQueues MySupportQueues MyReminders RefreshHomepage Dashboards SavedSearches FindUser ) # loc_qw ] ); @@ -1184,16 +1287,13 @@ Set( =item C<$UseSQLForACLChecks> Historically, ACLs were checked on display, which could lead to empty -search pages and wrong ticket counts. Set C<$UseSQLForACLChecks> to 1 -to limit search results in SQL instead, which eliminates these -problems. - -This option is still relatively new; it may result in performance -problems in some cases, or significant speedups in others. +search pages and wrong ticket counts. Set C<$UseSQLForACLChecks> to 0 +to go back to this method; this will reduce the complexity of the +generated SQL statements, at the cost of the aforementioned bugs. =cut -Set($UseSQLForACLChecks, undef); +Set($UseSQLForACLChecks, 1); =item C<$TicketsItemMapSize> @@ -1234,7 +1334,7 @@ Set ($DefaultSearchResultFormat, qq{ Customer, Status, QueueName, - OwnerName, + Owner, Priority, '__NEWLINE__', '__NBSP__', @@ -1245,6 +1345,23 @@ Set ($DefaultSearchResultFormat, qq{ '<small>__LastUpdatedRelative__</small>', '<small>__TimeLeft__</small>'}); +=item C<$DefaultSearchResultOrderBy> + +What Tickets column should we order by for RT Ticket search results. + +=cut + +Set($DefaultSearchResultOrderBy, 'id'); + +=item C<$DefaultSearchResultOrder> + +When ordering RT Ticket search results by C<$DefaultSearchResultOrderBy>, +should the sort be ascending (ASC) or descending (DESC). + +=cut + +Set($DefaultSearchResultOrder, 'ASC'); + =item C<$DefaultSelfServiceSearchResultFormat> C<$DefaultSelfServiceSearchResultFormat> is the default format of @@ -1257,7 +1374,7 @@ Set($DefaultSelfServiceSearchResultFormat, qq{ '<B><A HREF="__WebPath__/SelfService/Display.html?id=__id__">__Subject__</a></B>/TITLE:Subject', Status, Requestors, - OwnerName}); + Owner}); =item C<%FullTextSearch> @@ -1337,6 +1454,20 @@ Ticket/Display.html. This option can be controlled by users also. Set($MoreAboutRequestorTicketList, "Active"); +=item C<$MoreAboutRequestorTicketListFormat> + +Control the appearance of the ticket lists in the 'More About Requestors' box. + +=cut + +Set($MoreAboutRequestorTicketListFormat, q{ + '<a href="__WebPath__/Ticket/Display.html?id=__id__">__id__</a>', + '__Owner__', + '<a href="__WebPath__/Ticket/Display.html?id=__id__">__Subject__</a>', + '__Status__', +}); + + =item C<$MoreAboutRequestorExtraInfo> By default, the 'More about requestor' box on Ticket/Display.html @@ -1398,6 +1529,12 @@ builder are replaced by text fields that autocomplete. This can alleviate the sometimes huge owner list for installations where many users have the OwnTicket right. +Autocompleter is automatically turned on if list contains more than +50 users, but penalty of executing potentially slow query is still paid. + +Drop down doesn't show unprivileged users. If your setup allows unprivileged +to own ticket then you have to enable autocompleting. + =cut Set($AutocompleteOwners, 0); @@ -1412,15 +1549,19 @@ is ignored. Helpful when owners list is huge in the query builder. Set($AutocompleteOwnersForSearch, 0); -=item C<$UserAutocompleteFields> +=item C<$UserSearchFields> + +Used by the User Autocompleter as well as the User Search. -Specifies which fields of L<RT::User> to match against and how to -match each field when autocompleting users. Valid match methods are -LIKE, STARTSWITH, ENDSWITH, =, and !=. +Specifies which fields of L<RT::User> to match against and how to match +each field when autocompleting users. Valid match methods are LIKE, +STARTSWITH, ENDSWITH, =, and !=. Valid search fields are the core User +fields, as well as custom fields, which are specified as "CF.1234" or +"CF.Name" =cut -Set($UserAutocompleteFields, { +Set($UserSearchFields, { EmailAddress => 'STARTSWITH', Name => 'STARTSWITH', RealName => 'LIKE', @@ -1428,14 +1569,31 @@ Set($UserAutocompleteFields, { =item C<$AllowUserAutocompleteForUnprivileged> -Should unprivileged users be allowed to autocomplete users. Setting -this option to 1 means unprivileged users will be able to search all -your users. +Should unprivileged users (users of SelfService) be allowed to +autocomplete users. Setting this option to 1 means unprivileged users +will be able to search all your users. =cut Set($AllowUserAutocompleteForUnprivileged, 0); +=item C<$TicketAutocompleteFields> + +Specifies which fields of L<RT::Ticket> to match against and how to match each +field when autocompleting users. Valid match methods are LIKE, STARTSWITH, +ENDSWITH, C<=>, and C<!=>. + +Not all Ticket fields are publically accessible and hence won't work for +autocomplete unless you override their accessibility using a local overlay or a +plugin. Out of the box the following fields are public: id, Subject. + +=cut + +Set( $TicketAutocompleteFields, { + id => 'STARTSWITH', + Subject => 'LIKE', +}); + =item C<$DisplayTicketAfterQuickCreate> Enable this to redirect to the created ticket display page @@ -1542,15 +1700,6 @@ for Rich Text settings. Set($MessageBoxWidth, undef); Set($MessageBoxHeight, 15); -=item C<$MessageBoxWrap> - -Wrapping is disabled when using MessageBoxRichText because of a bad -interaction between IE and wrapping with the Rich Text Editor. - -=cut - -Set($MessageBoxWrap, "SOFT"); - =item C<$MessageBoxRichText> Should "rich text" editing be enabled? This option lets your users @@ -1580,7 +1729,7 @@ Set($MessageBoxIncludeSignature, 1); =item C<$MessageBoxIncludeSignatureOnComment> Should your users' signatures (from their Preferences page) be -included in Comments. Setting this to false overrides +included in Comments. Setting this to 0 overrides C<$MessageBoxIncludeSignature>. =cut @@ -1604,15 +1753,39 @@ option can be overridden by users in their preferences. Set($OldestTransactionsFirst, 1); -=item C<$DeferTransactionLoading> +=item C<$ShowHistory> + +This option controls how history is shown on the ticket display page. It +accepts one of three possible modes and is overrideable on a per-user +preference level. If you regularly deal with long tickets and don't care much +about the history, you may wish to change this option to C<click>. + +=over + +=item C<delay> (the default) + +When set to C<delay>, history is loaded via javascript after the rest of the +page has been loaded. This speeds up apparent page load times and generally +provides a smoother experience. You may notice slight delays before the ticket +history appears on very long tickets. + +=item C<click> -When set, defers loading ticket history until the user clicks a link. -This should end up serving pages to users quicker, since generating -all the HTML for transaction history can be slow for long tickets. +When set to C<click>, history is loaded on demand when a placeholder link is +clicked. This speeds up ticket display page loads and history is never loaded +if not requested. + +=item C<always> + +When set to C<always>, history is loaded before showing the page. This ensures +history is always available immediately, but at the expense of longer page load +times. This behaviour was the default in RT 4.0. + +=back =cut -# Set($DeferTransactionLoading, 1); +Set($ShowHistory, 'delay'); =item C<$ShowBccHeader> @@ -1642,28 +1815,24 @@ overrides C<TrustHTMLAttachments>. Set($AlwaysDownloadAttachments, undef); -=item C<$AttachmentUnits> - -Controls the units (kilobytes or bytes) that attachment sizes use for -display. The default is to display kilobytes if the attachment is -larger than 1024 bytes, bytes otherwise. If you set -C<$AttachmentUnits> to C<'k'> then attachment sizes will always be -displayed in kilobytes. If set to C<'b'>, then sizes will be bytes. - -=cut +=item C<$PreferRichText> -Set($AttachmentUnits, undef); +By default, RT shows rich text (HTML) messages if possible. If +C<$PreferRichText> is set to 0, RT will show plain text messages in +preference to any rich text alternatives. -=item C<$PreferRichText> +As a security precaution, RT limits the HTML that is displayed to a +known-good subset -- as allowing arbitrary HTML to be displayed exposes +multiple vectors for XSS and phishing attacks. If +L</$TrustHTMLAttachments> is enabled, the original HTML is available for +viewing via the "Download" link. -If C<$PreferRichText> is set to 1, RT will show HTML/Rich text messages -in preference to their plain-text alternatives. RT "scrubs" the HTML to -show only a minimal subset of HTML to avoid possible contamination by -cross-site-scripting attacks. +If the optional L<HTML::Gumbo> dependency is installed, RT will leverage +this to allow a broader set of HTML through, including tables. =cut -Set($PreferRichText, undef); +Set($PreferRichText, 1); =item C<$MaxInlineBody> @@ -1686,23 +1855,25 @@ behavior. Set($ShowTransactionImages, 1); -=item C<$PlainTextPre> +=item C<$ShowRemoteImages> -Normally plaintext attachments are displayed as HTML with line breaks -preserved. This causes space- and tab-based formatting not to be -displayed correctly. By setting $PlainTextPre messages will be -displayed using <pre>. +By default, RT doesn't show remote images attached to incoming (and outgoing) +ticket updates inline. Set this variable to 1 if you'd like to enable remote +image display. Showing remote images may allow spammers and other senders to +track when messages are viewed and see referer information. -=cut +Note that this setting is independent of L</$ShowTransactionImages> above. -Set($PlainTextPre, 0); +=cut +Set($ShowRemoteImages, 0); =item C<$PlainTextMono> -Set C<$PlainTextMono> to 1 to use monospaced font and preserve -formatting; unlike C<$PlainTextPre>, the text will wrap to fit width -of the browser window; this option overrides C<$PlainTextPre>. +Normally plaintext attachments are displayed as HTML with line breaks +preserved. This causes space- and tab-based formatting not to be +displayed correctly. Set C<$PlainTextMono> to 1 to use a monospaced +font and preserve formatting. =cut @@ -1729,17 +1900,35 @@ provides two formats: link after the URL. * 'httpurl_overwrite': also detects URLs as 'httpurl' format, but - replaces the URL with a link. + replaces the URL with a link. Enabled by default. See F<share/html/Elements/MakeClicky> for documentation on how to add your own styles of link detection. =cut -Set(@Active_MakeClicky, qw()); +Set(@Active_MakeClicky, qw(httpurl_overwrite)); -=back +=item C<$QuoteFolding> + +Quote folding is the hiding of old replies in transaction history. +It defaults to on. Set this to 0 to disable it. + +=cut + +Set($QuoteFolding, 1); + +=item C<$AllowLoginPasswordAutoComplete> +Allow browsers to remember the user's password on login (in case the +browser can do so, and has the appropriate setting enabled). Default +is 0. + +=cut + +Set($AllowLoginPasswordAutoComplete, 0); + +=back =head1 Application logic @@ -1805,8 +1994,9 @@ Set($ApprovalRejectionNotes, 1); =item C<$ForceApprovalsView> Should approval tickets only be viewed and modified through the standard -approval interface? Changing this setting to 1 will redirect any attempt to -use the normal ticket display and modify page for approval tickets. +approval interface? With this setting enabled (by default), any attempt to use +the normal ticket display and modify page for approval tickets will be +redirected. For example, with this option set to 1 and an approval ticket #123: @@ -1816,11 +2006,13 @@ is redirected to /Approval/Display.html?id=123 +With this option set to 0, the redirect won't happen. + =back =cut -Set($ForceApprovalsView, 0); +Set($ForceApprovalsView, 1); =head1 Extra security @@ -1832,7 +2024,7 @@ defaults alone. =item C<$DisallowExecuteCode> -If set to a true value, the C<ExecuteCode> right will be removed from +If set to 1, the C<ExecuteCode> right will be removed from all users, B<including> the superuser. This is intended for when RT is installed into a shared environment where even the superuser should not be allowed to run arbitrary Perl code on the server via scrips. @@ -1843,7 +2035,7 @@ Set($DisallowExecuteCode, 0); =item C<$Framebusting> -If set to a false value, framekiller javascript will be disabled and the +If set to 0, framekiller javascript will be disabled and the X-Frame-Options: DENY header will be suppressed from all responses. This disables RT's clickjacking protection. @@ -1853,7 +2045,7 @@ Set($Framebusting, 1); =item C<$RestrictReferrer> -If set to a false value, the HTTP C<Referer> (sic) header will not be +If set to 0, the HTTP C<Referer> (sic) header will not be checked to ensure that requests come from RT's own domain. As RT allows for GET requests to alter state, disabling this opens RT up to cross-site request forgery (CSRF) attacks. @@ -1864,9 +2056,9 @@ Set($RestrictReferrer, 1); =item C<$RestrictLoginReferrer> -If set to a false value, RT will allow the user to log in from any link +If set to 0, RT will allow the user to log in from any link or request, merely by passing in C<user> and C<pass> parameters; setting -it to a true value forces all logins to come from the login box, so the +it to 1 forces all logins to come from the login box, so the user is aware that they are being logged in. The default is off, for backwards compatability. @@ -1901,6 +2093,17 @@ Simple wildcards, similar to SSL certificates, are allowed. For example: Set(@ReferrerWhitelist, qw()); + +=item C<$BcryptCost> + +This sets the default cost parameter used for the C<bcrypt> key +derivation function. Valid values range from 4 to 31, inclusive, with +higher numbers denoting greater effort. + +=cut + +Set($BcryptCost, 10); + =back @@ -1909,74 +2112,89 @@ Set(@ReferrerWhitelist, qw()); =over 4 -=item C<$WebExternalAuth> +=item C<$WebRemoteUserAuth> -If C<$WebExternalAuth> is defined, RT will defer to the environment's -REMOTE_USER variable. +If C<$WebRemoteUserAuth> is defined, RT will defer to the environment's +REMOTE_USER variable, which should be set by the webserver's +authentication layer. =cut -Set($WebExternalAuth, undef); +Set($WebRemoteUserAuth, undef); -=item C<$WebExternalAuthContinuous> +=item C<$WebRemoteUserContinuous> -If C<$WebExternalAuthContinuous> is defined, RT will check for the +If C<$WebRemoteUserContinuous> is defined, RT will check for the REMOTE_USER on each access. If you would prefer this to only happen -once (at initial login) set this to a false value. The default -setting will help ensure that if your external authentication system +once (at initial login) set this to 0. The default +setting will help ensure that if your webserver's authentication layer deauthenticates a user, RT notices as soon as possible. =cut -Set($WebExternalAuthContinuous, 1); +Set($WebRemoteUserContinuous, 1); -=item C<$WebFallbackToInternalAuth> +=item C<$WebFallbackToRTLogin> -If C<$WebFallbackToInternalAuth> is defined, the user is allowed a +If C<$WebFallbackToRTLogin> is defined, the user is allowed a chance of fallback to the login screen, even if REMOTE_USER failed. =cut -Set($WebFallbackToInternalAuth, undef); +Set($WebFallbackToRTLogin, undef); -=item C<$WebExternalGecos> +=item C<$WebRemoteUserGecos> -C<$WebExternalGecos> means to match 'gecos' field as the user -identity); useful with mod_auth_pwcheck and IIS Integrated Windows -logon. +C<$WebRemoteUserGecos> means to match 'gecos' field as the user +identity; useful with C<mod_auth_external>. =cut -Set($WebExternalGecos, undef); +Set($WebRemoteUserGecos, undef); -=item C<$WebExternalAuto> +=item C<$WebRemoteUserAutocreate> -C<$WebExternalAuto> will create users under the same name as -REMOTE_USER upon login, if it's missing in the Users table. +C<$WebRemoteUserAutocreate> will create users under the same name as +REMOTE_USER upon login, if they are missing from the Users table. =cut -Set($WebExternalAuto, undef); +Set($WebRemoteUserAutocreate, undef); -=item C<$AutoCreate> +=item C<$UserAutocreateDefaultsOnLogin> -If C<$WebExternalAuto> is set to 1, C<$AutoCreate> will be passed to -User's Create method. Use it to set defaults, such as creating -Unprivileged users with C<{ Privileged => 0 }> This must be a hashref. +If C<$WebRemoteUserAutocreate> is set to 1, C<$UserAutocreateDefaultsOnLogin> +will be passed to L<RT::User/Create>. Use it to set defaults, such as +creating unprivileged users with C<<{ Privileged => 0 }>>. This must be +a hashref. =cut -Set($AutoCreate, undef); +Set($UserAutocreateDefaultsOnLogin, undef); =item C<$WebSessionClass> -C<$WebSessionClass> is the class you wish to use for managing sessions. -It defaults to use your SQL database, except on Oracle, where it -defaults to files on disk. +C<$WebSessionClass> is the class you wish to use for storing sessions. On +MySQL, Pg, and Oracle it defaults to using your database, in other cases +sessions are stored in files using L<Apache::Session::File>. Other installed +Apache::Session::* modules can be used to store sessions. + + Set($WebSessionClass, "Apache::Session::File"); =cut -# Set($WebSessionClass, "Apache::Session::File"); +Set($WebSessionClass, undef); + +=item C<%WebSessionProperties> + +C<%WebSessionProperties> is the hash to configure class L</$WebSessionClass> +in case custom class is used. By default it's empty and values are picked +depending on the class. Make sure that it's empty if you're using DB as session +backend. + +=cut + +Set( %WebSessionProperties ); =item C<$AutoLogoff> @@ -2149,12 +2367,139 @@ them. Set($SimpleSearchIncludeResolved, 0); +=item C<$TimeInICal> + +By default, events in the iCal feed on the ticket search page +contain only dates, making them all day calendar events. Set +C<$TimeInICal> if you have start or due dates on tickets that +have significant time values and you want those times to be +included in the events in the iCal feed. + +This option can also be set as an individual user preference. + +=cut + +Set($TimeInICal, 0); + =back +=head1 Cryptography + +A complete description of RT's cryptography capabilities can be found in +L<RT::Crypt>. At this moment, GnuPG (PGP) and SMIME security protocols are +supported. + +=over 4 + +=item C<%Crypt> + +The following options apply to all cryptography protocols. + +By default, all enabled security protocols will analyze each incoming +email. You may set C<Incoming> to a subset of this list, if some enabled +protocols do not apply to incoming mail; however, this is usually +unnecessary. Note that for any verification or decryption to occur for +incoming mail, the C<Auth::Crypt> mail plugin must be added to +L</@MailPlugins> as specified in L<RT::Crypt/Handling incoming messages>. + +For outgoing emails, the first security protocol from the above list is +used. Use the C<Outgoing> option to set a security protocol that should +be used in outgoing emails. At this moment, only one protocol can be +used to protect outgoing emails. + +Set C<RejectOnUnencrypted> to 1 if all incoming email must be +properly encrypted. All unencrypted emails will be rejected by RT. + +Set C<RejectOnMissingPrivateKey> to 0 if you don't want to reject +emails encrypted for key RT doesn't have and can not decrypt. + +Set C<RejectOnBadData> to 0 if you don't want to reject letters +with incorrect data. + +If you want to allow people to encrypt attachments inside the DB then +set C<AllowEncryptDataInDB> to 1. + +Set C<Dashboards> to a hash with Encrypt and Sign keys to control +whether dashboards should be encrypted and/or signed correspondingly. +By default they are not encrypted or signed. + +=back + +=cut -=head1 GnuPG integration +Set( %Crypt, + Incoming => undef, # ['GnuPG', 'SMIME'] + Outgoing => undef, # 'SMIME' + + RejectOnUnencrypted => 0, + RejectOnMissingPrivateKey => 1, + RejectOnBadData => 1, + + AllowEncryptDataInDB => 0, + + Dashboards => { + Encrypt => 0, + Sign => 0, + }, +); + +=head2 SMIME configuration + +A full description of the SMIME integration can be found in +L<RT::Crypt::SMIME>. + +=over 4 + +=item C<%SMIME> + +Set C<Enable> to 0 or 1 to disable or enable SMIME for +encrypting and signing messages. + +Set C<OpenSSL> to path to F<openssl> executable. + +Set C<Keyring> to directory with key files. Key and certificates should +be stored in a PEM file in this directory named named, e.g., +F<email.address@example.com.pem>. + +Set C<CAPath> to either a PEM-formatted certificate of a single signing +certificate authority, or a directory of such (including hash symlinks +as created by the openssl tool C<c_rehash>). Only SMIME certificates +signed by these certificate authorities will be treated as valid +signatures. If left unset (and C<AcceptUntrustedCAs> is unset, as it is +by default), no signatures will be marked as valid! + +Set C<AcceptUntrustedCAs> to allow arbitrary SMIME certificates, no +matter their signing entities. Such mails will be marked as untrusted, +but signed; C<CAPath> will be used to mark which mails are signed by +trusted certificate authorities. This configuration is generally +insecure, as it allows the possibility of accepting forged mail signed +by an untrusted certificate authority. + +Setting C<AcceptUntrustedCAs> also allows encryption to users with +certificates created by untrusted CAs. + +Set C<Passphrase> to a scalar (to use for all keys), an anonymous +function, or a hash (to look up by address). If the hash is used, the +'' key is used as a default. + +See L<RT::Crypt::SMIME> for details. + +=back + +=cut + +Set( %SMIME, + Enable => @RT_SMIME@, + OpenSSL => 'openssl', + Keyring => q{@RT_VAR_PATH@/data/smime}, + CAPath => undef, + AcceptUntrustedCAs => undef, + Passphrase => undef, +); + +=head2 GnuPG configuration A full description of the (somewhat extensive) GnuPG integration can be found by running the command `perldoc L<RT::Crypt::GnuPG>` (or @@ -2164,27 +2509,25 @@ be found by running the command `perldoc L<RT::Crypt::GnuPG>` (or =item C<%GnuPG> -Set C<OutgoingMessagesFormat> to 'inline' to use inline encryption and -signatures instead of 'RFC' (GPG/MIME: RFC3156 and RFC1847) format. +Set C<Enable> to 0 or 1 to disable or enable GnuPG interfaces +for encrypting and signing outgoing messages. -If you want to allow people to encrypt attachments inside the DB then -set C<AllowEncryptDataInDB> to 1. +Set C<GnuPG> to the name or path of the gpg binary to use. -Set C<RejectOnMissingPrivateKey> to false if you don't want to reject -emails encrypted for key RT doesn't have and can not decrypt. +Set C<Passphrase> to a scalar (to use for all keys), an anonymous +function, or a hash (to look up by address). If the hash is used, the +'' key is used as a default. -Set C<RejectOnBadData> to false if you don't want to reject letters -with incorrect GnuPG data. +Set C<OutgoingMessagesFormat> to 'inline' to use inline encryption and +signatures instead of 'RFC' (GPG/MIME: RFC3156 and RFC1847) format. =cut Set(%GnuPG, - Enable => @RT_GPG@, + Enable => @RT_GPG@, + GnuPG => 'gpg', + Passphrase => undef, OutgoingMessagesFormat => "RFC", # Inline - AllowEncryptDataInDB => 0, - - RejectOnMissingPrivateKey => 1, - RejectOnBadData => 1, ); =item C<%GnuPGOptions> @@ -2204,9 +2547,6 @@ Set(%GnuPGOptions, # URL of a keyserver # keyserver => 'hkp://subkeys.pgp.net', -# enables the automatic retrieving of keys when encrypting -# 'auto-key-locate' => 'keyserver', - # enables the automatic retrieving of keys when verifying signatures # 'keyserver-options' => 'auto-key-retrieve', ); @@ -2348,6 +2688,14 @@ all possible transitions in each lifecycle using the following format: ... }, +The order of items in the listing for each transition line affects +the order they appear in the drop-down. If you change the config +for 'open' state listing to: + + open => [qw(stalled rejected deleted resolved)], + +then the 'resolved' status will appear as the last item in the drop-down. + =head3 Statuses available during ticket creation By default users can create tickets with a status of new, @@ -2450,8 +2798,8 @@ For example: Unless there is an explicit mapping between statuses in two different lifecycles, you can not move tickets between queues with these -lifecycles. This is true even if the different lifecycles use the exact -same set of statuses. Such a mapping is defined as follows: +lifecycles -- even if both use the exact same set of statuses. +Such a mapping is defined as follows: __maps__ => { 'from lifecycle -> to lifecycle' => { @@ -2465,9 +2813,9 @@ same set of statuses. Such a mapping is defined as follows: Set(%Lifecycles, default => { - initial => [ 'new' ], - active => [ 'open', 'stalled' ], - inactive => [ 'resolved', 'rejected', 'deleted' ], + initial => [qw(new)], # loc_qw + active => [qw(open stalled)], # loc_qw + inactive => [qw(resolved rejected deleted)], # loc_qw defaults => { on_create => 'new', @@ -2479,64 +2827,32 @@ Set(%Lifecycles, }, transitions => { - '' => [qw(new open resolved)], + "" => [qw(new open resolved)], # from => [ to list ], - new => [qw(open stalled resolved rejected deleted)], - open => [qw(new stalled resolved rejected deleted)], - stalled => [qw(new open rejected resolved deleted)], - resolved => [qw(new open stalled rejected deleted)], - rejected => [qw(new open stalled resolved deleted)], - deleted => [qw(new open stalled rejected resolved)], + new => [qw( open stalled resolved rejected deleted)], + open => [qw(new stalled resolved rejected deleted)], + stalled => [qw(new open rejected resolved deleted)], + resolved => [qw(new open stalled rejected deleted)], + rejected => [qw(new open stalled resolved deleted)], + deleted => [qw(new open stalled rejected resolved )], }, rights => { '* -> deleted' => 'DeleteTicket', '* -> *' => 'ModifyTicket', }, actions => [ - 'new -> open' => { - label => 'Open It', # loc - update => 'Respond', - }, - 'new -> resolved' => { - label => 'Resolve', # loc - update => 'Comment', - }, - 'new -> rejected' => { - label => 'Reject', # loc - update => 'Respond', - }, - 'new -> deleted' => { - label => 'Delete', # loc - }, - - 'open -> stalled' => { - label => 'Stall', # loc - update => 'Comment', - }, - 'open -> resolved' => { - label => 'Resolve', # loc - update => 'Comment', - }, - 'open -> rejected' => { - label => 'Reject', # loc - update => 'Respond', - }, - - 'stalled -> open' => { - label => 'Open It', # loc - }, - 'resolved -> open' => { - label => 'Re-open', # loc - update => 'Comment', - }, - 'rejected -> open' => { - label => 'Re-open', # loc - update => 'Comment', - }, - 'deleted -> open' => { - label => 'Undelete', # loc - }, + 'new -> open' => { label => 'Open It', update => 'Respond' }, # loc{label} + 'new -> resolved' => { label => 'Resolve', update => 'Comment' }, # loc{label} + 'new -> rejected' => { label => 'Reject', update => 'Respond' }, # loc{label} + 'new -> deleted' => { label => 'Delete', }, # loc{label} + 'open -> stalled' => { label => 'Stall', update => 'Comment' }, # loc{label} + 'open -> resolved' => { label => 'Resolve', update => 'Comment' }, # loc{label} + 'open -> rejected' => { label => 'Reject', update => 'Respond' }, # loc{label} + 'stalled -> open' => { label => 'Open It', }, # loc{label} + 'resolved -> open' => { label => 'Re-open', update => 'Comment' }, # loc{label} + 'rejected -> open' => { label => 'Re-open', update => 'Comment' }, # loc{label} + 'deleted -> open' => { label => 'Undelete', }, # loc{label} ], }, # don't change lifecyle of the approvals, they are not capable to deal with @@ -2570,49 +2886,17 @@ Set(%Lifecycles, '* -> *' => 'ModifyTicket', }, actions => [ - 'new -> open' => { - label => 'Open It', # loc - update => 'Respond', - }, - 'new -> resolved' => { - label => 'Resolve', # loc - update => 'Comment', - }, - 'new -> rejected' => { - label => 'Reject', # loc - update => 'Respond', - }, - 'new -> deleted' => { - label => 'Delete', # loc - }, - - 'open -> stalled' => { - label => 'Stall', # loc - update => 'Comment', - }, - 'open -> resolved' => { - label => 'Resolve', # loc - update => 'Comment', - }, - 'open -> rejected' => { - label => 'Reject', # loc - update => 'Respond', - }, - - 'stalled -> open' => { - label => 'Open It', # loc - }, - 'resolved -> open' => { - label => 'Re-open', # loc - update => 'Comment', - }, - 'rejected -> open' => { - label => 'Re-open', # loc - update => 'Comment', - }, - 'deleted -> open' => { - label => 'Undelete', # loc - }, + 'new -> open' => { label => 'Open It', update => 'Respond' }, # loc{label} + 'new -> resolved' => { label => 'Resolve', update => 'Comment' }, # loc{label} + 'new -> rejected' => { label => 'Reject', update => 'Respond' }, # loc{label} + 'new -> deleted' => { label => 'Delete', }, # loc{label} + 'open -> stalled' => { label => 'Stall', update => 'Comment' }, # loc{label} + 'open -> resolved' => { label => 'Resolve', update => 'Comment' }, # loc{label} + 'open -> rejected' => { label => 'Reject', update => 'Respond' }, # loc{label} + 'stalled -> open' => { label => 'Open It', }, # loc{label} + 'resolved -> open' => { label => 'Re-open', update => 'Comment' }, # loc{label} + 'rejected -> open' => { label => 'Re-open', update => 'Comment' }, # loc{label} + 'deleted -> open' => { label => 'Undelete', }, # loc{label} ], }, ); @@ -2629,7 +2913,7 @@ Set(%Lifecycles, RT can show administrators a feed of recent RT releases and other related announcements and information from Best Practical on the top -level Configuration page. This feature helps you stay up to date on +level Admin page. This feature helps you stay up to date on RT security announcements and version updates. RT provides this feature using an "iframe" on C</Admin/index.html> @@ -2637,7 +2921,7 @@ which asks the administrator's browser to show an inline page from Best Practical's website. If you'd rather not make this feature available to your -administrators, set C<$ShowRTPortal> to a false value. +administrators, set C<$ShowRTPortal> to 0. =cut @@ -2655,41 +2939,53 @@ Set(%AdminSearchResultFormat, Queues => q{'<a href="__WebPath__/Admin/Queues/Modify.html?id=__id__">__id__</a>/TITLE:#'} .q{,'<a href="__WebPath__/Admin/Queues/Modify.html?id=__id__">__Name__</a>/TITLE:Name'} - .q{,__Description__,__Address__,__Priority__,__DefaultDueIn__,__Disabled__,__Lifecycle__}, + .q{,__Description__,__Address__,__Priority__,__DefaultDueIn__,__Lifecycle__,__SubjectTag__,__Disabled__}, Groups => q{'<a href="__WebPath__/Admin/Groups/Modify.html?id=__id__">__id__</a>/TITLE:#'} .q{,'<a href="__WebPath__/Admin/Groups/Modify.html?id=__id__">__Name__</a>/TITLE:Name'} - .q{,'__Description__'}, + .q{,'__Description__',__Disabled__}, Users => q{'<a href="__WebPath__/Admin/Users/Modify.html?id=__id__">__id__</a>/TITLE:#'} .q{,'<a href="__WebPath__/Admin/Users/Modify.html?id=__id__">__Name__</a>/TITLE:Name'} - .q{,__RealName__, __EmailAddress__}, + .q{,__RealName__, __EmailAddress__,__Disabled__}, CustomFields => q{'<a href="__WebPath__/Admin/CustomFields/Modify.html?id=__id__">__id__</a>/TITLE:#'} .q{,'<a href="__WebPath__/Admin/CustomFields/Modify.html?id=__id__">__Name__</a>/TITLE:Name'} - .q{,__AppliedTo__, __FriendlyType__, __FriendlyPattern__}, + .q{,__AddedTo__, __FriendlyType__, __FriendlyPattern__,__Disabled__}, Scrips => - q{'<a href="__WebPath__/Admin/Queues/Scrip.html?id=__id__&Queue=__QueueId__">__id__</a>/TITLE:#'} - .q{,'<a href="__WebPath__/Admin/Queues/Scrip.html?id=__id__&Queue=__QueueId__">__Description__</a>/TITLE:Description'} - .q{,__Stage__, __Condition__, __Action__, __Template__}, - - GlobalScrips => - q{'<a href="__WebPath__/Admin/Global/Scrip.html?id=__id__">__id__</a>/TITLE:#'} - .q{,'<a href="__WebPath__/Admin/Global/Scrip.html?id=__id__">__Description__</a>/TITLE:Description'} - .q{,__Stage__, __Condition__, __Action__, __Template__}, + q{'<a href="__WebPath__/Admin/Scrips/Modify.html?id=__id____From__">__id__</a>/TITLE:#'} + .q{,'<a href="__WebPath__/Admin/Scrips/Modify.html?id=__id____From__">__Description__</a>/TITLE:Description'} + .q{,__Condition__, __Action__, __Template__, __Disabled__}, Templates => q{'<a href="__WebPath__/__WebRequestPathDir__/Template.html?Queue=__QueueId__&Template=__id__">__id__</a>/TITLE:#'} .q{,'<a href="__WebPath__/__WebRequestPathDir__/Template.html?Queue=__QueueId__&Template=__id__">__Name__</a>/TITLE:Name'} - .q{,'__Description__'}, + .q{,'__Description__','__UsedBy__','__IsEmpty__'}, Classes => q{ '<a href="__WebPath__/Admin/Articles/Classes/Modify.html?id=__id__">__id__</a>/TITLE:#'} .q{,'<a href="__WebPath__/Admin/Articles/Classes/Modify.html?id=__id__">__Name__</a>/TITLE:Name'} - .q{,__Description__}, + .q{,__Description__,__Disabled__}, +); + +=item C<%AdminSearchResultRows> + +Use C<%AdminSearchResultRows> to define the search result rows in the admin +interface on a per-RT-class basis. + +=cut + +Set(%AdminSearchResultRows, + Queues => 50, + Groups => 50, + Users => 50, + CustomFields => 50, + Scrips => 50, + Templates => 50, + Classes => 50, ); =back @@ -2741,7 +3037,7 @@ be added while the server is running. =cut -Set($DevelMode, "@RT_DEVEL_MODE@"); +Set($DevelMode, 0); =item C<$RecordBaseClass> @@ -2777,7 +3073,7 @@ C<$StatementLog> to be the level that you wish SQL statements to be logged at. Enabling this option will also expose the SQL Queries page in the -Configuration -> Tools menu for SuperUsers. +Admin -> Tools menu for SuperUsers. =cut @@ -2785,30 +3081,6 @@ Set($StatementLog, undef); =back - - - -=head1 Deprecated options - -=over 4 - -=item C<$LinkTransactionsRun1Scrip> - -RT-3.4 backward compatibility setting. Add/Delete Link used to record -one transaction and run one scrip. Set this value to 1 if you want -only one of the link transactions to have scrips run. - -=cut - -Set($LinkTransactionsRun1Scrip, 0); - -=item C<$ResolveDefaultUpdateType> - -This option has been deprecated. You can configure this site-wide -with L</Lifecycles> (see L</Labeling and defining actions>). - -=back - =cut 1; diff --git a/rt/etc/RT_SiteConfig.pm b/rt/etc/RT_SiteConfig.pm index 4a397fa16..daf136399 100644 --- a/rt/etc/RT_SiteConfig.pm +++ b/rt/etc/RT_SiteConfig.pm @@ -10,7 +10,7 @@ # # The converse is also true, if this file isn't valid perl, you're # going to run into trouble. To check your SiteConfig file, use -# this comamnd: +# this command: # # perl -c /path/to/your/etc/RT_SiteConfig.pm diff --git a/rt/etc/acl.Pg b/rt/etc/acl.Pg index 9da28dba7..a659d8e99 100755 --- a/rt/etc/acl.Pg +++ b/rt/etc/acl.Pg @@ -23,6 +23,8 @@ sub acl { Transactions scrips_id_seq Scrips + objectscrips_id_seq + ObjectScrips acl_id_seq ACL groupmembers_id_seq @@ -64,17 +66,14 @@ sub acl { # if there's already an rt_user, use it. my @row = $dbh->selectrow_array( "SELECT usename FROM pg_user WHERE usename = '$db_user'" ); unless ( $row[0] ) { - push @acls, "CREATE USER \"$db_user\" WITH PASSWORD '$db_pass' NOCREATEDB NOCREATEUSER;"; + push @acls, "CREATE USER \"$db_user\" WITH PASSWORD '$db_pass' NOCREATEDB NOCREATEUSER;"; } - my $sequence_right - = ( $dbh->{pg_server_version} >= 80200 ) - ? "USAGE, SELECT, UPDATE" - : "SELECT, UPDATE"; foreach my $table (@tables) { if ( $table =~ /^[a-z]/ && $table ne 'sessions' ) { -# table like objectcustomfields_id_s - push @acls, "GRANT $sequence_right ON $table TO \"$db_user\";" + # Sequences; not all end with _seq because + # objectcustomfieldvalues_id_s is too long + push @acls, "GRANT USAGE, SELECT, UPDATE ON $table TO \"$db_user\";" } else { push @acls, "GRANT SELECT, INSERT, UPDATE, DELETE ON $table TO \"$db_user\";" diff --git a/rt/etc/acl.mysql b/rt/etc/acl.mysql index 16882378e..26e27fbfb 100755 --- a/rt/etc/acl.mysql +++ b/rt/etc/acl.mysql @@ -5,15 +5,14 @@ sub acl { my $db_user = RT->Config->Get('DatabaseUser'); my $db_pass = RT->Config->Get('DatabasePassword'); unless ( $db_user ) { - print STDERR "DatabaseUser option is not defined or empty. Skipping...\n"; + RT->Logger->warn("DatabaseUser option is not defined or empty. Skipping..."); return; } if ( $db_user eq 'root' ) { - print STDERR "DatabaseUser is root. Skipping...\n"; + RT->Logger->warn("DatabaseUser is root. Skipping..."); return; } - print "Granting access to $db_user\@'$db_rthost' on $db_name.\n"; - $db_name =~ s/([_%])/\\$1/g; + $db_name =~ s/([_%\\])/\\$1/g; return ( "GRANT SELECT,INSERT,CREATE,INDEX,UPDATE,DELETE ON `$db_name`.* diff --git a/rt/etc/initialdata b/rt/etc/initialdata index a30110489..9b2af3744 100644 --- a/rt/etc/initialdata +++ b/rt/etc/initialdata @@ -58,7 +58,14 @@ Description => 'Sends mail to the administrative Ccs', # loc ExecModule => 'Notify', Argument => 'AdminCc' }, - + { Name => 'Notify Owner and AdminCcs', # loc + Description => 'Sends mail to the Owner and administrative Ccs', # loc + ExecModule => 'Notify', + Argument => 'Owner,AdminCc' }, + { Name => 'Notify Owner or AdminCcs', # loc + Description => 'Sends mail to the Owner if set, otherwise administrative Ccs', # loc + ExecModule => 'NotifyOwnerOrAdminCc', + }, { Name => 'Notify Requestors and Ccs as Comment', # loc Description => 'Send mail to requestors and Ccs as a comment', # loc ExecModule => 'NotifyAsComment', @@ -99,10 +106,15 @@ { Name => 'Open Tickets', # loc Description => 'Open tickets on correspondence', # loc ExecModule => 'AutoOpen' }, + { Name => 'Open Inactive Tickets', # loc + Description => 'Open inactive tickets', # loc + ExecModule => 'AutoOpenInactive' }, { Name => 'Extract Subject Tag', # loc Description => 'Extract tags from a Transaction\'s subject and add them to the Ticket\'s subject.', # loc ExecModule => 'ExtractSubjectTag' }, - + { Name => 'Send Forward', # loc + Description => 'Send forwarded message', # loc + ExecModule => 'SendForward', }, #freeside { Name => 'Set Priority', Description => 'Set ticket priority', @@ -255,7 +267,7 @@ Content => '', }, { Queue => '0', Name => 'Autoreply', # loc - Description => 'Default Autoresponse template', # loc + Description => 'Plain text Autoresponse template', # loc Content => 'Subject: AutoReply: {$Ticket->Subject} @@ -263,7 +275,7 @@ Greetings, This message has been automatically generated in response to the creation of a trouble ticket regarding: - "{$Ticket->Subject()}", + "{$Ticket->Subject()}", a summary of which appears below. There is no need to reply to this message right now. Your ticket has been @@ -283,10 +295,35 @@ you may reply to this message. {$Transaction->Content()} ' }, + { Queue => '0', + Name => 'Autoreply in HTML', # loc + Description => 'HTML Autoresponse template', # loc + Content => q[Subject: AutoReply: {$Ticket->Subject} +Content-Type: text/html + +<p>Greetings,</p> + +<p>This message has been automatically generated in response to the +creation of a trouble ticket regarding <b>{$Ticket->Subject()}</b>, +a summary of which appears below.</p> + +<p>There is no need to reply to this message right now. Your ticket has been +assigned an ID of <b>{$Ticket->SubjectTag}</b>.</p> + +<p>Please include the string <b>{$Ticket->SubjectTag}</b> +in the subject line of all future correspondence about this issue. To do so, +you may reply to this message.</p> +<p>Thank you,<br/> +{$Ticket->QueueObj->CorrespondAddress()}</p> + +<hr/> +{$Transaction->Content(Type => 'text/html')} +], + }, { Queue => '0', Name => 'Transaction', # loc - Description => 'Default transaction template', # loc + Description => 'Plain text transaction template', # loc Content => 'RT-Attach-Message: yes @@ -303,12 +340,43 @@ you may reply to this message. {$Transaction->Content()} ' }, - + { Queue => '0', + Name => 'Transaction in HTML', # loc + Description => 'HTML transaction template', # loc + Content => 'RT-Attach-Message: yes +Content-Type: text/html + +<b>{$Transaction->CreatedAsString}: Request <a href="{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}">{$Ticket->id}</a> was acted upon by {$Transaction->CreatorObj->Name}.</b> +<br> +<table border="0"> +<tr><td align="right"><b>Transaction:</b></td><td>{$Transaction->Description}</td></tr> +<tr><td align="right"><b>Queue:</b></td><td>{$Ticket->QueueObj->Name}</td></tr> +<tr><td align="right"><b>Subject:</b></td><td>{$Transaction->Subject || $Ticket->Subject || "(No subject given)"} </td></tr> +<tr><td align="right"><b>Owner:</b></td><td>{$Ticket->OwnerObj->Name}</td></tr> +<tr><td align="right"><b>Requestors:</b></td><td>{$Ticket->RequestorAddresses}</td></tr> +<tr><td align="right"><b>Status:</b></td><td>{$Ticket->Status}</td></tr> +<tr><td align="right"><b>Ticket URL:</b></td><td><a href="{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}">{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}</a></td></tr> +</table> +<br/> +<br/> +{$Transaction->Content( Type => "text/html")} +' + }, + # Shadow the global templates of the same name to suppress duplicate + # notifications until rules is ripped out. + { Queue => "___Approvals", + Name => "Transaction in HTML", + Content => "", + }, + { Queue => "___Approvals", + Name => "Transaction", + Content => "", + }, { Queue => '0', Name => 'Admin Correspondence', # loc - Description => 'Default admin correspondence template', # loc + Description => 'Plain text admin correspondence template', # loc Content => 'RT-Attach-Message: yes @@ -317,19 +385,38 @@ you may reply to this message. {$Transaction->Content()} ' }, + { Queue => '0', + Name => 'Admin Correspondence in HTML', # loc + Description => 'HTML admin correspondence template', # loc + Content => 'RT-Attach-Message: yes +Content-Type: text/html +Ticket URL: <a href="{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}">{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}</a> +<br /> +<br /> +{$Transaction->Content(Type => "text/html");} +' + }, { Queue => '0', Name => 'Correspondence', # loc - Description => 'Default correspondence template', # loc + Description => 'Plain text correspondence template', # loc Content => 'RT-Attach-Message: yes {$Transaction->Content()} ' }, + { Queue => '0', + Name => 'Correspondence in HTML', # loc + Description => 'HTML correspondence template', # loc + Content => 'RT-Attach-Message: yes +Content-Type: text/html +{$Transaction->Content( Type => "text/html")} +' + }, { Queue => '0', Name => 'Admin Comment', # loc - Description => 'Default admin comment template', # loc + Description => 'Plain text admin comment template', # loc Content => 'Subject: [Comment] {my $s=($Transaction->Subject||$Ticket->Subject||""); $s =~ s/\\[Comment\\]\\s*//g; $s =~ s/^Re:\\s*//i; $s;} RT-Attach-Message: yes @@ -341,6 +428,30 @@ This is a comment. It is not sent to the Requestor(s): {$Transaction->Content()} ' }, + { Queue => '0', + Name => 'Admin Comment in HTML', # loc + Description => 'HTML admin comment template', # loc + Content => +'Subject: [Comment] {my $s=($Transaction->Subject||$Ticket->Subject||""); $s =~ s/\\[Comment\\]\\s*//g; $s =~ s/^Re:\\s*//i; $s;} +RT-Attach-Message: yes +Content-Type: text/html + +<p>This is a comment about <a href="{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}">ticket {$Ticket->id}</a>. It is not sent to the Requestor(s):</p> + +{$Transaction->Content(Type => "text/html")} +' + }, + { Queue => '0', + Name => 'Reminder', # loc + Description => 'Default reminder template', # loc + Content => +'Subject:{$Ticket->Subject} is due {$Ticket->DueObj->AsString} + +This reminder is for ticket #{$Target = $Ticket->RefersTo->First->TargetObj;$Target->Id}. + +{RT->Config->Get(\'WebURL\')}Ticket/Display.html?id={$Target->Id} +' + }, { Queue => '0', Name => 'Status Change', # loc @@ -353,7 +464,18 @@ This is a comment. It is not sent to the Requestor(s): {$Transaction->Content()} ' }, + { Queue => '0', + Name => 'Status Change in HTML', # loc + Description => 'HTML Ticket status changed', # loc + Content => 'Subject: Status Changed to: {$Transaction->NewValue} +Content-Type: text/html +<a href="{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}">{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}</a> +<br/> +<br/> +{$Transaction->Content(Type => "text/html")} +' + }, { Queue => '0', @@ -365,6 +487,15 @@ According to our records, your request has been resolved. If you have any further questions or concerns, please respond to this message. ' }, + { Queue => '0', + Name => 'Resolved in HTML', # loc + Description => 'HTML Ticket Resolved', # loc + Content => 'Subject: Resolved: {$Ticket->Subject} +Content-Type: text/html + +<p>According to our records, your request has been resolved. If you have any further questions or concerns, please respond to this message.</p> +' + }, { Queue => '___Approvals', Name => "New Pending Approval", # loc Description => @@ -385,6 +516,25 @@ batch-process all your pending approvals. ' }, { Queue => '___Approvals', + Name => "New Pending Approval in HTML", # loc + Description => "Notify Owners and AdminCcs of new items pending their approval", # loc + Content => 'Subject: New Pending Approval: {$Ticket->Subject} +Content-Type: text/html + +<p>Greetings,</p> + +<p>There is a new item pending your approval: <b>{$Ticket->Subject()}</b>, +a summary of which appears below.</p> + +<p>Please <a href="{RT->Config->Get(\'WebURL\')}Approvals/Display.html?id={$Ticket->id}">approve +or reject this ticket</a>, or visit the <a href="{RT->Config->Get(\'WebURL\')}Approvals/">approvals +overview</a> to batch-process all your pending approvals.</p> + +<hr /> +{$Transaction->Content()} +' + }, + { Queue => '___Approvals', Name => "Approval Passed", # loc Description => "Notify Requestor of their ticket has been approved by some approver", # loc @@ -399,6 +549,22 @@ Approver\'s notes: { $Notes } ' }, { Queue => '___Approvals', + Name => "Approval Passed in HTML", # loc + Description => + "Notify Requestor of their ticket has been approved by some approver", # loc + Content => 'Subject: Ticket Approved: {$Ticket->Subject} +Content-Type: text/html + +<p>Greetings,</p> + +<p>Your ticket has been approved by <b>{ eval { $Approver->Name } }</b>. +Other approvals may be pending.</p> + +<p>Approver\'s notes:</p> +<blockquote>{ $Notes }</blockquote> +' + }, + { Queue => '___Approvals', Name => "All Approvals Passed", # loc Description => "Notify Requestor of their ticket has been approved by all approvers", # loc @@ -413,6 +579,22 @@ Approver\'s notes: { $Notes } ' }, { Queue => '___Approvals', + Name => "All Approvals Passed in HTML", # loc + Description => + "Notify Requestor of their ticket has been approved by all approvers", # loc + Content => 'Subject: Ticket Approved: {$Ticket->Subject} +Content-Type: text/html + +<p>Greetings,</p> + +<p>Your ticket has been approved by <b>{ eval { $Approver->Name } }</b>. +Its Owner may now start to act on it.</p> + +<p>Approver\'s notes:</p> +<blockquote>{ $Notes }</blockquote> +' + }, + { Queue => '___Approvals', Name => "Approval Rejected", # loc Description => "Notify Owner of their rejected ticket", # loc @@ -426,6 +608,21 @@ Approver\'s notes: { $Notes } ' }, { Queue => '___Approvals', + Name => "Approval Rejected in HTML", # loc + Description => + "Notify Owner of their rejected ticket", # loc + Content => 'Subject: Ticket Rejected: {$Ticket->Subject} +Content-Type: text/html + +<p>Greetings,</p> + +<p>Your ticket has been rejected by <b>{ eval { $Approver->Name } }</b>.</p> + +<p>Approver\'s notes:</p> +<blockquote>{ $Notes }</blockquote> +' + }, + { Queue => '___Approvals', Name => "Approval Ready for Owner", # loc Description => "Notify Owner of their ticket has been approved and is ready to be acted on", # loc @@ -437,19 +634,42 @@ The ticket has been approved, you may now start to act on it. ' }, + { Queue => '___Approvals', + Name => "Approval Ready for Owner in HTML", # loc + Description => + "Notify Owner of their ticket has been approved and is ready to be acted on", # loc + Content => 'Subject: Ticket Approved: {$Ticket->Subject} +Content-Type: text/html + +<p>Greetings,</p> + +<p>The ticket has been approved, you may now start to act on it.</p> + +' + }, { Queue => 0, Name => "Forward", # loc - Description => "Heading of a forwarded message", # loc + Description => "Forwarded message", # loc Content => q{ -This is a forward of transaction #{$Transaction->id} of ticket #{ $Ticket->id } + +{ $ForwardTransaction->Content =~ /\S/ ? $ForwardTransaction->Content : "This is a forward of transaction #".$Transaction->id." of ticket #". $Ticket->id } } }, { Queue => 0, Name => "Forward Ticket", # loc - Description => "Heading of a forwarded Ticket", # loc + Description => "Forwarded ticket message", # loc Content => q{ -This is a forward of ticket #{ $Ticket->id } +{ $ForwardTransaction->Content =~ /\S/ ? $ForwardTransaction->Content : "This is a forward of ticket #". $Ticket->id } +} + }, + { Queue => 0, + Name => "Error: unencrypted message", # loc + Description => + "Inform user that their unencrypted mail has been rejected", # loc + Content => q{Subject: RT requires that all incoming mail be encrypted + +You received this message because RT received mail from you that was not encrypted. As such, it has been rejected. } }, { Queue => 0, @@ -487,12 +707,12 @@ Please, check that you encrypt messages with correct keys or contact the system administrator.} }, { Queue => 0, - Name => "Error: bad GnuPG data", # loc + Name => "Error: bad encrypted data", # loc Description => - "Inform user that a message he sent has invalid GnuPG data", # loc + "Inform user that a message he sent has invalid encryption data", # loc Content => q{Subject: We received a message we cannot handle -You sent us a message that we cannot handle due to corrupted GnuPG signature or encrypted block. we get the following error(s): +You sent us a message that we cannot handle due to corrupted signature or encrypted block. we get the following error(s): { foreach my $msg ( @Messages ) { $OUT .= "* $msg\n"; } @@ -513,10 +733,10 @@ Your new password is: } }, - { Queue => '0', - Name => 'Email Digest', # loc - Description => 'Email template for periodic notification digests', # loc - Content => q[Subject: RT Email Digest + { Queue => '0', + Name => 'Email Digest', # loc + Description => 'Email template for periodic notification digests', # loc + Content => q[Subject: RT Email Digest { $Argument } ], @@ -561,58 +781,66 @@ Hour: { $SubscriptionObj->SubValue('Hour') } ); @Scrips = ( - { Description => 'On Correspond Open Tickets', - ScripCondition => 'On Correspond', - ScripAction => 'Open Tickets', - Template => 'Blank' }, - { Description => 'On Owner Change Notify Owner', - ScripCondition => 'On Owner Change', - ScripAction => 'Notify Owner', - Template => 'Transaction' }, - { Description => 'On Create Autoreply To Requestors', - ScripCondition => 'On Create', - ScripAction => 'AutoReply To Requestors', - Template => 'AutoReply' }, - { Description => 'On Create Notify AdminCcs', - ScripCondition => 'On Create', - ScripAction => 'Notify AdminCcs', - Template => 'Transaction' }, - { Description => 'On Correspond Notify AdminCcs', - ScripCondition => 'On Correspond', - ScripAction => 'Notify AdminCcs', - Template => 'Admin Correspondence' }, -# { Description => 'On Correspond Notify Requestors and Ccs', -# ScripCondition => 'On Correspond', -# ScripAction => 'Notify Requestors And Ccs', -# Template => 'Correspondence' }, -# { Description => 'On Correspond Notify Other Recipients', -# ScripCondition => 'On Correspond', -# ScripAction => 'Notify Other Recipients', -# Template => 'Correspondence' }, - { Description => 'On Correspond Notify Requestors, Ccs, and Other Recipients', - ScripCondition => 'On Correspond', - ScripAction => 'Notify Requestors, Ccs, and Other Recipients', - Template => 'Correspondence', }, { Description => 'On Comment Notify AdminCcs as Comment', ScripCondition => 'On Comment', ScripAction => 'Notify AdminCcs As Comment', - Template => 'Admin Comment' }, + Template => 'Admin Comment in HTML' }, { Description => 'On Comment Notify Other Recipients as Comment', ScripCondition => 'On Comment', ScripAction => 'Notify Other Recipients As Comment', - Template => 'Correspondence' }, + Template => 'Correspondence in HTML' }, + { Description => 'On Correspond Notify Owner and AdminCcs', + ScripCondition => 'On Correspond', + ScripAction => 'Notify Owner and AdminCcs', + Template => 'Admin Correspondence in HTML' }, +# { Description => 'On Correspond Notify Other Recipients', +# ScripCondition => 'On Correspond', +# ScripAction => 'Notify Other Recipients', +# Template => 'Correspondence in HTML' }, +# { Description => 'On Correspond Notify Requestors and Ccs', +# ScripCondition => 'On Correspond', +# ScripAction => 'Notify Requestors And Ccs', +# Template => 'Correspondence in HTML' }, + { Description => 'On Correspond Open Inactive Tickets', + ScripCondition => 'On Correspond', + ScripAction => 'Open Inactive Tickets', + Template => 'Blank' }, + { Description => 'On Create Autoreply To Requestors', + ScripCondition => 'On Create', + ScripAction => 'AutoReply To Requestors', + Template => 'AutoReply in HTML' }, + { Description => 'On Create Notify Owner and AdminCcs', + ScripCondition => 'On Create', + ScripAction => 'Notify Owner and AdminCcs', + Template => 'Transaction in HTML' }, + { Description => 'On Create Notify Ccs', + ScripCondition => 'On Create', + ScripAction => 'Notify Ccs', + Template => 'Correspondence in HTML' }, + { Description => 'On Create Notify Other Recipients', + ScripCondition => 'On Create', + ScripAction => 'Notify Other Recipients', + Template => 'Correspondence in HTML' }, + { Description => 'On Owner Change Notify Owner', + ScripCondition => 'On Owner Change', + ScripAction => 'Notify Owner', + Template => 'Transaction in HTML' }, { Description => 'On Resolve Notify Requestors', ScripCondition => 'On Resolve', ScripAction => 'Notify Requestors', - Template => 'Resolved' }, + Template => 'Resolved in HTML' }, { Description => "On transaction, add any tags in the transaction's subject to the ticket's subject", ScripCondition => 'On Transaction', ScripAction => 'Extract Subject Tag', Template => 'Blank' }, - { Description => 'On Correspond, cancel future resolve', - ScripCondition => 'On Correspond', - ScripAction => 'Cancel Scheduled Resolve', - Template => 'Blank' }, + { Description => 'On Forward Transaction Send forwarded message', + ScripCondition => 'On Forward Transaction', + ScripAction => 'Send Forward', + Template => 'Forward' }, + { Description => 'On Forward Ticket Send forwarded message', + ScripCondition => 'On Forward Ticket', + ScripAction => 'Send Forward', + Template => 'Forward Ticket' }, ); @ACL = ( @@ -666,7 +894,7 @@ Hour: { $SubscriptionObj->SubValue('Hour') } Name => 'HomepageSettings', Description => 'HomepageSettings', Content => { - 'body' => # loc + 'body' => # loc_left_pair [ { type => 'system', @@ -685,7 +913,7 @@ Hour: { $SubscriptionObj->SubValue('Hour') } name => 'QuickCreate' # loc }, ], - 'summary' => # loc + 'sidebar' => # loc_left_pair [ { type => 'component', diff --git a/rt/etc/schema.Pg b/rt/etc/schema.Pg index ccd1ee531..25455be6a 100755 --- a/rt/etc/schema.Pg +++ b/rt/etc/schema.Pg @@ -63,7 +63,7 @@ CREATE TABLE Queues ( PRIMARY KEY (id) ); -CREATE UNIQUE INDEX Queues1 ON Queues (Name) ; +CREATE UNIQUE INDEX Queues1 ON Queues (LOWER(Name)) ; @@ -144,8 +144,9 @@ CREATE TABLE Groups ( PRIMARY KEY (id) ); -CREATE UNIQUE INDEX Groups1 ON Groups (Domain,Instance,Type,id, Name); -CREATE INDEX Groups2 On Groups (Type, Instance, Domain); +CREATE INDEX Groups1 ON Groups (LOWER(Domain), LOWER(Type), Instance); +CREATE INDEX Groups2 ON Groups (LOWER(Domain), LOWER(Name), Instance); +CREATE INDEX Groups3 On Groups (Instance); @@ -225,14 +226,11 @@ CREATE TABLE Scrips ( Description varchar(255), ScripCondition integer NOT NULL DEFAULT 0 , ScripAction integer NOT NULL DEFAULT 0 , - ConditionRules text NULL , - ActionRules text NULL , CustomIsApplicableCode text NULL , CustomPrepareCode text NULL , CustomCommitCode text NULL , - Stage varchar(32) NULL , - Queue integer NOT NULL DEFAULT 0 , - Template integer NOT NULL DEFAULT 0 , + Disabled integer NOT NULL DEFAULT 0 , + Template varchar(200) NOT NULL, Creator integer NOT NULL DEFAULT 0 , Created TIMESTAMP NULL , LastUpdatedBy integer NOT NULL DEFAULT 0 , @@ -242,7 +240,24 @@ CREATE TABLE Scrips ( ); +CREATE SEQUENCE objectscrips_id_seq; + +CREATE TABLE ObjectScrips ( + id INTEGER DEFAULT nextval('objectscrips_id_seq'), + Scrip integer NOT NULL, + Stage varchar(32) NOT NULL DEFAULT 'TransactionCreate' , + ObjectId integer NOT NULL, + SortOrder integer NOT NULL DEFAULT 0 , + + Creator integer NOT NULL DEFAULT 0 , + Created TIMESTAMP NULL , + LastUpdatedBy integer NOT NULL DEFAULT 0 , + LastUpdated TIMESTAMP NULL , + PRIMARY KEY (id) + +); +CREATE UNIQUE INDEX ObjectScrips1 ON ObjectScrips (ObjectId, Scrip); @@ -320,9 +335,9 @@ CREATE TABLE CachedGroupMembers ( ); -CREATE INDEX CachedGroupMembers2 on CachedGroupMembers (MemberId); -CREATE INDEX CachedGroupMembers3 on CachedGroupMembers (GroupId); -CREATE INDEX DisGrouMem on CachedGroupMembers (GroupId,MemberId,Disabled); +CREATE INDEX CachedGroupMembers2 on CachedGroupMembers (MemberId, GroupId, Disabled); +CREATE INDEX DisGrouMem on CachedGroupMembers (GroupId,MemberId,Disabled); +CREATE INDEX CachedGroupMembers3 on CachedGroupMembers (MemberId,ImmediateParentId); @@ -368,6 +383,7 @@ CREATE TABLE Users ( Country varchar(50) NULL , Timezone varchar(50) NULL , PGPKey text NULL, + SMIMECertificate text NULL, Creator integer NOT NULL DEFAULT 0 , Created TIMESTAMP NULL , @@ -378,8 +394,7 @@ CREATE TABLE Users ( ); -CREATE UNIQUE INDEX Users1 ON Users (Name) ; -CREATE INDEX Users3 ON Users (id, EmailAddress); +CREATE UNIQUE INDEX Users1 ON Users (LOWER(Name)) ; CREATE INDEX Users4 ON Users (EmailAddress); @@ -398,6 +413,7 @@ CREATE SEQUENCE tickets_id_seq; CREATE TABLE Tickets ( id INTEGER DEFAULT nextval('tickets_id_seq'), EffectiveId integer NOT NULL DEFAULT 0 , + IsMerged smallint NULL DEFAULT NULL , Queue integer NOT NULL DEFAULT 0 , Type varchar(16) NULL , IssueStatement integer NOT NULL DEFAULT 0 , @@ -431,13 +447,6 @@ CREATE TABLE Tickets ( CREATE INDEX Tickets1 ON Tickets (Queue, Status) ; CREATE INDEX Tickets2 ON Tickets (Owner) ; CREATE INDEX Tickets3 ON Tickets (EffectiveId) ; -CREATE INDEX Tickets4 ON Tickets (id, Status) ; -CREATE INDEX Tickets5 ON Tickets (id, EffectiveId) ; - - - - - -- @@ -478,8 +487,6 @@ CREATE TABLE Templates ( Name varchar(200) NOT NULL , Description varchar(255) NULL , Type varchar(16) NULL , - Language varchar(16) NULL , - TranslationOf integer NOT NULL DEFAULT 0 , Content text NULL , LastUpdated TIMESTAMP NULL , LastUpdatedBy integer NOT NULL DEFAULT 0 , @@ -543,7 +550,6 @@ CREATE TABLE CustomFields ( Type varchar(200) NULL , RenderType varchar(64) NULL , MaxValues integer NOT NULL DEFAULT 0 , - Repeated integer NOT NULL DEFAULT 0 , ValuesClass varchar(64) NULL , BasedOn integer NULL, Pattern varchar(65536) NULL , diff --git a/rt/etc/schema.SQLite b/rt/etc/schema.SQLite index 6897be2d6..c50e5b122 100644 --- a/rt/etc/schema.SQLite +++ b/rt/etc/schema.SQLite @@ -4,13 +4,13 @@ CREATE TABLE Attachments ( id INTEGER PRIMARY KEY , TransactionId INTEGER , Parent integer NULL DEFAULT 0 , - MessageId varchar(160) NULL , - Subject varchar(255) NULL , - Filename varchar(255) NULL , - ContentType varchar(80) NULL , - ContentEncoding varchar(80) NULL , - Content LONGTEXT NULL , - Headers LONGTEXT NULL , + MessageId varchar(160) collate NOCASE NULL , + Subject varchar(255) collate NOCASE NULL , + Filename varchar(255) collate NOCASE NULL , + ContentType varchar(80) collate NOCASE NULL , + ContentEncoding varchar(80) collate NOCASE NULL , + Content LONGTEXT collate NOCASE NULL , + Headers LONGTEXT collate NOCASE NULL , Creator integer NULL DEFAULT 0 , Created DATETIME NULL @@ -24,12 +24,12 @@ CREATE INDEX Attachments3 ON Attachments (Parent, TransactionId) ; --- {{{ Queues CREATE TABLE Queues ( id INTEGER PRIMARY KEY , - Name varchar(200) NOT NULL , - Description varchar(255) NULL , - CorrespondAddress varchar(120) NULL , - CommentAddress varchar(120) NULL , - Lifecycle varchar(32) NULL , - SubjectTag varchar(120) NULL , + Name varchar(200) collate NOCASE NOT NULL , + Description varchar(255) collate NOCASE NULL , + CorrespondAddress varchar(120) collate NOCASE NULL , + CommentAddress varchar(120) collate NOCASE NULL , + Lifecycle varchar(32) collate NOCASE NULL , + SubjectTag varchar(120) collate NOCASE NULL , InitialPriority integer NULL DEFAULT 0 , FinalPriority integer NULL DEFAULT 0 , DefaultDueIn integer NULL DEFAULT 0 , @@ -48,9 +48,9 @@ CREATE UNIQUE INDEX Queues1 ON Queues (Name) ; CREATE TABLE Links ( id INTEGER PRIMARY KEY , - Base varchar(240) NULL , - Target varchar(240) NULL , - Type varchar(20) NOT NULL , + Base varchar(240) collate NOCASE NULL , + Target varchar(240) collate NOCASE NULL , + Type varchar(20) collate NOCASE NOT NULL , LocalTarget integer NULL DEFAULT 0 , LocalBase integer NULL DEFAULT 0 , LastUpdatedBy integer NULL DEFAULT 0 , @@ -68,7 +68,7 @@ CREATE INDEX Links4 ON Links(Type,LocalBase); CREATE TABLE Principals ( id INTEGER PRIMARY KEY, - PrincipalType VARCHAR(16) not null, + PrincipalType VARCHAR(16) collate NOCASE not null, ObjectId integer, Disabled int2 NOT NULL DEFAULT 0 @@ -80,10 +80,10 @@ CREATE TABLE Principals ( CREATE TABLE Groups ( id INTEGER , - Name varchar(200) NULL , - Description varchar(255) NULL , - Domain varchar(64), - Type varchar(64), + Name varchar(200) collate NOCASE NULL , + Description varchar(255) collate NOCASE NULL , + Domain varchar(64) collate NOCASE, + Type varchar(64) collate NOCASE, Instance integer, Creator integer NOT NULL DEFAULT 0 , Created DATETIME NULL , @@ -92,7 +92,9 @@ CREATE TABLE Groups ( ) ; -CREATE UNIQUE INDEX Groups1 ON Groups (Name,Domain,Type,Instance) ; +CREATE INDEX Groups1 ON Groups (Domain,Type,Instance); +CREATE INDEX Groups2 ON Groups (Domain,Name,Instance); +CREATE INDEX Groups3 ON Groups (Instance); --- }}} @@ -100,11 +102,11 @@ CREATE UNIQUE INDEX Groups1 ON Groups (Name,Domain,Type,Instance) ; CREATE TABLE ScripConditions ( id INTEGER PRIMARY KEY , - Name varchar(200) NULL , - Description varchar(255) NULL , - ExecModule varchar(60) NULL , - Argument varchar(255) NULL , - ApplicableTransTypes varchar(60) NULL , + Name varchar(200) collate NOCASE NULL , + Description varchar(255) collate NOCASE NULL , + ExecModule varchar(60) collate NOCASE NULL , + Argument varchar(255) collate NOCASE NULL , + ApplicableTransTypes varchar(60) collate NOCASE NULL , Creator integer NULL DEFAULT 0 , Created DATETIME NULL , @@ -118,17 +120,17 @@ CREATE TABLE ScripConditions ( --- {{{ Transactions CREATE TABLE Transactions ( id INTEGER PRIMARY KEY , - ObjectType varchar(255) NULL , + ObjectType varchar(255) collate NOCASE NULL , ObjectId integer NULL DEFAULT 0 , TimeTaken integer NULL DEFAULT 0 , - Type varchar(20) NULL , - Field varchar(40) NULL , - OldValue varchar(255) NULL , - NewValue varchar(255) NULL , - ReferenceType varchar(255) NULL , + Type varchar(20) collate NOCASE NULL , + Field varchar(40) collate NOCASE NULL , + OldValue varchar(255) collate NOCASE NULL , + NewValue varchar(255) collate NOCASE NULL , + ReferenceType varchar(255) collate NOCASE NULL , OldReference integer NULL , NewReference integer NULL , - Data varchar(255) NULL , + Data varchar(255) collate NOCASE NULL , Creator integer NULL DEFAULT 0 , Created DATETIME NULL @@ -142,17 +144,14 @@ CREATE INDEX Transactions1 ON Transactions (ObjectType, ObjectId); CREATE TABLE Scrips ( id INTEGER PRIMARY KEY , - Description varchar(255), + Description varchar(255) collate NOCASE, ScripCondition integer NULL DEFAULT 0 , ScripAction integer NULL DEFAULT 0 , - ConditionRules text NULL , - ActionRules text NULL , - CustomIsApplicableCode text NULL , - CustomPrepareCode text NULL , - CustomCommitCode text NULL , - Stage varchar(32) NULL , - Queue integer NULL DEFAULT 0 , - Template integer NULL DEFAULT 0 , + CustomIsApplicableCode text collate NOCASE NULL , + CustomPrepareCode text collate NOCASE NULL , + CustomCommitCode text collate NOCASE NULL , + Disabled int2 NOT NULL DEFAULT 0 , + Template varchar(200) collate NOCASE NOT NULL , Creator integer NULL DEFAULT 0 , Created DATETIME NULL , LastUpdatedBy integer NULL DEFAULT 0 , @@ -162,14 +161,29 @@ CREATE TABLE Scrips ( --- }}} +CREATE TABLE ObjectScrips ( + id INTEGER NOT NULL , + Scrip int NOT NULL , + Stage varchar(32) collate NOCASE NOT NULL DEFAULT 'TransactionCreate' , + ObjectId integer NOT NULL, + SortOrder integer NOT NULL DEFAULT 0 , + + Creator integer NOT NULL DEFAULT 0 , + Created DATETIME NULL , + LastUpdatedBy integer NOT NULL DEFAULT 0 , + LastUpdated DATETIME NULL , + PRIMARY KEY (id) +); +CREATE UNIQUE INDEX ObjectScrips1 ON ObjectScrips (ObjectId, Scrip); + --- {{{ ACL CREATE TABLE ACL ( id INTEGER PRIMARY KEY , - PrincipalType varchar(25) NOT NULL, + PrincipalType varchar(25) collate NOCASE NOT NULL, PrincipalId INTEGER DEFAULT 0, - RightName varchar(25) NOT NULL , - ObjectType varchar(25) NOT NULL , + RightName varchar(25) collate NOCASE NOT NULL , + ObjectType varchar(25) collate NOCASE NOT NULL , ObjectId INTEGER default 0, Creator integer NOT NULL DEFAULT 0 , Created DATETIME NULL , @@ -194,6 +208,8 @@ CREATE TABLE GroupMembers ( ) ; +CREATE UNIQUE INDEX GroupMembers1 ON GroupMembers(GroupId, MemberId); + --- }}} --- {{{ CachedGroupMembers @@ -213,42 +229,47 @@ create table CachedGroupMembers ( ) ; +CREATE INDEX CachedGroupMembers1 ON CachedGroupMembers (GroupId, MemberId, Disabled); +CREATE INDEX CachedGroupMembers2 ON CachedGroupMembers (MemberId, GroupId, Disabled); +CREATE INDEX CachedGroupMembers3 ON CachedGroupMembers (MemberId, ImmediateParentId); + --- }}} --- {{{ Users CREATE TABLE Users ( id INTEGER , - Name varchar(200) NOT NULL , - Password varchar(256) NULL , - AuthToken varchar(16) NULL , + Name varchar(200) collate NOCASE NOT NULL , + Password varchar(256) collate NOCASE NULL , + AuthToken varchar(16) collate NOCASE NULL , Comments blob NULL , Signature blob NULL , - EmailAddress varchar(120) NULL , + EmailAddress varchar(120) collate NOCASE NULL , FreeformContactInfo blob NULL , - Organization varchar(200) NULL , - RealName varchar(120) NULL , - NickName varchar(16) NULL , - Lang varchar(16) NULL , - EmailEncoding varchar(16) NULL , - WebEncoding varchar(16) NULL , - ExternalContactInfoId varchar(100) NULL , - ContactInfoSystem varchar(30) NULL , - ExternalAuthId varchar(100) NULL , - AuthSystem varchar(30) NULL , - Gecos varchar(16) NULL , - HomePhone varchar(30) NULL , - WorkPhone varchar(30) NULL , - MobilePhone varchar(30) NULL , - PagerPhone varchar(30) NULL , - Address1 varchar(200) NULL , - Address2 varchar(200) NULL , - City varchar(100) NULL , - State varchar(100) NULL , - Zip varchar(16) NULL , - Country varchar(50) NULL , + Organization varchar(200) collate NOCASE NULL , + RealName varchar(120) collate NOCASE NULL , + NickName varchar(16) collate NOCASE NULL , + Lang varchar(16) collate NOCASE NULL , + EmailEncoding varchar(16) collate NOCASE NULL , + WebEncoding varchar(16) collate NOCASE NULL , + ExternalContactInfoId varchar(100) collate NOCASE NULL , + ContactInfoSystem varchar(30) collate NOCASE NULL , + ExternalAuthId varchar(100) collate NOCASE NULL , + AuthSystem varchar(30) collate NOCASE NULL , + Gecos varchar(16) collate NOCASE NULL , + HomePhone varchar(30) collate NOCASE NULL , + WorkPhone varchar(30) collate NOCASE NULL , + MobilePhone varchar(30) collate NOCASE NULL , + PagerPhone varchar(30) collate NOCASE NULL , + Address1 varchar(200) collate NOCASE NULL , + Address2 varchar(200) collate NOCASE NULL , + City varchar(100) collate NOCASE NULL , + State varchar(100) collate NOCASE NULL , + Zip varchar(16) collate NOCASE NULL , + Country varchar(50) collate NOCASE NULL , Timezone char(50) NULL , - PGPKey text NULL, + PGPKey text collate NOCASE NULL, + SMIMECertificate text collate NOCASE NULL, Creator integer NULL DEFAULT 0 , Created DATETIME NULL , @@ -259,8 +280,6 @@ CREATE TABLE Users ( CREATE UNIQUE INDEX Users1 ON Users (Name) ; -CREATE INDEX Users2 ON Users (Name); -CREATE INDEX Users3 ON Users (id, EmailAddress); CREATE INDEX Users4 ON Users (EmailAddress); @@ -271,18 +290,19 @@ CREATE INDEX Users4 ON Users (EmailAddress); CREATE TABLE Tickets ( id INTEGER PRIMARY KEY , EffectiveId integer NULL DEFAULT 0 , + IsMerged int2 NULL DEFAULT NULL, Queue integer NULL DEFAULT 0 , - Type varchar(16) NULL , + Type varchar(16) collate NOCASE NULL , IssueStatement integer NULL DEFAULT 0 , Resolution integer NULL DEFAULT 0 , Owner integer NULL DEFAULT 0 , - Subject varchar(200) NULL DEFAULT '[no subject]' , + Subject varchar(200) collate NOCASE NULL DEFAULT '[no subject]' , InitialPriority integer NULL DEFAULT 0 , FinalPriority integer NULL DEFAULt 0 , Priority integer NULL DEFAULT 0 , TimeEstimated integer NULL DEFAULT 0 , TimeWorked integer NULL DEFAULT 0 , - Status varchar(64) NULL , + Status varchar(64) collate NOCASE NULL , TimeLeft integer NULL DEFAULT 0 , Told DATETIME NULL , Starts DATETIME NULL , @@ -302,8 +322,6 @@ CREATE TABLE Tickets ( CREATE INDEX Tickets1 ON Tickets (Queue, Status) ; CREATE INDEX Tickets2 ON Tickets (Owner) ; CREATE INDEX Tickets3 ON Tickets (EffectiveId) ; -CREATE INDEX Tickets4 ON Tickets (id, Status) ; -CREATE INDEX Tickets5 ON Tickets (id, EffectiveId) ; --- }}} @@ -311,10 +329,10 @@ CREATE INDEX Tickets5 ON Tickets (id, EffectiveId) ; CREATE TABLE ScripActions ( id INTEGER PRIMARY KEY , - Name varchar(200) NULL , - Description varchar(255) NULL , - ExecModule varchar(60) NULL , - Argument varchar(255) NULL , + Name varchar(200) collate NOCASE NULL , + Description varchar(255) collate NOCASE NULL , + ExecModule varchar(60) collate NOCASE NULL , + Argument varchar(255) collate NOCASE NULL , Creator integer NULL DEFAULT 0 , Created DATETIME NULL , LastUpdatedBy integer NULL DEFAULT 0 , @@ -329,11 +347,9 @@ CREATE TABLE ScripActions ( CREATE TABLE Templates ( id INTEGER PRIMARY KEY , Queue integer NOT NULL DEFAULT 0 , - Name varchar(200) NOT NULL , - Description varchar(255) NULL , - Type varchar(16) NULL , - Language varchar(16) NULL , - TranslationOf integer NULL DEFAULT 0 , + Name varchar(200) collate NOCASE NOT NULL , + Description varchar(255) collate NOCASE NULL , + Type varchar(16) collate NOCASE NULL , Content blob NULL , LastUpdated DATETIME NULL , LastUpdatedBy integer NULL DEFAULT 0 , @@ -350,14 +366,14 @@ CREATE TABLE Templates ( CREATE TABLE ObjectCustomFieldValues ( id INTEGER NOT NULL , CustomField int NOT NULL , - ObjectType varchar(255) NOT NULL, # Final target of the Object - ObjectId int NOT NULL , # New -- Replaces Ticket + ObjectType varchar(255) collate NOCASE NOT NULL, # Final target of the Object + ObjectId int NOT NULL , # New -- Replaces Ticket SortOrder integer NOT NULL DEFAULT 0 , - Content varchar(255) NULL , - LargeContent LONGTEXT NULL, # New -- to hold 255+ strings - ContentType varchar(80) NULL, # New -- only text/* gets searched - ContentEncoding varchar(80) NULL , # New -- for binary Content + Content varchar(255) collate NOCASE NULL , + LargeContent LONGTEXT collate NOCASE NULL, # New -- to hold 255+ strings + ContentType varchar(80) collate NOCASE NULL, # New -- only text/* gets searched + ContentEncoding varchar(80) collate NOCASE NULL , # New -- for binary Content Creator integer NOT NULL DEFAULT 0 , Created DATETIME NULL , @@ -374,17 +390,16 @@ CREATE INDEX ObjectCustomFieldValues2 ON ObjectCustomFieldValues (CustomField,Ob CREATE TABLE CustomFields ( id INTEGER NOT NULL , - Name varchar(200) NULL , - Type varchar(200) NULL , # Changed -- 'Single' and 'Multiple' is moved out - RenderType varchar(64) NULL , - MaxValues integer, # New -- was 'Single'(1) and 'Multiple'(0) - Pattern varchar(65536) NULL , # New -- Must validate against this - Repeated int2 NOT NULL DEFAULT 0 , # New -- repeated table entry + Name varchar(200) collate NOCASE NULL , + Type varchar(200) collate NOCASE NULL , # Changed -- 'Single' and 'Multiple' is moved out + RenderType varchar(64) collate NOCASE NULL , + MaxValues integer, # New -- was 'Single'(1) and 'Multiple'(0) + Pattern varchar(65536) collate NOCASE NULL , # New -- Must validate against this BasedOn INTEGER NULL, - ValuesClass varchar(64) NULL , - Description varchar(255) NULL , + ValuesClass varchar(64) collate NOCASE NULL , + Description varchar(255) collate NOCASE NULL , SortOrder integer NOT NULL DEFAULT 0 , - LookupType varchar(255) NOT NULL, + LookupType varchar(255) collate NOCASE NOT NULL, Creator integer NOT NULL DEFAULT 0 , Created DATETIME NULL , @@ -414,10 +429,10 @@ CREATE TABLE ObjectCustomFields ( CREATE TABLE CustomFieldValues ( id INTEGER NOT NULL , CustomField int NOT NULL , - Name varchar(200) NULL , - Description varchar(255) NULL , + Name varchar(200) collate NOCASE NULL , + Description varchar(255) collate NOCASE NULL , SortOrder integer NOT NULL DEFAULT 0 , - Category varchar(255) NULL , + Category varchar(255) collate NOCASE NULL , Creator integer NOT NULL DEFAULT 0 , Created DATETIME NULL , @@ -432,11 +447,11 @@ CREATE INDEX CustomFieldValues1 ON CustomFieldValues (CustomField); --- {{{ Attributes CREATE TABLE Attributes ( id INTEGER PRIMARY KEY , - Name varchar(255) NOT NULL , - Description varchar(255) NULL , - Content LONGTEXT NULL , - ContentType varchar(16), - ObjectType varchar(25) NOT NULL , + Name varchar(255) collate NOCASE NOT NULL , + Description varchar(255) collate NOCASE NULL , + Content LONGTEXT collate NOCASE NULL , + ContentType varchar(16) collate NOCASE, + ObjectType varchar(25) collate NOCASE NOT NULL , ObjectId INTEGER , Creator integer NULL DEFAULT 0 , Created DATETIME NULL , @@ -451,8 +466,8 @@ CREATE INDEX Attributes2 on Attributes(ObjectType, ObjectId); CREATE TABLE Classes ( id INTEGER PRIMARY KEY, -Name varchar(255) NOT NULL DEFAULT '', -Description varchar(255) NOT NULL DEFAULT '', +Name varchar(255) collate NOCASE NOT NULL DEFAULT '', +Description varchar(255) collate NOCASE NOT NULL DEFAULT '', SortOrder integer NOT NULL DEFAULT 0, Disabled smallint NOT NULL DEFAULT 0, Creator integer NOT NULL DEFAULT 0, @@ -464,12 +479,12 @@ HotList smallint NOT NULL DEFAULT 0 CREATE TABLE Articles ( id INTEGER PRIMARY KEY, -Name varchar(255) NOT NULL DEFAULT '', -Summary varchar(255) NOT NULL DEFAULT '', +Name varchar(255) collate NOCASE NOT NULL DEFAULT '', +Summary varchar(255) collate NOCASE NOT NULL DEFAULT '', SortOrder integer NOT NULL DEFAULT 0, Class integer NOT NULL DEFAULT 0, Parent integer NOT NULL DEFAULT 0, -URI varchar(255), +URI varchar(255) collate NOCASE, Creator integer NOT NULL DEFAULT 0, Created TIMESTAMP NULL, LastUpdatedBy integer NOT NULL DEFAULT 0, @@ -480,9 +495,9 @@ LastUpdated TIMESTAMP NULL CREATE TABLE Topics ( id INTEGER PRIMARY KEY, Parent integer NOT NULL DEFAULT 0, -Name varchar(255) NOT NULL DEFAULT '', -Description varchar(255) NOT NULL DEFAULT '', -ObjectType varchar(64) NOT NULL DEFAULT '', +Name varchar(255) collate NOCASE NOT NULL DEFAULT '', +Description varchar(255) collate NOCASE NOT NULL DEFAULT '', +ObjectType varchar(64) collate NOCASE NOT NULL DEFAULT '', ObjectId integer NOT NULL DEFAULT 0 ); @@ -490,14 +505,14 @@ ObjectId integer NOT NULL DEFAULT 0 CREATE TABLE ObjectTopics ( id INTEGER PRIMARY KEY, Topic integer NOT NULL DEFAULT 0, -ObjectType varchar(64) NOT NULL DEFAULT '', +ObjectType varchar(64) collate NOCASE NOT NULL DEFAULT '', ObjectId integer NOT NULL DEFAULT 0 ); CREATE TABLE ObjectClasses ( id INTEGER PRIMARY KEY, Class integer NOT NULL DEFAULT 0, -ObjectType varchar(64) NOT NULL DEFAULT '', +ObjectType varchar(64) collate NOCASE NOT NULL DEFAULT '', ObjectId integer NOT NULL DEFAULT 0, Creator integer NOT NULL DEFAULT 0, Created TIMESTAMP NULL, diff --git a/rt/etc/schema.mysql b/rt/etc/schema.mysql index e0ccecb52..da14e72ed 100644 --- a/rt/etc/schema.mysql +++ b/rt/etc/schema.mysql @@ -46,7 +46,7 @@ CREATE TABLE Links ( id INTEGER NOT NULL AUTO_INCREMENT, Base varchar(240) NULL, Target varchar(240) NULL, - Type varchar(20) NOT NULL, + Type varchar(20) CHARACTER SET ascii NOT NULL , LocalTarget integer NOT NULL DEFAULT 0 , LocalBase integer NOT NULL DEFAULT 0 , LastUpdatedBy integer NOT NULL DEFAULT 0 , @@ -54,7 +54,7 @@ CREATE TABLE Links ( Creator integer NOT NULL DEFAULT 0 , Created DATETIME NULL , PRIMARY KEY (id) -) ENGINE=InnoDB CHARACTER SET ascii; +) ENGINE=InnoDB CHARACTER SET utf8; CREATE INDEX Links2 ON Links (Base, Type) ; CREATE INDEX Links3 ON Links (Target, Type) ; @@ -88,10 +88,9 @@ CREATE TABLE Groups ( PRIMARY KEY (id) ) ENGINE=InnoDB CHARACTER SET utf8; -CREATE INDEX Groups1 ON Groups (Domain,Instance,Type,id); -CREATE INDEX Groups2 On Groups (Type, Instance); - - +CREATE INDEX Groups1 ON Groups (Domain, Type, Instance); +CREATE INDEX Groups2 ON Groups (Domain, Name, Instance); +CREATE INDEX Groups3 On Groups (Instance); CREATE TABLE ScripConditions ( id INTEGER NOT NULL AUTO_INCREMENT, @@ -137,14 +136,25 @@ CREATE TABLE Scrips ( Description varchar(255), ScripCondition integer NOT NULL DEFAULT 0 , ScripAction integer NOT NULL DEFAULT 0 , - ConditionRules text NULL , - ActionRules text NULL , CustomIsApplicableCode text NULL , CustomPrepareCode text NULL , CustomCommitCode text NULL , - Stage varchar(32) CHARACTER SET ascii NULL , - Queue integer NOT NULL DEFAULT 0 , - Template integer NOT NULL DEFAULT 0 , + Disabled int2 NOT NULL DEFAULT 0 , + Template varchar(200) NOT NULL , + Creator integer NOT NULL DEFAULT 0 , + Created DATETIME NULL , + LastUpdatedBy integer NOT NULL DEFAULT 0 , + LastUpdated DATETIME NULL , + PRIMARY KEY (id) +) ENGINE=InnoDB CHARACTER SET utf8; + +CREATE TABLE ObjectScrips ( + id INTEGER NOT NULL AUTO_INCREMENT, + Scrip integer NOT NULL , + Stage varchar(32) CHARACTER SET ascii NOT NULL DEFAULT 'TransactionCreate', + ObjectId integer NOT NULL, + SortOrder integer NOT NULL DEFAULT 0 , + Creator integer NOT NULL DEFAULT 0 , Created DATETIME NULL , LastUpdatedBy integer NOT NULL DEFAULT 0 , @@ -152,6 +162,7 @@ CREATE TABLE Scrips ( PRIMARY KEY (id) ) ENGINE=InnoDB CHARACTER SET utf8; +CREATE UNIQUE INDEX ObjectScrips1 ON ObjectScrips (ObjectId, Scrip); CREATE TABLE ACL ( id INTEGER NOT NULL AUTO_INCREMENT, @@ -204,6 +215,7 @@ create table CachedGroupMembers ( ) ENGINE=InnoDB CHARACTER SET utf8; CREATE INDEX DisGrouMem on CachedGroupMembers (GroupId,MemberId,Disabled); +CREATE INDEX CachedGroupMembers2 on CachedGroupMembers (MemberId, GroupId, Disabled); CREATE INDEX CachedGroupMembers3 on CachedGroupMembers (MemberId, ImmediateParentId); @@ -240,6 +252,7 @@ CREATE TABLE Users ( Country varchar(50) NULL , Timezone varchar(50) NULL , PGPKey text NULL, + SMIMECertificate text NULL, Creator integer NOT NULL DEFAULT 0 , Created DATETIME NULL , @@ -258,6 +271,7 @@ CREATE INDEX Users4 ON Users (EmailAddress); CREATE TABLE Tickets ( id INTEGER NOT NULL AUTO_INCREMENT, EffectiveId integer NOT NULL DEFAULT 0 , + IsMerged int2 NULL DEFAULT NULL, Queue integer NOT NULL DEFAULT 0 , Type varchar(16) CHARACTER SET ascii NULL , IssueStatement integer NOT NULL DEFAULT 0 , @@ -313,8 +327,6 @@ CREATE TABLE Templates ( Name varchar(200) NOT NULL , Description varchar(255) NULL , Type varchar(16) CHARACTER SET ascii NULL , - Language varchar(16) CHARACTER SET ascii NULL , - TranslationOf integer NOT NULL DEFAULT 0 , Content TEXT NULL , LastUpdated DATETIME NULL , LastUpdatedBy integer NOT NULL DEFAULT 0 , @@ -328,14 +340,14 @@ CREATE TABLE Templates ( CREATE TABLE ObjectCustomFieldValues ( id INTEGER NOT NULL AUTO_INCREMENT, CustomField int NOT NULL , - ObjectType varchar(255) CHARACTER SET ascii NOT NULL, # Final target of the Object - ObjectId int NOT NULL , # New -- Replaces Ticket + ObjectType varchar(255) CHARACTER SET ascii NOT NULL, # Final target of the Object + ObjectId int NOT NULL , # New -- Replaces Ticket SortOrder integer NOT NULL DEFAULT 0 , # New -- ordering for multiple values Content varchar(255) NULL , - LargeContent LONGBLOB NULL, # New -- to hold 255+ strings - ContentType varchar(80) CHARACTER SET ascii NULL, # New -- only text/* gets searched - ContentEncoding varchar(80) CHARACTER SET ascii NULL , # New -- for binary Content + LargeContent LONGBLOB NULL, # New -- to hold 255+ strings + ContentType varchar(80) CHARACTER SET ascii NULL, # New -- only text/* gets searched + ContentEncoding varchar(80) CHARACTER SET ascii NULL , # New -- for binary Content Creator integer NOT NULL DEFAULT 0 , Created DATETIME NULL , @@ -353,11 +365,10 @@ CREATE INDEX ObjectCustomFieldValues2 ON ObjectCustomFieldValues (CustomField,Ob CREATE TABLE CustomFields ( id INTEGER NOT NULL AUTO_INCREMENT, Name varchar(200) NULL , - Type varchar(200) CHARACTER SET ascii NULL , # Changed -- 'Single' and 'Multiple' is moved out + Type varchar(200) CHARACTER SET ascii NULL , # Changed -- 'Single' and 'Multiple' is moved out RenderType varchar(64) CHARACTER SET ascii NULL , - MaxValues integer, # New -- was 'Single'(1) and 'Multiple'(0) - Pattern TEXT NULL , # New -- Must validate against this - Repeated int2 NOT NULL DEFAULT 0 , # New -- repeated table entry + MaxValues integer, # New -- was 'Single'(1) and 'Multiple'(0) + Pattern TEXT NULL , # New -- Must validate against this BasedOn INTEGER NULL, ValuesClass varchar(64) CHARACTER SET ascii NULL , Description varchar(255) NULL , diff --git a/rt/etc/upgrade/3.1.0/content b/rt/etc/upgrade/3.1.0/content deleted file mode 100644 index 3117dafc5..000000000 --- a/rt/etc/upgrade/3.1.0/content +++ /dev/null @@ -1,2 +0,0 @@ -# nothing to do -1; diff --git a/rt/etc/upgrade/3.1.0/schema.Oracle b/rt/etc/upgrade/3.1.0/schema.Oracle index a8aae18b5..8a3c14241 100644 --- a/rt/etc/upgrade/3.1.0/schema.Oracle +++ b/rt/etc/upgrade/3.1.0/schema.Oracle @@ -1,16 +1,16 @@ CREATE SEQUENCE ATTRIBUTES_seq; CREATE TABLE Attributes ( - id NUMBER(11,0) PRIMARY KEY, - Name VARCHAR2(255) NOT NULL, - Description VARCHAR2(255), - Content CLOB, + id NUMBER(11,0) PRIMARY KEY, + Name VARCHAR2(255) NOT NULL, + Description VARCHAR2(255), + Content CLOB, ContentType VARCHAR(16), - ObjectType VARCHAR2(25) NOT NULL, - ObjectId NUMBER(11,0) DEFAULT 0 NOT NULL, - Creator NUMBER(11,0) DEFAULT 0 NOT NULL, - Created DATE, - LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL, - LastUpdated DATE + ObjectType VARCHAR2(25) NOT NULL, + ObjectId NUMBER(11,0) DEFAULT 0 NOT NULL, + Creator NUMBER(11,0) DEFAULT 0 NOT NULL, + Created DATE, + LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL, + LastUpdated DATE ); CREATE INDEX Attributes1 on Attributes(Name); diff --git a/rt/etc/upgrade/3.1.15/content b/rt/etc/upgrade/3.1.15/content index d23125a0b..9e4b25320 100644 --- a/rt/etc/upgrade/3.1.15/content +++ b/rt/etc/upgrade/3.1.15/content @@ -1,4 +1,7 @@ -@Scrips = ( +use strict; +use warnings; + +our @Scrips = ( { ScripCondition => 'On Owner Change', ScripAction => 'Notify Owner', Template => 'Transaction' }, diff --git a/rt/etc/upgrade/3.1.17/content b/rt/etc/upgrade/3.1.17/content index 1d648d82f..a6b5c542d 100644 --- a/rt/etc/upgrade/3.1.17/content +++ b/rt/etc/upgrade/3.1.17/content @@ -1,4 +1,7 @@ -@ScripActions = ( +use strict; +use warnings; + +our @ScripActions = ( { Name => 'Notify Ccs as Comment', # loc Description => 'Sends mail to the Ccs as a comment', # loc ExecModule => 'NotifyAsComment', @@ -10,7 +13,7 @@ ); -@ScripConditions = ( +our @ScripConditions = ( { Name => 'On Priority Change', # loc Description => 'Whenever a ticket\'s priority changes', # loc diff --git a/rt/etc/upgrade/3.3.0/content b/rt/etc/upgrade/3.3.0/content deleted file mode 100644 index 0afc6045c..000000000 --- a/rt/etc/upgrade/3.3.0/content +++ /dev/null @@ -1 +0,0 @@ -1; diff --git a/rt/etc/upgrade/3.3.11/content b/rt/etc/upgrade/3.3.11/content deleted file mode 100644 index 0afc6045c..000000000 --- a/rt/etc/upgrade/3.3.11/content +++ /dev/null @@ -1 +0,0 @@ -1; diff --git a/rt/etc/upgrade/3.5.1/content b/rt/etc/upgrade/3.5.1/content index 02d6a0cac..59f9dfd2c 100644 --- a/rt/etc/upgrade/3.5.1/content +++ b/rt/etc/upgrade/3.5.1/content @@ -1,4 +1,7 @@ -@Attributes = ( +use strict; +use warnings; + +our @Attributes = ( { Name => 'Search - My Tickets', Description => '[_1] highest priority tickets I own', Content => @@ -19,16 +22,16 @@ Description => 'HomepageSettings', Content => { 'body' => - [ { type => 'system', name => 'My Tickets' }, - { type => 'system', name => 'Unowned Tickets' }, - { type => 'component', name => 'QuickCreate'}, - ], + [ { type => 'system', name => 'My Tickets' }, + { type => 'system', name => 'Unowned Tickets' }, + { type => 'component', name => 'QuickCreate'}, + ], 'summary' => - [ - { type => 'component', name => 'MyReminders' }, + [ + { type => 'component', name => 'MyReminders' }, { type => 'component', name => 'Quicksearch' }, - { type => 'component', name => 'RefreshHomepage' }, - ] + { type => 'component', name => 'RefreshHomepage' }, + ] }, } ); diff --git a/rt/etc/upgrade/3.7.1/content b/rt/etc/upgrade/3.7.1/content index fdd506144..e39ef8a95 100644 --- a/rt/etc/upgrade/3.7.1/content +++ b/rt/etc/upgrade/3.7.1/content @@ -1,4 +1,7 @@ -@ScripConditions = ( +use strict; +use warnings; + +our @ScripConditions = ( { Name => 'On Close', # loc Description => 'Whenever a ticket is closed', # loc ApplicableTransTypes => 'Status,Set', diff --git a/rt/etc/upgrade/3.7.10/content b/rt/etc/upgrade/3.7.10/content index d19f9e6fa..fd4628de9 100644 --- a/rt/etc/upgrade/3.7.10/content +++ b/rt/etc/upgrade/3.7.10/content @@ -1,5 +1,8 @@ +use strict; +use warnings; -@Templates = ( + +our @Templates = ( { Queue => 0, Name => "Error: public key", # loc Description => diff --git a/rt/etc/upgrade/3.7.15/content b/rt/etc/upgrade/3.7.15/content index 9d97c356c..a3a27fdf7 100644 --- a/rt/etc/upgrade/3.7.15/content +++ b/rt/etc/upgrade/3.7.15/content @@ -1,5 +1,8 @@ +use strict; +use warnings; -@Templates = ( + +our @Templates = ( { Queue => 0, Name => "Forward", # loc Description => "Heading of a forwarded message", # loc diff --git a/rt/etc/upgrade/3.7.19/content b/rt/etc/upgrade/3.7.19/content index ff43dd053..34af55095 100644 --- a/rt/etc/upgrade/3.7.19/content +++ b/rt/etc/upgrade/3.7.19/content @@ -1,26 +1,28 @@ - -{ use strict; -add_description_to_all_scrips(); - -sub add_description_to_all_scrips { - require RT::Scrips; - my $scrips = RT::Scrips->new( RT->SystemUser ); - $scrips->Limit( FIELD => 'Description', OPERATOR => 'IS', VALUE => 'NULL' ); - $scrips->Limit( FIELD => 'Description', VALUE => '' ); - while ( my $scrip = $scrips->Next ) { - my $desc = $scrip->Description; - next if defined $desc && length $desc; - - $desc = gen_scrip_description( $scrip ); - - my ($status, $msg) = $scrip->SetDescription( $desc ); - unless ( $status ) { - print STDERR "Couldn't set description of a scrip: $msg"; - } else { - print "Added description to scrip #". $scrip->id ."\n"; +use strict; +use warnings; + +our @Final = ( + sub { + require RT::Scrips; + my $scrips = RT::Scrips->new( RT->SystemUser ); + $scrips->{'with_disabled_column'} = 0; + $scrips->Limit( FIELD => 'Description', OPERATOR => 'IS', VALUE => 'NULL' ); + $scrips->Limit( FIELD => 'Description', VALUE => '' ); + while ( my $scrip = $scrips->Next ) { + my $desc = $scrip->Description; + next if defined $desc && length $desc; + + $desc = gen_scrip_description( $scrip ); + + my ($status, $msg) = $scrip->SetDescription( $desc ); + unless ( $status ) { + print STDERR "Couldn't set description of a scrip: $msg"; + } else { + print "Added description to scrip #". $scrip->id ."\n"; + } } - } -} + }, +); sub gen_scrip_description { my $scrip = shift; @@ -29,7 +31,7 @@ sub gen_scrip_description { eval{ $condition = $scrip->ConditionObj->Name || $scrip->ConditionObj->Description - || ('On Condition #'. $scrip->Condition); + || ('On Condition #'. $scrip->Condition); }; if ($@){ @@ -42,7 +44,6 @@ sub gen_scrip_description { || $scrip->ActionObj->Description || ('Run Action #'. $scrip->Action); return join ' ', $condition, $action; - } } 1; diff --git a/rt/etc/upgrade/3.7.82/content b/rt/etc/upgrade/3.7.82/content index a1c555f78..da406c4cf 100644 --- a/rt/etc/upgrade/3.7.82/content +++ b/rt/etc/upgrade/3.7.82/content @@ -1,4 +1,7 @@ -@Attributes = ( +use strict; +use warnings; + +our @Attributes = ( { Name => 'Search - Bookmarked Tickets', Description => 'Bookmarked Tickets', #loc Content => diff --git a/rt/etc/upgrade/3.7.85/content b/rt/etc/upgrade/3.7.85/content index 49ab2860f..e9ec15c10 100644 --- a/rt/etc/upgrade/3.7.85/content +++ b/rt/etc/upgrade/3.7.85/content @@ -1,9 +1,12 @@ -@Templates = ( - - { Queue => '0', - Name => 'Email Digest', # loc - Description => 'Email template for periodic notification digests', # loc - Content => q[Subject: RT Email Digest +use strict; +use warnings; + +our @Templates = ( + + { Queue => '0', + Name => 'Email Digest', # loc + Description => 'Email template for periodic notification digests', # loc + Content => q[Subject: RT Email Digest { $Argument } ], diff --git a/rt/etc/upgrade/3.7.86/content b/rt/etc/upgrade/3.7.86/content index 94912d626..029939db5 100644 --- a/rt/etc/upgrade/3.7.86/content +++ b/rt/etc/upgrade/3.7.86/content @@ -1,13 +1,16 @@ -@Final = ( +use strict; +use warnings; + +our @Final = ( sub { - $RT::Logger->debug("Adding search for bookmarked tickets to defaults"); + RT->Logger->debug("Adding search for bookmarked tickets to defaults"); my $sys = RT::System->new(RT->SystemUser); my $attrs = RT::Attributes->new( RT->SystemUser ); $attrs->LimitToObject( $sys ); my ($attr) = $attrs->Named( 'HomepageSettings' ); unless ($attr) { - $RT::Logger->error("You have no global home page settings"); + RT->Logger->error("You have no global home page settings"); return; } my $content = $attr->Content; @@ -15,9 +18,9 @@ { type => 'system', name => 'Bookmarked Tickets' }; my ($status, $msg) = $attr->SetContent( $content ); - $RT::Logger->error($msg) unless $status; + RT->Logger->error($msg) unless $status; - $RT::Logger->debug("done."); + RT->Logger->debug("done."); return 1; }, ); diff --git a/rt/etc/upgrade/3.7.87/content b/rt/etc/upgrade/3.7.87/content index 0c677c4a1..c67feb406 100644 --- a/rt/etc/upgrade/3.7.87/content +++ b/rt/etc/upgrade/3.7.87/content @@ -1,4 +1,7 @@ -@Templates = ( +use strict; +use warnings; + +our @Templates = ( { Queue => 0, Name => "Error: Missing dashboard", # loc diff --git a/rt/etc/upgrade/3.8-ical-extension.in b/rt/etc/upgrade/3.8-ical-extension.in index 89e5191e7..928888fa2 100644 --- a/rt/etc/upgrade/3.8-ical-extension.in +++ b/rt/etc/upgrade/3.8-ical-extension.in @@ -46,16 +46,16 @@ # those contributions and any derivatives thereof. # # END BPS TAGGED BLOCK }}} +use 5.10.1; use strict; use warnings; use lib "@LOCAL_LIB_PATH@"; use lib "@RT_LIB_PATH@"; +use RT -init; -use RT; -RT::LoadConfig(); -RT::Init(); +$| = 1; use RT::Attributes; my $attrs = RT::Attributes->new( RT->SystemUser ); diff --git a/rt/etc/upgrade/3.8.0/content b/rt/etc/upgrade/3.8.0/content index 4fa5ac7d8..ae3a9fc0b 100644 --- a/rt/etc/upgrade/3.8.0/content +++ b/rt/etc/upgrade/3.8.0/content @@ -1,21 +1,24 @@ -@Final = ( +use strict; +use warnings; + +our @Final = ( # by incident we've changed 'My Bookmarks' to 'Bookmarked Tickets' when # 3.7.82 upgrade script still was creating 'My Bookmarks', try to fix it sub { - $RT::Logger->debug("Going to rename 'My Bookmarks' to 'Bookmarked Tickets'"); + RT->Logger->debug("Going to rename 'My Bookmarks' to 'Bookmarked Tickets'"); my $sys = RT::System->new(RT->SystemUser); my $attrs = RT::Attributes->new( RT->SystemUser ); $attrs->LimitToObject( $sys ); my ($attr) = $attrs->Named( 'Search - My Bookmarks' ); unless ($attr) { - $RT::Logger->debug("You have no global search 'My Bookmarks'. Skipped."); + RT->Logger->debug("You have no global search 'My Bookmarks'. Skipped."); return 1; } my ($status, $msg) = $attr->SetName( 'Search - Bookmarked Tickets' ); - $RT::Logger->error($msg) and return undef unless $status; + RT->Logger->error($msg) and return undef unless $status; - $RT::Logger->debug("Renamed."); + RT->Logger->debug("Renamed."); return 1; }, ); diff --git a/rt/etc/upgrade/3.8.1/content b/rt/etc/upgrade/3.8.1/content index 1667efa78..08c64306f 100644 --- a/rt/etc/upgrade/3.8.1/content +++ b/rt/etc/upgrade/3.8.1/content @@ -1,22 +1,25 @@ -@Final = ( +use strict; +use warnings; + +our @Final = ( sub { - $RT::Logger->debug("Going to adjust 'Bookmarked Tickets'"); + RT->Logger->debug("Going to adjust 'Bookmarked Tickets'"); my $sys = RT::System->new(RT->SystemUser); my $attrs = RT::Attributes->new( RT->SystemUser ); $attrs->LimitToObject( $sys ); my ($attr) = $attrs->Named( 'Search - Bookmarked Tickets' ); unless ($attr) { - $RT::Logger->debug("You have no global search 'Bookmarked Tickets'. Skipped."); + RT->Logger->debug("You have no global search 'Bookmarked Tickets'. Skipped."); return 1; } my $props = $attr->Content; $props->{'Query'} =~ s/__Bookmarks__/id = '__Bookmarked__'/g; my ($status, $msg) = $attr->SetContent( $props ); - $RT::Logger->error($msg) and return undef unless $status; + RT->Logger->error($msg) and return undef unless $status; - $RT::Logger->debug("Fixed."); + RT->Logger->debug("Fixed."); return 1; }, ); diff --git a/rt/etc/upgrade/3.8.2/content b/rt/etc/upgrade/3.8.2/content index 0eef401b8..dc68c9273 100644 --- a/rt/etc/upgrade/3.8.2/content +++ b/rt/etc/upgrade/3.8.2/content @@ -1,6 +1,19 @@ -@Initial = ( +use strict; +use warnings; + +our @Initial = ( + sub { + # We do the delete in pure SQL because Attribute collections + # otherwise attempt to hash everything in memory. As this may + # be a large list, do it directly. + RT->DatabaseHandle->dbh->do(<<EOSQL); + DELETE FROM Attributes + WHERE Name = 'DeferredRecipients' + AND Content IS NULL; +EOSQL + }, sub { - $RT::Logger->warning( + RT->Logger->warning( "Going to add [OLD] prefix to all templates in approvals queue." ." If you have never used approvals, you can safely delete all the" ." templates with the [OLD] prefix. Leave the new Approval templates because" @@ -10,7 +23,7 @@ my $approvals_q = RT::Queue->new( RT->SystemUser ); $approvals_q->Load('___Approvals'); unless ( $approvals_q->id ) { - $RT::Logger->error("You have no approvals queue."); + RT->Logger->error("You have no approvals queue."); return 1; } @@ -19,19 +32,32 @@ while ( my $tmpl = $templates->Next ) { my ($status, $msg) = $tmpl->SetName( "[OLD] ". $tmpl->Name ); unless ( $status ) { - $RT::Logger->error("Couldn't rename template #". $tmpl->id .": $msg"); + RT->Logger->error("Couldn't rename template #". $tmpl->id .": $msg"); } } return 1; }, -); -@ACL = ( - { GroupDomain => 'SystemInternal', - GroupType => 'privileged', - Right => 'ShowApprovalsTab', }, + + sub { + my $group = RT::Group->new( RT->SystemUser ); + $group->DBIx::SearchBuilder::Record::LoadByCols( + Domain => 'SystemInternal', + Type => 'Privileged', + ); + unless ($group->id) { + RT->Logger->warn("Failed to load Privilged group"); + return; + } + my ( $return, $msg ) = $group->PrincipalObj->GrantRight( + Right => 'ShowApprovalsTab', + Object => RT->System, + ); + RT->Logger->warn("Failed to grant ShowApprovalsTab right: $msg") + unless $return; + }, ); -@Templates = ( +our @Templates = ( { Queue => '___Approvals', Name => "New Pending Approval", # loc Description => @@ -106,17 +132,17 @@ The ticket has been approved, you may now start to act on it. }, ); -@Final = ( +our @Final = ( sub { - $RT::Logger->debug("Going to adjust dashboards"); + RT->Logger->debug("Going to adjust dashboards"); my $sys = RT::System->new(RT->SystemUser); my $attrs = RT::Attributes->new( RT->SystemUser ); - $attrs->UnLimit; + $attrs->Limit( FIELD => "Name", VALUE => "Dashboard"); my @dashboards = $attrs->Named('Dashboard'); if (@dashboards == 0) { - $RT::Logger->debug("You have no dashboards. Skipped."); + RT->Logger->debug("You have no dashboards. Skipped."); return 1; } @@ -140,28 +166,28 @@ The ticket has been approved, you may now start to act on it. }; } my ($status, $msg) = $attr->SetContent( $props ); - $RT::Logger->error($msg) unless $status; + RT->Logger->error($msg) unless $status; } - $RT::Logger->debug("Fixed."); + RT->Logger->debug("Fixed."); return 1; }, sub { my $approvals_q = RT::Queue->new( RT->SystemUser ); $approvals_q->Load('___Approvals'); unless ( $approvals_q->id ) { - $RT::Logger->error("You have no approvals queue."); + RT->Logger->error("You have no approvals queue."); return 1; } require File::Temp; my ($tmp_fh, $tmp_fn) = File::Temp::tempfile( 'rt-approvals-scrips-XXXX', CLEANUP => 0 ); unless ( $tmp_fh ) { - $RT::Logger->error("Couldn't create temporary file."); + RT->Logger->error("Couldn't create temporary file."); return 0; } - $RT::Logger->warning( + RT->Logger->warning( "IMPORTANT: We're going to delete all scrips in Approvals queue" ." and save them in '$tmp_fn' file." ); @@ -169,17 +195,20 @@ The ticket has been approved, you may now start to act on it. require Data::Dumper; my $scrips = RT::Scrips->new( RT->SystemUser ); - $scrips->LimitToQueue( $approvals_q->id ); + $scrips->{'with_disabled_column'} = 0; + $scrips->Limit( FIELD => 'Queue', VALUE => $approvals_q->id ); while ( my $scrip = $scrips->Next ) { my %tmp = - map { $tmp->{ $_ } = $scrip->_Value( $_ ) } - $scrip->ReadableAttributes; + map { $_ => $scrip->_Value( $_ ) } + qw/id Description ScripCondition ScripAction + CustomIsApplicableCode CustomPrepareCode CustomCommitCode + Stage Queue Template Creator Created LastUpdatedBy LastUpdated/; print $tmp_fh Data::Dumper::Dumper( \%tmp ); - my ($status, $msg) = $scrip->Delete; + my ($status, $msg) = $scrip->DBIx::SearchBuilder::Record::Delete; unless ( $status ) { - $RT::Logger->error( "Couldn't delete scrip: $msg"); + RT->Logger->error( "Couldn't delete scrip: $msg"); } } }, diff --git a/rt/etc/upgrade/3.8.3/content b/rt/etc/upgrade/3.8.3/content index b8052acde..3147c87e2 100644 --- a/rt/etc/upgrade/3.8.3/content +++ b/rt/etc/upgrade/3.8.3/content @@ -1,4 +1,7 @@ -@ScripConditions = ( +use strict; +use warnings; + +our @ScripConditions = ( { Name => 'On Reject', # loc Description => 'Whenever a ticket is rejected', # loc ApplicableTransTypes => 'Status', @@ -8,9 +11,9 @@ }, ); -@Final = ( +our @Final = ( sub { - $RT::Logger->debug("Going to correct descriptions of notify actions in the DB"); + RT->Logger->debug("Going to correct descriptions of notify actions in the DB"); my $actions = RT::ScripActions->new( RT->SystemUser ); $actions->Limit( @@ -23,11 +26,11 @@ ); while ( my $action = $actions->Next ) { my ($status, $msg) = $action->__Set( Field => 'Name', Value => 'Notify Owner, Requestors, Ccs and AdminCcs' ); - $RT::Logger->warning( "Couldn't change action name: $msg" ) + RT->Logger->warning( "Couldn't change action name: $msg" ) unless $status; ($status, $msg) = $action->__Set( Field => 'Description', Value => 'Send mail to owner and all watchers' ); - $RT::Logger->warning( "Couldn't change action description: $msg" ) + RT->Logger->warning( "Couldn't change action description: $msg" ) unless $status; } @@ -42,24 +45,24 @@ ); while ( my $action = $actions->Next ) { my ($status, $msg) = $action->__Set( Field => 'Name', Value => 'Notify Owner, Requestors, Ccs and AdminCcs as Comment' ); - $RT::Logger->warning( "Couldn't change action name: $msg" ) + RT->Logger->warning( "Couldn't change action name: $msg" ) unless $status; ($status, $msg) = $action->__Set( Field => 'Description', Value => 'Send mail to owner and all watchers as a "comment"' ); - $RT::Logger->warning( "Couldn't change action description: $msg" ) + RT->Logger->warning( "Couldn't change action description: $msg" ) unless $status; } - $RT::Logger->debug("Corrected descriptions of notify actions in the DB."); + RT->Logger->debug("Corrected descriptions of notify actions in the DB."); return 1; }, ); - +our (@ScripActions, @Scrips); { -$RT::Logger->debug("Going to add in Extract Subject Tag actions if they were missed during a previous upgrade"); +RT->Logger->debug("Going to add in Extract Subject Tag actions if they were missed during a previous upgrade"); -$actions = RT::ScripActions->new( RT->SystemUser ); +my $actions = RT::ScripActions->new( RT->SystemUser ); $actions->Limit( FIELD => 'ExecModule', VALUE => 'ExtractSubjectTag', @@ -67,10 +70,10 @@ $actions->Limit( my $extract_action = $actions->First; if ( $extract_action && $extract_action->Id ) { - $RT::Logger->debug("You appear to already have an Extract Subject Tag action, skipping"); + RT->Logger->debug("You appear to already have an Extract Subject Tag action, skipping"); return 1; } else { - $RT::Logger->debug("Didn't find an existing Extract Subject Tag action, adding it"); + RT->Logger->debug("Didn't find an existing Extract Subject Tag action, adding it"); push @ScripActions, ( { Name => 'Extract Subject Tag', # loc Description => 'Extract tags from a Transaction\'s subject and add them to the Ticket\'s subject.', # loc @@ -78,14 +81,24 @@ if ( $extract_action && $extract_action->Id ) { }, ); - $RT::Logger->debug("Adding Extract Subject Tag Scrip"); - push @Scrips, ( - { Description => "On transaction, add any tags in the transaction's subject to the ticket's subject", - ScripCondition => 'On Transaction', - ScripAction => 'Extract Subject Tag', - Template => 'Blank' - }, - ); + RT->Logger->debug("Adding Extract Subject Tag Scrip"); + push @Final, sub { + my $action = RT::ScripAction->new( RT->SystemUser ); + $action->Load( 'Extract Subject Tag' ); + my $condition = RT::ScripCondition->new( RT->SystemUser ); + $condition->Load( 'On Transaction' ); + my $template = RT::Template->new( RT->SystemUser ); + $template->LoadByName( Name => 'Blank', Queue => 0 ); + my $scrip = RT::Scrip->new( RT->SystemUser ); + $scrip->RT::Record::Create( + Description => "On transaction, add any tags in the transaction's subject to the ticket's subject", + ScripCondition => $condition->id, + ScripAction => $action->id, + Template => $template->id, + Stage => 'TransactionCreate', + Queue => 0, + ); + }; } } diff --git a/rt/etc/upgrade/3.8.4/content b/rt/etc/upgrade/3.8.4/content index 14ecba461..ac490d3e1 100644 --- a/rt/etc/upgrade/3.8.4/content +++ b/rt/etc/upgrade/3.8.4/content @@ -1,8 +1,10 @@ +use strict; +use warnings; -@Final = ( + +our @Final = ( sub { - $RT::Logger->debug("Going to correct arguments of NotifyGroup actions if you have any"); - use strict; + RT->Logger->debug("Going to correct arguments of NotifyGroup actions if you have any"); my $actions = RT::ScripActions->new( RT->SystemUser ); $actions->Limit( @@ -50,7 +52,7 @@ next if $new eq $argument; my ($status, $msg) = $action->__Set( Field => 'Argument', Value => $new ); - $RT::Logger->warning( "Couldn't change argument value of the action: $msg" ) + RT->Logger->warning( "Couldn't change argument value of the action: $msg" ) unless $status; } }, diff --git a/rt/etc/upgrade/3.8.6/content b/rt/etc/upgrade/3.8.6/content index a9793c6e1..3651a663c 100644 --- a/rt/etc/upgrade/3.8.6/content +++ b/rt/etc/upgrade/3.8.6/content @@ -1,4 +1,7 @@ -@Templates = ( +use strict; +use warnings; + +our @Templates = ( { Queue => 0, Name => "Forward Ticket", # loc Description => "Heading of a forwarded Ticket", # loc diff --git a/rt/etc/upgrade/3.8.8/content b/rt/etc/upgrade/3.8.8/content index cad77e948..50b331441 100644 --- a/rt/etc/upgrade/3.8.8/content +++ b/rt/etc/upgrade/3.8.8/content @@ -1,4 +1,7 @@ -@Initial = ( +use strict; +use warnings; + +our @Initial = ( sub { # make sure global CFs are not applied to local objects my $ocfs = RT::ObjectCustomFields->new( RT->SystemUser ); @@ -15,7 +18,7 @@ }, sub { # sort SortOrder - my $sth = $RT::Handle->dbh->prepare( + my $sth = RT->DatabaseHandle->dbh->prepare( "SELECT cfs.LookupType, ocfs.id" ." FROM ObjectCustomFields ocfs, CustomFields cfs" ." WHERE cfs.id = ocfs.CustomField" @@ -29,7 +32,7 @@ my $ocf = RT::ObjectCustomField->new( RT->SystemUser ); $ocf->Load( $id ); my ($status, $msg) = $ocf->SetSortOrder( $i++ ); - $RT::Logger->warning("Couldn't set SortOrder: $msg") + RT->Logger->warning("Couldn't set SortOrder: $msg") unless $status; $prev_type = $lt; } diff --git a/rt/etc/upgrade/3.8.9/content b/rt/etc/upgrade/3.8.9/content index d7d64f599..d0a251648 100644 --- a/rt/etc/upgrade/3.8.9/content +++ b/rt/etc/upgrade/3.8.9/content @@ -1,7 +1,9 @@ -@Initial = ( +use strict; +use warnings; + +our @Initial = ( sub { - use strict; - $RT::Logger->debug('Make sure local links are local'); + RT->Logger->debug('Make sure local links are local'); use RT::URI::fsck_com_rt; my $prefix = RT::URI::fsck_com_rt->LocalURIPrefix . '/ticket/'; @@ -53,7 +55,7 @@ # there is only one OwnerObj->Name normally, so no need /g if ( $content =~ -s!(?<=Your ticket has been (?:approved|rejected) by { eval { )\$Approval->OwnerObj->Name!\$Approver->Name! +s!(?<=Your ticket has been (?:approved|rejected) by \{ eval \{ )\$Approval->OwnerObj->Name!\$Approver->Name! ) { $template->SetType('Perl'); diff --git a/rt/etc/upgrade/3.9.1/content b/rt/etc/upgrade/3.9.1/content index acdc0adb7..3e35f47cf 100644 --- a/rt/etc/upgrade/3.9.1/content +++ b/rt/etc/upgrade/3.9.1/content @@ -1,7 +1,9 @@ -@Initial = ( +use strict; +use warnings; + +our @Initial = ( sub { - use strict; - $RT::Logger->debug('Make sure templates all have known types'); + RT->Logger->debug('Make sure templates all have known types'); # We update all NULL rows, below. We want to find non-NULL # rows, which weren't created by the current codebase running @@ -26,12 +28,11 @@ ); while (my $template = $templates->Next) { my ($status, $msg) = $template->SetType('Perl'); - $RT::Logger->warning( "Couldn't change Type of Template #" . $template->Id . ": $msg" ) unless $status; + RT->Logger->warning( "Couldn't change Type of Template #" . $template->Id . ": $msg" ) unless $status; } }, sub { - use strict; - $RT::Logger->debug('Adding ExecuteCode right to principals that currently have ModifyTemplate or ModifyScrips'); + RT->Logger->debug('Adding ExecuteCode right to principals that currently have ModifyTemplate or ModifyScrips'); my $acl = RT::ACL->new(RT->SystemUser); $acl->Limit( @@ -60,7 +61,7 @@ ); if (!$ok) { - $RT::Logger->warn("Unable to grant ExecuteCode on principal " . $principal->id . ": $msg"); + RT->Logger->warn("Unable to grant ExecuteCode on principal " . $principal->id . ": $msg"); } } }, diff --git a/rt/etc/upgrade/3.9.2/content b/rt/etc/upgrade/3.9.2/content index d0dbbfd0a..1851a9e99 100644 --- a/rt/etc/upgrade/3.9.2/content +++ b/rt/etc/upgrade/3.9.2/content @@ -1,7 +1,9 @@ -@Initial = ( +use strict; +use warnings; + +our @Initial = ( sub { - use strict; - $RT::Logger->debug('Removing all delegated rights'); + RT->Logger->debug('Removing all delegated rights'); my $acl = RT::ACL->new(RT->SystemUser); $acl->Limit( CLAUSE => 'search', @@ -20,7 +22,7 @@ my ( $ok, $msg ) = $ace->Delete(); if ( !$ok ) { - $RT::Logger->warn( + RT->Logger->warn( "Unable to delete ACE " . $ace->id . ": " . $msg ); } } @@ -28,14 +30,15 @@ my $groups = RT::Groups->new(RT->SystemUser); $groups->Limit( FIELD => 'Domain', OPERATOR => '=', - VALUE => 'Personal' + VALUE => 'Personal', + CASESENSITIVE => 0, ); while ( my $group = $groups->Next ) { my $members = $group->MembersObj(); while ( my $member = $members->Next ) { my ( $ok, $msg ) = $group->DeleteMember( $member->MemberId ); if ( !$ok ) { - $RT::Logger->warn( "Unable to remove group member " + RT->Logger->warn( "Unable to remove group member " . $member->id . ": " . $msg ); } diff --git a/rt/etc/upgrade/3.9.3/schema.Oracle b/rt/etc/upgrade/3.9.3/schema.Oracle index 4ee50c446..6ca1bdf58 100644 --- a/rt/etc/upgrade/3.9.3/schema.Oracle +++ b/rt/etc/upgrade/3.9.3/schema.Oracle @@ -1,2 +1 @@ -ALTER TABLE ACL DROP COLUMN DelegatedBy; -ALTER TABLE ACL DROP COLUMN DelegatedFrom; +ALTER TABLE ACL DROP( DelegatedBy, DelegatedFrom ); diff --git a/rt/etc/upgrade/3.9.3/schema.Pg b/rt/etc/upgrade/3.9.3/schema.Pg index 4ee50c446..9b34ac78e 100644 --- a/rt/etc/upgrade/3.9.3/schema.Pg +++ b/rt/etc/upgrade/3.9.3/schema.Pg @@ -1,2 +1,3 @@ -ALTER TABLE ACL DROP COLUMN DelegatedBy; -ALTER TABLE ACL DROP COLUMN DelegatedFrom; +ALTER TABLE ACL + DROP COLUMN DelegatedBy, + DROP COLUMN DelegatedFrom; diff --git a/rt/etc/upgrade/3.9.3/schema.mysql b/rt/etc/upgrade/3.9.3/schema.mysql index 4ee50c446..9b34ac78e 100644 --- a/rt/etc/upgrade/3.9.3/schema.mysql +++ b/rt/etc/upgrade/3.9.3/schema.mysql @@ -1,2 +1,3 @@ -ALTER TABLE ACL DROP COLUMN DelegatedBy; -ALTER TABLE ACL DROP COLUMN DelegatedFrom; +ALTER TABLE ACL + DROP COLUMN DelegatedBy, + DROP COLUMN DelegatedFrom; diff --git a/rt/etc/upgrade/3.9.5/backcompat b/rt/etc/upgrade/3.9.5/backcompat index 611ab5186..ca0b289c9 100644 --- a/rt/etc/upgrade/3.9.5/backcompat +++ b/rt/etc/upgrade/3.9.5/backcompat @@ -1 +1,15 @@ -RT::ACE LastUpdated LastUpdatedBy Creator Created +my ($upgrade) = @_; + +my %removed; +my @fields = qw/LastUpdated LastUpdatedBy Creator Created/; + +RT::ACE->_BuildTableAttributes; +$RT::Logger->debug("Temporarily removing @fields from RT::ACE"); +$removed{$_} = delete $RT::Record::_TABLE_ATTR->{"RT::ACE"}{$_} + for @fields; + +$upgrade->(); + +# Put back the fields we chopped off +$RT::Record::_TABLE_ATTR->{"RT::ACE"}{$_} = $removed{$_} + for @fields; diff --git a/rt/etc/upgrade/3.9.5/schema.Oracle b/rt/etc/upgrade/3.9.5/schema.Oracle index 065776dfb..bcf5b1f08 100644 --- a/rt/etc/upgrade/3.9.5/schema.Oracle +++ b/rt/etc/upgrade/3.9.5/schema.Oracle @@ -6,15 +6,21 @@ AND CustomFieldValues.id = Attributes.ObjectId); DELETE FROM Attributes WHERE Name = 'Category' AND ObjectType = 'RT::CustomFieldValue'; -ALTER TABLE Groups ADD Creator NUMBER(11,0) DEFAULT 0 NOT NULL; -ALTER TABLE Groups ADD Created DATE; -ALTER TABLE Groups ADD LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL; -ALTER TABLE Groups ADD LastUpdated DATE; -ALTER TABLE GroupMembers ADD Creator NUMBER(11,0) DEFAULT 0 NOT NULL; -ALTER TABLE GroupMembers ADD Created DATE; -ALTER TABLE GroupMembers ADD LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL; -ALTER TABLE GroupMembers ADD LastUpdated DATE; -ALTER TABLE ACL ADD Creator NUMBER(11,0) DEFAULT 0 NOT NULL; -ALTER TABLE ACL ADD Created DATE; -ALTER TABLE ACL ADD LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL; -ALTER TABLE ACL ADD LastUpdated DATE; +ALTER TABLE Groups ADD( + Creator NUMBER(11,0) DEFAULT 0 NOT NULL, + Created DATE, + LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL, + LastUpdated DATE +); +ALTER TABLE GroupMembers ADD( + Creator NUMBER(11,0) DEFAULT 0 NOT NULL, + Created DATE, + LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL, + LastUpdated DATE +); +ALTER TABLE ACL ADD( + Creator NUMBER(11,0) DEFAULT 0 NOT NULL, + Created DATE, + LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL, + LastUpdated DATE +); diff --git a/rt/etc/upgrade/3.9.5/schema.Pg b/rt/etc/upgrade/3.9.5/schema.Pg index cea2c4410..cd9190113 100644 --- a/rt/etc/upgrade/3.9.5/schema.Pg +++ b/rt/etc/upgrade/3.9.5/schema.Pg @@ -6,15 +6,18 @@ AND CustomFieldValues.id = Attributes.ObjectId); DELETE FROM Attributes WHERE Name = 'Category' AND ObjectType = 'RT::CustomFieldValue'; -ALTER TABLE Groups ADD COLUMN Creator integer NOT NULL DEFAULT 0; -ALTER TABLE Groups ADD COLUMN Created TIMESTAMP NULL; -ALTER TABLE Groups ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0; -ALTER TABLE Groups ADD COLUMN LastUpdated TIMESTAMP NULL; -ALTER TABLE GroupMembers ADD COLUMN Creator integer NOT NULL DEFAULT 0; -ALTER TABLE GroupMembers ADD COLUMN Created TIMESTAMP NULL; -ALTER TABLE GroupMembers ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0; -ALTER TABLE GroupMembers ADD COLUMN LastUpdated TIMESTAMP NULL; -ALTER TABLE ACL ADD COLUMN Creator integer NOT NULL DEFAULT 0; -ALTER TABLE ACL ADD COLUMN Created TIMESTAMP NULL; -ALTER TABLE ACL ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0; -ALTER TABLE ACL ADD COLUMN LastUpdated TIMESTAMP NULL; +ALTER TABLE Groups + ADD COLUMN Creator integer NOT NULL DEFAULT 0, + ADD COLUMN Created TIMESTAMP NULL, + ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0, + ADD COLUMN LastUpdated TIMESTAMP NULL; +ALTER TABLE GroupMembers + ADD COLUMN Creator integer NOT NULL DEFAULT 0, + ADD COLUMN Created TIMESTAMP NULL, + ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0, + ADD COLUMN LastUpdated TIMESTAMP NULL; +ALTER TABLE ACL + ADD COLUMN Creator integer NOT NULL DEFAULT 0, + ADD COLUMN Created TIMESTAMP NULL, + ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0, + ADD COLUMN LastUpdated TIMESTAMP NULL; diff --git a/rt/etc/upgrade/3.9.5/schema.mysql b/rt/etc/upgrade/3.9.5/schema.mysql index fe5018c78..83f2f4087 100644 --- a/rt/etc/upgrade/3.9.5/schema.mysql +++ b/rt/etc/upgrade/3.9.5/schema.mysql @@ -6,15 +6,18 @@ AND CustomFieldValues.id = Attributes.ObjectId); DELETE FROM Attributes WHERE Name = 'Category' AND ObjectType = 'RT::CustomFieldValue'; -ALTER TABLE Groups ADD COLUMN Creator integer NOT NULL DEFAULT 0, +ALTER TABLE Groups + ADD COLUMN Creator integer NOT NULL DEFAULT 0, ADD COLUMN Created DATETIME NULL, ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0, ADD COLUMN LastUpdated DATETIME NULL; -ALTER TABLE GroupMembers ADD COLUMN Creator integer NOT NULL DEFAULT 0, +ALTER TABLE GroupMembers + ADD COLUMN Creator integer NOT NULL DEFAULT 0, ADD COLUMN Created DATETIME NULL, ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0, ADD COLUMN LastUpdated DATETIME NULL; -ALTER TABLE ACL ADD COLUMN Creator integer NOT NULL DEFAULT 0, +ALTER TABLE ACL + ADD COLUMN Creator integer NOT NULL DEFAULT 0, ADD COLUMN Created DATETIME NULL, ADD COLUMN LastUpdatedBy integer NOT NULL DEFAULT 0, ADD COLUMN LastUpdated DATETIME NULL; diff --git a/rt/etc/upgrade/3.9.7/content b/rt/etc/upgrade/3.9.7/content index 504ddf18f..9b48b4b51 100644 --- a/rt/etc/upgrade/3.9.7/content +++ b/rt/etc/upgrade/3.9.7/content @@ -1,24 +1,27 @@ +use strict; +use warnings; + my $move_attributes = sub { my ($table, $type, $column) = @_; my $query = "UPDATE $table SET $column = (SELECT Content FROM Attributes WHERE" ." Name = ? AND ObjectType = ? AND $table.id = Attributes.ObjectId)"; - my $res = $RT::Handle->SimpleQuery( $query, $column, $type ); + my $res = RT->DatabaseHandle->SimpleQuery( $query, $column, $type ); unless ( $res ) { - $RT::Logger->error("Failed to move $column on $type from Attributes into $table table"); + RT->Logger->error("Failed to move $column on $type from Attributes into $table table"); return; } $query = 'DELETE FROM Attributes WHERE Name = ? AND ObjectType = ?'; - $res = $RT::Handle->SimpleQuery( $query, $column, $type ); + $res = RT->DatabaseHandle->SimpleQuery( $query, $column, $type ); unless ( $res ) { - $RT::Logger->error("Failed to delete $column on $type from Attributes"); + RT->Logger->error("Failed to delete $column on $type from Attributes"); return; } return 1; }; -@Initial = ( +our @Initial = ( sub { return $move_attributes->( 'Users', 'RT::User', 'AuthToken'); }, @@ -26,7 +29,7 @@ my $move_attributes = sub { return $move_attributes->( 'CustomFields', 'RT::CustomField', 'RenderType'); }, sub { - my $cfs = RT::CustomFields->new($RT::SystemUser); + my $cfs = RT::CustomFields->new( RT->SystemUser ); $cfs->UnLimit; $cfs->FindAllRows; while ( my $cf = $cfs->Next ) { @@ -39,10 +42,10 @@ my $move_attributes = sub { next unless $attr; $cf->SetBasedOn($attr->Content); } - $query = 'DELETE FROM Attributes WHERE Name = ? AND ObjectType = ?'; - $res = $RT::Handle->SimpleQuery( $query, 'BasedOn', 'RT::CustomField' ); + my $query = 'DELETE FROM Attributes WHERE Name = ? AND ObjectType = ?'; + my $res = RT->DatabaseHandle->SimpleQuery( $query, 'BasedOn', 'RT::CustomField' ); unless ( $res ) { - $RT::Logger->error("Failed to delete BasedOn CustomFields from Attributes"); + RT->Logger->error("Failed to delete BasedOn CustomFields from Attributes"); return; } return 1; @@ -52,9 +55,9 @@ my $move_attributes = sub { or return; my $query = "UPDATE CustomFields SET ValuesClass = NULL WHERE ValuesClass = ?"; - my $res = $RT::Handle->SimpleQuery( $query, 'RT::CustomFieldValues' ); + my $res = RT->DatabaseHandle->SimpleQuery( $query, 'RT::CustomFieldValues' ); unless ( $res ) { - $RT::Logger->error("Failed to replace default with NULLs"); + RT->Logger->error("Failed to replace default with NULLs"); return; } return 1; @@ -68,13 +71,13 @@ my $move_attributes = sub { my $queue = RT::Queue->new( RT->SystemUser ); $queue->Load( $qid ); unless ( $queue->id ) { - $RT::Logger->warning("Couldn't load queue #$qid. Skipping..."); + RT->Logger->warning("Couldn't load queue #$qid. Skipping..."); next; } my ($status, $msg) = $queue->SetSubjectTag($tag); unless ( $status ) { - $RT::Logger->error("Couldn't set subject tag for queue #$qid: $msg"); + RT->Logger->error("Couldn't set subject tag for queue #$qid: $msg"); next; } } diff --git a/rt/etc/upgrade/3.9.7/schema.Oracle b/rt/etc/upgrade/3.9.7/schema.Oracle index 3c75c917d..70b4a12f9 100644 --- a/rt/etc/upgrade/3.9.7/schema.Oracle +++ b/rt/etc/upgrade/3.9.7/schema.Oracle @@ -1,6 +1,12 @@ ALTER TABLE Users ADD AuthToken VARCHAR2(16) NULL; -ALTER TABLE CustomFields ADD BasedOn NUMBER(11,0) NULL; -ALTER TABLE CustomFields ADD RenderType VARCHAR2(64) NULL; -ALTER TABLE CustomFields ADD ValuesClass VARCHAR2(64) NULL; -ALTER TABLE Queues ADD SubjectTag VARCHAR2(120) NULL; -ALTER TABLE Queues ADD Lifecycle VARCHAR2(32) NULL; + +ALTER TABLE CustomFields ADD( + BasedOn NUMBER(11,0) NULL, + RenderType VARCHAR2(64) NULL, + ValuesClass VARCHAR2(64) NULL +); + +ALTER TABLE Queues ADD( + SubjectTag VARCHAR2(120) NULL, + Lifecycle VARCHAR2(32) NULL +); diff --git a/rt/etc/upgrade/3.9.7/schema.Pg b/rt/etc/upgrade/3.9.7/schema.Pg index 1704fa673..d6fe7cca6 100644 --- a/rt/etc/upgrade/3.9.7/schema.Pg +++ b/rt/etc/upgrade/3.9.7/schema.Pg @@ -1,6 +1,10 @@ ALTER TABLE Users ADD COLUMN AuthToken VARCHAR(16) NULL; -ALTER TABLE CustomFields ADD COLUMN BasedOn INTEGER NULL; -ALTER TABLE CustomFields ADD COLUMN RenderType VARCHAR(64) NULL; -ALTER TABLE CustomFields ADD COLUMN ValuesClass VARCHAR(64) NULL; -ALTER TABLE Queues ADD COLUMN SubjectTag VARCHAR(120) NULL; -ALTER TABLE Queues ADD COLUMN Lifecycle VARCHAR(32) NULL; + +ALTER TABLE CustomFields + ADD COLUMN BasedOn INTEGER NULL, + ADD COLUMN RenderType VARCHAR(64) NULL, + ADD COLUMN ValuesClass VARCHAR(64) NULL; + +ALTER TABLE Queues + ADD COLUMN SubjectTag VARCHAR(120) NULL, + ADD COLUMN Lifecycle VARCHAR(32) NULL; diff --git a/rt/etc/upgrade/3.9.7/schema.mysql b/rt/etc/upgrade/3.9.7/schema.mysql index 4cbed6cc7..0e61d6422 100644 --- a/rt/etc/upgrade/3.9.7/schema.mysql +++ b/rt/etc/upgrade/3.9.7/schema.mysql @@ -1,6 +1,10 @@ ALTER TABLE Users ADD COLUMN AuthToken VARCHAR(16) CHARACTER SET ascii NULL; -ALTER TABLE CustomFields ADD COLUMN BasedOn INTEGER NULL, + +ALTER TABLE CustomFields + ADD COLUMN BasedOn INTEGER NULL, ADD COLUMN RenderType VARCHAR(64) NULL, ADD COLUMN ValuesClass VARCHAR(64) CHARACTER SET ascii NULL; -ALTER TABLE Queues ADD COLUMN SubjectTag VARCHAR(120) NULL, + +ALTER TABLE Queues + ADD COLUMN SubjectTag VARCHAR(120) NULL, ADD COLUMN Lifecycle VARCHAR(32) NULL; diff --git a/rt/etc/upgrade/3.9.8/content b/rt/etc/upgrade/3.9.8/content index 24242fda2..e9a1a324d 100644 --- a/rt/etc/upgrade/3.9.8/content +++ b/rt/etc/upgrade/3.9.8/content @@ -1,4 +1,7 @@ -@Initial = sub { +use strict; +use warnings; + +our @Initial = sub { my $found_fm_tables = {}; foreach my $name ( $RT::Handle->_TableNames ) { next unless $name =~ /^fm_/i; @@ -8,15 +11,15 @@ return unless %$found_fm_tables; unless ( $found_fm_tables->{fm_topics} && $found_fm_tables->{fm_objecttopics} ) { - $RT::Logger->error("You appear to be upgrading from RTFM 2.0 - We don't support upgrading this old of an RTFM yet"); + RT->Logger->error("You appear to be upgrading from RTFM 2.0 - We don't support upgrading this old of an RTFM yet"); } - $RT::Logger->error("We found RTFM tables in your database. Checking for content."); + RT->Logger->error("We found RTFM tables in your database. Checking for content."); my $dbh = $RT::Handle->dbh; my $result = $dbh->selectall_arrayref("SELECT count(*) AS articlecount FROM FM_Articles", { Slice => {} } ); if ($result->[0]{articlecount} > 0) { - $RT::Logger->error("You appear to have RTFM Articles. You can upgrade using the etc/upgrade/upgrade-articles script. Read more about it in docs/UPGRADING-4.0"); + RT->Logger->error("You appear to have RTFM Articles. You can upgrade using the /opt/rt4/etc/upgrade/upgrade-articles script. Read more about it in docs/UPGRADING-4.0"); } }; diff --git a/rt/etc/upgrade/3.9.8/schema.Pg b/rt/etc/upgrade/3.9.8/schema.Pg index d12e27a73..1f56d3b41 100644 --- a/rt/etc/upgrade/3.9.8/schema.Pg +++ b/rt/etc/upgrade/3.9.8/schema.Pg @@ -1,3 +1,4 @@ +DROP TABLE IF EXISTS Classes; CREATE TABLE Classes ( id SERIAL, Name varchar(255) NOT NULL DEFAULT '', @@ -12,6 +13,7 @@ HotList smallint NOT NULL DEFAULT 0, PRIMARY KEY (id) ); +DROP TABLE IF EXISTS Articles; CREATE TABLE Articles ( id SERIAL, Name varchar(255) NOT NULL DEFAULT '', @@ -28,6 +30,7 @@ PRIMARY KEY (id) ); +DROP TABLE IF EXISTS Topics; CREATE TABLE Topics ( id SERIAL, Parent integer NOT NULL DEFAULT 0, @@ -39,6 +42,7 @@ PRIMARY KEY (id) ); +DROP TABLE IF EXISTS ObjectTopics; CREATE TABLE ObjectTopics ( id SERIAL, Topic integer NOT NULL, @@ -48,6 +52,7 @@ PRIMARY KEY (id) ); +DROP TABLE IF EXISTS ObjectClasses; CREATE TABLE ObjectClasses ( id SERIAL, Class integer NOT NULL, diff --git a/rt/etc/upgrade/3.9.8/schema.SQLite b/rt/etc/upgrade/3.9.8/schema.SQLite index 29ed7e87a..b5af93686 100644 --- a/rt/etc/upgrade/3.9.8/schema.SQLite +++ b/rt/etc/upgrade/3.9.8/schema.SQLite @@ -1,3 +1,4 @@ +DROP TABLE IF EXISTS Classes; CREATE TABLE Classes ( id INTEGER PRIMARY KEY, Name varchar(255) NOT NULL DEFAULT '', @@ -11,6 +12,7 @@ LastUpdated TIMESTAMP NULL, HotList smallint NOT NULL DEFAULT 0 ); +DROP TABLE IF EXISTS Articles; CREATE TABLE Articles ( id INTEGER PRIMARY KEY, Name varchar(255) NOT NULL DEFAULT '', @@ -25,7 +27,7 @@ LastUpdatedBy integer NOT NULL DEFAULT 0, LastUpdated TIMESTAMP NULL ); - +DROP TABLE IF EXISTS Topics; CREATE TABLE Topics ( id INTEGER PRIMARY KEY, Parent integer NOT NULL DEFAULT 0, @@ -36,6 +38,7 @@ ObjectId integer NOT NULL ); +DROP TABLE IF EXISTS ObjectTopics; CREATE TABLE ObjectTopics ( id INTEGER PRIMARY KEY, Topic integer NOT NULL, @@ -43,6 +46,7 @@ ObjectType varchar(64) NOT NULL DEFAULT '', ObjectId integer NOT NULL ); +DROP TABLE IF EXISTS ObjectClasses; CREATE TABLE ObjectClasses ( id INTEGER PRIMARY KEY, Class integer NOT NULL, diff --git a/rt/etc/upgrade/3.9.8/schema.mysql b/rt/etc/upgrade/3.9.8/schema.mysql index e7ed84de7..4eaa3a127 100644 --- a/rt/etc/upgrade/3.9.8/schema.mysql +++ b/rt/etc/upgrade/3.9.8/schema.mysql @@ -1,3 +1,4 @@ +DROP TABLE IF EXISTS Classes; CREATE TABLE Classes ( id int(11) NOT NULL auto_increment, Name varchar(255) NOT NULL default '', @@ -12,6 +13,7 @@ CREATE TABLE Classes ( PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +DROP TABLE IF EXISTS Articles; CREATE TABLE Articles ( id int(11) NOT NULL auto_increment, Name varchar(255) NOT NULL default '', @@ -27,6 +29,7 @@ CREATE TABLE Articles ( PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +DROP TABLE IF EXISTS Topics; CREATE TABLE Topics ( id int(11) NOT NULL auto_increment, Parent int(11) NOT NULL default '0', @@ -37,6 +40,7 @@ CREATE TABLE Topics ( PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +DROP TABLE IF EXISTS ObjectTopics; CREATE TABLE ObjectTopics ( id int(11) NOT NULL auto_increment, Topic int(11) NOT NULL default '0', @@ -45,6 +49,7 @@ CREATE TABLE ObjectTopics ( PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +DROP TABLE IF EXISTS ObjectClasses; CREATE TABLE ObjectClasses ( id int(11) NOT NULL auto_increment, Class int(11) NOT NULL default '0', diff --git a/rt/etc/upgrade/4.0-customfield-checkbox-extension b/rt/etc/upgrade/4.0-customfield-checkbox-extension index 5f04cb1f0..dc8904e43 100755 --- a/rt/etc/upgrade/4.0-customfield-checkbox-extension +++ b/rt/etc/upgrade/4.0-customfield-checkbox-extension @@ -46,15 +46,16 @@ # those contributions and any derivatives thereof. # # END BPS TAGGED BLOCK }}} +use 5.10.1; use strict; use warnings; use lib "/opt/rt3/local/lib"; use lib "/opt/rt3/lib"; -use RT; -RT::LoadConfig(); -RT::Init(); +use RT -init + +$| = 1; use RT::CustomFields; my $cfs = RT::CustomFields->new( RT->SystemUser ); diff --git a/rt/etc/upgrade/4.0-customfield-checkbox-extension.in b/rt/etc/upgrade/4.0-customfield-checkbox-extension.in index 8cc0ec7be..b3d466e73 100644 --- a/rt/etc/upgrade/4.0-customfield-checkbox-extension.in +++ b/rt/etc/upgrade/4.0-customfield-checkbox-extension.in @@ -46,15 +46,16 @@ # those contributions and any derivatives thereof. # # END BPS TAGGED BLOCK }}} +use 5.10.1; use strict; use warnings; use lib "@LOCAL_LIB_PATH@"; use lib "@RT_LIB_PATH@"; -use RT; -RT::LoadConfig(); -RT::Init(); +use RT -init; + +$| = 1; use RT::CustomFields; my $cfs = RT::CustomFields->new( RT->SystemUser ); diff --git a/rt/etc/upgrade/4.0.0rc7/content b/rt/etc/upgrade/4.0.0rc7/content index d0d210b7b..4fd63e71c 100644 --- a/rt/etc/upgrade/4.0.0rc7/content +++ b/rt/etc/upgrade/4.0.0rc7/content @@ -1,19 +1,22 @@ -@Initial = ( +use strict; +use warnings; + +our @Initial = ( sub { - $RT::Logger->debug("Going to set lifecycle for approvals"); + RT->Logger->debug("Going to set lifecycle for approvals"); my $queue = RT::Queue->new( RT->SystemUser ); $queue->Load('___Approvals'); unless ( $queue->id ) { - $RT::Logger->warning("There is no ___Approvals queue in the DB"); + RT->Logger->warning("There is no ___Approvals queue in the DB"); return 1; } - return 1 if $queue->Lifecycle->Name eq 'approvals'; + return 1 if $queue->Lifecycle && $queue->Lifecycle eq 'approvals'; my ($status, $msg) = $queue->SetLifecycle('approvals'); unless ( $status ) { - $RT::Logger->error("Couldn't set lifecycle for '___Approvals' queue: $msg"); + RT->Logger->error("Couldn't set lifecycle for '___Approvals' queue: $msg"); return 0; } return 1; diff --git a/rt/etc/upgrade/4.0.1/content b/rt/etc/upgrade/4.0.1/content index 9b74ff1a8..cc3b5f14a 100644 --- a/rt/etc/upgrade/4.0.1/content +++ b/rt/etc/upgrade/4.0.1/content @@ -1,40 +1,44 @@ -@Initial = ( +use strict; +use warnings; + +our @Initial = ( sub { - use strict; - $RT::Logger->debug('Removing all delegated rights'); + RT->Logger->debug('Removing all delegated rights'); my $acl = RT::ACL->new(RT->SystemUser); - my $groupjoin = $acl->NewAlias('Groups'); - $acl->Join( ALIAS1 => 'main', - FIELD1 => 'PrincipalId', - ALIAS2 => $groupjoin, - FIELD2 => 'id' - ); + my $groupjoin = $acl->Join( + ALIAS1 => 'main', + FIELD1 => 'PrincipalId', + TABLE2 => 'Groups', + FIELD2 => 'id', + ); $acl->Limit( ALIAS => $groupjoin, FIELD => 'Domain', OPERATOR => '=', VALUE => 'Personal', + CASESENSITIVE => 0, ); while ( my $ace = $acl->Next ) { my ( $ok, $msg ) = $ace->Delete(); if ( !$ok ) { - $RT::Logger->warn( "Unable to delete ACE " . $ace->id . ": " . $msg ); + RT->Logger->warn( "Unable to delete ACE " . $ace->id . ": " . $msg ); } } my $groups = RT::Groups->new(RT->SystemUser); $groups->Limit( FIELD => 'Domain', OPERATOR => '=', - VALUE => 'Personal' + VALUE => 'Personal', + CASESENSITIVE => 0, ); while ( my $group = $groups->Next ) { my $members = $group->MembersObj(); while ( my $member = $members->Next ) { my ( $ok, $msg ) = $group->DeleteMember( $member->MemberId ); if ( !$ok ) { - $RT::Logger->warn( "Unable to remove group member " + RT->Logger->warn( "Unable to remove group member " . $member->id . ": " . $msg ); } @@ -44,8 +48,7 @@ } }, sub { - use strict; - $RT::Logger->debug('Removing all Delegate and PersonalGroup rights'); + RT->Logger->debug('Removing all Delegate and PersonalGroup rights'); my $acl = RT::ACL->new(RT->SystemUser); for my $right (qw/AdminOwnPersonalGroups AdminAllPersonalGroups DelegateRights/) { @@ -54,16 +57,15 @@ while ( my $ace = $acl->Next ) { my ( $ok, $msg ) = $ace->Delete(); - $RT::Logger->debug("Removing ACE ".$ace->id." for right ".$ace->__Value('RightName')); + RT->Logger->debug("Removing ACE ".$ace->id." for right ".$ace->__Value('RightName')); if ( !$ok ) { - $RT::Logger->warn( "Unable to delete ACE " . $ace->id . ": " . $msg ); + RT->Logger->warn( "Unable to delete ACE " . $ace->id . ": " . $msg ); } } }, sub { - use strict; - $RT::Logger->debug('Removing unimplemented RejectTicket and ModifyTicketStatus rights'); + RT->Logger->debug('Removing unimplemented RejectTicket and ModifyTicketStatus rights'); my $acl = RT::ACL->new(RT->SystemUser); for my $right (qw/RejectTicket ModifyTicketStatus/) { @@ -72,10 +74,10 @@ while ( my $ace = $acl->Next ) { my ( $ok, $msg ) = $ace->Delete(); - $RT::Logger->debug("Removing ACE ".$ace->id." for right ".$ace->__Value('RightName')); + RT->Logger->debug("Removing ACE ".$ace->id." for right ".$ace->__Value('RightName')); if ( !$ok ) { - $RT::Logger->warn( "Unable to delete ACE " . $ace->id . ": " . $msg ); + RT->Logger->warn( "Unable to delete ACE " . $ace->id . ": " . $msg ); } } }, diff --git a/rt/etc/upgrade/4.0.18/content b/rt/etc/upgrade/4.0.18/content new file mode 100644 index 000000000..64eea9af4 --- /dev/null +++ b/rt/etc/upgrade/4.0.18/content @@ -0,0 +1,14 @@ +use strict; +use warnings; + +our @Initial = ( + sub { + my $attr = RT->System->FirstAttribute('BrandedSubjectTag'); + return 1 unless $attr; + my ( $status, $msg ) = $attr->Delete; + unless ( $status ) { + RT->Logger->error("Couldn't delete System BrandedSubjectTag: $msg"); + } + return 1; + }, +); diff --git a/rt/etc/upgrade/4.0.19/content b/rt/etc/upgrade/4.0.19/content new file mode 100644 index 000000000..31e4d9fb6 --- /dev/null +++ b/rt/etc/upgrade/4.0.19/content @@ -0,0 +1,29 @@ +use strict; +use warnings; + +our @Initial = ( + sub { + use RT::CustomFields; + my $cfs = RT::CustomFields->new(RT->SystemUser); + $cfs->{'find_disabled_rows'} = 1; + $cfs->Limit( FIELD => 'LookupType', VALUE => 'RT::FM::Class-RT::FM::Article' ); + while ( my $cf = $cfs->Next ) { + my ($ret, $msg) = $cf->__Set( Field => 'LookupType', Value => 'RT::Class-RT::Article' ); + RT->Logger->warning("Update Custom Field LookupType for CF.".$cf->Id." $msg"); + } + return 1; + }, + + sub { + use RT::ObjectCustomFieldValues; + my $ocfvs = RT::ObjectCustomFieldValues->new(RT->System); + $ocfvs->{'find_expired_rows'} = 1; + $ocfvs->Limit( FIELD => 'ObjectType', VALUE => 'RT::FM::Article' ); + while ( my $ocfv = $ocfvs->Next ) { + my ($ret, $msg) = $ocfv->__Set( Field => 'ObjectType', Value => 'RT::Article' ); + RT->Logger->warning("Updated CF ".$ocfv->__Value('CustomField')." Value for Article ".$ocfv->__Value('ObjectId')); + } + return 1; + }, +); + diff --git a/rt/etc/upgrade/4.0.19/schema.mysql b/rt/etc/upgrade/4.0.19/schema.mysql new file mode 100644 index 000000000..de28cc9e7 --- /dev/null +++ b/rt/etc/upgrade/4.0.19/schema.mysql @@ -0,0 +1,5 @@ +ALTER TABLE Users MODIFY EmailAddress varchar(120) CHARACTER SET utf8; +ALTER TABLE Queues + MODIFY Lifecycle varchar(32) CHARACTER SET utf8, + MODIFY CorrespondAddress varchar(120) CHARACTER SET utf8, + MODIFY CommentAddress varchar(120) CHARACTER SET utf8; diff --git a/rt/etc/upgrade/4.0.3/content b/rt/etc/upgrade/4.0.3/content index 3e06c89d0..74870aa7b 100644 --- a/rt/etc/upgrade/4.0.3/content +++ b/rt/etc/upgrade/4.0.3/content @@ -1,4 +1,7 @@ -@ScripConditions = ( +use strict; +use warnings; + +our @ScripConditions = ( { Name => 'On Forward', # loc diff --git a/rt/etc/upgrade/4.0.4/content b/rt/etc/upgrade/4.0.4/content index fdfcb3e27..477028995 100644 --- a/rt/etc/upgrade/4.0.4/content +++ b/rt/etc/upgrade/4.0.4/content @@ -1,4 +1,7 @@ -@Initial = ( +use strict; +use warnings; + +our @Initial = ( sub { use strict; my $templates = RT::Templates->new(RT->SystemUser); @@ -9,7 +12,7 @@ ); while (my $template = $templates->Next) { my ($status, $msg) = $template->SetType('Perl'); - $RT::Logger->warning( "Couldn't change Type of Template #" . $template->Id . ": $msg" ) unless $status; + RT->Logger->warning( "Couldn't change Type of Template #" . $template->Id . ": $msg" ) unless $status; } }, ); diff --git a/rt/etc/upgrade/4.0.6/content b/rt/etc/upgrade/4.0.6/content index dc1a00951..ef01f4eaa 100644 --- a/rt/etc/upgrade/4.0.6/content +++ b/rt/etc/upgrade/4.0.6/content @@ -1,6 +1,9 @@ -@Initial = ( +use strict; +use warnings; + +our @Initial = ( sub { - my $txns = RT::Transactions->new( $RT::SystemUser ); + my $txns = RT::Transactions->new( RT->SystemUser ); $txns->Limit( FIELD => "ObjectType", VALUE => "RT::User", diff --git a/rt/etc/upgrade/4.0.9/content b/rt/etc/upgrade/4.0.9/content index f2abf623b..6f526ce56 100644 --- a/rt/etc/upgrade/4.0.9/content +++ b/rt/etc/upgrade/4.0.9/content @@ -1,6 +1,9 @@ -@Initial = ( +use strict; +use warnings; + +our @Initial = ( sub { - $RT::Logger->debug( + RT->Logger->debug( 'Going to update empty Queue Lifecycle column to "default"'); my $queues = RT::Queues->new( RT->SystemUser ); @@ -32,7 +35,8 @@ my $groups = RT::Groups->new(RT->SystemUser); $groups->Limit( FIELD => 'Domain', OPERATOR => '=', - VALUE => 'Personal' + VALUE => 'Personal', + CASESENSITIVE => 0, ); $groups->LimitToDeleted; while ( my $group = $groups->Next ) { @@ -40,7 +44,7 @@ while ( my $member = $members->Next ) { my ( $ok, $msg ) = $group->DeleteMember( $member->MemberId ); if ( !$ok ) { - $RT::Logger->warn( "Unable to remove group member " + RT->Logger->warn( "Unable to remove group member " . $member->id . ": " . $msg ); } diff --git a/rt/etc/upgrade/4.1.0/content b/rt/etc/upgrade/4.1.0/content new file mode 100644 index 000000000..2a02c6823 --- /dev/null +++ b/rt/etc/upgrade/4.1.0/content @@ -0,0 +1,43 @@ +use strict; +use warnings; + +our @Initial = ( + sub { + my $users = RT::Users->new(RT->SystemUser); + my $attributes = $users->Join( + ALIAS1 => "main", + FIELD1 => "id", + TABLE2 => "Attributes", + FIELD2 => "ObjectId", + ); + $users->Limit( + ALIAS => $attributes, + FIELD => "ObjectType", + VALUE => "RT::User", + ); + $users->Limit( + ALIAS => $attributes, + FIELD => "Name", + VALUE => RT::User::_PrefName('HomepageSettings'), + ); + + while (my $user = $users->Next) { + my $settings = $user->Preferences('HomepageSettings') + or next; + next if exists $settings->{sidebar}; + + $settings->{sidebar} = delete $settings->{summary}; + $user->SetPreferences('HomepageSettings', $settings); + } + }, + sub { + my ($default_portlets) = RT->System->Attributes->Named('HomepageSettings'); + my $settings = $default_portlets->Content; + return if exists $settings->{sidebar}; + + $settings->{sidebar} = delete $settings->{summary}; + $default_portlets->SetContent($settings); + }, +); + + diff --git a/rt/etc/upgrade/4.1.1/acl.Pg b/rt/etc/upgrade/4.1.1/acl.Pg new file mode 100644 index 000000000..9e8fc0af0 --- /dev/null +++ b/rt/etc/upgrade/4.1.1/acl.Pg @@ -0,0 +1,31 @@ + +sub acl { + my $dbh = shift; + + my @acls; + + my @tables = qw ( + objectscrips_id_seq + ObjectScrips + ); + + my $db_user = RT->Config->Get('DatabaseUser'); + + my $sequence_right + = ( $dbh->{pg_server_version} >= 80200 ) + ? "USAGE, SELECT, UPDATE" + : "SELECT, UPDATE"; + + foreach my $table (@tables) { + # Tables are upper-case, sequences are lowercase in @tables + if ( $table =~ /^[a-z]/ ) { + push @acls, "GRANT $sequence_right ON $table TO \"$db_user\";" + } + else { + push @acls, "GRANT SELECT, INSERT, UPDATE, DELETE ON $table TO \"$db_user\";" + } + } + return (@acls); +} + +1; diff --git a/rt/etc/upgrade/4.1.1/content b/rt/etc/upgrade/4.1.1/content new file mode 100644 index 000000000..f3580bdc0 --- /dev/null +++ b/rt/etc/upgrade/4.1.1/content @@ -0,0 +1,36 @@ +use strict; +use warnings; + +our @Initial = ( + sub { + require RT::ObjectScrips; + foreach my $stage ('TransactionCreate', 'TransactionBatch') { + my $applications = RT::ObjectScrips->new( RT->SystemUser ); + $applications->Limit( FIELD => 'Stage', VALUE => $stage ); + my $alias = $applications->Join( + FIELD1 => 'Scrip', + TABLE2 => 'Scrips', FIELD2 => 'id' + ); + $applications->OrderByCols( + { ALIAS => $alias, FIELD => 'Description', ORDER => 'ASC' }, + ); + my %h; my $top_so = $h{0} = 0; + while ( my $record = $applications->Next ) { + my $oid = $record->ObjectId || 0; + + my $so; + unless ( $oid ) { + %h = (); $h{0} = $so = ++$top_so; + } + else { + $so = $h{ $oid } = ($h{$oid}||$h{0}) + 1; + } + next if $record->SortOrder == $so; + + my ($status, $msg) = $record->SetSortOrder($so); + RT->Logger->error("Couldn't set sort order: $msg") + unless $status; + } + } + }, +); diff --git a/rt/etc/upgrade/4.1.1/schema.Oracle b/rt/etc/upgrade/4.1.1/schema.Oracle new file mode 100644 index 000000000..33ea73806 --- /dev/null +++ b/rt/etc/upgrade/4.1.1/schema.Oracle @@ -0,0 +1,29 @@ +CREATE SEQUENCE OBJECTSCRIPS_seq; +CREATE TABLE ObjectScrips ( + id NUMBER(11,0) + CONSTRAINT ObjectScrips_Key PRIMARY KEY, + Scrip NUMBER(11,0) NOT NULL, + Stage VARCHAR2(32) DEFAULT 'TransactionCreate' NOT NULL, + ObjectId NUMBER(11,0) NOT NULL, + SortOrder NUMBER(11,0) DEFAULT 0 NOT NULL, + Creator NUMBER(11,0) DEFAULT 0 NOT NULL, + Created DATE, + LastUpdatedBy NUMBER(11,0) DEFAULT 0 NOT NULL, + LastUpdated DATE +); +ALTER TABLE Scrips ADD Disabled NUMBER(11,0) DEFAULT 0 NOT NULL; + +INSERT INTO ObjectScrips( + id, Scrip, Stage, ObjectId, + Creator, Created, LastUpdatedBy, LastUpdated +) +(SELECT OBJECTSCRIPS_seq.nextval, id, Stage, Queue, Creator, Created, LastUpdatedBy, LastUpdated +FROM Scrips) +; + +UPDATE Scrips SET Disabled = 1 WHERE Stage = 'Disabled'; +UPDATE ObjectScrips SET Stage = 'TransactionCreate' WHERE Stage = 'Disabled'; + +CREATE UNIQUE INDEX ObjectScrips1 ON ObjectScrips (ObjectId, Scrip); + +ALTER TABLE Scrips DROP( Stage, Queue ); diff --git a/rt/etc/upgrade/4.1.1/schema.Pg b/rt/etc/upgrade/4.1.1/schema.Pg new file mode 100644 index 000000000..91ba5a688 --- /dev/null +++ b/rt/etc/upgrade/4.1.1/schema.Pg @@ -0,0 +1,36 @@ +DROP TABLE IF EXISTS ObjectScrips; +DROP SEQUENCE IF EXISTS objectscrips_id_seq; + +CREATE SEQUENCE objectscrips_id_seq; +CREATE TABLE ObjectScrips ( + id INTEGER DEFAULT nextval('objectscrips_id_seq'), + Scrip integer NOT NULL, + Stage varchar(32) NOT NULL DEFAULT 'TransactionCreate' , + ObjectId integer NOT NULL, + SortOrder integer NOT NULL DEFAULT 0 , + + Creator integer NOT NULL DEFAULT 0 , + Created TIMESTAMP NULL , + LastUpdatedBy integer NOT NULL DEFAULT 0 , + LastUpdated TIMESTAMP NULL , + PRIMARY KEY (id) + +); +ALTER TABLE Scrips ADD COLUMN Disabled int2 NOT NULL DEFAULT 0; + +INSERT INTO ObjectScrips( + Scrip, Stage, ObjectId, + Creator, Created, LastUpdatedBy, LastUpdated +) +SELECT id, Stage, Queue, Creator, Created, LastUpdatedBy, LastUpdated +FROM Scrips +; + +UPDATE Scrips SET Disabled = 1 WHERE Stage = 'Disabled'; +UPDATE ObjectScrips SET Stage = 'TransactionCreate' WHERE Stage = 'Disabled'; + +CREATE UNIQUE INDEX ObjectScrips1 ON ObjectScrips (ObjectId, Scrip); + +ALTER TABLE Scrips + DROP COLUMN Stage, + DROP COLUMN Queue; diff --git a/rt/etc/upgrade/4.1.1/schema.SQLite b/rt/etc/upgrade/4.1.1/schema.SQLite new file mode 100644 index 000000000..2a6a2c4a4 --- /dev/null +++ b/rt/etc/upgrade/4.1.1/schema.SQLite @@ -0,0 +1,31 @@ +DROP TABLE IF EXISTS ObjectScrips; +CREATE TABLE ObjectScrips ( + id INTEGER NOT NULL , + Scrip int NOT NULL , + Stage varchar(32) NOT NULL DEFAULT 'TransactionCreate' , + ObjectId integer NOT NULL, + SortOrder integer NOT NULL DEFAULT 0 , + + Creator integer NOT NULL DEFAULT 0 , + Created DATETIME NULL , + LastUpdatedBy integer NOT NULL DEFAULT 0 , + LastUpdated DATETIME NULL , + PRIMARY KEY (id) +); +ALTER TABLE Scrips ADD COLUMN Disabled int2 NOT NULL DEFAULT 0; + +INSERT INTO ObjectScrips( + Scrip, Stage, ObjectId, + Creator, Created, LastUpdatedBy, LastUpdated +) +SELECT id, Stage, Queue, Creator, Created, LastUpdatedBy, LastUpdated +FROM Scrips +; + +UPDATE Scrips SET Disabled = 1 WHERE Stage = 'Disabled'; +UPDATE ObjectScrips SET Stage = 'TransactionCreate' WHERE Stage = 'Disabled'; + +CREATE UNIQUE INDEX ObjectScrips1 ON ObjectScrips (ObjectId, Scrip); + +# TODO: ALTER TABLE Scrips DROP COLUMN Stage; +# TODO: ALTER TABLE Scrips DROP COLUMN Queue; diff --git a/rt/etc/upgrade/4.1.1/schema.mysql b/rt/etc/upgrade/4.1.1/schema.mysql new file mode 100644 index 000000000..82f3f8452 --- /dev/null +++ b/rt/etc/upgrade/4.1.1/schema.mysql @@ -0,0 +1,32 @@ +DROP TABLE IF EXISTS ObjectScrips; +CREATE TABLE ObjectScrips ( + id INTEGER NOT NULL AUTO_INCREMENT, + Scrip integer NOT NULL , + Stage varchar(32) CHARACTER SET ascii NOT NULL DEFAULT 'TransactionCreate', + ObjectId integer NOT NULL, + SortOrder integer NOT NULL DEFAULT 0 , + + Creator integer NOT NULL DEFAULT 0 , + Created DATETIME NULL , + LastUpdatedBy integer NOT NULL DEFAULT 0 , + LastUpdated DATETIME NULL , + PRIMARY KEY (id) +) ENGINE=InnoDB CHARACTER SET utf8; +ALTER TABLE Scrips ADD COLUMN Disabled int2 NOT NULL DEFAULT 0; + +INSERT INTO ObjectScrips( + Scrip, Stage, ObjectId, + Creator, Created, LastUpdatedBy, LastUpdated +) +SELECT id, Stage, Queue, Creator, Created, LastUpdatedBy, LastUpdated +FROM Scrips +; + +UPDATE Scrips SET Disabled = 1 WHERE Stage = 'Disabled'; +UPDATE ObjectScrips SET Stage = 'TransactionCreate' WHERE Stage = 'Disabled'; + +CREATE UNIQUE INDEX ObjectScrips1 ON ObjectScrips (ObjectId, Scrip); + +ALTER TABLE Scrips + DROP COLUMN Stage, + DROP COLUMN Queue; diff --git a/rt/etc/upgrade/4.1.10/schema.Oracle b/rt/etc/upgrade/4.1.10/schema.Oracle new file mode 100644 index 000000000..93f036f6c --- /dev/null +++ b/rt/etc/upgrade/4.1.10/schema.Oracle @@ -0,0 +1 @@ +-- No update is necessary, given that '' == NULL on Oracle diff --git a/rt/etc/upgrade/4.1.10/schema.Pg b/rt/etc/upgrade/4.1.10/schema.Pg new file mode 100644 index 000000000..af862b6fe --- /dev/null +++ b/rt/etc/upgrade/4.1.10/schema.Pg @@ -0,0 +1 @@ +UPDATE ObjectCustomFieldValues SET Content = NULL WHERE LargeContent IS NOT NULL AND Content = ''; diff --git a/rt/etc/upgrade/4.1.10/schema.mysql b/rt/etc/upgrade/4.1.10/schema.mysql new file mode 100644 index 000000000..af862b6fe --- /dev/null +++ b/rt/etc/upgrade/4.1.10/schema.mysql @@ -0,0 +1 @@ +UPDATE ObjectCustomFieldValues SET Content = NULL WHERE LargeContent IS NOT NULL AND Content = ''; diff --git a/rt/etc/upgrade/4.1.11/schema.Oracle b/rt/etc/upgrade/4.1.11/schema.Oracle new file mode 100644 index 000000000..6ae68bdf8 --- /dev/null +++ b/rt/etc/upgrade/4.1.11/schema.Oracle @@ -0,0 +1 @@ +ALTER TABLE CustomFields DROP COLUMN Repeated; diff --git a/rt/etc/upgrade/4.1.11/schema.Pg b/rt/etc/upgrade/4.1.11/schema.Pg new file mode 100644 index 000000000..6ae68bdf8 --- /dev/null +++ b/rt/etc/upgrade/4.1.11/schema.Pg @@ -0,0 +1 @@ +ALTER TABLE CustomFields DROP COLUMN Repeated; diff --git a/rt/etc/upgrade/4.1.11/schema.mysql b/rt/etc/upgrade/4.1.11/schema.mysql new file mode 100644 index 000000000..6ae68bdf8 --- /dev/null +++ b/rt/etc/upgrade/4.1.11/schema.mysql @@ -0,0 +1 @@ +ALTER TABLE CustomFields DROP COLUMN Repeated; diff --git a/rt/etc/upgrade/4.1.12/content b/rt/etc/upgrade/4.1.12/content new file mode 100644 index 000000000..1f0473d24 --- /dev/null +++ b/rt/etc/upgrade/4.1.12/content @@ -0,0 +1,10 @@ +use strict; +use warnings; + +our @ACL = ( { + Right => 'ShowArticlesMenu', + GroupDomain => 'SystemInternal', + GroupType => 'Privileged', +} ); + +1; diff --git a/rt/etc/upgrade/4.1.13/backcompat b/rt/etc/upgrade/4.1.13/backcompat new file mode 100644 index 000000000..0dc53d224 --- /dev/null +++ b/rt/etc/upgrade/4.1.13/backcompat @@ -0,0 +1,34 @@ +my $upgrade = shift; + +my $groups = RT::Groups->new( RT->SystemUser ); +$groups->Limit( + FIELD => 'Name', OPERATOR => '!=', VALUE => 'main.Type', QUOTEVALUE => 0 +); +$groups->Limit( + FIELD => 'Name', OPERATOR => 'IS', VALUE => 'NULL', +); +$groups->Limit( + FIELD => 'Domain', + VALUE => 'SystemInternal', + CASESENSITIVE => 0, +); +$groups->RowsPerPage(1); +if ( $groups->Next ) { + my $dbh = $RT::Handle->dbh; + my $db_type = RT->Config->Get('DatabaseType'); + if ( $db_type eq 'Oracle' || $db_type eq 'Pg' ) { + $dbh->do( + "UPDATE Groups SET Name = Type + WHERE LOWER(Domain) IN ('aclequivalence', 'systeminternal') + OR LOWER(Domain) LIKE '%-role'" + ); + } else { + $dbh->do( + "UPDATE Groups SET Name = Type + WHERE Domain IN ('ACLEquivalence', 'SystemInternal') + OR Domain LIKE '%-Role'" + ); + } +} + +$upgrade->(); diff --git a/rt/etc/upgrade/4.1.13/schema.Oracle b/rt/etc/upgrade/4.1.13/schema.Oracle new file mode 100644 index 000000000..96869c64f --- /dev/null +++ b/rt/etc/upgrade/4.1.13/schema.Oracle @@ -0,0 +1,3 @@ +UPDATE Groups SET Name = Type +WHERE LOWER(Domain) IN ('aclequivalence', 'systeminternal') OR LOWER(Domain) LIKE '%-role'; + diff --git a/rt/etc/upgrade/4.1.13/schema.Pg b/rt/etc/upgrade/4.1.13/schema.Pg new file mode 100644 index 000000000..96869c64f --- /dev/null +++ b/rt/etc/upgrade/4.1.13/schema.Pg @@ -0,0 +1,3 @@ +UPDATE Groups SET Name = Type +WHERE LOWER(Domain) IN ('aclequivalence', 'systeminternal') OR LOWER(Domain) LIKE '%-role'; + diff --git a/rt/etc/upgrade/4.1.13/schema.SQLite b/rt/etc/upgrade/4.1.13/schema.SQLite new file mode 100644 index 000000000..9ea6a9121 --- /dev/null +++ b/rt/etc/upgrade/4.1.13/schema.SQLite @@ -0,0 +1,3 @@ +UPDATE Groups SET Name = Type +WHERE Domain IN ('ACLEquivalence', 'SystemInternal') OR Domain LIKE '%-Role'; + diff --git a/rt/etc/upgrade/4.1.13/schema.mysql b/rt/etc/upgrade/4.1.13/schema.mysql new file mode 100644 index 000000000..a429007e3 --- /dev/null +++ b/rt/etc/upgrade/4.1.13/schema.mysql @@ -0,0 +1,2 @@ +UPDATE Groups SET Name = Type +WHERE Domain IN ('ACLEquivalence', 'SystemInternal') OR Domain LIKE '%-Role';
\ No newline at end of file diff --git a/rt/etc/upgrade/4.1.14/schema.Oracle b/rt/etc/upgrade/4.1.14/schema.Oracle new file mode 100644 index 000000000..f626093a0 --- /dev/null +++ b/rt/etc/upgrade/4.1.14/schema.Oracle @@ -0,0 +1 @@ +ALTER TABLE Scrips DROP( ConditionRules, ActionRules ); diff --git a/rt/etc/upgrade/4.1.14/schema.Pg b/rt/etc/upgrade/4.1.14/schema.Pg new file mode 100644 index 000000000..0b45d5178 --- /dev/null +++ b/rt/etc/upgrade/4.1.14/schema.Pg @@ -0,0 +1,3 @@ +ALTER TABLE Scrips + DROP COLUMN ConditionRules, + DROP COLUMN ActionRules; diff --git a/rt/etc/upgrade/4.1.14/schema.mysql b/rt/etc/upgrade/4.1.14/schema.mysql new file mode 100644 index 000000000..0b45d5178 --- /dev/null +++ b/rt/etc/upgrade/4.1.14/schema.mysql @@ -0,0 +1,3 @@ +ALTER TABLE Scrips + DROP COLUMN ConditionRules, + DROP COLUMN ActionRules; diff --git a/rt/etc/upgrade/4.1.15/content b/rt/etc/upgrade/4.1.15/content new file mode 100644 index 000000000..3e1f1d55a --- /dev/null +++ b/rt/etc/upgrade/4.1.15/content @@ -0,0 +1,22 @@ +use strict; +use warnings; + +our @ScripActions = ( + { Name => 'Notify Owner and AdminCcs', # loc + Description => 'Sends mail to the Owner and administrative Ccs', # loc + ExecModule => 'Notify', + Argument => 'Owner,AdminCc' }, +); + +our @Templates = ( + # Shadow the global templates of the same name to suppress duplicate + # notifications until rules is ripped out. + { Queue => "___Approvals", + Name => "Transaction in HTML", + Content => "", + }, + { Queue => "___Approvals", + Name => "Transaction", + Content => "", + }, +); diff --git a/rt/etc/upgrade/4.1.16/content b/rt/etc/upgrade/4.1.16/content new file mode 100644 index 000000000..44f212977 --- /dev/null +++ b/rt/etc/upgrade/4.1.16/content @@ -0,0 +1,16 @@ +use strict; +use warnings; + +our @Templates = ( + { Queue => '0', + Name => 'Reminder', # loc + Description => 'Default reminder template', # loc + Content => +'Subject:{$Ticket->Subject} is due {$Ticket->DueObj->AsString} + +This reminder is for ticket #{$Target = $Ticket->RefersTo->First->TargetObj;$Target->Id}. + +{RT->Config->Get(\'WebURL\')}Ticket/Display.html?id={$Target->Id} +' + }, +); diff --git a/rt/etc/upgrade/4.1.17/content b/rt/etc/upgrade/4.1.17/content new file mode 100644 index 000000000..2e6a78cda --- /dev/null +++ b/rt/etc/upgrade/4.1.17/content @@ -0,0 +1,26 @@ +use strict; +use warnings; + +our @Initial = (sub { + my $searches = RT::Attributes->new(RT->SystemUser); + $searches->Limit( FIELD => 'Name', VALUE => 'SavedSearch' ); + $searches->OrderBy( FIELD => 'id' ); + + while (my $search = $searches->Next) { + my $content = $search->Content; + next unless ref $content eq 'HASH'; + next unless ($content->{SearchType} || '') eq 'Chart'; + + # Switch from PrimaryGroupBy to GroupBy name + # Switch from "CreatedMonthly" to "Created.Monthly" + $content->{GroupBy} ||= [delete $content->{PrimaryGroupBy}]; + for (@{$content->{GroupBy}}) { + next if !defined || /\./; + s/(?<=[a-z])(?=[A-Z])/./; + } + + my ($ok, $msg) = $search->SetContent($content); + RT->Logger->error("Unable to upgrade saved chart #@{[$search->id]}: $msg") + unless $ok; + } +}); diff --git a/rt/etc/upgrade/4.1.18/content b/rt/etc/upgrade/4.1.18/content new file mode 100644 index 000000000..818351bfa --- /dev/null +++ b/rt/etc/upgrade/4.1.18/content @@ -0,0 +1,16 @@ +use strict; +use warnings; + +# Ticket-level notifications +our @ScripActions = ({ + Name => 'On SetStarted Open Ticket', + Description => 'When Started is Updated Set Ticket Status to Open', + ExecModule => 'OpenOnStarted', +}); + +our @Scrips = ({ + Description => "On transaction and SetStarted Open Ticket", + ScripCondition => 'On Transaction', + ScripAction => 'On SetStarted Open Ticket', + Template => 'Blank' +}); diff --git a/rt/etc/upgrade/4.1.19/schema.Oracle b/rt/etc/upgrade/4.1.19/schema.Oracle new file mode 100644 index 000000000..2371a5d2b --- /dev/null +++ b/rt/etc/upgrade/4.1.19/schema.Oracle @@ -0,0 +1 @@ +ALTER TABLE Templates DROP( Language, TranslationOf ); diff --git a/rt/etc/upgrade/4.1.19/schema.Pg b/rt/etc/upgrade/4.1.19/schema.Pg new file mode 100644 index 000000000..cfaa9a72f --- /dev/null +++ b/rt/etc/upgrade/4.1.19/schema.Pg @@ -0,0 +1,3 @@ +ALTER TABLE Templates + DROP COLUMN Language, + DROP COLUMN TranslationOf; diff --git a/rt/etc/upgrade/4.1.19/schema.mysql b/rt/etc/upgrade/4.1.19/schema.mysql new file mode 100644 index 000000000..cfaa9a72f --- /dev/null +++ b/rt/etc/upgrade/4.1.19/schema.mysql @@ -0,0 +1,3 @@ +ALTER TABLE Templates + DROP COLUMN Language, + DROP COLUMN TranslationOf; diff --git a/rt/etc/upgrade/4.1.20/content b/rt/etc/upgrade/4.1.20/content new file mode 100644 index 000000000..edde022c9 --- /dev/null +++ b/rt/etc/upgrade/4.1.20/content @@ -0,0 +1,56 @@ +use strict; +use warnings; + +our @ScripActions = ( + { Name => 'Send Forward', + Description => 'Send forwarded message', + ExecModule => 'SendForward', }, +); + +our @Scrips = ( + { Description => 'On Forward Transaction Send forwarded message', + ScripCondition => 'On Forward Transaction', + ScripAction => 'Send Forward', + Template => 'Forward' }, + { Description => 'On Forward Ticket Send forwarded message', + ScripCondition => 'On Forward Ticket', + ScripAction => 'Send Forward', + Template => 'Forward Ticket' }, +); + +our @Initial = ( + sub { + my $forward_template = RT::Template->new(RT->SystemUser); + $forward_template->Load('Forward'); + $forward_template->SetDescription('Forwarded message'); + + if ( $forward_template->Content =~ + m/^\n*This is (a )?forward of transaction #\{\s*\$Transaction->id\s*\} of (a )?ticket #\{\s*\$Ticket->id\s*\}\n*$/ + ) { + $forward_template->SetContent(q{ + +{ $ForwardTransaction->Content =~ /\S/ ? $ForwardTransaction->Content : "This is a forward of transaction #".$Transaction->id." of ticket #". $Ticket->id } +}); + } + else { + RT->Logger->error('Current "Forward" template is not the default version, please check docs/UPGRADING-4.2'); + } + + my $forward_ticket_template = RT::Template->new(RT->SystemUser); + $forward_ticket_template->Load('Forward Ticket'); + $forward_ticket_template->SetDescription('Forwarded ticket message'); + if ( $forward_ticket_template->Content eq q{ + +This is a forward of ticket #{ $Ticket->id } +} ) { + $forward_ticket_template->SetContent(q{ + +{ $ForwardTransaction->Content =~ /\S/ ? $ForwardTransaction->Content : "This is a forward of ticket #". $Ticket->id } +}); + + } + else { + RT->Logger->error('Current "Forward Ticket" template is not the default version, please check docs/UPGRADING-4.2'); + } + }, +); diff --git a/rt/etc/upgrade/4.1.21/content b/rt/etc/upgrade/4.1.21/content new file mode 100644 index 000000000..dbf75c7cd --- /dev/null +++ b/rt/etc/upgrade/4.1.21/content @@ -0,0 +1,64 @@ +use strict; +use warnings; + +sub dashboards_for_object { + my $object = shift; + my $user = shift; + my %dashboards; + my $privacy = RT::Dashboard->_build_privacy($object); + + while ( my $attr = $object->Attributes->Next ) { + if ( $attr->Name =~ /^Dashboard\b/ ) { + my $dashboard = RT::Dashboard->new($user); + my ( $ok, $msg ) = $dashboard->Load( $privacy, $attr->id ); + next unless $ok; + + if ( $object->isa('RT::System') ) { + push @{ $dashboards{system} }, $dashboard; + } + elsif ( $object->isa('RT::User') ) { + push @{ $dashboards{personal} }, $dashboard; + } + elsif ( $object->isa('RT::Group') ) { + push @{ $dashboards{group}{ $object->Name } }, $dashboard; + } + } + } + return \%dashboards; +} + +our @Final = ( + sub { + my $users = RT::Users->new( RT->SystemUser ); + $users->LimitToPrivileged(); + while ( my $user = $users->Next ) { + my @objs = RT::Dashboard->new($user)->ObjectsForLoading( IncludeSuperuserGroups => 0 ); + + my %dashboard_map; + + for my $object (@objs) { + my $dashboards = dashboards_for_object( $object, $user ); + push @{ $dashboard_map{$_} }, @{ $dashboards->{$_} || [] } for qw/personal system/; + + push @{ $dashboard_map{group}{$_} }, @{ $dashboards->{group}{$_} } + for keys %{ $dashboards->{group} || {} }; + } + + my @dashboards = ( + ( sort { $a->Id <=> $b->Id } @{ $dashboard_map{personal} || [] } ), + ( sort { $a->Id <=> $b->Id } @{ $dashboard_map{system} || [] } ), + + map { + sort { $a->Id <=> $b->Id } + @{ $dashboard_map{group}{$_} } + } + keys %{ $dashboard_map{group} || {} }, + ); + + splice @dashboards, 7 if @dashboards > 7; + @dashboards = map { $_->id } @dashboards; + my ( $ret, $msg ) = $user->SetPreferences( 'DashboardsInMenu', { dashboards => \@dashboards } ); + RT->Logger->error( $msg ) unless $ret; + } + }, +); diff --git a/rt/etc/upgrade/4.1.22/content b/rt/etc/upgrade/4.1.22/content new file mode 100644 index 000000000..c9f18ff40 --- /dev/null +++ b/rt/etc/upgrade/4.1.22/content @@ -0,0 +1,85 @@ +use strict; +use warnings; + +our @Initial = ( + sub { + my $template = RT::Template->new( RT->SystemUser ); + $template->Load("Error: bad GnuPG data"); + unless ($template->id) { + RT->Logger->error( "Couldn't find 'Error: bad GnuPG data' template to rename" ); + return; + } + + my ($ok, $msg) = $template->SetName("Error: bad encrypted data"); + RT->Logger->error( "Couldn't rename 'Error: bad GnuPG data' template: $msg") + unless $ok; + + ($ok, $msg) = $template->SetDescription("Inform user that a message he sent has invalid encryption data"); + RT->Logger->error( "Couldn't update 'Error: bad encrypted data' template description: $msg") + unless $ok; + + my $content = $template->Content; + $content =~ s/GnuPG signature/signature/g; + ($ok, $msg) = $template->SetContent( $content ); + RT->Logger->error( "Couldn't update 'Error: bad encrypted data' template content: $msg") + unless $ok; + }, + sub { + my $type = RT::User->new( $RT::SystemUser )->CustomFieldLookupType; + my $cf = RT::CustomField->new( $RT::SystemUser ); + $cf->LoadByCols( Name => 'SMIME Key', LookupType => $type ); + $cf->LoadByCols( Name => 'PublicKey', LookupType => $type ) unless $cf->id; + unless ( $cf->id ) { + $RT::Logger->debug("You don't have an 'SMIME Key' or 'PublicKey' user CF -- nothing to do."); + return; + } + + my $users = RT::Users->new( RT->SystemUser ); + $users->LimitCustomField( + CUSTOMFIELD => $cf->id, + OPERATOR => "IS NOT", + VALUE => "NULL", + ); + while (my $u = $users->Next) { + $u->SetSMIMECertificate( + $u->FirstCustomFieldValue( $cf->id ), + ); + } + + my $ocfs = $cf->AddedTo; + while (my $ocf = $ocfs->Next) { + my ($ok, $msg) = $ocf->Delete; + RT->Logger->error( "Couldn't delete OCF ".$ocf->id." while deleting ".$cf->Name." CF: $msg") + unless $ok; + } + + my ($ok, $msg) = $cf->Delete; + RT->Logger->error( "Couldn't delete ".$cf->Name." CF: $msg") + unless $ok; + }, + sub { + $RT::Logger->info("Going to delete all SMIMEKeyNotAfter attributes"); + my $attrs = RT::Attributes->new( $RT::SystemUser ); + $attrs->Limit( FIELD => 'ObjectType', VALUE => 'RT::User' ); + $attrs->Limit( FIELD => 'Name', VALUE => 'SMIMEKeyNotAfter' ); + while ( my $attr = $attrs->Next ) { + my ($status, $msg) = $attr->Delete; + unless ( $status ) { + $RT::Logger->error("Couldn't delete attribute: $msg"); + } + } + return 1; + }, +); + +our @Templates = ( + { Queue => 0, + Name => "Error: unencrypted message", # loc + Description => + "Inform user that their unencrypted mail has been rejected", # loc + Content => q{Subject: RT requires that all incoming mail be encrypted + +You received this message because RT received mail from you that was not encrypted. As such, it has been rejected. +} + }, +); diff --git a/rt/etc/upgrade/4.1.22/schema.Oracle b/rt/etc/upgrade/4.1.22/schema.Oracle new file mode 100644 index 000000000..273779b45 --- /dev/null +++ b/rt/etc/upgrade/4.1.22/schema.Oracle @@ -0,0 +1 @@ +ALTER TABLE Users ADD SMIMECertificate CLOB; diff --git a/rt/etc/upgrade/4.1.22/schema.Pg b/rt/etc/upgrade/4.1.22/schema.Pg new file mode 100644 index 000000000..7da9d2c89 --- /dev/null +++ b/rt/etc/upgrade/4.1.22/schema.Pg @@ -0,0 +1 @@ +ALTER TABLE Users ADD COLUMN SMIMECertificate TEXT NULL; diff --git a/rt/etc/upgrade/4.1.22/schema.SQLite b/rt/etc/upgrade/4.1.22/schema.SQLite new file mode 100644 index 000000000..3b7d6cedb --- /dev/null +++ b/rt/etc/upgrade/4.1.22/schema.SQLite @@ -0,0 +1 @@ +ALTER TABLE Users ADD COLUMN SMIMECertificate TEXT COLLATE NOCASE NULL; diff --git a/rt/etc/upgrade/4.1.22/schema.mysql b/rt/etc/upgrade/4.1.22/schema.mysql new file mode 100644 index 000000000..7da9d2c89 --- /dev/null +++ b/rt/etc/upgrade/4.1.22/schema.mysql @@ -0,0 +1 @@ +ALTER TABLE Users ADD COLUMN SMIMECertificate TEXT NULL; diff --git a/rt/etc/upgrade/4.1.23/indexes b/rt/etc/upgrade/4.1.23/indexes new file mode 100644 index 000000000..78db4aee6 --- /dev/null +++ b/rt/etc/upgrade/4.1.23/indexes @@ -0,0 +1,168 @@ +use strict; +use warnings; + +# groups table +{ + foreach my $name ( qw(Groups1 Groups2 Groups3) ) { + my ($status, $msg) = $RT::Handle->DropIndexIfExists( + Table => 'Groups', Name => $name, + ); + my $method = $status ? 'debug' : 'warning'; + RT->Logger->$method($msg); + } + + my ($name, $msg) = $RT::Handle->CreateIndex( + Table => 'Groups', + Columns => [qw(Domain Type Instance)], + CaseInsensitive => { domain => 1, type => 1 }, + ); + my $method = $name ? 'debug' : 'warning'; + RT->Logger->$method($msg); + + ($name, $msg) = $RT::Handle->CreateIndex( + Table => 'Groups', + Columns => [qw(Domain Name Instance)], + CaseInsensitive => { domain => 1, name => 1 }, + ); + $method = $name ? 'debug' : 'warning'; + RT->Logger->$method($msg); + + ($name, $msg) = $RT::Handle->CreateIndex( + Table => 'Groups', + Columns => [qw(Instance)], + ); + $method = $name ? 'debug' : 'warning'; + RT->Logger->$method($msg); +} + +my $dedup = sub { + my ($table, $column) = (@_); + + my $collection_class = "RT::$table"; + my $record_class = $collection_class; + $record_class =~ s/s$//; + + my $sql; + + my $cs = $RT::Handle->CaseSensitive; + if ($cs) { + $sql = "SELECT DISTINCT LOWER(t1.$column) FROM $table t1, $table t2" + ." WHERE LOWER(t1.$column) = LOWER(t2.$column)" + .' AND t1.id != t2.id'; + } else { + $sql = "SELECT DISTINCT t1.$column FROM $table t1, $table t2" + ." WHERE t1.$column = t2.$column" + .' AND t1.id != t2.id'; + } + + my $dbh = $RT::Handle->dbh; + my $sth = $dbh->prepare($sql); + $sth->execute; + + my $found = 0; + while ( my ($value) = $sth->fetchrow_array ) { + $found = 1; + + my $ids = $dbh->selectcol_arrayref( + "SELECT id FROM $table WHERE ". ($cs? "LOWER($column)" : $column) ." = LOWER(?)", + undef, + $value + ); + + # skip first + shift @$ids; + + foreach my $id ( @$ids ) { + RT->Logger->debug("Changing $column of $record_class #". $id ); + $dbh->do("UPDATE $table SET $column = ? WHERE id = ?", undef, $value . '-dup-'.$id, $id); + } + } + + if ( $found ) { + RT->Logger->warning( + "Records in $table table had non-unique values in $column column." + ." $column has been changed for such records, and now matches '%-dup-%'" + ); + } +}; + +# a few case insensitive and unique indexes +{ + my @list = ( + { Table => 'Queues', Column => 'Name' }, + { Table => 'Users', Column => 'Name' }, + ); + foreach my $e (@list) { + RT->Logger->debug("Checking index on ". $e->{'Column'} ." in ". $e->{'Table'} ); + my (@indexes) = $RT::Handle->IndexesThatBeginWith( + Table => $e->{'Table'}, Columns => [$e->{'Column'}] + ); + @indexes = grep {@{$_->{'Columns'}} == 1} @indexes; + if (grep {$_->{Unique} && ($RT::Handle->CaseSensitive? $_->{'CaseInsensitive'}{ lc $e->{'Column'} } : 1 ) } @indexes + ) { + RT->Logger->debug("Required index exists. Skipping."); + next; + } + + $dedup->( $e->{'Table'}, $e->{'Column'} ); + + for my $index ( @indexes ) { + my ($status, $msg) = $RT::Handle->DropIndex( + Table => $e->{'Table'}, Name => $index->{'Name'}, + ); + my $method = $status ? 'debug' : 'warning'; + RT->Logger->$method($msg); + } + + my ($status, $msg) = $RT::Handle->CreateIndex( + Table => $e->{'Table'}, Columns => [$e->{'Column'}], + Unique => 1, CaseInsensitive => { lc $e->{'Column'} => 1 }, + ); + my $method = $status ? 'debug' : 'warning'; + RT->Logger->$method($msg); + } +} + +# cached group members +{ + $RT::Handle->MakeSureIndexExists( + Table => 'CachedGroupMembers', + Columns => ['MemberId', 'ImmediateParentId'], + ); + $RT::Handle->MakeSureIndexExists( + Table => 'CachedGroupMembers', + Columns => ['MemberId', 'GroupId'], + Optional => ['Disabled'], + ); + $RT::Handle->DropIndexesThatArePrefix( + Table => 'CachedGroupMembers', + Columns => ['MemberId', 'GroupId', 'Disabled'], + ); + $RT::Handle->MakeSureIndexExists( + Table => 'CachedGroupMembers', + Columns => ['GroupId', 'MemberId'], + Optional => ['Disabled'], + ); + $RT::Handle->DropIndexesThatArePrefix( + Table => 'CachedGroupMembers', + Columns => ['GroupId', 'MemberId', 'Disabled'], + ); +} + +# drop indexes that start with 'id' column +foreach my $table ('Users', 'Tickets') { + my @list = $RT::Handle->IndexesThatBeginWith( + Table => $table, Columns => ['id'], + ); + @list = grep @{ $_->{'Columns'} } > 1, @list; + + foreach my $index (@list) { + my ($status, $msg) = $RT::Handle->DropIndex( + Table => $table, Name => $index->{'Name'}, + ); + my $method = $status ? 'debug' : 'warning'; + RT->Logger->$method($msg); + } +} + +1; diff --git a/rt/etc/upgrade/4.1.4/content b/rt/etc/upgrade/4.1.4/content new file mode 100644 index 000000000..b320695cb --- /dev/null +++ b/rt/etc/upgrade/4.1.4/content @@ -0,0 +1,49 @@ +use strict; +use warnings; + +our (@Final); + +push @Final, sub { + my %global = %{ RT->System->AvailableRights }; + my $handle = RT->DatabaseHandle; + + for my $role (RT::System->Roles) { + my $group = RT::Group->new( RT->SystemUser ); + my ($ok, $msg) = $group->LoadRoleGroup( + Object => RT->System, + Name => $role, + ); + + unless ($group->id) { + RT->Logger->error("Can't load role group $role: $msg"); + next; + } + + my %rights = %{ RT->System->AvailableRights( $group->PrincipalObj ) }; + + # Global rights which aren't available on the role anymore + my @remove = grep { not $rights{$_} } + keys %global; + my $placeholders = join ",", map { "?" } 1 .. scalar @remove; + + my $query = <<" SQL"; + DELETE FROM ACL + WHERE PrincipalType = ? + AND PrincipalId = ? + AND ObjectType = 'RT::System' + AND RightName IN ($placeholders) + SQL + + my $res = $handle->SimpleQuery( + $query, + $role, # Type + $group->PrincipalId, # Id + @remove, # Right names + ); + + unless ($res) { + RT->Logger->error("Failed to delete invalid rights on system role $role!"); + next; + } + } +}; diff --git a/rt/etc/upgrade/4.1.4/schema.Oracle b/rt/etc/upgrade/4.1.4/schema.Oracle new file mode 100644 index 000000000..e530ede81 --- /dev/null +++ b/rt/etc/upgrade/4.1.4/schema.Oracle @@ -0,0 +1 @@ +UPDATE Groups SET Instance = 1 WHERE Domain = 'RT::System-Role' AND Instance = 0; diff --git a/rt/etc/upgrade/4.1.4/schema.Pg b/rt/etc/upgrade/4.1.4/schema.Pg new file mode 100644 index 000000000..e530ede81 --- /dev/null +++ b/rt/etc/upgrade/4.1.4/schema.Pg @@ -0,0 +1 @@ +UPDATE Groups SET Instance = 1 WHERE Domain = 'RT::System-Role' AND Instance = 0; diff --git a/rt/etc/upgrade/4.1.4/schema.SQLite b/rt/etc/upgrade/4.1.4/schema.SQLite new file mode 100644 index 000000000..e530ede81 --- /dev/null +++ b/rt/etc/upgrade/4.1.4/schema.SQLite @@ -0,0 +1 @@ +UPDATE Groups SET Instance = 1 WHERE Domain = 'RT::System-Role' AND Instance = 0; diff --git a/rt/etc/upgrade/4.1.4/schema.mysql b/rt/etc/upgrade/4.1.4/schema.mysql new file mode 100644 index 000000000..e530ede81 --- /dev/null +++ b/rt/etc/upgrade/4.1.4/schema.mysql @@ -0,0 +1 @@ +UPDATE Groups SET Instance = 1 WHERE Domain = 'RT::System-Role' AND Instance = 0; diff --git a/rt/etc/upgrade/4.1.5/content b/rt/etc/upgrade/4.1.5/content new file mode 100644 index 000000000..0ed1dda39 --- /dev/null +++ b/rt/etc/upgrade/4.1.5/content @@ -0,0 +1,34 @@ +use strict; +use warnings; + +our @Initial = ( + # upgrade Template from id to name + sub { + require RT::Scrips; + my $scrips = RT::Scrips->new( RT->SystemUser ); + $scrips->UnLimit; + while ( my $scrip = $scrips->Next ) { + my $id = $scrip->Template; + if ( $id =~ /\D/ ) { + $RT::Logger->info('Template column for scrip #'. $scrip->id .' already contains characters'); + next; + } + + my $name; + + my $template = RT::Template->new( RT->SystemUser ); + $template->Load( $id ); + unless ( $template->id ) { + $RT::Logger->error("Scrip #". $scrip->id ." has template set to #$id, but it's not in DB, setting it 'Blank'"); + $name = 'Blank'; + } else { + $name = $template->Name; + } + + my ($status, $msg) = $scrip->_Set( Field => 'Template', Value => $name ); + unless ( $status ) { + $RT::Logger->error("Couldn't set template: $msg"); + } + } + }, +); diff --git a/rt/etc/upgrade/4.1.5/schema.Oracle b/rt/etc/upgrade/4.1.5/schema.Oracle new file mode 100644 index 000000000..648784dca --- /dev/null +++ b/rt/etc/upgrade/4.1.5/schema.Oracle @@ -0,0 +1,6 @@ +# Template column +ALTER TABLE Scrips RENAME COLUMN Template TO TemplateOld; +ALTER TABLE Scrips ADD Template VARCHAR2(200); +UPDATE Scrips SET Template = CAST(TemplateOld AS varchar2(200)); +ALTER TABLE Scrips MODIFY Template VARCHAR2(200) NOT NULL; +ALTER TABLE Scrips DROP COLUMN TemplateOld; diff --git a/rt/etc/upgrade/4.1.5/schema.Pg b/rt/etc/upgrade/4.1.5/schema.Pg new file mode 100644 index 000000000..3a12d4d88 --- /dev/null +++ b/rt/etc/upgrade/4.1.5/schema.Pg @@ -0,0 +1,2 @@ +# Template colum +ALTER TABLE Scrips ALTER COLUMN Template TYPE varchar(200); diff --git a/rt/etc/upgrade/4.1.5/schema.mysql b/rt/etc/upgrade/4.1.5/schema.mysql new file mode 100644 index 000000000..d35d73071 --- /dev/null +++ b/rt/etc/upgrade/4.1.5/schema.mysql @@ -0,0 +1,2 @@ +# Template column +ALTER TABLE Scrips CHANGE Template Template varchar(200) NOT NULL; diff --git a/rt/etc/upgrade/4.1.6/content b/rt/etc/upgrade/4.1.6/content new file mode 100644 index 000000000..d27014c94 --- /dev/null +++ b/rt/etc/upgrade/4.1.6/content @@ -0,0 +1,43 @@ +use strict; +use warnings; + +our @Initial = (sub { + my $users = RT::Users->new(RT->SystemUser); + $users->FindAllRows; + + my $attributes = $users->Join( + ALIAS1 => "main", + FIELD1 => "id", + TABLE2 => RT::Attributes->Table, + FIELD2 => "ObjectId", + ); + $users->Limit( + ALIAS => $attributes, + FIELD => "ObjectType", + VALUE => "RT::User", + ); + $users->Limit( + ALIAS => $attributes, + FIELD => "Name", + VALUE => RT::User::_PrefName( RT->System ), + ); + + # Iterate all users (including disabled), with config preferences set. + # Avoids running a query for every user in the system by only selecting + # those known to have preferences. + while (my $user = $users->Next) { + RT->Logger->debug(sprintf "User #%d has config preferences", $user->id); + + my $config = $user->Preferences( RT->System ) + or next; + next unless exists $config->{DeferTransactionLoading}; + + $config->{ShowHistory} = delete $config->{DeferTransactionLoading} + ? "click" : "delay"; + + $user->SetPreferences( RT->System, $config ); + RT->Logger->debug(sprintf "Updated config Preferences for user %s (#%d)", $user->Name, $user->id); + } +}); + +1; diff --git a/rt/etc/upgrade/4.1.7/schema.Oracle b/rt/etc/upgrade/4.1.7/schema.Oracle new file mode 100644 index 000000000..b53dceb02 --- /dev/null +++ b/rt/etc/upgrade/4.1.7/schema.Oracle @@ -0,0 +1,5 @@ +UPDATE Transactions +SET TimeTaken + = COALESCE(TO_NUMBER(REGEXP_SUBSTR(NewValue, '^-?\d+$')), 0) + - COALESCE(TO_NUMBER(OldValue),0) +WHERE ObjectType = 'RT::Ticket' AND Type = 'Set' AND Field = 'TimeWorked';
\ No newline at end of file diff --git a/rt/etc/upgrade/4.1.7/schema.Pg b/rt/etc/upgrade/4.1.7/schema.Pg new file mode 100644 index 000000000..2949e32e4 --- /dev/null +++ b/rt/etc/upgrade/4.1.7/schema.Pg @@ -0,0 +1,5 @@ +UPDATE Transactions +SET TimeTaken + = (CASE WHEN NewValue~E'^-?\\d+$' THEN NewValue::integer ELSE 0 END) + - COALESCE(OldValue::integer, 0) +WHERE ObjectType = 'RT::Ticket' AND Type = 'Set' AND Field = 'TimeWorked';
\ No newline at end of file diff --git a/rt/etc/upgrade/4.1.7/schema.SQLite b/rt/etc/upgrade/4.1.7/schema.SQLite new file mode 100644 index 000000000..8d6680d65 --- /dev/null +++ b/rt/etc/upgrade/4.1.7/schema.SQLite @@ -0,0 +1,2 @@ +UPDATE Transactions SET TimeTaken = NewValue - OldValue +WHERE ObjectType = 'RT::Ticket' AND Type = 'Set' AND Field = 'TimeWorked';
\ No newline at end of file diff --git a/rt/etc/upgrade/4.1.7/schema.mysql b/rt/etc/upgrade/4.1.7/schema.mysql new file mode 100644 index 000000000..95013f333 --- /dev/null +++ b/rt/etc/upgrade/4.1.7/schema.mysql @@ -0,0 +1,5 @@ +UPDATE Transactions +SET TimeTaken + = COALESCE(NewValue,0) + - COALESCE(OldValue,0) +WHERE ObjectType = 'RT::Ticket' AND Type = 'Set' AND Field = 'TimeWorked';
\ No newline at end of file diff --git a/rt/etc/upgrade/4.1.8/schema.Oracle b/rt/etc/upgrade/4.1.8/schema.Oracle new file mode 100644 index 000000000..07cd14834 --- /dev/null +++ b/rt/etc/upgrade/4.1.8/schema.Oracle @@ -0,0 +1,2 @@ +ALTER TABLE Tickets ADD IsMerged NUMBER(11,0) DEFAULT NULL NULL; +UPDATE Tickets SET IsMerged = 1 WHERE id != EffectiveId; diff --git a/rt/etc/upgrade/4.1.8/schema.Pg b/rt/etc/upgrade/4.1.8/schema.Pg new file mode 100644 index 000000000..a35287e05 --- /dev/null +++ b/rt/etc/upgrade/4.1.8/schema.Pg @@ -0,0 +1,2 @@ +ALTER TABLE Tickets ADD COLUMN IsMerged smallint NULL DEFAULT NULL; +UPDATE Tickets SET IsMerged = 1 WHERE id != EffectiveId; diff --git a/rt/etc/upgrade/4.1.8/schema.SQLite b/rt/etc/upgrade/4.1.8/schema.SQLite new file mode 100644 index 000000000..4e28e3b0d --- /dev/null +++ b/rt/etc/upgrade/4.1.8/schema.SQLite @@ -0,0 +1,3 @@ +ALTER TABLE Tickets ADD COLUMN IsMerged int2 NULL DEFAULT NULL; +UPDATE Tickets SET IsMerged = 1 WHERE id != EffectiveId; + diff --git a/rt/etc/upgrade/4.1.8/schema.mysql b/rt/etc/upgrade/4.1.8/schema.mysql new file mode 100644 index 000000000..8977c10a8 --- /dev/null +++ b/rt/etc/upgrade/4.1.8/schema.mysql @@ -0,0 +1,2 @@ +ALTER TABLE Tickets ADD COLUMN IsMerged int2 NULL DEFAULT NULL; +UPDATE Tickets SET IsMerged = 1 WHERE id != EffectiveId; diff --git a/rt/etc/upgrade/4.1.9/content b/rt/etc/upgrade/4.1.9/content new file mode 100644 index 000000000..3c68b6915 --- /dev/null +++ b/rt/etc/upgrade/4.1.9/content @@ -0,0 +1,190 @@ +use strict; +use warnings; + +# New HTML templates + +our @Templates = ( + { Queue => '0', + Name => 'Autoreply in HTML', # loc + Description => 'HTML Autoresponse template', # loc + Content => q[Subject: AutoReply: {$Ticket->Subject} +Content-Type: text/html + +<p>Greetings,</p> + +<p>This message has been automatically generated in response to the +creation of a trouble ticket regarding <b>{$Ticket->Subject()}</b>, +a summary of which appears below.</p> + +<p>There is no need to reply to this message right now. Your ticket has been +assigned an ID of <b>{$Ticket->SubjectTag}</b>.</p> + +<p>Please include the string <b>{$Ticket->SubjectTag}</b> +in the subject line of all future correspondence about this issue. To do so, +you may reply to this message.</p> + +<p>Thank you,<br/> +{$Ticket->QueueObj->CorrespondAddress()}</p> + +<hr/> +{$Transaction->Content(Type => 'text/html')} +], + }, + { Queue => '0', + Name => 'Transaction in HTML', # loc + Description => 'HTML transaction template', # loc + Content => 'RT-Attach-Message: yes +Content-Type: text/html + +<b>{$Transaction->CreatedAsString}: Request <a href="{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}">{$Ticket->id}</a> was acted upon by {$Transaction->CreatorObj->Name}.</b> +<br> +<table border="0"> +<tr><td align="right"><b>Transaction:</b></td><td>{$Transaction->Description}</td></tr> +<tr><td align="right"><b>Queue:</b></td><td>{$Ticket->QueueObj->Name}</td></tr> +<tr><td align="right"><b>Subject:</b></td><td>{$Transaction->Subject || $Ticket->Subject || "(No subject given)"} </td></tr> +<tr><td align="right"><b>Owner:</b></td><td>{$Ticket->OwnerObj->Name}</td></tr> +<tr><td align="right"><b>Requestors:</b></td><td>{$Ticket->RequestorAddresses}</td></tr> +<tr><td align="right"><b>Status:</b></td><td>{$Ticket->Status}</td></tr> +<tr><td align="right"><b>Ticket URL:</b></td><td><a href="{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}">{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}</a></td></tr> +</table> +<br/> +<br/> +{$Transaction->Content( Type => "text/html")} +' + }, + { Queue => '0', + Name => 'Admin Correspondence in HTML', # loc + Description => 'HTML admin correspondence template', # loc + Content => 'RT-Attach-Message: yes +Content-Type: text/html + +Ticket URL: <a href="{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}">{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}</a> +<br /> +<br /> +{$Transaction->Content(Type => "text/html");} +' + }, + { Queue => '0', + Name => 'Correspondence in HTML', # loc + Description => 'HTML correspondence template', # loc + Content => 'RT-Attach-Message: yes +Content-Type: text/html + +{$Transaction->Content( Type => "text/html")} +' + }, + { Queue => '0', + Name => 'Admin Comment in HTML', # loc + Description => 'HTML admin comment template', # loc + Content => +'Subject: [Comment] {my $s=($Transaction->Subject||$Ticket->Subject); $s =~ s/\\[Comment\\]\\s*//g; $s =~ s/^Re:\\s*//i; $s;} +RT-Attach-Message: yes +Content-Type: text/html + +<p>This is a comment about <a href="{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}">ticket {$Ticket->id}</a>. It is not sent to the Requestor(s):</p> + +{$Transaction->Content(Type => "text/html")} +' + }, + { Queue => '0', + Name => 'Status Change in HTML', # loc + Description => 'HTML Ticket status changed', # loc + Content => 'Subject: Status Changed to: {$Transaction->NewValue} +Content-Type: text/html + +<a href="{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}">{RT->Config->Get("WebURL")}Ticket/Display.html?id={$Ticket->id}</a> +<br/> +<br/> +{$Transaction->Content(Type => "text/html")} +' + }, + { Queue => '0', + Name => 'Resolved in HTML', # loc + Description => 'HTML Ticket Resolved', # loc + Content => 'Subject: Resolved: {$Ticket->Subject} +Content-Type: text/html + +<p>According to our records, your request has been resolved. If you have any further questions or concerns, please respond to this message.</p> +' + }, + { Queue => '___Approvals', + Name => "New Pending Approval in HTML", # loc + Description => "Notify Owners and AdminCcs of new items pending their approval", # loc + Content => 'Subject: New Pending Approval: {$Ticket->Subject} +Content-Type: text/html + +<p>Greetings,</p> + +<p>There is a new item pending your approval: <b>{$Ticket->Subject()}</b>, +a summary of which appears below.</p> + +<p>Please <a href="{RT->Config->Get(\'WebURL\')}Approvals/Display.html?id={$Ticket->id}">approve +or reject this ticket</a>, or visit the <a href="{RT->Config->Get(\'WebURL\')}Approvals/">approvals +overview</a> to batch-process all your pending approvals.</p> + +<hr /> +{$Transaction->Content()} +' + }, + { Queue => '___Approvals', + Name => "Approval Passed in HTML", # loc + Description => + "Notify Requestor of their ticket has been approved by some approver", # loc + Content => 'Subject: Ticket Approved: {$Ticket->Subject} +Content-Type: text/html + +<p>Greetings,</p> + +<p>Your ticket has been approved by <b>{ eval { $Approver->Name } }</b>. +Other approvals may be pending.</p> + +<p>Approver\'s notes:</p> +<blockquote>{ $Notes }</blockquote> +' + }, + { Queue => '___Approvals', + Name => "All Approvals Passed in HTML", # loc + Description => + "Notify Requestor of their ticket has been approved by all approvers", # loc + Content => 'Subject: Ticket Approved: {$Ticket->Subject} +Content-Type: text/html + +<p>Greetings,</p> + +<p>Your ticket has been approved by <b>{ eval { $Approver->Name } }</b>. +Its Owner may now start to act on it.</p> + +<p>Approver\'s notes:</p> +<blockquote>{ $Notes }</blockquote> +' + }, + { Queue => '___Approvals', + Name => "Approval Rejected in HTML", # loc + Description => + "Notify Owner of their rejected ticket", # loc + Content => 'Subject: Ticket Rejected: {$Ticket->Subject} +Content-Type: text/html + +<p>Greetings,</p> + +<p>Your ticket has been rejected by <b>{ eval { $Approver->Name } }</b>.</p> + +<p>Approver\'s notes:</p> +<blockquote>{ $Notes }</blockquote> +' + }, + { Queue => '___Approvals', + Name => "Approval Ready for Owner in HTML", # loc + Description => + "Notify Owner of their ticket has been approved and is ready to be acted on", # loc + Content => 'Subject: Ticket Approved: {$Ticket->Subject} +Content-Type: text/html + +<p>Greetings,</p> + +<p>The ticket has been approved, you may now start to act on it.</p> + +' + }, +); + diff --git a/rt/etc/upgrade/4.2.1/content b/rt/etc/upgrade/4.2.1/content new file mode 100644 index 000000000..64eea9af4 --- /dev/null +++ b/rt/etc/upgrade/4.2.1/content @@ -0,0 +1,14 @@ +use strict; +use warnings; + +our @Initial = ( + sub { + my $attr = RT->System->FirstAttribute('BrandedSubjectTag'); + return 1 unless $attr; + my ( $status, $msg ) = $attr->Delete; + unless ( $status ) { + RT->Logger->error("Couldn't delete System BrandedSubjectTag: $msg"); + } + return 1; + }, +); diff --git a/rt/etc/upgrade/4.2.10/content b/rt/etc/upgrade/4.2.10/content new file mode 100644 index 000000000..d9aadccd5 --- /dev/null +++ b/rt/etc/upgrade/4.2.10/content @@ -0,0 +1,19 @@ +use strict; +use warnings; + +our @Initial = ( + sub { + my $attrs = RT::Attributes->new(RT->SystemUser); + $attrs->Limit( FIELD => 'Name', VALUE => 'SavedSearch' ); + while ( my $attr = $attrs->Next ) { + my $content = $attr->Content; + if ( $content->{ChartStyle} && $content->{ChartStyle} =~ /^(?:pie|bar)$/ ) { + $content->{ChartStyle} .= '+table+sql'; + my ($ret, $msg) = $attr->SetContent($content); + unless ( $ret ) { + RT->Logger->error("Failed to update ChartStyle for SavedSearch #" . $attr->id . ": $msg"); + } + } + } + }, +); diff --git a/rt/etc/upgrade/4.2.11/content b/rt/etc/upgrade/4.2.11/content new file mode 100644 index 000000000..5e43db739 --- /dev/null +++ b/rt/etc/upgrade/4.2.11/content @@ -0,0 +1,60 @@ +use strict; +use warnings; + +our @Initial = ( + sub { + # We do the delete in pure SQL because Attribute collections + # otherwise attempt to hash everything in memory. As this may + # be a large list, do it directly. + RT->DatabaseHandle->dbh->do(<<EOSQL); + DELETE FROM Attributes + WHERE Name = 'DeferredRecipients' + AND Content IS NULL +EOSQL + }, + sub { + # Remove globally-granted role rights which couldn't also apply + # to some other object. That is, globally granting that + # AdminCcs have SuperUser makes no sense. + + # Find rights which apply globally + no warnings 'once'; + my @rights = sort map {$_->{Name}} values %{$RT::ACE::RIGHTS{'RT::System'}}; + + # Those are not allowed to be granted on global role groups + my $invalid = RT::ACL->new( RT->SystemUser ); + $invalid->LimitToObject( 'RT::System' ); + $invalid->LimitToPrincipal( Id => RT::System->RoleGroup($_)->PrincipalId ) + for RT::System->Roles; + $invalid->Limit( FIELD => 'RightName', OPERATOR => 'IN', VALUE => \@rights ); + + return unless $invalid->Count; + + # Remove them, warning in the process + $RT::Logger->warning("There are invalid global role rights; removing:"); + while (my $right = $invalid->Next) { + $RT::Logger->warning(" ".$right->RightName." granted globally to ".$right->PrincipalObj->Object->Name); + my ($ok, $msg) = $right->Delete; + $RT::Logger->error("Failed to remove right ".$right->id.": $msg") unless $ok; + } + }, + sub { + my $txns = RT::Transactions->new(RT->SystemUser); + $txns->Limit( FIELD => 'Type', VALUE => 'Forward Transaction' ); + $txns->Limit( FIELD => 'Type', VALUE => 'Forward Ticket' ); + while ( my $txn = $txns->Next ) { + my $att = $txn->Attachments->First; + next unless $att; + + # we only need to process ascii-only strings + unless ( $att->Subject =~ /[^\x00-\x7F]/ ) { + $att->__Set( Field => 'Subject', Value => Encode::decode("UTF-8", RT::I18N::DecodeMIMEWordsToUTF8($att->Subject, 'Subject')) ); + } + for my $field ( qw/Subject From To Cc Bcc/ ) { + next if !$att->GetHeader($field) || $att->GetHeader($field) =~ /[^\x00-\x7F]/; + # Subject here is not a typo, because we don't really want to parse email addresses here + $att->SetHeader( $field, Encode::decode("UTF-8", RT::I18N::DecodeMIMEWordsToUTF8($att->GetHeader($field), 'Subject')) ); + } + } + }, +); diff --git a/rt/etc/upgrade/4.2.2/content b/rt/etc/upgrade/4.2.2/content new file mode 100644 index 000000000..762289a0c --- /dev/null +++ b/rt/etc/upgrade/4.2.2/content @@ -0,0 +1,59 @@ +use strict; +use warnings; + +our @Initial = ( + sub { + use RT::CustomFields; + my $cfs = RT::CustomFields->new(RT->SystemUser); + $cfs->{'find_disabled_rows'} = 1; + $cfs->Limit( FIELD => 'LookupType', VALUE => 'RT::FM::Class-RT::FM::Article' ); + while ( my $cf = $cfs->Next ) { + my ($ret, $msg) = $cf->__Set( Field => 'LookupType', Value => 'RT::Class-RT::Article' ); + RT->Logger->warning("Update Custom Field LookupType for CF.".$cf->Id." $msg"); + } + return 1; + }, + + sub { + use RT::ObjectCustomFieldValues; + my $ocfvs = RT::ObjectCustomFieldValues->new(RT->System); + $ocfvs->{'find_expired_rows'} = 1; + $ocfvs->Limit( FIELD => 'ObjectType', VALUE => 'RT::FM::Article' ); + while ( my $ocfv = $ocfvs->Next ) { + my ($ret, $msg) = $ocfv->__Set( Field => 'ObjectType', Value => 'RT::Article' ); + RT->Logger->warning("Updated CF ".$ocfv->__Value('CustomField')." Value for Article ".$ocfv->__Value('ObjectId')); + } + return 1; + }, + + sub { + require RT::Scrips; + my $scrips = RT::Scrips->new( RT->SystemUser ); + $scrips->{'find_disabled_rows'} = 1; + $scrips->Limit( FIELD => 'Disabled', VALUE => 1 );; + while ( my $scrip = $scrips->Next ) { + my $id = $scrip->Template; + if ( $id =~ /\D/ ) { + $RT::Logger->info('Template column for scrip #'. $scrip->id .' already contains characters'); + next; + } + + my $name; + + my $template = RT::Template->new( RT->SystemUser ); + $template->Load( $id ); + unless ( $template->id ) { + $RT::Logger->error("Scrip #". $scrip->id ." has template set to #$id, but it's not in DB, setting it 'Blank'"); + $name = 'Blank'; + } else { + $name = $template->Name; + } + + my ($status, $msg) = $scrip->_Set( Field => 'Template', Value => $name ); + unless ( $status ) { + $RT::Logger->error("Couldn't set template: $msg"); + } + } + }, +); + diff --git a/rt/etc/upgrade/4.2.2/schema.mysql b/rt/etc/upgrade/4.2.2/schema.mysql new file mode 100644 index 000000000..de28cc9e7 --- /dev/null +++ b/rt/etc/upgrade/4.2.2/schema.mysql @@ -0,0 +1,5 @@ +ALTER TABLE Users MODIFY EmailAddress varchar(120) CHARACTER SET utf8; +ALTER TABLE Queues + MODIFY Lifecycle varchar(32) CHARACTER SET utf8, + MODIFY CorrespondAddress varchar(120) CHARACTER SET utf8, + MODIFY CommentAddress varchar(120) CHARACTER SET utf8; diff --git a/rt/etc/upgrade/4.2.4/content b/rt/etc/upgrade/4.2.4/content new file mode 100644 index 000000000..c56e36911 --- /dev/null +++ b/rt/etc/upgrade/4.2.4/content @@ -0,0 +1,47 @@ +use strict; +use warnings; + +our @ScripActions = ( + { Name => 'Open Inactive Tickets', # loc + Description => 'Open inactive tickets', # loc + ExecModule => 'AutoOpenInactive' }, +); + +# Ignore the above if there is already an AutoOpenInactive in the +# database -- i.e. originally a 4.2 install, or someone added one +# themselves. +our @Initial; +push @Initial, sub { + my $exist = RT::ScripAction->new( RT->SystemUser ); + $exist->LoadByCols( ExecModule => 'AutoOpenInactive' ); + @ScripActions = () if $exist->Id; +}; + +push @Initial, sub { + my $queue = RT::Queue->new( RT->SystemUser ); + my ($ok, $msg) = $queue->Load('___Approvals'); + unless ($ok) { + RT->Logger->warning("Unable to load ___Approvals: $msg"); + return; + } + unless ($queue->Disabled == 2) { + RT->Logger->warning("Going to force ___Approvals queue to be Disabled = 2"); + ($ok, $msg) = $queue->SetDisabled( 2 ); + unless ($ok) { + RT->Logger->error("Unable to set ___Approvals.Disabled = 2: $msg"); + return; + } + } + + unless ($queue->Lifecycle eq "approvals") { + RT->Logger->warning("Going to force ___Approvals queue to the approvals lifecycle"); + ($ok, $msg) = $queue->SetLifecycle( "approvals" ); + unless ($ok) { + RT->Logger->error("Unable to set ___Approvals lifecycle: $msg"); + return; + } + } + + return 1; + +}; diff --git a/rt/etc/upgrade/4.2.6/content b/rt/etc/upgrade/4.2.6/content new file mode 100644 index 000000000..e17c5ea24 --- /dev/null +++ b/rt/etc/upgrade/4.2.6/content @@ -0,0 +1,9 @@ +use strict; +use warnings; + +our @ScripActions = ( + { Name => 'Notify Owner or AdminCcs', # loc + Description => 'Sends mail to the Owner if set, otherwise administrative Ccs', # loc + ExecModule => 'NotifyOwnerOrAdminCc', + }, +); diff --git a/rt/etc/upgrade/4.2.6/schema.mysql b/rt/etc/upgrade/4.2.6/schema.mysql new file mode 100644 index 000000000..71f8f6440 --- /dev/null +++ b/rt/etc/upgrade/4.2.6/schema.mysql @@ -0,0 +1,4 @@ +ALTER TABLE Links + DEFAULT CHARACTER SET utf8, + MODIFY Base varchar(240) CHARACTER SET utf8 NULL, + MODIFY Target varchar(240) CHARACTER SET utf8 NULL; diff --git a/rt/etc/upgrade/4.2.7/content b/rt/etc/upgrade/4.2.7/content new file mode 100644 index 000000000..e828cc72c --- /dev/null +++ b/rt/etc/upgrade/4.2.7/content @@ -0,0 +1,15 @@ +use strict; +use warnings; + +our @Initial = ( + sub { + # We do the delete in pure SQL because Attribute collections + # otherwise attempt to hash everything in memory. As this may + # be a large list, do it directly. + RT->DatabaseHandle->dbh->do(<<EOSQL); + DELETE FROM Attributes + WHERE (Name = 'LinkValueTo' OR Name = 'IncludeContentForValue') + AND (LENGTH(Content) = 0 OR Content IS NULL) +EOSQL + }, +); diff --git a/rt/etc/upgrade/4.2.8/content b/rt/etc/upgrade/4.2.8/content new file mode 100644 index 000000000..64b61def7 --- /dev/null +++ b/rt/etc/upgrade/4.2.8/content @@ -0,0 +1,16 @@ +use strict; +use warnings; + +our @Initial = ( + sub { + # This upgrade step is identical to the 4.2.7 upgrade, but only + # runs on Oracle because 4.2.7 was originally released with + # flawed SQL which did not run on Oracle. + return unless RT->Config->Get('DatabaseType') eq 'Oracle'; + RT->DatabaseHandle->dbh->do(<<EOSQL); + DELETE FROM Attributes + WHERE (Name = 'LinkValueTo' OR Name = 'IncludeContentForValue') + AND (LENGTH(Content) = 0 OR Content IS NULL) +EOSQL + }, +); diff --git a/rt/etc/upgrade/generate-rtaddressregexp.in b/rt/etc/upgrade/generate-rtaddressregexp.in index a6262dffe..3cdd5a60e 100644 --- a/rt/etc/upgrade/generate-rtaddressregexp.in +++ b/rt/etc/upgrade/generate-rtaddressregexp.in @@ -46,18 +46,15 @@ # those contributions and any derivatives thereof. # # END BPS TAGGED BLOCK }}} +use 5.10.1; use strict; use warnings; use lib "@LOCAL_LIB_PATH@"; use lib "@RT_LIB_PATH@"; -use RT; -RT::LoadConfig(); -RT->Config->Set('LogToScreen' => 'debug'); -RT::Init(); - -$| = 1; +use RT::Interface::CLI qw(Init); +Init(); if (my $re = RT->Config->Get('RTAddressRegexp')) { print "No need to use this script, you already have RTAddressRegexp set to $re\n"; @@ -86,7 +83,7 @@ for my $domain (sort keys %merged) { } } if (@addresses > 1) { - push @domains, "(?:".join("|", @addresses).")\Q\@".$domain."\E"; + push @domains, "(?:".join("|", @addresses).")\Q\@$domain\E"; } else { push @domains, "$addresses[0]\Q\@$domain\E"; } diff --git a/rt/etc/upgrade/sanity-check-stylesheets.pl b/rt/etc/upgrade/sanity-check-stylesheets.in index cdc5588df..510abf7db 100644 --- a/rt/etc/upgrade/sanity-check-stylesheets.pl +++ b/rt/etc/upgrade/sanity-check-stylesheets.in @@ -1,3 +1,4 @@ +#!@PERL@ # BEGIN BPS TAGGED BLOCK {{{ # # COPYRIGHT: @@ -45,34 +46,34 @@ # those contributions and any derivatives thereof. # # END BPS TAGGED BLOCK }}} +use 5.10.1; use strict; use warnings; -use RT; -RT::LoadConfig(); -RT->Config->Set('LogToScreen' => 'debug'); -RT::Init(); +use lib "@LOCAL_LIB_PATH@"; +use lib "@RT_LIB_PATH@"; -$| = 1; +use RT::Interface::CLI qw(Init); +Init(); use RT::Users; my $users = RT::Users->new( $RT::SystemUser ); $users->UnLimit(); -my @comp_roots = RT::Interface::Web->ComponentRoots; -my %comp_root_check_cache; +my @static_roots = RT::Interface::Web->StaticRoots; +my %static_root_check_cache; sub stylesheet_exists { my $stylesheet = shift; - return $comp_root_check_cache{$stylesheet} - if exists $comp_root_check_cache{$stylesheet}; + return $static_root_check_cache{$stylesheet} + if exists $static_root_check_cache{$stylesheet}; - for my $comp_root (@comp_roots) { - return ++$comp_root_check_cache{$stylesheet} - if -d "$comp_root/NoAuth/css/$stylesheet"; + for my $static_root (@static_roots) { + return ++$static_root_check_cache{$stylesheet} + if -d "$static_root/css/$stylesheet"; } - return $comp_root_check_cache{$stylesheet} = 0; + return $static_root_check_cache{$stylesheet} = 0; } my $system_stylesheet = RT->Config->Get('WebDefaultStylesheet'); diff --git a/rt/etc/upgrade/shrink_cgm_table.pl b/rt/etc/upgrade/shrink-cgm-table.in index 85aa30747..8654271b9 100644 --- a/rt/etc/upgrade/shrink_cgm_table.pl +++ b/rt/etc/upgrade/shrink-cgm-table.in @@ -1,4 +1,4 @@ -#!/usr/bin/env perl +#!@PERL@ # BEGIN BPS TAGGED BLOCK {{{ # # COPYRIGHT: @@ -46,14 +46,15 @@ # those contributions and any derivatives thereof. # # END BPS TAGGED BLOCK }}} -use 5.8.3; +use 5.10.1; use strict; use warnings; -use RT; -RT::LoadConfig(); -RT->Config->Set('LogToScreen' => 'debug'); -RT::Init(); +use lib "@LOCAL_LIB_PATH@"; +use lib "@RT_LIB_PATH@"; + +use RT::Interface::CLI qw(Init); +Init(); use RT::CachedGroupMembers; my $cgms = RT::CachedGroupMembers->new( RT->SystemUser ); @@ -89,7 +90,6 @@ $cgms->Limit( ENTRYAGGREGATOR => 'AND', ); -$| = 1; my $total = $cgms->Count; my $i = 0; @@ -100,7 +100,7 @@ while ( my $rec = FetchNext( $cgms ) ) { $RT::Handle->BeginTransaction; my ($status) = $rec->Delete; unless ($status) { - print STDERR "Couldn't delete CGM #". $rec->id; + $RT::Logger->error( "Couldn't delete CGM #". $rec->id ); exit 1; } $RT::Handle->Commit; diff --git a/rt/etc/upgrade/shrink_transactions_table.pl b/rt/etc/upgrade/shrink-transactions-table.in index 0d0287f34..8eea6edcd 100644 --- a/rt/etc/upgrade/shrink_transactions_table.pl +++ b/rt/etc/upgrade/shrink-transactions-table.in @@ -1,4 +1,4 @@ -#!/usr/bin/env perl +#!@PERL@ # BEGIN BPS TAGGED BLOCK {{{ # # COPYRIGHT: @@ -46,14 +46,15 @@ # those contributions and any derivatives thereof. # # END BPS TAGGED BLOCK }}} -use 5.8.3; +use 5.10.1; use strict; use warnings; -use RT; -RT::LoadConfig(); -RT->Config->Set('LogToScreen' => 'debug'); -RT::Init(); +use lib "@LOCAL_LIB_PATH@"; +use lib "@RT_LIB_PATH@"; + +use RT::Interface::CLI qw(Init); +Init(); use RT::Transactions; my $txns = RT::Transactions->new( RT->SystemUser ); @@ -76,20 +77,21 @@ $txns->Limit( FIELD => 'Domain', OPERATOR => '=', VALUE => 'ACLEquivalence', + CASESENSITIVE => 0, QUOTEVALUE => 1, ENTRYAGGREGATOR => 'AND', ); $txns->Limit( ALIAS => $alias, - FIELD => 'Type', + FIELD => 'Name', OPERATOR => '=', VALUE => 'UserEquiv', QUOTEVALUE => 1, + CASESENSITIVE => 0, ENTRYAGGREGATOR => 'AND', ); -$| = 1; my $total = $txns->Count; my $i = 0; @@ -100,7 +102,7 @@ while ( my $rec = FetchNext( $txns ) ) { $RT::Handle->BeginTransaction; my ($status) = $rec->Delete; unless ($status) { - print STDERR "Couldn't delete TXN #". $rec->id; + $RT::Logger->error( "Couldn't delete TXN #". $rec->id ); exit 1; } $RT::Handle->Commit; diff --git a/rt/etc/upgrade/split-out-cf-categories.in b/rt/etc/upgrade/split-out-cf-categories.in index d7dd117a9..6faf29c9e 100644 --- a/rt/etc/upgrade/split-out-cf-categories.in +++ b/rt/etc/upgrade/split-out-cf-categories.in @@ -46,18 +46,15 @@ # those contributions and any derivatives thereof. # # END BPS TAGGED BLOCK }}} +use 5.10.1; use strict; use warnings; use lib "@LOCAL_LIB_PATH@"; use lib "@RT_LIB_PATH@"; -use RT; -RT::LoadConfig(); -RT->Config->Set('LogToScreen' => 'debug'); -RT::Init(); - -$| = 1; +use RT::Interface::CLI qw(Init); +Init(); $RT::Handle->BeginTransaction(); @@ -168,4 +165,4 @@ while (my $cf = $CFs->Next ) { } $RT::Handle->Commit; -print "No custom fields with categories found\n" unless $seen;
\ No newline at end of file +print "No custom fields with categories found\n" unless $seen; diff --git a/rt/etc/upgrade/switch-templates-to.in b/rt/etc/upgrade/switch-templates-to.in new file mode 100644 index 000000000..384d8f710 --- /dev/null +++ b/rt/etc/upgrade/switch-templates-to.in @@ -0,0 +1,145 @@ +#!@PERL@ +# BEGIN BPS TAGGED BLOCK {{{ +# +# COPYRIGHT: +# +# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC +# <sales@bestpractical.com> +# +# (Except where explicitly superseded by other copyright notices) +# +# +# LICENSE: +# +# This work is made available to you under the terms of Version 2 of +# the GNU General Public License. A copy of that license should have +# been provided with this software, but in any event can be snarfed +# from www.gnu.org. +# +# This work is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 or visit their web page on the internet at +# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +# +# +# 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 5.10.1; +use strict; +use warnings; + +use lib "@LOCAL_LIB_PATH@"; +use lib "@RT_LIB_PATH@"; + +use RT::Interface::CLI qw(Init); +Init(); + +my $to = shift || ''; +my $from; + +if ($to =~ /html|text/i) { + $to = $to =~ /html/i ? 'html' : 'text'; + $from = $to eq 'html' ? 'text' : 'html'; +} else { + print "Usage: $0 [html|text]\n"; + warn "Please specify if you'd like to switch to HTML or text templates.\n"; + exit 1; +} + + +my @templates = ( + "Autoreply", + "Transaction", + "Admin Correspondence", + "Correspondence", + "Admin Comment", + "Status Change", + "Resolved", + "New Pending Approval", + "Approval Passed", + "All Approvals Passed", + "Approval Rejected", + "Approval Ready for Owner", +); + +$RT::Handle->BeginTransaction(); + +use RT::Scrips; +my $scrips = RT::Scrips->new( RT->SystemUser ); +$scrips->UnLimit; + +for (@templates) { + $scrips->Limit( + FIELD => 'Template', + VALUE => ($to eq 'html' ? $_ : "$_ in HTML"), + ENTRYAGGREGATOR => 'OR' + ); +} + +my $switched = 0; +while ( my $s = $scrips->Next ) { + my $new = $s->TemplateObj->Name; + + if ($to eq 'html') { + $new .= ' in HTML'; + } else { + $new =~ s/ in HTML$//; + } + + print $s->id, ": ", $s->Description, "\n"; + print " ", $s->TemplateObj->Name, " -> $new\n\n"; + + my ($ok, $msg) = $s->SetTemplate($new); + + if ($ok) { + $switched++; + } else { + warn " Couldn't switch templates: $msg\n"; + } +} + +$RT::Handle->Commit; + +if ($switched) { + print <<" EOT"; +Switched $switched scrips to $to templates. You should now manually port any +customizations from the old templates to the new templates. + EOT + exit 1 if $switched != $scrips->Count; +} +elsif ($scrips->Count) { + print <<" EOT"; +@{[$scrips->Count]} scrips using $from templates were found, but none were +successfully switched to $to. See the errors above. + EOT + exit 1; +} +else { + print <<" EOT"; +No scrips were found using the $from templates, so none were switched to +$to templates. + EOT +} + diff --git a/rt/etc/upgrade/time-worked-history.in b/rt/etc/upgrade/time-worked-history.in new file mode 100644 index 000000000..fe216fa22 --- /dev/null +++ b/rt/etc/upgrade/time-worked-history.in @@ -0,0 +1,111 @@ +#!@PERL@ +# BEGIN BPS TAGGED BLOCK {{{ +# +# COPYRIGHT: +# +# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC +# <sales@bestpractical.com> +# +# (Except where explicitly superseded by other copyright notices) +# +# +# LICENSE: +# +# This work is made available to you under the terms of Version 2 of +# the GNU General Public License. A copy of that license should have +# been provided with this software, but in any event can be snarfed +# from www.gnu.org. +# +# This work is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA +# 02110-1301 or visit their web page on the internet at +# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html. +# +# +# 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 5.10.1; +use strict; +use warnings; + +use lib "@LOCAL_LIB_PATH@"; +use lib "@RT_LIB_PATH@"; + +use RT::Interface::CLI qw(Init); +Init(); + +my $dbh = RT->DatabaseHandle->dbh; +my $ids = $dbh->selectcol_arrayref( + "SELECT t1.id FROM Tickets t1, Tickets t2 WHERE t1.id = t2.EffectiveId" + ." AND t2.id != t2.EffectiveId AND t2.EffectiveId = t1.id" +); +foreach my $id ( @$ids ) { + my $t = RT::Ticket->new( RT->SystemUser ); + $t->Load( $id ); + unless ( $t->id ) { + $RT::Logger->error("Couldn't load ticket #$id"); + next; + } + + fix_time_worked_history($t); +} + +sub fix_time_worked_history { + my ($t) = (@_); + + my $history = 0; + my $candidate = undef; + my @delete = (); + my $delete_time = 0; + + my $txns = $t->Transactions; + while ( my $txn = $txns->Next ) { + if ( $txn->Type =~ /^(Create|Correspond|Comment)$/ ) { + $history += $txn->TimeTaken || 0; + } elsif ( $txn->Type eq 'Set' && $txn->Field eq 'TimeWorked' ) { + $history += $txn->NewValue - $txn->OldValue; + $candidate = $txn; + } elsif ( $candidate && ($txn->Field||'') eq 'MergedInto' ) { + if ($candidate->Creator eq $txn->Creator ) { + push @delete, $candidate; + $delete_time += $candidate->NewValue - $candidate->OldValue; + } + + $candidate = undef; + } + } + + if ( $history == $t->TimeWorked ) { + $RT::Logger->info("Ticket #". $t->id . " has TimeWorked matching history. Skipping"); + } elsif ( $history - $delete_time == $t->TimeWorked ) { + $RT::Logger->warn( "Ticket #". $t->id ." has TimeWorked mismatch. Deleting transactions" ); + foreach my $dtxn ( @delete ) { + my ($status, $msg) = $dtxn->Delete; + $RT::Logger->error("Couldn't delete transaction: $msg") unless $status; + } + } else { + $RT::Logger->error( "Ticket #". $t->id ." has TimeWorked mismatch, but we couldn't find correct transactions to delete. Skipping" ); + } +} diff --git a/rt/etc/upgrade/upgrade-articles b/rt/etc/upgrade/upgrade-articles index ec1b5f450..6ff4a2a13 100755 --- a/rt/etc/upgrade/upgrade-articles +++ b/rt/etc/upgrade/upgrade-articles @@ -46,21 +46,18 @@ # those contributions and any derivatives thereof. # # END BPS TAGGED BLOCK }}} +use 5.10.1; use strict; use warnings; use lib "/opt/rt3/local/lib"; use lib "/opt/rt3/lib"; -use RT; -RT::LoadConfig(); -RT->Config->Set('LogToScreen' => 'debug'); -RT::Init(); +use RT::Interface::CLI qw(Init); +Init(); -$| = 1; - -my $db_name = RT->Config->Get('DatabaseName'); -my $db_type = RT->Config->Get('DatabaseType'); + my $db_name = RT->Config->Get('DatabaseName'); + my $db_type = RT->Config->Get('DatabaseType'); my $dbh = $RT::Handle->dbh; diff --git a/rt/etc/upgrade/upgrade-articles.in b/rt/etc/upgrade/upgrade-articles.in index 21cba4b8a..742fd17dc 100644 --- a/rt/etc/upgrade/upgrade-articles.in +++ b/rt/etc/upgrade/upgrade-articles.in @@ -46,18 +46,15 @@ # those contributions and any derivatives thereof. # # END BPS TAGGED BLOCK }}} +use 5.10.1; use strict; use warnings; use lib "@LOCAL_LIB_PATH@"; use lib "@RT_LIB_PATH@"; -use RT; -RT::LoadConfig(); -RT->Config->Set('LogToScreen' => 'debug'); -RT::Init(); - -$| = 1; +use RT::Interface::CLI qw(Init); +Init(); my $db_name = RT->Config->Get('DatabaseName'); my $db_type = RT->Config->Get('DatabaseType'); diff --git a/rt/etc/upgrade/vulnerable-passwords.in b/rt/etc/upgrade/vulnerable-passwords.in index b00625c7e..1ccf0a180 100755 --- a/rt/etc/upgrade/vulnerable-passwords.in +++ b/rt/etc/upgrade/vulnerable-passwords.in @@ -46,15 +46,14 @@ # those contributions and any derivatives thereof. # # END BPS TAGGED BLOCK }}} +use 5.10.1; use strict; use warnings; use lib "@LOCAL_LIB_PATH@"; use lib "@RT_LIB_PATH@"; -use RT; -RT::LoadConfig; -RT::Init; +use RT -init; $| = 1; |