summaryrefslogtreecommitdiff
path: root/rt/lib
diff options
context:
space:
mode:
authorIvan Kohler <ivan@freeside.biz>2017-08-06 10:11:28 -0700
committerIvan Kohler <ivan@freeside.biz>2017-08-06 10:11:28 -0700
commitde9d037528895f7151a9aead6724ce2df95f9586 (patch)
tree3ba47a923a1d6033605ffc5586ed1af439d8c141 /rt/lib
parentb226bc6bd81f999176cdbfa53a799033ff0a0307 (diff)
rt 4.2.14 (#13852)
Diffstat (limited to 'rt/lib')
-rw-r--r--rt/lib/RT.pm11
-rwxr-xr-xrt/lib/RT/ACE.pm2
-rwxr-xr-xrt/lib/RT/ACL.pm2
-rwxr-xr-xrt/lib/RT/Action.pm2
-rw-r--r--rt/lib/RT/Action/AutoOpen.pm2
-rw-r--r--rt/lib/RT/Action/AutoOpenInactive.pm2
-rwxr-xr-xrt/lib/RT/Action/Autoreply.pm2
-rw-r--r--rt/lib/RT/Action/CreateTickets.pm2
-rw-r--r--rt/lib/RT/Action/EscalatePriority.pm2
-rw-r--r--rt/lib/RT/Action/ExtractSubjectTag.pm2
-rwxr-xr-xrt/lib/RT/Action/LinearEscalate.pm2
-rwxr-xr-xrt/lib/RT/Action/Notify.pm2
-rwxr-xr-xrt/lib/RT/Action/NotifyAsComment.pm2
-rw-r--r--rt/lib/RT/Action/NotifyGroup.pm2
-rw-r--r--rt/lib/RT/Action/NotifyGroupAsComment.pm2
-rw-r--r--rt/lib/RT/Action/NotifyOwnerOrAdminCc.pm2
-rw-r--r--rt/lib/RT/Action/OpenOnStarted.pm2
-rw-r--r--rt/lib/RT/Action/RecordComment.pm2
-rw-r--r--rt/lib/RT/Action/RecordCorrespondence.pm2
-rwxr-xr-xrt/lib/RT/Action/SendEmail.pm2
-rw-r--r--rt/lib/RT/Action/SendForward.pm2
-rw-r--r--rt/lib/RT/Action/SetPriority.pm2
-rw-r--r--rt/lib/RT/Action/SetStatus.pm2
-rw-r--r--rt/lib/RT/Action/UserDefined.pm2
-rw-r--r--rt/lib/RT/Approval.pm2
-rw-r--r--rt/lib/RT/Approval/Rule.pm2
-rw-r--r--rt/lib/RT/Approval/Rule/Created.pm2
-rw-r--r--rt/lib/RT/Approval/Rule/NewPending.pm2
-rw-r--r--rt/lib/RT/Approval/Rule/Passed.pm2
-rw-r--r--rt/lib/RT/Approval/Rule/Rejected.pm2
-rw-r--r--rt/lib/RT/Article.pm2
-rw-r--r--rt/lib/RT/Articles.pm2
-rwxr-xr-xrt/lib/RT/Attachment.pm2
-rwxr-xr-xrt/lib/RT/Attachments.pm2
-rw-r--r--rt/lib/RT/Attribute.pm272
-rw-r--r--rt/lib/RT/Attributes.pm2
-rw-r--r--rt/lib/RT/Base.pm2
-rw-r--r--rt/lib/RT/CachedGroupMember.pm2
-rw-r--r--rt/lib/RT/CachedGroupMembers.pm2
-rw-r--r--rt/lib/RT/Class.pm2
-rw-r--r--rt/lib/RT/Classes.pm2
-rwxr-xr-xrt/lib/RT/Condition.pm2
-rw-r--r--rt/lib/RT/Condition/AnyTransaction.pm2
-rw-r--r--rt/lib/RT/Condition/BeforeDue.pm2
-rw-r--r--rt/lib/RT/Condition/CloseTicket.pm2
-rw-r--r--rt/lib/RT/Condition/Overdue.pm2
-rw-r--r--rt/lib/RT/Condition/OwnerChange.pm2
-rw-r--r--rt/lib/RT/Condition/PriorityChange.pm2
-rw-r--r--rt/lib/RT/Condition/PriorityExceeds.pm2
-rw-r--r--rt/lib/RT/Condition/QueueChange.pm2
-rw-r--r--rt/lib/RT/Condition/ReopenTicket.pm2
-rw-r--r--rt/lib/RT/Condition/StatusChange.pm2
-rw-r--r--rt/lib/RT/Condition/UserDefined.pm2
-rw-r--r--rt/lib/RT/Config.pm80
-rw-r--r--rt/lib/RT/Crypt.pm8
-rw-r--r--rt/lib/RT/Crypt/GnuPG.pm2
-rw-r--r--rt/lib/RT/Crypt/GnuPG/CRLFHandle.pm2
-rw-r--r--rt/lib/RT/Crypt/Role.pm2
-rw-r--r--rt/lib/RT/Crypt/SMIME.pm10
-rwxr-xr-xrt/lib/RT/CurrentUser.pm2
-rw-r--r--rt/lib/RT/CustomField.pm2
-rw-r--r--rt/lib/RT/CustomFieldValue.pm2
-rw-r--r--rt/lib/RT/CustomFieldValues.pm2
-rw-r--r--rt/lib/RT/CustomFieldValues/External.pm2
-rw-r--r--rt/lib/RT/CustomFieldValues/Groups.pm2
-rw-r--r--rt/lib/RT/CustomFields.pm2
-rw-r--r--rt/lib/RT/Dashboard.pm2
-rw-r--r--rt/lib/RT/Dashboard/Mailer.pm2
-rw-r--r--rt/lib/RT/Dashboards.pm2
-rw-r--r--rt/lib/RT/Date.pm2
-rw-r--r--rt/lib/RT/DependencyWalker.pm2
-rw-r--r--rt/lib/RT/DependencyWalker/FindDependencies.pm2
-rw-r--r--rt/lib/RT/EmailParser.pm5
-rw-r--r--rt/lib/RT/Generated.pm.in2
-rw-r--r--rt/lib/RT/Graph/Tickets.pm2
-rwxr-xr-xrt/lib/RT/Group.pm39
-rwxr-xr-xrt/lib/RT/GroupMember.pm2
-rwxr-xr-xrt/lib/RT/GroupMembers.pm2
-rwxr-xr-xrt/lib/RT/Groups.pm2
-rw-r--r--rt/lib/RT/Handle.pm2
-rw-r--r--rt/lib/RT/I18N.pm11
-rw-r--r--rt/lib/RT/I18N/cs.pm2
-rw-r--r--rt/lib/RT/I18N/de.pm2
-rw-r--r--rt/lib/RT/I18N/fr.pm2
-rw-r--r--rt/lib/RT/I18N/i_default.pm2
-rwxr-xr-xrt/lib/RT/I18N/ru.pm2
-rw-r--r--rt/lib/RT/Installer.pm2
-rw-r--r--rt/lib/RT/Interface/CLI.pm2
-rwxr-xr-xrt/lib/RT/Interface/Email.pm65
-rw-r--r--rt/lib/RT/Interface/Email/Auth/Crypt.pm2
-rw-r--r--rt/lib/RT/Interface/Email/Auth/MailFrom.pm2
-rw-r--r--rt/lib/RT/Interface/REST.pm2
-rw-r--r--rt/lib/RT/Interface/Web.pm20
-rw-r--r--rt/lib/RT/Interface/Web/Handler.pm2
-rw-r--r--rt/lib/RT/Interface/Web/Menu.pm50
-rw-r--r--rt/lib/RT/Interface/Web/Middleware/StaticHeaders.pm2
-rwxr-xr-xrt/lib/RT/Interface/Web/QueryBuilder.pm2
-rwxr-xr-xrt/lib/RT/Interface/Web/QueryBuilder/Tree.pm2
-rw-r--r--rt/lib/RT/Interface/Web/Request.pm2
-rw-r--r--rt/lib/RT/Interface/Web/Session.pm2
-rw-r--r--rt/lib/RT/Lifecycle.pm2
-rw-r--r--rt/lib/RT/Lifecycle/Ticket.pm2
-rw-r--r--rt/lib/RT/Link.pm23
-rw-r--r--rt/lib/RT/Links.pm2
-rw-r--r--rt/lib/RT/Migrate.pm2
-rw-r--r--rt/lib/RT/Migrate/Importer.pm27
-rw-r--r--rt/lib/RT/Migrate/Importer/File.pm4
-rw-r--r--rt/lib/RT/Migrate/Incremental.pm2
-rw-r--r--rt/lib/RT/Migrate/Serializer.pm43
-rw-r--r--rt/lib/RT/Migrate/Serializer/File.pm2
-rw-r--r--rt/lib/RT/Migrate/Serializer/IncrementalRecord.pm2
-rw-r--r--rt/lib/RT/Migrate/Serializer/IncrementalRecords.pm2
-rw-r--r--rt/lib/RT/ObjectClass.pm14
-rw-r--r--rt/lib/RT/ObjectClasses.pm2
-rw-r--r--rt/lib/RT/ObjectCustomField.pm2
-rw-r--r--rt/lib/RT/ObjectCustomFieldValue.pm2
-rw-r--r--rt/lib/RT/ObjectCustomFieldValues.pm5
-rw-r--r--rt/lib/RT/ObjectCustomFields.pm2
-rw-r--r--rt/lib/RT/ObjectScrip.pm15
-rw-r--r--rt/lib/RT/ObjectScrips.pm2
-rw-r--r--rt/lib/RT/ObjectTopic.pm15
-rw-r--r--rt/lib/RT/ObjectTopics.pm2
-rw-r--r--rt/lib/RT/PlackRunner.pm2
-rw-r--r--rt/lib/RT/Plugin.pm13
-rw-r--r--rt/lib/RT/Pod/HTML.pm2
-rw-r--r--rt/lib/RT/Pod/HTMLBatch.pm2
-rw-r--r--rt/lib/RT/Pod/Search.pm2
-rw-r--r--rt/lib/RT/Principal.pm2
-rw-r--r--rt/lib/RT/Principals.pm2
-rwxr-xr-xrt/lib/RT/Queue.pm2
-rwxr-xr-xrt/lib/RT/Queues.pm2
-rwxr-xr-xrt/lib/RT/Record.pm2
-rw-r--r--rt/lib/RT/Record/AddAndSort.pm2
-rw-r--r--rt/lib/RT/Record/Role.pm2
-rw-r--r--rt/lib/RT/Record/Role/Lifecycle.pm2
-rw-r--r--rt/lib/RT/Record/Role/Links.pm2
-rw-r--r--rt/lib/RT/Record/Role/Rights.pm2
-rw-r--r--rt/lib/RT/Record/Role/Roles.pm2
-rw-r--r--rt/lib/RT/Record/Role/Status.pm2
-rw-r--r--rt/lib/RT/Reminders.pm2
-rw-r--r--rt/lib/RT/Report/Tickets.pm2
-rw-r--r--rt/lib/RT/Report/Tickets/Entry.pm2
-rw-r--r--rt/lib/RT/Rule.pm2
-rw-r--r--rt/lib/RT/Ruleset.pm2
-rw-r--r--rt/lib/RT/SQL.pm2
-rw-r--r--rt/lib/RT/SavedSearch.pm2
-rw-r--r--rt/lib/RT/SavedSearches.pm2
-rwxr-xr-xrt/lib/RT/Scrip.pm2
-rwxr-xr-xrt/lib/RT/ScripAction.pm2
-rwxr-xr-xrt/lib/RT/ScripActions.pm2
-rwxr-xr-xrt/lib/RT/ScripCondition.pm2
-rwxr-xr-xrt/lib/RT/ScripConditions.pm2
-rwxr-xr-xrt/lib/RT/Scrips.pm2
-rwxr-xr-xrt/lib/RT/Search.pm2
-rw-r--r--rt/lib/RT/Search/ActiveTicketsInQueue.pm2
-rw-r--r--rt/lib/RT/Search/FromSQL.pm2
-rw-r--r--rt/lib/RT/Search/Simple.pm2
-rw-r--r--rt/lib/RT/SearchBuilder.pm2
-rw-r--r--rt/lib/RT/SearchBuilder/AddAndSort.pm2
-rw-r--r--rt/lib/RT/SearchBuilder/Role.pm2
-rw-r--r--rt/lib/RT/SearchBuilder/Role/Roles.pm2
-rw-r--r--rt/lib/RT/SharedSetting.pm2
-rw-r--r--rt/lib/RT/SharedSettings.pm2
-rw-r--r--rt/lib/RT/Shredder.pm2
-rw-r--r--rt/lib/RT/Shredder/Constants.pm2
-rw-r--r--rt/lib/RT/Shredder/Dependencies.pm2
-rw-r--r--rt/lib/RT/Shredder/Dependency.pm2
-rw-r--r--rt/lib/RT/Shredder/Exceptions.pm2
-rw-r--r--rt/lib/RT/Shredder/POD.pm2
-rw-r--r--rt/lib/RT/Shredder/Plugin.pm2
-rw-r--r--rt/lib/RT/Shredder/Plugin/Attachments.pm2
-rw-r--r--rt/lib/RT/Shredder/Plugin/Base.pm2
-rw-r--r--rt/lib/RT/Shredder/Plugin/Base/Dump.pm2
-rw-r--r--rt/lib/RT/Shredder/Plugin/Base/Search.pm2
-rw-r--r--rt/lib/RT/Shredder/Plugin/Objects.pm2
-rw-r--r--rt/lib/RT/Shredder/Plugin/SQLDump.pm2
-rw-r--r--rt/lib/RT/Shredder/Plugin/Summary.pm2
-rw-r--r--rt/lib/RT/Shredder/Plugin/Tickets.pm2
-rw-r--r--rt/lib/RT/Shredder/Plugin/Users.pm2
-rw-r--r--rt/lib/RT/Squish.pm2
-rw-r--r--rt/lib/RT/Squish/CSS.pm2
-rw-r--r--rt/lib/RT/Squish/JS.pm2
-rw-r--r--rt/lib/RT/StyleGuide.pod22
-rw-r--r--rt/lib/RT/System.pm2
-rwxr-xr-xrt/lib/RT/Template.pm2
-rwxr-xr-xrt/lib/RT/Templates.pm2
-rw-r--r--rt/lib/RT/Test.pm6
-rw-r--r--rt/lib/RT/Test/Apache.pm2
-rw-r--r--rt/lib/RT/Test/Email.pm2
-rw-r--r--rt/lib/RT/Test/GnuPG.pm16
-rw-r--r--rt/lib/RT/Test/SMIME.pm4
-rw-r--r--rt/lib/RT/Test/Shredder.pm2
-rw-r--r--rt/lib/RT/Test/Web.pm2
-rwxr-xr-xrt/lib/RT/Ticket.pm20
-rwxr-xr-xrt/lib/RT/Tickets.pm2
-rw-r--r--rt/lib/RT/Topic.pm2
-rw-r--r--rt/lib/RT/Topics.pm2
-rwxr-xr-xrt/lib/RT/Transaction.pm75
-rwxr-xr-xrt/lib/RT/Transactions.pm2
-rw-r--r--rt/lib/RT/URI.pm2
-rw-r--r--rt/lib/RT/URI/a.pm2
-rw-r--r--rt/lib/RT/URI/base.pm2
-rw-r--r--rt/lib/RT/URI/fsck_com_article.pm2
-rw-r--r--rt/lib/RT/URI/fsck_com_rt.pm2
-rw-r--r--rt/lib/RT/URI/t.pm2
-rwxr-xr-xrt/lib/RT/User.pm58
-rwxr-xr-xrt/lib/RT/Users.pm2
-rw-r--r--rt/lib/RT/Util.pm68
208 files changed, 1045 insertions, 314 deletions
diff --git a/rt/lib/RT.pm b/rt/lib/RT.pm
index 069309dc7..91aeb1590 100644
--- a/rt/lib/RT.pm
+++ b/rt/lib/RT.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -81,6 +81,10 @@ use vars qw($BasePath
$MasonDataDir
$MasonSessionDir);
+# Set Email::Address module var before anything else loads.
+# This avoids an algorithmic complexity denial of service vulnerability.
+# See T#157608 and CVE-2015-7686 for more information.
+$Email::Address::COMMENT_NEST_LEVEL = 1;
RT->LoadGeneratedData();
@@ -765,6 +769,7 @@ sub InstallMode {
sub LoadGeneratedData {
my $class = shift;
my $pm_path = ( File::Spec->splitpath( $INC{'RT.pm'} ) )[1];
+ $pm_path = File::Spec->rel2abs( $pm_path );
require "$pm_path/RT/Generated.pm" || die "Couldn't load RT::Generated: $@";
$class->CanonicalizeGeneratedPaths();
@@ -964,7 +969,9 @@ sub Deprecated {
Please report them to rt-bugs@bestpractical.com, if you know what's
broken and have at least some idea of what needs to be fixed.
-If you're not sure what's going on, report them rt-devel@lists.bestpractical.com.
+If you're not sure what's going on, start a discussion in the RT Developers
+category on the community forum at L<https://forum.bestpractical.com> or
+send email to sales@bestpractical.com for professional assistance.
=head1 SEE ALSO
diff --git a/rt/lib/RT/ACE.pm b/rt/lib/RT/ACE.pm
index 0a79ecb39..64dd58719 100755
--- a/rt/lib/RT/ACE.pm
+++ b/rt/lib/RT/ACE.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/ACL.pm b/rt/lib/RT/ACL.pm
index fb3f4011d..1a9a1cc7a 100755
--- a/rt/lib/RT/ACL.pm
+++ b/rt/lib/RT/ACL.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Action.pm b/rt/lib/RT/Action.pm
index ac4dfe695..0f8002d9e 100755
--- a/rt/lib/RT/Action.pm
+++ b/rt/lib/RT/Action.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Action/AutoOpen.pm b/rt/lib/RT/Action/AutoOpen.pm
index 9cc324e27..72ee89ce4 100644
--- a/rt/lib/RT/Action/AutoOpen.pm
+++ b/rt/lib/RT/Action/AutoOpen.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Action/AutoOpenInactive.pm b/rt/lib/RT/Action/AutoOpenInactive.pm
index 9a48706ca..91f20659d 100644
--- a/rt/lib/RT/Action/AutoOpenInactive.pm
+++ b/rt/lib/RT/Action/AutoOpenInactive.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Action/Autoreply.pm b/rt/lib/RT/Action/Autoreply.pm
index a7a46277c..905b86c23 100755
--- a/rt/lib/RT/Action/Autoreply.pm
+++ b/rt/lib/RT/Action/Autoreply.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Action/CreateTickets.pm b/rt/lib/RT/Action/CreateTickets.pm
index dd32da70c..0fcdf0d44 100644
--- a/rt/lib/RT/Action/CreateTickets.pm
+++ b/rt/lib/RT/Action/CreateTickets.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Action/EscalatePriority.pm b/rt/lib/RT/Action/EscalatePriority.pm
index 1b63d53f4..311a7c04b 100644
--- a/rt/lib/RT/Action/EscalatePriority.pm
+++ b/rt/lib/RT/Action/EscalatePriority.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Action/ExtractSubjectTag.pm b/rt/lib/RT/Action/ExtractSubjectTag.pm
index 1dece09b4..ce8628d1c 100644
--- a/rt/lib/RT/Action/ExtractSubjectTag.pm
+++ b/rt/lib/RT/Action/ExtractSubjectTag.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Action/LinearEscalate.pm b/rt/lib/RT/Action/LinearEscalate.pm
index 23a796cdf..b20917725 100755
--- a/rt/lib/RT/Action/LinearEscalate.pm
+++ b/rt/lib/RT/Action/LinearEscalate.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Action/Notify.pm b/rt/lib/RT/Action/Notify.pm
index ec98fa3ac..d7e0f35c3 100755
--- a/rt/lib/RT/Action/Notify.pm
+++ b/rt/lib/RT/Action/Notify.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Action/NotifyAsComment.pm b/rt/lib/RT/Action/NotifyAsComment.pm
index 924419be3..03fc3913f 100755
--- a/rt/lib/RT/Action/NotifyAsComment.pm
+++ b/rt/lib/RT/Action/NotifyAsComment.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Action/NotifyGroup.pm b/rt/lib/RT/Action/NotifyGroup.pm
index e9638b725..41f2b7880 100644
--- a/rt/lib/RT/Action/NotifyGroup.pm
+++ b/rt/lib/RT/Action/NotifyGroup.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Action/NotifyGroupAsComment.pm b/rt/lib/RT/Action/NotifyGroupAsComment.pm
index f6e986d65..82841d50c 100644
--- a/rt/lib/RT/Action/NotifyGroupAsComment.pm
+++ b/rt/lib/RT/Action/NotifyGroupAsComment.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Action/NotifyOwnerOrAdminCc.pm b/rt/lib/RT/Action/NotifyOwnerOrAdminCc.pm
index 33ca47723..b64f20505 100644
--- a/rt/lib/RT/Action/NotifyOwnerOrAdminCc.pm
+++ b/rt/lib/RT/Action/NotifyOwnerOrAdminCc.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Action/OpenOnStarted.pm b/rt/lib/RT/Action/OpenOnStarted.pm
index c1634519c..56382f78e 100644
--- a/rt/lib/RT/Action/OpenOnStarted.pm
+++ b/rt/lib/RT/Action/OpenOnStarted.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Action/RecordComment.pm b/rt/lib/RT/Action/RecordComment.pm
index 8ec0b0edf..999ca7bf2 100644
--- a/rt/lib/RT/Action/RecordComment.pm
+++ b/rt/lib/RT/Action/RecordComment.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Action/RecordCorrespondence.pm b/rt/lib/RT/Action/RecordCorrespondence.pm
index 73695cd2f..ab656fd5c 100644
--- a/rt/lib/RT/Action/RecordCorrespondence.pm
+++ b/rt/lib/RT/Action/RecordCorrespondence.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Action/SendEmail.pm b/rt/lib/RT/Action/SendEmail.pm
index 2361ead7f..8f64fddb7 100755
--- a/rt/lib/RT/Action/SendEmail.pm
+++ b/rt/lib/RT/Action/SendEmail.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Action/SendForward.pm b/rt/lib/RT/Action/SendForward.pm
index 3fa6e3b6b..db510012d 100644
--- a/rt/lib/RT/Action/SendForward.pm
+++ b/rt/lib/RT/Action/SendForward.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Action/SetPriority.pm b/rt/lib/RT/Action/SetPriority.pm
index 4ebf5e555..54c152d93 100644
--- a/rt/lib/RT/Action/SetPriority.pm
+++ b/rt/lib/RT/Action/SetPriority.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Action/SetStatus.pm b/rt/lib/RT/Action/SetStatus.pm
index 158afe15c..f6692c410 100644
--- a/rt/lib/RT/Action/SetStatus.pm
+++ b/rt/lib/RT/Action/SetStatus.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Action/UserDefined.pm b/rt/lib/RT/Action/UserDefined.pm
index 48bee186d..f7dee1072 100644
--- a/rt/lib/RT/Action/UserDefined.pm
+++ b/rt/lib/RT/Action/UserDefined.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Approval.pm b/rt/lib/RT/Approval.pm
index cd6d661cf..1ce3077ed 100644
--- a/rt/lib/RT/Approval.pm
+++ b/rt/lib/RT/Approval.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Approval/Rule.pm b/rt/lib/RT/Approval/Rule.pm
index 9bf39f03d..484ff8a52 100644
--- a/rt/lib/RT/Approval/Rule.pm
+++ b/rt/lib/RT/Approval/Rule.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Approval/Rule/Created.pm b/rt/lib/RT/Approval/Rule/Created.pm
index fbbf9f5ae..262eccea2 100644
--- a/rt/lib/RT/Approval/Rule/Created.pm
+++ b/rt/lib/RT/Approval/Rule/Created.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Approval/Rule/NewPending.pm b/rt/lib/RT/Approval/Rule/NewPending.pm
index 238ad63c5..6088d31ca 100644
--- a/rt/lib/RT/Approval/Rule/NewPending.pm
+++ b/rt/lib/RT/Approval/Rule/NewPending.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Approval/Rule/Passed.pm b/rt/lib/RT/Approval/Rule/Passed.pm
index cd083d516..ae2aa6889 100644
--- a/rt/lib/RT/Approval/Rule/Passed.pm
+++ b/rt/lib/RT/Approval/Rule/Passed.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Approval/Rule/Rejected.pm b/rt/lib/RT/Approval/Rule/Rejected.pm
index 8661bf4ec..1b6f9cb26 100644
--- a/rt/lib/RT/Approval/Rule/Rejected.pm
+++ b/rt/lib/RT/Approval/Rule/Rejected.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Article.pm b/rt/lib/RT/Article.pm
index 2c955cc12..6d179fe0f 100644
--- a/rt/lib/RT/Article.pm
+++ b/rt/lib/RT/Article.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Articles.pm b/rt/lib/RT/Articles.pm
index 726758ac8..63ddd66fb 100644
--- a/rt/lib/RT/Articles.pm
+++ b/rt/lib/RT/Articles.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Attachment.pm b/rt/lib/RT/Attachment.pm
index 00f790abf..14b639f72 100755
--- a/rt/lib/RT/Attachment.pm
+++ b/rt/lib/RT/Attachment.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Attachments.pm b/rt/lib/RT/Attachments.pm
index 73da9bbfa..2041bd15c 100755
--- a/rt/lib/RT/Attachments.pm
+++ b/rt/lib/RT/Attachments.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Attribute.pm b/rt/lib/RT/Attribute.pm
index 9943b5789..aa965e07a 100644
--- a/rt/lib/RT/Attribute.pm
+++ b/rt/lib/RT/Attribute.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -632,6 +632,65 @@ sub FindDependencies {
$self->SUPER::FindDependencies($walker, $deps);
$deps->Add( out => $self->Object );
+
+ # dashboards in menu attribute has dependencies on each of its dashboards
+ if ($self->Name eq RT::User::_PrefName("DashboardsInMenu")) {
+ my $content = $self->Content;
+ for my $pane (values %{ $content || {} }) {
+ for my $dash_id (@$pane) {
+ my $attr = RT::Attribute->new($self->CurrentUser);
+ $attr->LoadById($dash_id);
+ $deps->Add( out => $attr );
+ }
+ }
+ }
+ # homepage settings attribute has dependencies on each of the searches in it
+ elsif ($self->Name eq RT::User::_PrefName("HomepageSettings")) {
+ my $content = $self->Content;
+ for my $pane (values %{ $content || {} }) {
+ for my $component (@$pane) {
+ # this hairy code mirrors what's in the saved search loader
+ # in /Elements/ShowSearch
+ if ($component->{type} eq 'saved') {
+ if ($component->{name} =~ /^(.*?)-(\d+)-SavedSearch-(\d+)$/) {
+ my $attr = RT::Attribute->new($self->CurrentUser);
+ $attr->LoadById($3);
+ $deps->Add( out => $attr );
+ }
+ }
+ elsif ($component->{type} eq 'system') {
+ my ($search) = RT::System->new($self->CurrentUser)->Attributes->Named( 'Search - ' . $component->{name} );
+ unless ( $search && $search->Id ) {
+ my (@custom_searches) = RT::System->new($self->CurrentUser)->Attributes->Named('SavedSearch');
+ foreach my $custom (@custom_searches) {
+ if ($custom->Description eq $component->{name}) { $search = $custom; last }
+ }
+ }
+ $deps->Add( out => $search ) if $search;
+ }
+ }
+ }
+ }
+ # dashboards have dependencies on all the searches and dashboards they use
+ elsif ($self->Name eq 'Dashboard') {
+ my $content = $self->Content;
+ for my $pane (values %{ $content->{Panes} || {} }) {
+ for my $component (@$pane) {
+ if ($component->{portlet_type} eq 'search' || $component->{portlet_type} eq 'dashboard') {
+ my $attr = RT::Attribute->new($self->CurrentUser);
+ $attr->LoadById($component->{id});
+ $deps->Add( out => $attr );
+ }
+ }
+ }
+ }
+ # each subscription depends on its dashboard
+ elsif ($self->Name eq 'Subscription') {
+ my $content = $self->Content;
+ my $attr = RT::Attribute->new($self->CurrentUser);
+ $attr->LoadById($content->{DashboardId});
+ $deps->Add( out => $attr );
+ }
}
sub PreInflate {
@@ -640,11 +699,220 @@ sub PreInflate {
if ($data->{Object} and ref $data->{Object}) {
my $on_uid = ${ $data->{Object} };
- return if $importer->ShouldSkipTransaction($on_uid);
+
+ # skip attributes of objects we're not inflating
+ # exception: we don't inflate RT->System, but we want RT->System's searches
+ unless ($on_uid eq RT->System->UID && $data->{Name} =~ /Search/) {
+ return if $importer->ShouldSkipTransaction($on_uid);
+ }
}
+
return $class->SUPER::PreInflate( $importer, $uid, $data );
}
+# this method will be called repeatedly to fix up this attribute's contents
+# (a list of searches, dashboards) during the import process, as the
+# ordinary dependency resolution system can't quite handle the subtlety
+# involved (e.g. a user simply declares out-dependencies on all of her
+# attributes, but those attributes (e.g. dashboards, saved searches,
+# dashboards in menu preferences) have dependencies amongst themselves).
+# if this attribute (e.g. a user's dashboard) fails to load an attribute
+# (e.g. a user's saved search) then it postpones and repeats the postinflate
+# process again when that user's saved search has been imported
+# this method updates Content each time through, each time getting closer and
+# closer to the fully inflated attribute
+sub PostInflateFixup {
+ my $self = shift;
+ my $importer = shift;
+ my $spec = shift;
+
+ # decode UIDs to be raw dashboard IDs
+ if ($self->Name eq RT::User::_PrefName("DashboardsInMenu")) {
+ my $content = $self->Content;
+
+ for my $pane (values %{ $content || {} }) {
+ for (@$pane) {
+ if (ref($_) eq 'SCALAR') {
+ my $attr = $importer->LookupObj($$_);
+ if ($attr) {
+ $_ = $attr->Id;
+ }
+ else {
+ $importer->Postpone(
+ for => $$_,
+ uid => $spec->{uid},
+ method => 'PostInflateFixup',
+ );
+ }
+ }
+ }
+ }
+ $self->SetContent($content);
+ }
+ # decode UIDs to be saved searches
+ elsif ($self->Name eq RT::User::_PrefName("HomepageSettings")) {
+ my $content = $self->Content;
+
+ for my $pane (values %{ $content || {} }) {
+ for (@$pane) {
+ if (ref($_->{uid}) eq 'SCALAR') {
+ my $uid = $_->{uid};
+ my $attr = $importer->LookupObj($$uid);
+
+ if ($attr) {
+ if ($_->{type} eq 'saved') {
+ $_->{name} = join '-', $attr->ObjectType, $attr->ObjectId, 'SavedSearch', $attr->id;
+ }
+ # if type is system, name doesn't need to change
+ # if type is anything else, pass it through as is
+ delete $_->{uid};
+ }
+ else {
+ $importer->Postpone(
+ for => $$uid,
+ uid => $spec->{uid},
+ method => 'PostInflateFixup',
+ );
+ }
+ }
+ }
+ }
+ $self->SetContent($content);
+ }
+ elsif ($self->Name eq 'Dashboard') {
+ my $content = $self->Content;
+
+ for my $pane (values %{ $content->{Panes} || {} }) {
+ for (@$pane) {
+ if (ref($_->{uid}) eq 'SCALAR') {
+ my $uid = $_->{uid};
+ my $attr = $importer->LookupObj($$uid);
+
+ if ($attr) {
+ # update with the new id numbers assigned to us
+ $_->{id} = $attr->Id;
+ $_->{privacy} = join '-', $attr->ObjectType, $attr->ObjectId;
+ delete $_->{uid};
+ }
+ else {
+ $importer->Postpone(
+ for => $$uid,
+ uid => $spec->{uid},
+ method => 'PostInflateFixup',
+ );
+ }
+ }
+ }
+ }
+ $self->SetContent($content);
+ }
+ elsif ($self->Name eq 'Subscription') {
+ my $content = $self->Content;
+ if (ref($content->{DashboardId}) eq 'SCALAR') {
+ my $attr = $importer->LookupObj(${ $content->{DashboardId} });
+ if ($attr) {
+ $content->{DashboardId} = $attr->Id;
+ }
+ else {
+ $importer->Postpone(
+ for => ${ $content->{DashboardId} },
+ uid => $spec->{uid},
+ method => 'PostInflateFixup',
+ );
+ }
+ }
+ $self->SetContent($content);
+ }
+}
+
+sub PostInflate {
+ my $self = shift;
+ my ($importer, $uid) = @_;
+
+ $self->SUPER::PostInflate( $importer, $uid );
+
+ # this method is separate because it needs to be callable multple times,
+ # and we can't guarantee that SUPER::PostInflate can deal with that
+ $self->PostInflateFixup($importer, { uid => $uid });
+}
+
+sub Serialize {
+ my $self = shift;
+ my %args = (@_);
+ my %store = $self->SUPER::Serialize(@_);
+
+ # encode raw dashboard IDs to be UIDs
+ if ($store{Name} eq RT::User::_PrefName("DashboardsInMenu")) {
+ my $content = $self->_DeserializeContent($store{Content});
+ for my $pane (values %{ $content || {} }) {
+ for (@$pane) {
+ my $attr = RT::Attribute->new($self->CurrentUser);
+ $attr->LoadById($_);
+ $_ = \($attr->UID);
+ }
+ }
+ $store{Content} = $self->_SerializeContent($content);
+ }
+ # encode saved searches to be UIDs
+ elsif ($store{Name} eq RT::User::_PrefName("HomepageSettings")) {
+ my $content = $self->_DeserializeContent($store{Content});
+ for my $pane (values %{ $content || {} }) {
+ for (@$pane) {
+ # this hairy code mirrors what's in the saved search loader
+ # in /Elements/ShowSearch
+ if ($_->{type} eq 'saved') {
+ if ($_->{name} =~ /^(.*?)-(\d+)-SavedSearch-(\d+)$/) {
+ my $attr = RT::Attribute->new($self->CurrentUser);
+ $attr->LoadById($3);
+ $_->{uid} = \($attr->UID);
+ }
+ # if we can't parse the name, just pass it through
+ }
+ elsif ($_->{type} eq 'system') {
+ my ($search) = RT::System->new($self->CurrentUser)->Attributes->Named( 'Search - ' . $_->{name} );
+ unless ( $search && $search->Id ) {
+ my (@custom_searches) = RT::System->new($self->CurrentUser)->Attributes->Named('SavedSearch');
+ foreach my $custom (@custom_searches) {
+ if ($custom->Description eq $_->{name}) { $search = $custom; last }
+ }
+ }
+ # if we can't load the search, just pass it through
+ if ($search) {
+ $_->{uid} = \($search->UID);
+ }
+ }
+ # pass through everything else (e.g. component)
+ }
+ }
+ $store{Content} = $self->_SerializeContent($content);
+ }
+ # encode saved searches and dashboards to be UIDs
+ elsif ($store{Name} eq 'Dashboard') {
+ my $content = $self->_DeserializeContent($store{Content}) || {};
+ for my $pane (values %{ $content->{Panes} || {} }) {
+ for (@$pane) {
+ if ($_->{portlet_type} eq 'search' || $_->{portlet_type} eq 'dashboard') {
+ my $attr = RT::Attribute->new($self->CurrentUser);
+ $attr->LoadById($_->{id});
+ $_->{uid} = \($attr->UID);
+ }
+ # pass through everything else (e.g. component)
+ }
+ }
+ $store{Content} = $self->_SerializeContent($content);
+ }
+ # encode subscriptions to have dashboard UID
+ elsif ($store{Name} eq 'Subscription') {
+ my $content = $self->_DeserializeContent($store{Content});
+ my $attr = RT::Attribute->new($self->CurrentUser);
+ $attr->LoadById($content->{DashboardId});
+ $content->{DashboardId} = \($attr->UID);
+ $store{Content} = $self->_SerializeContent($content);
+ }
+
+ return %store;
+}
+
RT::Base->_ImportOverlays();
1;
diff --git a/rt/lib/RT/Attributes.pm b/rt/lib/RT/Attributes.pm
index e0ede6a06..2a8869a04 100644
--- a/rt/lib/RT/Attributes.pm
+++ b/rt/lib/RT/Attributes.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Base.pm b/rt/lib/RT/Base.pm
index 77b3736d2..679e10c3d 100644
--- a/rt/lib/RT/Base.pm
+++ b/rt/lib/RT/Base.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/CachedGroupMember.pm b/rt/lib/RT/CachedGroupMember.pm
index 21ea33655..63d991402 100644
--- a/rt/lib/RT/CachedGroupMember.pm
+++ b/rt/lib/RT/CachedGroupMember.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/CachedGroupMembers.pm b/rt/lib/RT/CachedGroupMembers.pm
index cb483cb43..f3d0bf0cb 100644
--- a/rt/lib/RT/CachedGroupMembers.pm
+++ b/rt/lib/RT/CachedGroupMembers.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Class.pm b/rt/lib/RT/Class.pm
index c98564134..eea9be511 100644
--- a/rt/lib/RT/Class.pm
+++ b/rt/lib/RT/Class.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Classes.pm b/rt/lib/RT/Classes.pm
index 6ff2b574b..91a5adf05 100644
--- a/rt/lib/RT/Classes.pm
+++ b/rt/lib/RT/Classes.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Condition.pm b/rt/lib/RT/Condition.pm
index 537aa541b..f371cd4b4 100755
--- a/rt/lib/RT/Condition.pm
+++ b/rt/lib/RT/Condition.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Condition/AnyTransaction.pm b/rt/lib/RT/Condition/AnyTransaction.pm
index 44a265507..092162b38 100644
--- a/rt/lib/RT/Condition/AnyTransaction.pm
+++ b/rt/lib/RT/Condition/AnyTransaction.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Condition/BeforeDue.pm b/rt/lib/RT/Condition/BeforeDue.pm
index 6302726f8..d72b2c351 100644
--- a/rt/lib/RT/Condition/BeforeDue.pm
+++ b/rt/lib/RT/Condition/BeforeDue.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Condition/CloseTicket.pm b/rt/lib/RT/Condition/CloseTicket.pm
index 66c810681..5e1224bce 100644
--- a/rt/lib/RT/Condition/CloseTicket.pm
+++ b/rt/lib/RT/Condition/CloseTicket.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Condition/Overdue.pm b/rt/lib/RT/Condition/Overdue.pm
index e005f696c..3196bd39c 100644
--- a/rt/lib/RT/Condition/Overdue.pm
+++ b/rt/lib/RT/Condition/Overdue.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Condition/OwnerChange.pm b/rt/lib/RT/Condition/OwnerChange.pm
index 651a4bb2a..3e4e3ce6f 100644
--- a/rt/lib/RT/Condition/OwnerChange.pm
+++ b/rt/lib/RT/Condition/OwnerChange.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Condition/PriorityChange.pm b/rt/lib/RT/Condition/PriorityChange.pm
index a1629e9d0..4e9dc05aa 100644
--- a/rt/lib/RT/Condition/PriorityChange.pm
+++ b/rt/lib/RT/Condition/PriorityChange.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Condition/PriorityExceeds.pm b/rt/lib/RT/Condition/PriorityExceeds.pm
index 72319eedc..657d65f53 100644
--- a/rt/lib/RT/Condition/PriorityExceeds.pm
+++ b/rt/lib/RT/Condition/PriorityExceeds.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Condition/QueueChange.pm b/rt/lib/RT/Condition/QueueChange.pm
index 73c1b8424..08b89cdf6 100644
--- a/rt/lib/RT/Condition/QueueChange.pm
+++ b/rt/lib/RT/Condition/QueueChange.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Condition/ReopenTicket.pm b/rt/lib/RT/Condition/ReopenTicket.pm
index 31f014349..0a7189d45 100644
--- a/rt/lib/RT/Condition/ReopenTicket.pm
+++ b/rt/lib/RT/Condition/ReopenTicket.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Condition/StatusChange.pm b/rt/lib/RT/Condition/StatusChange.pm
index 97153c675..73bfb048a 100644
--- a/rt/lib/RT/Condition/StatusChange.pm
+++ b/rt/lib/RT/Condition/StatusChange.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Condition/UserDefined.pm b/rt/lib/RT/Condition/UserDefined.pm
index a6e0132a6..bbb90dc04 100644
--- a/rt/lib/RT/Condition/UserDefined.pm
+++ b/rt/lib/RT/Condition/UserDefined.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Config.pm b/rt/lib/RT/Config.pm
index 656741ca9..7d9fbf33a 100644
--- a/rt/lib/RT/Config.pm
+++ b/rt/lib/RT/Config.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -143,6 +143,14 @@ can be set for each config optin:
our %META;
%META = (
# General user overridable options
+ RestrictReferrerLogin => {
+ PostLoadCheck => sub {
+ my $self = shift;
+ if (defined($self->Get('RestrictReferrerLogin'))) {
+ RT::Logger->error("The config option 'RestrictReferrerLogin' is incorrect, and should be 'RestrictLoginReferrer' instead.");
+ }
+ },
+ },
DefaultQueue => {
Section => 'General',
Overridable => 1,
@@ -307,23 +315,42 @@ our %META;
Hints => 'Only for entry, not display', #loc
},
},
+ RefreshIntervals => {
+ Type => 'ARRAY',
+ PostLoadCheck => sub {
+ my $self = shift;
+ my @intervals = $self->Get('RefreshIntervals');
+ if (grep { $_ == 0 } @intervals) {
+ $RT::Logger->warning("Please do not include a 0 value in RefreshIntervals, as that default is already added for you.");
+ }
+ },
+ },
SearchResultsRefreshInterval => {
Section => 'General', #loc
Overridable => 1,
SortOrder => 9,
Widget => '/Widgets/Form/Select',
WidgetArguments => {
- Description => 'Search results refresh interval', #loc
- Values => [qw(0 120 300 600 1200 3600 7200)],
- ValuesLabel => {
- 0 => "Don't refresh search results.", #loc
- 120 => "Refresh search results every 2 minutes.", #loc
- 300 => "Refresh search results every 5 minutes.", #loc
- 600 => "Refresh search results every 10 minutes.", #loc
- 1200 => "Refresh search results every 20 minutes.", #loc
- 3600 => "Refresh search results every 60 minutes.", #loc
- 7200 => "Refresh search results every 120 minutes.", #loc
- },
+ Description => 'Search results refresh interval', #loc
+ Callback => sub {
+ my @values = RT->Config->Get('RefreshIntervals');
+ my %labels = (
+ 0 => "Don't refresh search results.", # loc
+ );
+
+ for my $value (@values) {
+ if ($value % 60 == 0) {
+ $labels{$value} = ['Refresh search results every [quant,_1,minute,minutes].', $value / 60]; # loc
+ }
+ else {
+ $labels{$value} = ['Refresh search results every [quant,_1,second,seconds].', $value]; # loc
+ }
+ }
+
+ unshift @values, 0;
+
+ return { Values => \@values, ValuesLabel => \%labels };
+ },
},
},
@@ -335,16 +362,25 @@ our %META;
Widget => '/Widgets/Form/Select',
WidgetArguments => {
Description => 'Home page refresh interval', #loc
- Values => [qw(0 120 300 600 1200 3600 7200)],
- ValuesLabel => {
- 0 => "Don't refresh home page.", #loc
- 120 => "Refresh home page every 2 minutes.", #loc
- 300 => "Refresh home page every 5 minutes.", #loc
- 600 => "Refresh home page every 10 minutes.", #loc
- 1200 => "Refresh home page every 20 minutes.", #loc
- 3600 => "Refresh home page every 60 minutes.", #loc
- 7200 => "Refresh home page every 120 minutes.", #loc
- },
+ Callback => sub {
+ my @values = RT->Config->Get('RefreshIntervals');
+ my %labels = (
+ 0 => "Don't refresh home page.", # loc
+ );
+
+ for my $value (@values) {
+ if ($value % 60 == 0) {
+ $labels{$value} = ['Refresh home page every [quant,_1,minute,minutes].', $value / 60]; # loc
+ }
+ else {
+ $labels{$value} = ['Refresh home page every [quant,_1,second,seconds].', $value]; # loc
+ }
+ }
+
+ unshift @values, 0;
+
+ return { Values => \@values, ValuesLabel => \%labels };
+ },
},
},
diff --git a/rt/lib/RT/Crypt.pm b/rt/lib/RT/Crypt.pm
index dfc0bf0f9..2f2d2c77c 100644
--- a/rt/lib/RT/Crypt.pm
+++ b/rt/lib/RT/Crypt.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -430,7 +430,11 @@ An un-localized error message desribing the problem.
sub SignEncrypt {
my $self = shift;
- my %args = (@_);
+ my %args = (
+ Sign => 1,
+ Encrypt => 1,
+ @_,
+ );
my $entity = $args{'Entity'};
if ( $args{'Sign'} && !defined $args{'Signer'} ) {
diff --git a/rt/lib/RT/Crypt/GnuPG.pm b/rt/lib/RT/Crypt/GnuPG.pm
index e986447c8..69d25bbcb 100644
--- a/rt/lib/RT/Crypt/GnuPG.pm
+++ b/rt/lib/RT/Crypt/GnuPG.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Crypt/GnuPG/CRLFHandle.pm b/rt/lib/RT/Crypt/GnuPG/CRLFHandle.pm
index 2dfc45224..f96f4eeb5 100644
--- a/rt/lib/RT/Crypt/GnuPG/CRLFHandle.pm
+++ b/rt/lib/RT/Crypt/GnuPG/CRLFHandle.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Crypt/Role.pm b/rt/lib/RT/Crypt/Role.pm
index 6a33e5d77..8e39b95d7 100644
--- a/rt/lib/RT/Crypt/Role.pm
+++ b/rt/lib/RT/Crypt/Role.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Crypt/SMIME.pm b/rt/lib/RT/Crypt/SMIME.pm
index 743ab2bb8..fbd8108b2 100644
--- a/rt/lib/RT/Crypt/SMIME.pm
+++ b/rt/lib/RT/Crypt/SMIME.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -184,6 +184,14 @@ sub Probe {
\$buf, \$err
) };
+ if ($err && $err =~ /Invalid command/) {
+ ($buf, $err) = ('', '');
+ safe_run_child { run3( [$bin, "list", "-commands"],
+ \undef,
+ \$buf, \$err
+ ) };
+ }
+
if ($? or $err) {
$RT::Logger->warning(
"RT's SMIME libraries couldn't successfully execute openssl.".
diff --git a/rt/lib/RT/CurrentUser.pm b/rt/lib/RT/CurrentUser.pm
index 74d44e304..60a2fa739 100755
--- a/rt/lib/RT/CurrentUser.pm
+++ b/rt/lib/RT/CurrentUser.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/CustomField.pm b/rt/lib/RT/CustomField.pm
index 3940e83e7..ac714a900 100644
--- a/rt/lib/RT/CustomField.pm
+++ b/rt/lib/RT/CustomField.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/CustomFieldValue.pm b/rt/lib/RT/CustomFieldValue.pm
index e4a6a96ef..6e6e35cc6 100644
--- a/rt/lib/RT/CustomFieldValue.pm
+++ b/rt/lib/RT/CustomFieldValue.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/CustomFieldValues.pm b/rt/lib/RT/CustomFieldValues.pm
index 6b5c624cb..d8706f601 100644
--- a/rt/lib/RT/CustomFieldValues.pm
+++ b/rt/lib/RT/CustomFieldValues.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/CustomFieldValues/External.pm b/rt/lib/RT/CustomFieldValues/External.pm
index 100c0353a..5d2617e74 100644
--- a/rt/lib/RT/CustomFieldValues/External.pm
+++ b/rt/lib/RT/CustomFieldValues/External.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/CustomFieldValues/Groups.pm b/rt/lib/RT/CustomFieldValues/Groups.pm
index 5ec729318..d37f7a430 100644
--- a/rt/lib/RT/CustomFieldValues/Groups.pm
+++ b/rt/lib/RT/CustomFieldValues/Groups.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/CustomFields.pm b/rt/lib/RT/CustomFields.pm
index dc15c2fb7..488d90359 100644
--- a/rt/lib/RT/CustomFields.pm
+++ b/rt/lib/RT/CustomFields.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Dashboard.pm b/rt/lib/RT/Dashboard.pm
index b30f3b2fa..7f76853d9 100644
--- a/rt/lib/RT/Dashboard.pm
+++ b/rt/lib/RT/Dashboard.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Dashboard/Mailer.pm b/rt/lib/RT/Dashboard/Mailer.pm
index c88fb67a6..0125dda61 100644
--- a/rt/lib/RT/Dashboard/Mailer.pm
+++ b/rt/lib/RT/Dashboard/Mailer.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Dashboards.pm b/rt/lib/RT/Dashboards.pm
index a5436c693..ad31640ec 100644
--- a/rt/lib/RT/Dashboards.pm
+++ b/rt/lib/RT/Dashboards.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Date.pm b/rt/lib/RT/Date.pm
index 7f4e323e4..216e5ecb9 100644
--- a/rt/lib/RT/Date.pm
+++ b/rt/lib/RT/Date.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/DependencyWalker.pm b/rt/lib/RT/DependencyWalker.pm
index a1412e53d..aad2f252a 100644
--- a/rt/lib/RT/DependencyWalker.pm
+++ b/rt/lib/RT/DependencyWalker.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/DependencyWalker/FindDependencies.pm b/rt/lib/RT/DependencyWalker/FindDependencies.pm
index 396223d61..78156d1fe 100644
--- a/rt/lib/RT/DependencyWalker/FindDependencies.pm
+++ b/rt/lib/RT/DependencyWalker/FindDependencies.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/EmailParser.pm b/rt/lib/RT/EmailParser.pm
index 51d5dae10..8c4c0f114 100644
--- a/rt/lib/RT/EmailParser.pm
+++ b/rt/lib/RT/EmailParser.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -123,7 +123,8 @@ sub SmartParseMIMEEntityFromScalar {
if ( -f $temp_file ) {
my $entity = $self->ParseMIMEEntityFromFile( $temp_file, $args{'Decode'}, $args{'Exact'} );
- unlink($temp_file);
+ unlink($temp_file)
+ or RT->Logger->error("Unable to delete temp file $temp_file, error: $!");
return $entity;
}
}
diff --git a/rt/lib/RT/Generated.pm.in b/rt/lib/RT/Generated.pm.in
index 3634e14ce..77a49d9a4 100644
--- a/rt/lib/RT/Generated.pm.in
+++ b/rt/lib/RT/Generated.pm.in
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Graph/Tickets.pm b/rt/lib/RT/Graph/Tickets.pm
index cd1254eb6..7dba4942e 100644
--- a/rt/lib/RT/Graph/Tickets.pm
+++ b/rt/lib/RT/Graph/Tickets.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Group.pm b/rt/lib/RT/Group.pm
index c412ba690..6fca91bbc 100755
--- a/rt/lib/RT/Group.pm
+++ b/rt/lib/RT/Group.pm
@@ -3,7 +3,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -1107,6 +1107,19 @@ sub _AddMember {
unless $ok;
}
+ # Record transactions for UserDefined groups
+ if ($args{RecordTransaction} && $self->Domain eq 'UserDefined') {
+ $new_member_obj->Object->_NewTransaction(
+ Type => 'AddMembership',
+ Field => $self->PrincipalObj->id,
+ );
+
+ $self->_NewTransaction(
+ Type => 'AddMember',
+ Field => $new_member,
+ );
+ }
+
# Record an Add/SetWatcher txn on the object if we're a role group
if ($args{RecordTransaction} and $self->RoleClass) {
my $obj = $args{Object} || $self->RoleGroupObject;
@@ -1312,6 +1325,19 @@ sub _DeleteMember {
}
}
+ # Record transactions for UserDefined groups
+ if ($args{RecordTransaction} && $self->Domain eq 'UserDefined') {
+ $member_obj->MemberObj->Object->_NewTransaction(
+ Type => 'DeleteMembership',
+ Field => $self->PrincipalObj->id,
+ );
+
+ $self->_NewTransaction(
+ Type => 'DeleteMember',
+ Field => $member_id,
+ );
+ }
+
return ( $val, $self->loc("Member deleted") );
}
@@ -1686,6 +1712,12 @@ sub __DependsOn {
);
push( @$list, $objs );
+# Cleanup group's membership transactions
+ $objs = RT::Transactions->new( $self->CurrentUser );
+ $objs->Limit( FIELD => 'Type', OPERATOR => 'IN', VALUE => ['AddMember', 'DeleteMember'] );
+ $objs->Limit( FIELD => 'Field', VALUE => $self->PrincipalObj->id, ENTRYAGGREGATOR => 'AND' );
+ push( @$list, $objs );
+
$deps->_PushDependencies(
BaseObject => $self,
Flags => RT::Shredder::Constants::DEPENDS_ON,
@@ -1741,13 +1773,12 @@ sub PreInflate {
return;
};
- # Go looking for the pre-existing version of the it
+ # Go looking for the pre-existing version of it
if ($data->{Domain} eq "ACLEquivalence") {
$obj->LoadACLEquivalenceGroup( $data->{Instance} );
return $duplicated->() if $obj->Id;
- # Update the name and description for the new ID
- $data->{Name} = 'User '. $data->{Instance};
+ # Update description for the new ID
$data->{Description} = 'ACL equiv. for user '.$data->{Instance};
} elsif ($data->{Domain} eq "UserDefined") {
$data->{Name} = $importer->Qualify($data->{Name});
diff --git a/rt/lib/RT/GroupMember.pm b/rt/lib/RT/GroupMember.pm
index 5f35a7fb9..4de4592e0 100755
--- a/rt/lib/RT/GroupMember.pm
+++ b/rt/lib/RT/GroupMember.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/GroupMembers.pm b/rt/lib/RT/GroupMembers.pm
index 0396c3772..b6f252da4 100755
--- a/rt/lib/RT/GroupMembers.pm
+++ b/rt/lib/RT/GroupMembers.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Groups.pm b/rt/lib/RT/Groups.pm
index 38ba82961..7ea42fd6e 100755
--- a/rt/lib/RT/Groups.pm
+++ b/rt/lib/RT/Groups.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Handle.pm b/rt/lib/RT/Handle.pm
index a990e9d89..f0bce38c1 100644
--- a/rt/lib/RT/Handle.pm
+++ b/rt/lib/RT/Handle.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/I18N.pm b/rt/lib/RT/I18N.pm
index 60a66222d..a1a03093e 100644
--- a/rt/lib/RT/I18N.pm
+++ b/rt/lib/RT/I18N.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -56,6 +56,7 @@ package RT::I18N;
use strict;
use warnings;
+use Cwd ();
use Locale::Maketext 1.04;
@@ -97,10 +98,10 @@ sub Init {
@lang = ('*') unless @lang;
# load default functions
- require substr(__FILE__, 0, -3) . '/i_default.pm';
+ require substr(Cwd::abs_path(__FILE__), 0, -3) . '/i_default.pm';
# Load language-specific functions
- foreach my $file ( File::Glob::bsd_glob(substr(__FILE__, 0, -3) . "/*.pm") ) {
+ foreach my $file ( File::Glob::bsd_glob(substr(Cwd::abs_path(__FILE__), 0, -3) . "/*.pm") ) {
my ($lang) = ($file =~ /([^\\\/]+?)\.pm$/);
next unless grep $_ eq '*' || $_ eq $lang, @lang;
require $file;
@@ -442,11 +443,9 @@ sub _DecodeMIMEWordsToEncoding {
$charset = _CanonicalizeCharset($charset);
$encoding = lc $encoding;
- $trailing =~ s/\s?\t?$//; # Observed from Outlook Express
-
if ( $encoding eq 'q' ) {
use MIME::QuotedPrint;
- $enc_str =~ tr/_/ /; # Observed from Outlook Express
+ $enc_str =~ tr/_/ /; # RFC 2047, 4.2 (2)
$enc_str = decode_qp($enc_str);
} elsif ( $encoding eq 'b' ) {
use MIME::Base64;
diff --git a/rt/lib/RT/I18N/cs.pm b/rt/lib/RT/I18N/cs.pm
index a8bda070f..618786f38 100644
--- a/rt/lib/RT/I18N/cs.pm
+++ b/rt/lib/RT/I18N/cs.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/I18N/de.pm b/rt/lib/RT/I18N/de.pm
index eb86566de..ed1de3799 100644
--- a/rt/lib/RT/I18N/de.pm
+++ b/rt/lib/RT/I18N/de.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/I18N/fr.pm b/rt/lib/RT/I18N/fr.pm
index 80ef0574b..f9eb7470c 100644
--- a/rt/lib/RT/I18N/fr.pm
+++ b/rt/lib/RT/I18N/fr.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/I18N/i_default.pm b/rt/lib/RT/I18N/i_default.pm
index 23db4a251..09fd35796 100644
--- a/rt/lib/RT/I18N/i_default.pm
+++ b/rt/lib/RT/I18N/i_default.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/I18N/ru.pm b/rt/lib/RT/I18N/ru.pm
index d666d7fda..b3f8b5bfd 100755
--- a/rt/lib/RT/I18N/ru.pm
+++ b/rt/lib/RT/I18N/ru.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Installer.pm b/rt/lib/RT/Installer.pm
index 5b43acee3..372c33d32 100644
--- a/rt/lib/RT/Installer.pm
+++ b/rt/lib/RT/Installer.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Interface/CLI.pm b/rt/lib/RT/Interface/CLI.pm
index ab9091593..d2b40cfa7 100644
--- a/rt/lib/RT/Interface/CLI.pm
+++ b/rt/lib/RT/Interface/CLI.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Interface/Email.pm b/rt/lib/RT/Interface/Email.pm
index 9bff8f6d1..60a903b67 100755
--- a/rt/lib/RT/Interface/Email.pm
+++ b/rt/lib/RT/Interface/Email.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -352,6 +352,32 @@ sub WillSignEncrypt {
return wantarray ? %args : ($args{Sign} || $args{Encrypt});
}
+sub _OutgoingMailFrom {
+ my $TicketObj = shift;
+
+ my $MailFrom = RT->Config->Get('SetOutgoingMailFrom');
+ my $OutgoingMailAddress = $MailFrom =~ /\@/ ? $MailFrom : undef;
+ my $Overrides = RT->Config->Get('OverrideOutgoingMailFrom') || {};
+
+ if ($TicketObj) {
+ my $Queue = $TicketObj->QueueObj;
+ my $QueueAddressOverride = $Overrides->{$Queue->id}
+ || $Overrides->{$Queue->Name};
+
+ if ($QueueAddressOverride) {
+ $OutgoingMailAddress = $QueueAddressOverride;
+ } else {
+ $OutgoingMailAddress ||= $Queue->CorrespondAddress
+ || RT->Config->Get('CorrespondAddress');
+ }
+ }
+ elsif ($Overrides->{'Default'}) {
+ $OutgoingMailAddress = $Overrides->{'Default'};
+ }
+
+ return $OutgoingMailAddress;
+}
+
sub SendEmail {
my (%args) = (
Entity => undef,
@@ -389,7 +415,18 @@ sub SendEmail {
if (my $precedence = RT->Config->Get('DefaultMailPrecedence')
and !$args{'Entity'}->head->get("Precedence")
) {
- $args{'Entity'}->head->replace( 'Precedence', Encode::encode("UTF-8",$precedence) );
+ if ($TicketObj) {
+ my $Overrides = RT->Config->Get('OverrideMailPrecedence') || {};
+ my $Queue = $TicketObj->QueueObj;
+
+ $precedence = $Overrides->{$Queue->id}
+ if exists $Overrides->{$Queue->id};
+ $precedence = $Overrides->{$Queue->Name}
+ if exists $Overrides->{$Queue->Name};
+ }
+
+ $args{'Entity'}->head->replace( 'Precedence', Encode::encode("UTF-8",$precedence) )
+ if $precedence;
}
if ( $TransactionObj && !$TicketObj
@@ -437,25 +474,8 @@ sub SendEmail {
# SetOutgoingMailFrom and bounces conflict, since they both want -f
if ( $args{'Bounce'} ) {
push @args, shellwords(RT->Config->Get('SendmailBounceArguments'));
- } elsif ( my $MailFrom = RT->Config->Get('SetOutgoingMailFrom') ) {
- my $OutgoingMailAddress = $MailFrom =~ /\@/ ? $MailFrom : undef;
- my $Overrides = RT->Config->Get('OverrideOutgoingMailFrom') || {};
-
- if ($TicketObj) {
- my $Queue = $TicketObj->QueueObj;
- my $QueueAddressOverride = $Overrides->{$Queue->id}
- || $Overrides->{$Queue->Name};
-
- if ($QueueAddressOverride) {
- $OutgoingMailAddress = $QueueAddressOverride;
- } else {
- $OutgoingMailAddress ||= $Queue->CorrespondAddress
- || RT->Config->Get('CorrespondAddress');
- }
- }
- elsif ($Overrides->{'Default'}) {
- $OutgoingMailAddress = $Overrides->{'Default'};
- }
+ } elsif ( RT->Config->Get('SetOutgoingMailFrom') ) {
+ my $OutgoingMailAddress = _OutgoingMailFrom($TicketObj);
push @args, "-f", $OutgoingMailAddress
if $OutgoingMailAddress;
@@ -523,7 +543,8 @@ sub SendEmail {
}
my $content = $args{Entity}->stringify;
$content =~ s/^(>*From )/>$1/mg;
- print $fh "From $ENV{USER}\@localhost ".localtime()."\n";
+ my $user = $ENV{USER} || getpwuid($<);
+ print $fh "From $user\@localhost ".localtime()."\n";
print $fh $content, "\n";
close $fh;
} else {
diff --git a/rt/lib/RT/Interface/Email/Auth/Crypt.pm b/rt/lib/RT/Interface/Email/Auth/Crypt.pm
index c56b6d203..f6d0e72b5 100644
--- a/rt/lib/RT/Interface/Email/Auth/Crypt.pm
+++ b/rt/lib/RT/Interface/Email/Auth/Crypt.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Interface/Email/Auth/MailFrom.pm b/rt/lib/RT/Interface/Email/Auth/MailFrom.pm
index 96e94cc2d..7774520ba 100644
--- a/rt/lib/RT/Interface/Email/Auth/MailFrom.pm
+++ b/rt/lib/RT/Interface/Email/Auth/MailFrom.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Interface/REST.pm b/rt/lib/RT/Interface/REST.pm
index 24c4bbae1..040679dd9 100644
--- a/rt/lib/RT/Interface/REST.pm
+++ b/rt/lib/RT/Interface/REST.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Interface/Web.pm b/rt/lib/RT/Interface/Web.pm
index f26afde35..af41e5ba6 100644
--- a/rt/lib/RT/Interface/Web.pm
+++ b/rt/lib/RT/Interface/Web.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -1436,7 +1436,7 @@ sub IsCompCSRFWhitelisted {
# golden. This acts on the presumption that external forms may
# hardcode a username and password -- if a malicious attacker knew
# both already, CSRF is the least of your problems.
- my $AllowLoginCSRF = not RT->Config->Get('RestrictReferrerLogin');
+ my $AllowLoginCSRF = not RT->Config->Get('RestrictLoginReferrer');
if ($AllowLoginCSRF and defined($args{user}) and defined($args{pass})) {
my $user_obj = RT::CurrentUser->new();
$user_obj->Load($args{user});
@@ -1653,7 +1653,7 @@ sub MaybeShowInterstitialCSRFPage {
my $token = StoreRequestToken($ARGS);
$HTML::Mason::Commands::m->comp(
'/Elements/CSRF',
- OriginalURL => RT->Config->Get('WebPath') . $HTML::Mason::Commands::r->path_info,
+ OriginalURL => RT->Config->Get('WebBaseURL') . RT->Config->Get('WebPath') . $HTML::Mason::Commands::r->path_info,
Reason => HTML::Mason::Commands::loc( $msg, @loc ),
Token => $token,
);
@@ -3099,6 +3099,9 @@ sub ProcessObjectCustomFieldUpdates {
$Object = $class->new( $session{'CurrentUser'} )
unless $Object && ref $Object eq $class;
+ # skip if we have no object to update
+ next unless $id || $Object->id;
+
$Object->Load($id) unless ( $Object->id || 0 ) == $id;
unless ( $Object->id ) {
$RT::Logger->warning("Couldn't load object $class #$id");
@@ -3150,14 +3153,21 @@ sub ProcessObjectCustomFieldUpdates {
sub _ParseObjectCustomFieldArgs {
my $ARGSRef = shift || {};
+ my %args = (
+ IncludeBulkUpdate => 0,
+ @_,
+ );
my %custom_fields_to_mod;
foreach my $arg ( keys %$ARGSRef ) {
# format: Object-<object class>-<object id>-CustomField[:<grouping>]-<CF id>-<commands>
- # or: Bulk-<Add or Delete>-CustomField[:<grouping>]-<CF id>-<commands>
# you can use GetCustomFieldInputName to generate the complement input name
- next unless $arg =~ /^(?:Bulk-(?:Add|Delete)|Object-([\w:]+)-(\d*))-CustomField(?::(\w+))?-(\d+)-(.*)$/;
+ # or if IncludeBulkUpdate: Bulk-<Add or Delete>-CustomField[:<grouping>]-<CF id>-<commands>
+ next unless $arg =~ /^Object-([\w:]+)-(\d*)-CustomField(?::(\w+))?-(\d+)-(.*)$/
+ || ($args{IncludeBulkUpdate} && $arg =~ /^Bulk-(?:Add|Delete)-()()CustomField(?::(\w+))?-(\d+)-(.*)$/);
+ # need two empty groups because we must consume $1 and $2 with empty
+ # class and ID
next if $1 eq 'RT::Transaction';# don't try to update transaction fields
diff --git a/rt/lib/RT/Interface/Web/Handler.pm b/rt/lib/RT/Interface/Web/Handler.pm
index ad1068bac..3355d297c 100644
--- a/rt/lib/RT/Interface/Web/Handler.pm
+++ b/rt/lib/RT/Interface/Web/Handler.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Interface/Web/Menu.pm b/rt/lib/RT/Interface/Web/Menu.pm
index 3d22a15de..0c1683d4a 100644
--- a/rt/lib/RT/Interface/Web/Menu.pm
+++ b/rt/lib/RT/Interface/Web/Menu.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -375,4 +375,52 @@ sub _insert_sibling {
$parent->child( @_, sort_order => $sort_order );
}
+=head2 RemoveDashboardMenuItems
+
+Remove dashboards from individual user and system dash menus.
+
+Requires a hash with DashboardId and CurrentUser object.
+
+ $menu->RemoveDashboardMenuItem( DashboardId => $id, CurrentUser => $session{CurrentUser}->UserObj );
+
+=cut
+
+sub RemoveDashboardMenuItem {
+ my $self = shift;
+ my %args = @_;
+
+ return unless $args{'DashboardId'} and $args{'CurrentUser'};
+ my $dashboard_id = $args{'DashboardId'};
+ my $current_user = $args{'CurrentUser'};
+
+ # First clear from user's dashboards
+ my $dashboards_in_menu = $current_user->Preferences('DashboardsInMenu', {} );
+
+ my @dashboards = grep { $_ != $dashboard_id } @{$dashboards_in_menu->{'dashboards'}};
+ $dashboards_in_menu->{'dashboards'} = \@dashboards || [];
+
+ my ($ret, $msg) = $current_user->SetPreferences('DashboardsInMenu', $dashboards_in_menu);
+ RT::Logger->warn("Unable to update dashboard for user " . $current_user->Name . ": $msg")
+ unless $ret;
+
+ # Now update the system dashboard
+ my $system = RT::System->new( $current_user );
+ my ($default_dashboards) = $system->Attributes->Named('DashboardsInMenu');
+
+ if ($default_dashboards) {
+ $dashboards_in_menu = $default_dashboards->Content;
+ my @dashboards = grep { $_ != $dashboard_id } @{$dashboards_in_menu->{'dashboards'}};
+
+ # Update only if we removed one
+ if ( @{$dashboards_in_menu->{'dashboards'}} > @dashboards ){
+ $dashboards_in_menu->{'dashboards'} = \@dashboards || [];
+
+ ($ret, $msg) = $default_dashboards->SetContent($dashboards_in_menu);
+ RT::Logger->warn("Unable to update system dashboard menu: $msg")
+ unless $ret;
+ }
+ }
+ return;
+}
+
1;
diff --git a/rt/lib/RT/Interface/Web/Middleware/StaticHeaders.pm b/rt/lib/RT/Interface/Web/Middleware/StaticHeaders.pm
index 22047782d..8f4b00fff 100644
--- a/rt/lib/RT/Interface/Web/Middleware/StaticHeaders.pm
+++ b/rt/lib/RT/Interface/Web/Middleware/StaticHeaders.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Interface/Web/QueryBuilder.pm b/rt/lib/RT/Interface/Web/QueryBuilder.pm
index 057835393..eaa584ba1 100755
--- a/rt/lib/RT/Interface/Web/QueryBuilder.pm
+++ b/rt/lib/RT/Interface/Web/QueryBuilder.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Interface/Web/QueryBuilder/Tree.pm b/rt/lib/RT/Interface/Web/QueryBuilder/Tree.pm
index efcc43f15..f12c478da 100755
--- a/rt/lib/RT/Interface/Web/QueryBuilder/Tree.pm
+++ b/rt/lib/RT/Interface/Web/QueryBuilder/Tree.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Interface/Web/Request.pm b/rt/lib/RT/Interface/Web/Request.pm
index a1520e026..1cd08df3e 100644
--- a/rt/lib/RT/Interface/Web/Request.pm
+++ b/rt/lib/RT/Interface/Web/Request.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Interface/Web/Session.pm b/rt/lib/RT/Interface/Web/Session.pm
index 027662a46..03cc325cd 100644
--- a/rt/lib/RT/Interface/Web/Session.pm
+++ b/rt/lib/RT/Interface/Web/Session.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Lifecycle.pm b/rt/lib/RT/Lifecycle.pm
index 0d6ddb0e0..97b82e1bd 100644
--- a/rt/lib/RT/Lifecycle.pm
+++ b/rt/lib/RT/Lifecycle.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Lifecycle/Ticket.pm b/rt/lib/RT/Lifecycle/Ticket.pm
index ab1c91cb7..81219f581 100644
--- a/rt/lib/RT/Lifecycle/Ticket.pm
+++ b/rt/lib/RT/Lifecycle/Ticket.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Link.pm b/rt/lib/RT/Link.pm
index 0dadc3be8..3160d24fb 100644
--- a/rt/lib/RT/Link.pm
+++ b/rt/lib/RT/Link.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -558,6 +558,27 @@ sub Serialize {
delete $store{LocalBase} if $store{Base};
delete $store{LocalTarget} if $store{Target};
+
+ for my $dir (qw/Base Target/) {
+ my $uri = $self->${\($dir.'URI')};
+ my $object = $self->${\($dir.'Obj')};
+
+ if ($uri->IsLocal) {
+ if ($args{serializer}->Observe(object => $object)) {
+ # no action needed; the object is being migrated
+ }
+ elsif ($args{serializer}{HyperlinkUnmigrated}) {
+ # object is not being migrated; hyperlinkify
+ $store{$dir} = $uri->AsHREF;
+ }
+ else {
+ # object is not being migrated and hyperlinks not desired,
+ # so drop this RT::Link altogether
+ return;
+ }
+ }
+ }
+
return %store;
}
diff --git a/rt/lib/RT/Links.pm b/rt/lib/RT/Links.pm
index 272b79360..d2ecca256 100644
--- a/rt/lib/RT/Links.pm
+++ b/rt/lib/RT/Links.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Migrate.pm b/rt/lib/RT/Migrate.pm
index ba59c3a32..e00efbd7f 100644
--- a/rt/lib/RT/Migrate.pm
+++ b/rt/lib/RT/Migrate.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Migrate/Importer.pm b/rt/lib/RT/Migrate/Importer.pm
index 789743493..c0faadecb 100644
--- a/rt/lib/RT/Migrate/Importer.pm
+++ b/rt/lib/RT/Migrate/Importer.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -65,17 +65,20 @@ sub new {
sub Init {
my $self = shift;
my %args = (
- OriginalId => undef,
- Progress => undef,
- Statefile => undef,
- DumpObjects => undef,
- HandleError => undef,
+ OriginalId => undef,
+ Progress => undef,
+ Statefile => undef,
+ DumpObjects => undef,
+ HandleError => undef,
+ ExcludeOrganization => undef,
@_,
);
# Should we attempt to preserve record IDs as they are created?
$self->{OriginalId} = $args{OriginalId};
+ $self->{ExcludeOrganization} = $args{ExcludeOrganization};
+
$self->{Progress} = $args{Progress};
$self->{HandleError} = sub { 0 };
@@ -179,6 +182,9 @@ sub Resolve {
Field => $ref->{uri},
Value => $self->LookupObj($uid)->URI,
) if defined $ref->{uri};
+ if (my $method = $ref->{method}) {
+ $obj->$method($self, $ref, $class, $id);
+ }
}
delete $self->{Pending}{$uid};
}
@@ -291,6 +297,7 @@ sub Qualify {
my ($string) = @_;
return $string if $self->{Clone};
return $string if not defined $self->{Organization};
+ return $string if $self->{ExcludeOrganization};
return $string if $self->{Organization} eq $RT::Organization;
return $self->{Organization}.": $string";
}
@@ -332,7 +339,7 @@ sub Create {
# Load it back to get real values into the columns
$obj = $class->new( RT->SystemUser );
$obj->Load( $id );
- $obj->PostInflate( $self );
+ $obj->PostInflate( $self, $uid );
return $obj;
}
@@ -399,9 +406,13 @@ sub ReadStream {
# If it's a ticket, we might need to create a
# TicketCustomField for the previous ID
if ($class eq "RT::Ticket" and $self->{OriginalId}) {
+ my $value = $self->{ExcludeOrganization}
+ ? $origid
+ : $self->Organization . ":$origid";
+
my ($id, $msg) = $obj->AddCustomFieldValue(
Field => $self->{OriginalId},
- Value => $self->Organization . ":$origid",
+ Value => $value,
RecordTransaction => 0,
);
warn "Failed to add custom field to $uid: $msg"
diff --git a/rt/lib/RT/Migrate/Importer/File.pm b/rt/lib/RT/Migrate/Importer/File.pm
index cfad9ae9e..cf3362b0d 100644
--- a/rt/lib/RT/Migrate/Importer/File.pm
+++ b/rt/lib/RT/Migrate/Importer/File.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -192,7 +192,7 @@ sub SaveState {
NewQueues NewCFs
SkipTransactions Pending Invalid
UIDs
- OriginalId Clone
+ OriginalId ExcludeOrganization Clone
/;
Storable::nstore(\%data, $self->{Statefile});
diff --git a/rt/lib/RT/Migrate/Incremental.pm b/rt/lib/RT/Migrate/Incremental.pm
index f4ea8d288..b1e5c877a 100644
--- a/rt/lib/RT/Migrate/Incremental.pm
+++ b/rt/lib/RT/Migrate/Incremental.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Migrate/Serializer.pm b/rt/lib/RT/Migrate/Serializer.pm
index f938bc145..3855ee9e2 100644
--- a/rt/lib/RT/Migrate/Serializer.pm
+++ b/rt/lib/RT/Migrate/Serializer.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -58,6 +58,7 @@ sub cmp_version($$) { RT::Handle::cmp_version($_[0],$_[1]) };
use RT::Migrate::Incremental;
use RT::Migrate::Serializer::IncrementalRecord;
use RT::Migrate::Serializer::IncrementalRecords;
+use List::MoreUtils 'none';
sub Init {
my $self = shift;
@@ -88,6 +89,9 @@ sub Init {
FollowScrips
FollowTickets
FollowACL
+ Queues
+ CustomFields
+ HyperlinkUnmigrated
Clone
Incremental
/;
@@ -251,6 +255,11 @@ sub PushBasics {
OPERATOR => 'IN',
VALUE => [ qw/RT::User RT::Group RT::Queue/ ],
);
+
+ if ($self->{CustomFields}) {
+ $cfs->Limit(FIELD => 'id', OPERATOR => 'IN', VALUE => $self->{CustomFields});
+ }
+
$self->PushObj( $cfs );
# Global attributes
@@ -293,7 +302,14 @@ sub PushBasics {
$self->PushCollections(qw(Topics Classes));
}
- $self->PushCollections(qw(Queues));
+ if ($self->{Queues}) {
+ my $queues = RT::Queues->new(RT->SystemUser);
+ $queues->Limit(FIELD => 'id', OPERATOR => 'IN', VALUE => $self->{Queues});
+ $self->PushObj($queues);
+ }
+ else {
+ $self->PushCollections(qw(Queues));
+ }
}
sub InitStream {
@@ -400,7 +416,25 @@ sub Observe {
my $from = $args{from};
if ($obj->isa("RT::Ticket")) {
return 0 if $obj->Status eq "deleted" and not $self->{FollowDeleted};
+ my $queue = $obj->Queue;
+ return 0 if $self->{Queues} && none { $queue == $_ } @{ $self->{Queues} };
return $self->{FollowTickets};
+ } elsif ($obj->isa("RT::Queue")) {
+ my $id = $obj->Id;
+ return 0 if $self->{Queues} && none { $id == $_ } @{ $self->{Queues} };
+ return 1;
+ } elsif ($obj->isa("RT::CustomField")) {
+ my $id = $obj->Id;
+ return 0 if $self->{CustomFields} && none { $id == $_ } @{ $self->{CustomFields} };
+ return 1;
+ } elsif ($obj->isa("RT::ObjectCustomFieldValue")) {
+ my $id = $obj->CustomField;
+ return 0 if $self->{CustomFields} && none { $id == $_ } @{ $self->{CustomFields} };
+ return 1;
+ } elsif ($obj->isa("RT::ObjectCustomField")) {
+ my $id = $obj->CustomField;
+ return 0 if $self->{CustomFields} && none { $id == $_ } @{ $self->{CustomFields} };
+ return 1;
} elsif ($obj->isa("RT::ACE")) {
return $self->{FollowACL};
} elsif ($obj->isa("RT::Scrip") or $obj->isa("RT::Template") or $obj->isa("RT::ObjectScrip")) {
@@ -473,10 +507,13 @@ sub Visit {
\%data,
);
} else {
+ my %serialized = $obj->Serialize(serializer => $self);
+ return unless %serialized;
+
@store = (
ref($obj),
$obj->UID,
- { $obj->Serialize },
+ \%serialized,
);
}
diff --git a/rt/lib/RT/Migrate/Serializer/File.pm b/rt/lib/RT/Migrate/Serializer/File.pm
index c8642eab0..f5f503e74 100644
--- a/rt/lib/RT/Migrate/Serializer/File.pm
+++ b/rt/lib/RT/Migrate/Serializer/File.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Migrate/Serializer/IncrementalRecord.pm b/rt/lib/RT/Migrate/Serializer/IncrementalRecord.pm
index 4bbd4e8b6..111acf61a 100644
--- a/rt/lib/RT/Migrate/Serializer/IncrementalRecord.pm
+++ b/rt/lib/RT/Migrate/Serializer/IncrementalRecord.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Migrate/Serializer/IncrementalRecords.pm b/rt/lib/RT/Migrate/Serializer/IncrementalRecords.pm
index 3bb19c647..e3f530074 100644
--- a/rt/lib/RT/Migrate/Serializer/IncrementalRecords.pm
+++ b/rt/lib/RT/Migrate/Serializer/IncrementalRecords.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/ObjectClass.pm b/rt/lib/RT/ObjectClass.pm
index c51d9d4c8..3da8eafe8 100644
--- a/rt/lib/RT/ObjectClass.pm
+++ b/rt/lib/RT/ObjectClass.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -229,6 +229,18 @@ sub FindDependencies {
$deps->Add( out => $obj );
}
+sub Serialize {
+ my $self = shift;
+ my %args = (@_);
+ my %store = $self->SUPER::Serialize(@_);
+
+ if ($store{ObjectId}) {
+ my $obj = $self->ObjectType->new( RT->SystemUser );
+ $obj->Load( $store{ObjectId} );
+ $store{ObjectId} = \($obj->UID);
+ }
+ return %store;
+}
RT::Base->_ImportOverlays();
diff --git a/rt/lib/RT/ObjectClasses.pm b/rt/lib/RT/ObjectClasses.pm
index 96442a4b8..38f0216df 100644
--- a/rt/lib/RT/ObjectClasses.pm
+++ b/rt/lib/RT/ObjectClasses.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/ObjectCustomField.pm b/rt/lib/RT/ObjectCustomField.pm
index b9749aa4e..b2a8eef58 100644
--- a/rt/lib/RT/ObjectCustomField.pm
+++ b/rt/lib/RT/ObjectCustomField.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/ObjectCustomFieldValue.pm b/rt/lib/RT/ObjectCustomFieldValue.pm
index 6a49f3832..9af328a2f 100644
--- a/rt/lib/RT/ObjectCustomFieldValue.pm
+++ b/rt/lib/RT/ObjectCustomFieldValue.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/ObjectCustomFieldValues.pm b/rt/lib/RT/ObjectCustomFieldValues.pm
index b1cf3caa2..4ea660ca5 100644
--- a/rt/lib/RT/ObjectCustomFieldValues.pm
+++ b/rt/lib/RT/ObjectCustomFieldValues.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -50,6 +50,7 @@ package RT::ObjectCustomFieldValues;
use strict;
use warnings;
+use 5.010;
use base 'RT::SearchBuilder';
@@ -145,7 +146,7 @@ sub HasEntry {
return $item if lc $item->Content eq lc $args->{Content};
}
else {
- if ( ($item->_Value('Content') || '') eq $args->{Content} ) {
+ if ( ($item->_Value('Content') // '') eq $args->{Content} ) {
if ( defined $item->LargeContent ) {
return $item
if defined $args->{LargeContent}
diff --git a/rt/lib/RT/ObjectCustomFields.pm b/rt/lib/RT/ObjectCustomFields.pm
index 8dafe4c43..b563fe901 100644
--- a/rt/lib/RT/ObjectCustomFields.pm
+++ b/rt/lib/RT/ObjectCustomFields.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/ObjectScrip.pm b/rt/lib/RT/ObjectScrip.pm
index 839939871..495dcfd43 100644
--- a/rt/lib/RT/ObjectScrip.pm
+++ b/rt/lib/RT/ObjectScrip.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -272,6 +272,19 @@ sub FindDependencies {
}
}
+sub Serialize {
+ my $self = shift;
+ my %args = (@_);
+ my %store = $self->SUPER::Serialize(@_);
+
+ if ($store{ObjectId}) {
+ my $obj = RT::Queue->new( RT->SystemUser );
+ $obj->Load( $store{ObjectId} );
+ $store{ObjectId} = \($obj->UID);
+ }
+ return %store;
+}
+
RT::Base->_ImportOverlays();
1;
diff --git a/rt/lib/RT/ObjectScrips.pm b/rt/lib/RT/ObjectScrips.pm
index 40eca8a09..960598cbe 100644
--- a/rt/lib/RT/ObjectScrips.pm
+++ b/rt/lib/RT/ObjectScrips.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/ObjectTopic.pm b/rt/lib/RT/ObjectTopic.pm
index c9429fd1b..732af3e71 100644
--- a/rt/lib/RT/ObjectTopic.pm
+++ b/rt/lib/RT/ObjectTopic.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -212,6 +212,19 @@ sub FindDependencies {
$deps->Add( out => $obj );
}
+sub Serialize {
+ my $self = shift;
+ my %args = (@_);
+ my %store = $self->SUPER::Serialize(@_);
+
+ if ($store{ObjectId}) {
+ my $obj = $self->ObjectType->new( RT->SystemUser );
+ $obj->Load( $store{ObjectId} );
+ $store{ObjectId} = \($obj->UID);
+ }
+ return %store;
+}
+
RT::Base->_ImportOverlays();
1;
diff --git a/rt/lib/RT/ObjectTopics.pm b/rt/lib/RT/ObjectTopics.pm
index dcbda6cc1..058527b04 100644
--- a/rt/lib/RT/ObjectTopics.pm
+++ b/rt/lib/RT/ObjectTopics.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/PlackRunner.pm b/rt/lib/RT/PlackRunner.pm
index e30f4bd2f..16eed5c0e 100644
--- a/rt/lib/RT/PlackRunner.pm
+++ b/rt/lib/RT/PlackRunner.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Plugin.pm b/rt/lib/RT/Plugin.pm
index d10f639b3..76af07903 100644
--- a/rt/lib/RT/Plugin.pm
+++ b/rt/lib/RT/Plugin.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -84,6 +84,17 @@ sub Name {
return $self->{name};
}
+=head2 Version
+
+Returns the extension version.
+
+=cut
+
+sub Version {
+ my $self = shift;
+ return $self->Name->VERSION;
+}
+
=head2 Path
Takes a name of sub directory and returns its full path, for example:
diff --git a/rt/lib/RT/Pod/HTML.pm b/rt/lib/RT/Pod/HTML.pm
index d38a882c8..6b69901b1 100644
--- a/rt/lib/RT/Pod/HTML.pm
+++ b/rt/lib/RT/Pod/HTML.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Pod/HTMLBatch.pm b/rt/lib/RT/Pod/HTMLBatch.pm
index ed6f3aac7..231687d03 100644
--- a/rt/lib/RT/Pod/HTMLBatch.pm
+++ b/rt/lib/RT/Pod/HTMLBatch.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Pod/Search.pm b/rt/lib/RT/Pod/Search.pm
index d04c67ca0..47af29833 100644
--- a/rt/lib/RT/Pod/Search.pm
+++ b/rt/lib/RT/Pod/Search.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Principal.pm b/rt/lib/RT/Principal.pm
index 341a90c72..9fc4be5f2 100644
--- a/rt/lib/RT/Principal.pm
+++ b/rt/lib/RT/Principal.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Principals.pm b/rt/lib/RT/Principals.pm
index b909d2499..97f51f00e 100644
--- a/rt/lib/RT/Principals.pm
+++ b/rt/lib/RT/Principals.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Queue.pm b/rt/lib/RT/Queue.pm
index f8c0791a6..c1492385f 100755
--- a/rt/lib/RT/Queue.pm
+++ b/rt/lib/RT/Queue.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Queues.pm b/rt/lib/RT/Queues.pm
index e872cfd69..d36b24d05 100755
--- a/rt/lib/RT/Queues.pm
+++ b/rt/lib/RT/Queues.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Record.pm b/rt/lib/RT/Record.pm
index 4722d8660..1818c2d48 100755
--- a/rt/lib/RT/Record.pm
+++ b/rt/lib/RT/Record.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Record/AddAndSort.pm b/rt/lib/RT/Record/AddAndSort.pm
index 66f7ef5b9..cbacf270a 100644
--- a/rt/lib/RT/Record/AddAndSort.pm
+++ b/rt/lib/RT/Record/AddAndSort.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Record/Role.pm b/rt/lib/RT/Record/Role.pm
index d3484efef..eddc10e27 100644
--- a/rt/lib/RT/Record/Role.pm
+++ b/rt/lib/RT/Record/Role.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Record/Role/Lifecycle.pm b/rt/lib/RT/Record/Role/Lifecycle.pm
index 3cc92cb92..631c01bc6 100644
--- a/rt/lib/RT/Record/Role/Lifecycle.pm
+++ b/rt/lib/RT/Record/Role/Lifecycle.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Record/Role/Links.pm b/rt/lib/RT/Record/Role/Links.pm
index 5836433cb..59ee737ef 100644
--- a/rt/lib/RT/Record/Role/Links.pm
+++ b/rt/lib/RT/Record/Role/Links.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Record/Role/Rights.pm b/rt/lib/RT/Record/Role/Rights.pm
index fd3cac26f..108cbf81f 100644
--- a/rt/lib/RT/Record/Role/Rights.pm
+++ b/rt/lib/RT/Record/Role/Rights.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Record/Role/Roles.pm b/rt/lib/RT/Record/Role/Roles.pm
index 5f20a6337..fc2b9e87a 100644
--- a/rt/lib/RT/Record/Role/Roles.pm
+++ b/rt/lib/RT/Record/Role/Roles.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Record/Role/Status.pm b/rt/lib/RT/Record/Role/Status.pm
index 0fbce9f3e..602903862 100644
--- a/rt/lib/RT/Record/Role/Status.pm
+++ b/rt/lib/RT/Record/Role/Status.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Reminders.pm b/rt/lib/RT/Reminders.pm
index 2baab0113..fed03bc74 100644
--- a/rt/lib/RT/Reminders.pm
+++ b/rt/lib/RT/Reminders.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Report/Tickets.pm b/rt/lib/RT/Report/Tickets.pm
index 06b34f716..cd74e1cac 100644
--- a/rt/lib/RT/Report/Tickets.pm
+++ b/rt/lib/RT/Report/Tickets.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Report/Tickets/Entry.pm b/rt/lib/RT/Report/Tickets/Entry.pm
index 67017e8e5..58db2d302 100644
--- a/rt/lib/RT/Report/Tickets/Entry.pm
+++ b/rt/lib/RT/Report/Tickets/Entry.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Rule.pm b/rt/lib/RT/Rule.pm
index dda86fe18..05a8fe9ee 100644
--- a/rt/lib/RT/Rule.pm
+++ b/rt/lib/RT/Rule.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Ruleset.pm b/rt/lib/RT/Ruleset.pm
index acf1bf1e0..3966eb7bd 100644
--- a/rt/lib/RT/Ruleset.pm
+++ b/rt/lib/RT/Ruleset.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/SQL.pm b/rt/lib/RT/SQL.pm
index f470a91f1..6b6bafd73 100644
--- a/rt/lib/RT/SQL.pm
+++ b/rt/lib/RT/SQL.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/SavedSearch.pm b/rt/lib/RT/SavedSearch.pm
index d9bb69203..8bb1452d2 100644
--- a/rt/lib/RT/SavedSearch.pm
+++ b/rt/lib/RT/SavedSearch.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/SavedSearches.pm b/rt/lib/RT/SavedSearches.pm
index 734c946e8..ba18c9913 100644
--- a/rt/lib/RT/SavedSearches.pm
+++ b/rt/lib/RT/SavedSearches.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Scrip.pm b/rt/lib/RT/Scrip.pm
index 48547ccfd..9d901bad2 100755
--- a/rt/lib/RT/Scrip.pm
+++ b/rt/lib/RT/Scrip.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/ScripAction.pm b/rt/lib/RT/ScripAction.pm
index 712b10900..6cd758b44 100755
--- a/rt/lib/RT/ScripAction.pm
+++ b/rt/lib/RT/ScripAction.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/ScripActions.pm b/rt/lib/RT/ScripActions.pm
index 5735689e7..be0b55cd1 100755
--- a/rt/lib/RT/ScripActions.pm
+++ b/rt/lib/RT/ScripActions.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/ScripCondition.pm b/rt/lib/RT/ScripCondition.pm
index c93b6065d..b88612db4 100755
--- a/rt/lib/RT/ScripCondition.pm
+++ b/rt/lib/RT/ScripCondition.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/ScripConditions.pm b/rt/lib/RT/ScripConditions.pm
index 51a03a654..9e6890c83 100755
--- a/rt/lib/RT/ScripConditions.pm
+++ b/rt/lib/RT/ScripConditions.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Scrips.pm b/rt/lib/RT/Scrips.pm
index 193399d8c..3ec563b65 100755
--- a/rt/lib/RT/Scrips.pm
+++ b/rt/lib/RT/Scrips.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Search.pm b/rt/lib/RT/Search.pm
index 022819bae..160f3f3c2 100755
--- a/rt/lib/RT/Search.pm
+++ b/rt/lib/RT/Search.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Search/ActiveTicketsInQueue.pm b/rt/lib/RT/Search/ActiveTicketsInQueue.pm
index 6477632a4..68c424910 100644
--- a/rt/lib/RT/Search/ActiveTicketsInQueue.pm
+++ b/rt/lib/RT/Search/ActiveTicketsInQueue.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Search/FromSQL.pm b/rt/lib/RT/Search/FromSQL.pm
index 59679cf8f..a6284f5d4 100644
--- a/rt/lib/RT/Search/FromSQL.pm
+++ b/rt/lib/RT/Search/FromSQL.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Search/Simple.pm b/rt/lib/RT/Search/Simple.pm
index ac7b226b8..15b426ec3 100644
--- a/rt/lib/RT/Search/Simple.pm
+++ b/rt/lib/RT/Search/Simple.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/SearchBuilder.pm b/rt/lib/RT/SearchBuilder.pm
index 8b4596795..0d6e36f58 100644
--- a/rt/lib/RT/SearchBuilder.pm
+++ b/rt/lib/RT/SearchBuilder.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/SearchBuilder/AddAndSort.pm b/rt/lib/RT/SearchBuilder/AddAndSort.pm
index 90720f6b7..6a170a225 100644
--- a/rt/lib/RT/SearchBuilder/AddAndSort.pm
+++ b/rt/lib/RT/SearchBuilder/AddAndSort.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/SearchBuilder/Role.pm b/rt/lib/RT/SearchBuilder/Role.pm
index cf41522b3..231147b97 100644
--- a/rt/lib/RT/SearchBuilder/Role.pm
+++ b/rt/lib/RT/SearchBuilder/Role.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/SearchBuilder/Role/Roles.pm b/rt/lib/RT/SearchBuilder/Role/Roles.pm
index 7e205a0ee..327cd49ff 100644
--- a/rt/lib/RT/SearchBuilder/Role/Roles.pm
+++ b/rt/lib/RT/SearchBuilder/Role/Roles.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/SharedSetting.pm b/rt/lib/RT/SharedSetting.pm
index 6d0e29f30..30f9e099c 100644
--- a/rt/lib/RT/SharedSetting.pm
+++ b/rt/lib/RT/SharedSetting.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/SharedSettings.pm b/rt/lib/RT/SharedSettings.pm
index 5b1531731..1af114f4a 100644
--- a/rt/lib/RT/SharedSettings.pm
+++ b/rt/lib/RT/SharedSettings.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Shredder.pm b/rt/lib/RT/Shredder.pm
index 9590edba4..108164d44 100644
--- a/rt/lib/RT/Shredder.pm
+++ b/rt/lib/RT/Shredder.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Shredder/Constants.pm b/rt/lib/RT/Shredder/Constants.pm
index 11a1731dc..189787f26 100644
--- a/rt/lib/RT/Shredder/Constants.pm
+++ b/rt/lib/RT/Shredder/Constants.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Shredder/Dependencies.pm b/rt/lib/RT/Shredder/Dependencies.pm
index b0e620e47..f74e7ab33 100644
--- a/rt/lib/RT/Shredder/Dependencies.pm
+++ b/rt/lib/RT/Shredder/Dependencies.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Shredder/Dependency.pm b/rt/lib/RT/Shredder/Dependency.pm
index 63ee8ea8c..c0997e91a 100644
--- a/rt/lib/RT/Shredder/Dependency.pm
+++ b/rt/lib/RT/Shredder/Dependency.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Shredder/Exceptions.pm b/rt/lib/RT/Shredder/Exceptions.pm
index 7d44300cf..3c1fbc7fa 100644
--- a/rt/lib/RT/Shredder/Exceptions.pm
+++ b/rt/lib/RT/Shredder/Exceptions.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Shredder/POD.pm b/rt/lib/RT/Shredder/POD.pm
index 26e4aad62..5435e26e2 100644
--- a/rt/lib/RT/Shredder/POD.pm
+++ b/rt/lib/RT/Shredder/POD.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Shredder/Plugin.pm b/rt/lib/RT/Shredder/Plugin.pm
index c9eb86c9d..78ea13188 100644
--- a/rt/lib/RT/Shredder/Plugin.pm
+++ b/rt/lib/RT/Shredder/Plugin.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Shredder/Plugin/Attachments.pm b/rt/lib/RT/Shredder/Plugin/Attachments.pm
index 42518b5c0..7c63e1208 100644
--- a/rt/lib/RT/Shredder/Plugin/Attachments.pm
+++ b/rt/lib/RT/Shredder/Plugin/Attachments.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Shredder/Plugin/Base.pm b/rt/lib/RT/Shredder/Plugin/Base.pm
index be36cdc3f..c8bb4e09c 100644
--- a/rt/lib/RT/Shredder/Plugin/Base.pm
+++ b/rt/lib/RT/Shredder/Plugin/Base.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Shredder/Plugin/Base/Dump.pm b/rt/lib/RT/Shredder/Plugin/Base/Dump.pm
index 707096ec9..bc0ba4c22 100644
--- a/rt/lib/RT/Shredder/Plugin/Base/Dump.pm
+++ b/rt/lib/RT/Shredder/Plugin/Base/Dump.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Shredder/Plugin/Base/Search.pm b/rt/lib/RT/Shredder/Plugin/Base/Search.pm
index 26e3d160a..65a42d575 100644
--- a/rt/lib/RT/Shredder/Plugin/Base/Search.pm
+++ b/rt/lib/RT/Shredder/Plugin/Base/Search.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Shredder/Plugin/Objects.pm b/rt/lib/RT/Shredder/Plugin/Objects.pm
index 7e2aa7a60..876361771 100644
--- a/rt/lib/RT/Shredder/Plugin/Objects.pm
+++ b/rt/lib/RT/Shredder/Plugin/Objects.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Shredder/Plugin/SQLDump.pm b/rt/lib/RT/Shredder/Plugin/SQLDump.pm
index 4e29737f5..2d1011573 100644
--- a/rt/lib/RT/Shredder/Plugin/SQLDump.pm
+++ b/rt/lib/RT/Shredder/Plugin/SQLDump.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Shredder/Plugin/Summary.pm b/rt/lib/RT/Shredder/Plugin/Summary.pm
index 4dbfb9417..33bff3d67 100644
--- a/rt/lib/RT/Shredder/Plugin/Summary.pm
+++ b/rt/lib/RT/Shredder/Plugin/Summary.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Shredder/Plugin/Tickets.pm b/rt/lib/RT/Shredder/Plugin/Tickets.pm
index 0e2af36c0..9df85c529 100644
--- a/rt/lib/RT/Shredder/Plugin/Tickets.pm
+++ b/rt/lib/RT/Shredder/Plugin/Tickets.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Shredder/Plugin/Users.pm b/rt/lib/RT/Shredder/Plugin/Users.pm
index 0073a9e97..75f6a5718 100644
--- a/rt/lib/RT/Shredder/Plugin/Users.pm
+++ b/rt/lib/RT/Shredder/Plugin/Users.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Squish.pm b/rt/lib/RT/Squish.pm
index f580221af..a88e4ea78 100644
--- a/rt/lib/RT/Squish.pm
+++ b/rt/lib/RT/Squish.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Squish/CSS.pm b/rt/lib/RT/Squish/CSS.pm
index d22b03747..c21086341 100644
--- a/rt/lib/RT/Squish/CSS.pm
+++ b/rt/lib/RT/Squish/CSS.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Squish/JS.pm b/rt/lib/RT/Squish/JS.pm
index 18dd9a770..c1c9118da 100644
--- a/rt/lib/RT/Squish/JS.pm
+++ b/rt/lib/RT/Squish/JS.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/StyleGuide.pod b/rt/lib/RT/StyleGuide.pod
index 3a7556292..f6734ae80 100644
--- a/rt/lib/RT/StyleGuide.pod
+++ b/rt/lib/RT/StyleGuide.pod
@@ -20,7 +20,8 @@ degree to any Perl code written for use in RT.
Note that these are all guidelines, not unbreakable rules. If you have
a really good need to break one of the rules herein, however, then it is
-best to ask on the B<rt-devel> mailing list first.
+best to first start a discussion in the RT Developers category on the community
+forum at L<https://forum.bestpractical.com>.
Note that with much of this document, it is not so much the Right Way as
it is Our Way. We need to have conventions in order to make life easier
@@ -28,10 +29,6 @@ for everyone. So don't gripe, and just follow it, because you didn't
get a good grade in "Plays Well With Others" in kindergarten and you
want to make up for it now.
-If you have any questions, please ask us on the B<rt-devel> mailing list:
-
- http://www.bestpractical.com/rt/lists.html
-
We don't always follow this guide. We are making changes throughout
our code to be in line with it. But just because we didn't do
it yet, that is no excuse. Do it anyway. :-)
@@ -723,7 +720,7 @@ This is for new programs, modules, specific APIs, or anything else.
=over 4
-=item Present idea to rt-devel
+=item Create a topic in RT Developers on the Forum
We may know of a better way to approach the problem, or know of an
existing way to deal with it, or know someone else is working on it.
@@ -731,11 +728,11 @@ This is mostly informal, but a fairly complete explanation for the need
and use of the code should be provided.
-=item Present complete specs to rt-devel
+=item Present specs in RT Developers
The complete proposed API should be submitted for
-approval and discussion. For web and command-line programs, present the
-functionality and interface (op codes, command-lin switches, etc.).
+discussion. For web and command-line programs, present the
+functionality and interface (op codes, command-line switches, etc.).
The best way to do this is to take the documentation portion of the
boilerplate and fill it in. You can make changes later if necessary,
@@ -760,9 +757,10 @@ guide contained in this document.
=item Finish it up
After the code is done (possibly going through multiple code reviews),
-if you do not have repository access, submit it to rt-bugs@fsck.com as a
-unified diff. From that point on, it'll be handled by someone with
-repository access.
+submit your updates as a pull request on GitHub. If you don't have a GitHub
+account, you can generate patches and send email to rt-bugs@bestpractical.com
+which will create a ticket in our public issue tracker at
+L<https://issues.bestpractical.com>.
=back
diff --git a/rt/lib/RT/System.pm b/rt/lib/RT/System.pm
index af7a22bbb..fdbc8a6b8 100644
--- a/rt/lib/RT/System.pm
+++ b/rt/lib/RT/System.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Template.pm b/rt/lib/RT/Template.pm
index b8aa0aac4..13fdb5ee5 100755
--- a/rt/lib/RT/Template.pm
+++ b/rt/lib/RT/Template.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Templates.pm b/rt/lib/RT/Templates.pm
index 67f4783c6..c5a49fe44 100755
--- a/rt/lib/RT/Templates.pm
+++ b/rt/lib/RT/Templates.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Test.pm b/rt/lib/RT/Test.pm
index 257eea5b7..69019f6fe 100644
--- a/rt/lib/RT/Test.pm
+++ b/rt/lib/RT/Test.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -1733,7 +1733,9 @@ sub parse_mail {
require RT::EmailParser;
my $parser = RT::EmailParser->new;
$parser->ParseMIMEEntityFromScalar( $mail );
- return $parser->Entity;
+ my $entity = $parser->Entity;
+ $entity->{__store_link_to_object_to_avoid_early_cleanup} = $parser;
+ return $entity;
}
sub works {
diff --git a/rt/lib/RT/Test/Apache.pm b/rt/lib/RT/Test/Apache.pm
index e7e3cdd11..7dc308330 100644
--- a/rt/lib/RT/Test/Apache.pm
+++ b/rt/lib/RT/Test/Apache.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Test/Email.pm b/rt/lib/RT/Test/Email.pm
index 0a44aee3e..c407592ac 100644
--- a/rt/lib/RT/Test/Email.pm
+++ b/rt/lib/RT/Test/Email.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Test/GnuPG.pm b/rt/lib/RT/Test/GnuPG.pm
index e5a08b75a..d803399e0 100644
--- a/rt/lib/RT/Test/GnuPG.pm
+++ b/rt/lib/RT/Test/GnuPG.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -64,9 +64,9 @@ sub import {
my %args = @_;
my $t = $class->builder;
- $t->plan( skip_all => 'GnuPG required.' )
+ RT::Test::plan( skip_all => 'GnuPG required.' )
unless GnuPG::Interface->require;
- $t->plan( skip_all => 'gpg executable is required.' )
+ RT::Test::plan( skip_all => 'gpg executable is required.' )
unless RT::Test->find_executable('gpg');
$class->SUPER::import(%args);
@@ -204,13 +204,17 @@ sub check_text_emails {
my $content = $type eq 'email'
? "Some content"
- : "Attachment content";
+ : $args{Attachment};
if ( $args{'Encrypt'} ) {
- unlike $mail, qr/$content/, "outgoing $type was encrypted";
+ unlike $mail, qr/$content/, "outgoing $type is not in plaintext";
+ my $entity = RT::Test::parse_mail($mail);
+ my @res = RT::Crypt->VerifyDecrypt(Entity => $entity);
+ like $res[0]{'status'}, qr/DECRYPTION_OKAY/, "Decrypts OK";
+ like $entity->as_string, qr/$content/, "outgoing decrypts to contain $type content";
} else {
like $mail, qr/$content/, "outgoing $type was not encrypted";
- }
+ }
next unless $type eq 'email';
diff --git a/rt/lib/RT/Test/SMIME.pm b/rt/lib/RT/Test/SMIME.pm
index 36b436202..cc5a5ee4c 100644
--- a/rt/lib/RT/Test/SMIME.pm
+++ b/rt/lib/RT/Test/SMIME.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -61,7 +61,7 @@ sub import {
my %args = @_;
my $t = $class->builder;
- $t->plan( skip_all => 'openssl executable is required.' )
+ RT::Test::plan( skip_all => 'openssl executable is required.' )
unless RT::Test->find_executable('openssl');
require RT::Crypt;
diff --git a/rt/lib/RT/Test/Shredder.pm b/rt/lib/RT/Test/Shredder.pm
index 4ee0b3589..44a2fb39f 100644
--- a/rt/lib/RT/Test/Shredder.pm
+++ b/rt/lib/RT/Test/Shredder.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Test/Web.pm b/rt/lib/RT/Test/Web.pm
index b03e82227..ab1a421db 100644
--- a/rt/lib/RT/Test/Web.pm
+++ b/rt/lib/RT/Test/Web.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Ticket.pm b/rt/lib/RT/Ticket.pm
index ff75f450d..002d3232e 100755
--- a/rt/lib/RT/Ticket.pm
+++ b/rt/lib/RT/Ticket.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -762,13 +762,14 @@ sub DeleteWatcher {
-=head2 SquelchMailTo [EMAIL]
+=head2 SquelchMailTo ADDRESSES
-Takes an optional email address to never email about updates to this ticket.
-
-
-Returns an array of the RT::Attribute objects for this ticket's 'SquelchMailTo' attributes.
+Takes a list of email addresses to never email about updates to this ticket.
+Subsequent calls to this method add, rather than replace, the list of
+squelched addresses.
+Returns an array of the L<RT::Attribute> objects for this ticket's
+'SquelchMailTo' attributes.
=cut
@@ -789,7 +790,7 @@ sub SquelchMailTo {
sub _SquelchMailTo {
my $self = shift;
- if (@_) {
+ while (@_) {
my $attr = shift;
$self->AddAttribute( Name => 'SquelchMailTo', Content => $attr )
unless grep { $_->Content eq $attr }
@@ -1103,6 +1104,11 @@ sub TransactionAddresses {
$attachments->Columns( qw( id Headers TransactionId));
$attachments->Limit(
+ FIELD => 'Parent',
+ VALUE => 0,
+ );
+
+ $attachments->Limit(
ALIAS => $attachments->TransactionAlias,
FIELD => 'Type',
OPERATOR => 'IN',
diff --git a/rt/lib/RT/Tickets.pm b/rt/lib/RT/Tickets.pm
index 7bdbce4ef..521f4ae2b 100755
--- a/rt/lib/RT/Tickets.pm
+++ b/rt/lib/RT/Tickets.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Topic.pm b/rt/lib/RT/Topic.pm
index 4345b3db2..556cb78dc 100644
--- a/rt/lib/RT/Topic.pm
+++ b/rt/lib/RT/Topic.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Topics.pm b/rt/lib/RT/Topics.pm
index b5082cebd..0ae885a42 100644
--- a/rt/lib/RT/Topics.pm
+++ b/rt/lib/RT/Topics.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Transaction.pm b/rt/lib/RT/Transaction.pm
index 44175d49f..64c27c0e7 100755
--- a/rt/lib/RT/Transaction.pm
+++ b/rt/lib/RT/Transaction.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -1316,7 +1316,43 @@ sub _FormatUser {
} else {
return ("Reminder completed"); #loc()
}
- }
+ },
+ AddMember => sub {
+ my $self = shift;
+ my $principal = RT::Principal->new($self->CurrentUser);
+ $principal->Load($self->Field);
+
+ if ($principal->IsUser) {
+ return ("Added user '[_1]'", $principal->Object->Name); #loc()
+ }
+ else {
+ return ("Added group '[_1]'", $principal->Object->Name); #loc()
+ }
+ },
+ DeleteMember => sub {
+ my $self = shift;
+ my $principal = RT::Principal->new($self->CurrentUser);
+ $principal->Load($self->Field);
+
+ if ($principal->IsUser) {
+ return ("Removed user '[_1]'", $principal->Object->Name); #loc()
+ }
+ else {
+ return ("Removed group '[_1]'", $principal->Object->Name); #loc()
+ }
+ },
+ AddMembership => sub {
+ my $self = shift;
+ my $principal = RT::Principal->new($self->CurrentUser);
+ $principal->Load($self->Field);
+ return ("Added to group '[_1]'", $principal->Object->Name); #loc()
+ },
+ DeleteMembership => sub {
+ my $self = shift;
+ my $principal = RT::Principal->new($self->CurrentUser);
+ $principal->Load($self->Field);
+ return ("Removed from group '[_1]'", $principal->Object->Name); #loc()
+ },
);
@@ -2047,6 +2083,9 @@ sub Serialize {
my $cf = RT::CustomField->new( RT->SystemUser );
$cf->Load( $store{Field} );
$store{Field} = \($cf->UID);
+
+ $store{OldReference} = \($self->OldReferenceObject->UID) if $self->OldReference;
+ $store{NewReference} = \($self->NewReferenceObject->UID) if $self->NewReference;
} elsif ($type =~ /^(Take|Untake|Force|Steal|Give)$/) {
for my $field (qw/OldValue NewValue/) {
my $user = RT::User->new( RT->SystemUser );
@@ -2065,19 +2104,45 @@ sub Serialize {
if ($store{OldValue}) {
my $base = RT::URI->new( $self->CurrentUser );
$base->FromURI( $store{OldValue} );
- $store{OldValue} = \($base->Object->UID) if $base->Resolver and $base->Object;
+ if ($base->Resolver && (my $object = $base->Object)) {
+ if ($args{serializer}->Observe(object => $object)) {
+ $store{OldValue} = \($object->UID);
+ }
+ elsif ($args{serializer}{HyperlinkUnmigrated}) {
+ $store{OldValue} = $base->AsHREF;
+ }
+ else {
+ $store{OldValue} = "(not migrated)";
+ }
+ }
}
} elsif ($type eq "AddLink") {
if ($store{NewValue}) {
my $base = RT::URI->new( $self->CurrentUser );
$base->FromURI( $store{NewValue} );
- $store{NewValue} = \($base->Object->UID) if $base->Resolver and $base->Object;
+ if ($base->Resolver && (my $object = $base->Object)) {
+ if ($args{serializer}->Observe(object => $object)) {
+ $store{NewValue} = \($object->UID);
+ }
+ elsif ($args{serializer}{HyperlinkUnmigrated}) {
+ $store{NewValue} = $base->AsHREF;
+ }
+ else {
+ $store{NewValue} = "(not migrated)";
+ }
+ }
}
} elsif ($type eq "Set" and $store{Field} eq "Queue") {
for my $field (qw/OldValue NewValue/) {
my $queue = RT::Queue->new( RT->SystemUser );
$queue->Load( $store{$field} );
- $store{$field} = \($queue->UID);
+ if ($args{serializer}->Observe(object => $queue)) {
+ $store{$field} = \($queue->UID);
+ }
+ else {
+ $store{$field} = "$RT::Organization: " . $queue->Name . " (not migrated)";
+
+ }
}
} elsif ($type =~ /^(Add|Open|Resolve)Reminder$/) {
my $ticket = RT::Ticket->new( RT->SystemUser );
diff --git a/rt/lib/RT/Transactions.pm b/rt/lib/RT/Transactions.pm
index ffbd1ca3c..2a76738d5 100755
--- a/rt/lib/RT/Transactions.pm
+++ b/rt/lib/RT/Transactions.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/URI.pm b/rt/lib/RT/URI.pm
index 778469f60..5a29e33db 100644
--- a/rt/lib/RT/URI.pm
+++ b/rt/lib/RT/URI.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/URI/a.pm b/rt/lib/RT/URI/a.pm
index 640490ff1..8b7914d14 100644
--- a/rt/lib/RT/URI/a.pm
+++ b/rt/lib/RT/URI/a.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/URI/base.pm b/rt/lib/RT/URI/base.pm
index 9bb1887ee..852f93c57 100644
--- a/rt/lib/RT/URI/base.pm
+++ b/rt/lib/RT/URI/base.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/URI/fsck_com_article.pm b/rt/lib/RT/URI/fsck_com_article.pm
index d83386179..d94f0e56e 100644
--- a/rt/lib/RT/URI/fsck_com_article.pm
+++ b/rt/lib/RT/URI/fsck_com_article.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/URI/fsck_com_rt.pm b/rt/lib/RT/URI/fsck_com_rt.pm
index a0ecc34f8..86bb71208 100644
--- a/rt/lib/RT/URI/fsck_com_rt.pm
+++ b/rt/lib/RT/URI/fsck_com_rt.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/URI/t.pm b/rt/lib/RT/URI/t.pm
index cb703d6de..c5eb8f4f6 100644
--- a/rt/lib/RT/URI/t.pm
+++ b/rt/lib/RT/URI/t.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/User.pm b/rt/lib/RT/User.pm
index 3ffc1d27b..b9570bd60 100755
--- a/rt/lib/RT/User.pm
+++ b/rt/lib/RT/User.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -84,6 +84,7 @@ use RT::Principals;
use RT::ACE;
use RT::Interface::Email;
use Text::Password::Pronounceable;
+use RT::Util;
sub _OverlayAccessible {
{
@@ -363,6 +364,12 @@ sub _SetPrivileged {
}
my ($status, $msg) = $priv->_AddMember( InsideTransaction => 1, PrincipalId => $principal);
if ($status) {
+ $self->_NewTransaction(
+ Type => 'Set',
+ Field => 'Privileged',
+ NewValue => 1,
+ OldValue => 0,
+ );
return (1, $self->loc("That user is now privileged"));
} else {
return (0, $msg);
@@ -383,6 +390,12 @@ sub _SetPrivileged {
}
my ($status, $msg) = $unpriv->_AddMember( InsideTransaction => 1, PrincipalId => $principal);
if ($status) {
+ $self->_NewTransaction(
+ Type => 'Set',
+ Field => 'Privileged',
+ NewValue => 0,
+ OldValue => 1,
+ );
return (1, $self->loc("That user is now unprivileged"));
} else {
return (0, $msg);
@@ -977,11 +990,17 @@ sub IsPassword {
# If it's a new-style (>= RT 4.0) password, it starts with a '!'
my (undef, $method, @rest) = split /!/, $stored;
if ($method eq "bcrypt") {
- return 0 unless $self->_GeneratePassword_bcrypt($value, @rest) eq $stored;
+ return 0 unless RT::Util::constant_time_eq(
+ $self->_GeneratePassword_bcrypt($value, @rest),
+ $stored
+ );
# Upgrade to a larger number of rounds if necessary
return 1 unless $rest[0] < RT->Config->Get('BcryptCost');
} elsif ($method eq "sha512") {
- return 0 unless $self->_GeneratePassword_sha512($value, @rest) eq $stored;
+ return 0 unless RT::Util::constant_time_eq(
+ $self->_GeneratePassword_sha512($value, @rest),
+ $stored
+ );
} else {
$RT::Logger->warn("Unknown hash method $method");
return 0;
@@ -991,16 +1010,28 @@ sub IsPassword {
my $hash = MIME::Base64::decode_base64($stored);
# Decoding yields 30 byes; first 4 are the salt, the rest are substr(SHA256,0,26)
my $salt = substr($hash, 0, 4, "");
- return 0 unless substr(Digest::SHA::sha256($salt . Digest::MD5::md5(Encode::encode( "UTF-8", $value))), 0, 26) eq $hash;
+ return 0 unless RT::Util::constant_time_eq(
+ substr(Digest::SHA::sha256($salt . Digest::MD5::md5(Encode::encode( "UTF-8", $value))), 0, 26),
+ $hash, 1
+ );
} elsif (length $stored == 32) {
# Hex nonsalted-md5
- return 0 unless Digest::MD5::md5_hex(Encode::encode( "UTF-8", $value)) eq $stored;
+ return 0 unless RT::Util::constant_time_eq(
+ Digest::MD5::md5_hex(Encode::encode( "UTF-8", $value)),
+ $stored
+ );
} elsif (length $stored == 22) {
# Base64 nonsalted-md5
- return 0 unless Digest::MD5::md5_base64(Encode::encode( "UTF-8", $value)) eq $stored;
+ return 0 unless RT::Util::constant_time_eq(
+ Digest::MD5::md5_base64(Encode::encode( "UTF-8", $value)),
+ $stored
+ );
} elsif (length $stored == 13) {
# crypt() output
- return 0 unless crypt(Encode::encode( "UTF-8", $value), $stored) eq $stored;
+ return 0 unless RT::Util::constant_time_eq(
+ crypt(Encode::encode( "UTF-8", $value), $stored),
+ $stored
+ );
} else {
$RT::Logger->warning("Unknown password form");
return 0;
@@ -1096,19 +1127,20 @@ sub GenerateAuthString {
=head3 ValidateAuthString
-Takes auth string and protected string. Returns true is protected string
+Takes auth string and protected string. Returns true if protected string
has been protected by user's L</AuthToken>. See also L</GenerateAuthString>.
=cut
sub ValidateAuthString {
my $self = shift;
- my $auth_string = shift;
+ my $auth_string_to_validate = shift;
my $protected = shift;
my $str = Encode::encode( "UTF-8", $self->AuthToken . $protected );
+ my $valid_auth_string = substr(Digest::MD5::md5_hex($str),0,16);
- return $auth_string eq substr(Digest::MD5::md5_hex($str),0,16);
+ return RT::Util::constant_time_eq( $auth_string_to_validate, $valid_auth_string );
}
=head2 SetDisabled
@@ -2926,6 +2958,12 @@ sub __DependsOn {
$objs->Limit( FIELD => 'MemberId', VALUE => $self->Id );
push( @$list, $objs );
+# Cleanup user's membership transactions
+ $objs = RT::Transactions->new( $self->CurrentUser );
+ $objs->Limit( FIELD => 'Type', OPERATOR => 'IN', VALUE => ['AddMember', 'DeleteMember'] );
+ $objs->Limit( FIELD => 'Field', VALUE => $self->PrincipalObj->id, ENTRYAGGREGATOR => 'AND' );
+ push( @$list, $objs );
+
$deps->_PushDependencies(
BaseObject => $self,
Flags => RT::Shredder::Constants::DEPENDS_ON,
diff --git a/rt/lib/RT/Users.pm b/rt/lib/RT/Users.pm
index 4b9abfedf..39e45b9c0 100755
--- a/rt/lib/RT/Users.pm
+++ b/rt/lib/RT/Users.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
diff --git a/rt/lib/RT/Util.pm b/rt/lib/RT/Util.pm
index 70b557bb9..06cd046bc 100644
--- a/rt/lib/RT/Util.pm
+++ b/rt/lib/RT/Util.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2016 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2017 Best Practical Solutions, LLC
# <sales@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -54,6 +54,8 @@ use warnings;
use base 'Exporter';
our @EXPORT = qw/safe_run_child mime_recommended_filename/;
+use Encode qw/encode/;
+
sub safe_run_child (&) {
my $our_pid = $$;
@@ -150,6 +152,70 @@ sub assert_bytes {
}
+=head2 C<constant_time_eq($a, $b)>
+
+Compares two strings for equality in constant-time. Replacement for the C<eq>
+operator designed to avoid timing side-channel vulnerabilities. Returns zero
+or one.
+
+This is intended for use in cryptographic subsystems for comparing well-formed
+data such as hashes - not for direct use with user input or as a general
+replacement for the C<eq> operator.
+
+The two string arguments B<MUST> be of equal length. If the lengths differ,
+this function will call C<die()>, as proceeding with execution would create
+a timing vulnerability. Length is defined by characters, not bytes.
+
+Strings that should be treated as binary octets rather than Unicode text
+should pass a true value for the binary flag.
+
+This code has been tested to do what it claims. Do not change it without
+thorough statistical timing analysis to validate the changes.
+
+Added to resolve CVE-2017-5361
+
+For more on timing attacks, see this Wikipedia article:
+B<https://en.wikipedia.org/wiki/Timing_attack>
+
+=cut
+
+sub constant_time_eq {
+ my ($a, $b, $binary) = @_;
+
+ my $result = 0;
+
+ # generic error message avoids potential information leaks
+ my $generic_error = "Cannot compare values";
+ die $generic_error unless defined $a and defined $b;
+ die $generic_error unless length $a == length $b;
+ die $generic_error if ref($a) or ref($b);
+
+ for (my $i = 0; $i < length($a); $i++) {
+ my $a_char = substr($a, $i, 1);
+ my $b_char = substr($b, $i, 1);
+
+ my (@a_octets, @b_octets);
+
+ if ($binary) {
+ @a_octets = ord($a_char);
+ @b_octets = ord($b_char);
+ }
+ else {
+ # encode() is set to die on malformed
+ @a_octets = unpack("C*", encode('UTF-8', $a_char, Encode::FB_CROAK));
+ @b_octets = unpack("C*", encode('UTF-8', $b_char, Encode::FB_CROAK));
+ }
+
+ die $generic_error if (scalar @a_octets) != (scalar @b_octets);
+
+ for (my $j = 0; $j < scalar @a_octets; $j++) {
+ $result |= $a_octets[$j] ^ $b_octets[$j];
+ }
+ }
+ return 0 + not $result;
+}
+
+
RT::Base->_ImportOverlays();
1;