[Rt-commit] rtir branch 5.0/add-process-reference-articles created. 5.0.3-3-g1da9689d

BPS Git Server git at git.bestpractical.com
Tue Oct 11 18:12:25 UTC 2022


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "rtir".

The branch, 5.0/add-process-reference-articles has been created
        at  1da9689dcadfd8d32ae607b21bfdd0d9e1079f1e (commit)

- Log -----------------------------------------------------------------
commit 1da9689dcadfd8d32ae607b21bfdd0d9e1079f1e
Author: Brian Conry <bconry at bestpractical.com>
Date:   Wed Jul 13 13:03:33 2022 -0500

    Add portlet for incident process documentation
    
    This change adds an optional portlet (default: off) to the Incident
    display that can display an article based on an incident custom field.
    By default looks in the 'Playbook' Class for the article with a Name
    that matches the value of the 'Classification' CF.
    
    Creates the 'Playbook' Class, and the 'Procedures' HTML custom field
    for it, if they don't already exist.

diff --git a/docs/UPGRADING-5.0 b/docs/UPGRADING-5.0
index f7f16586..36bb4bc9 100644
--- a/docs/UPGRADING-5.0
+++ b/docs/UPGRADING-5.0
@@ -257,4 +257,20 @@ default for the Responses class.
 Neither of these changes are applied on upgrade because the content of the
 custom field may need to be tweaked after the conversion from text to HTML.
 
+=item * New Playbook articles and Portlet
+
+A new default article class "Playbook", with an HTML custom field "Procedures",
+is added with this upgrade.  On Incidents the contents of articles in this
+class can be displayed in a portlet, based on the Incident Classification, as
+guidance for the analyst.
+
+The article class and Incident custom field used to select the article can be
+customized in the configuration using C<$RTIR_PlaybookClass> and
+<$RTIR_PlaybookCriteriaCF>.
+
+This portlet is not enabled by default, controlled by
+C<$RTIR_ShowIncidentPlaybooks>.
+
+=back
+
 =cut
diff --git a/etc/RTIR_Config.pm b/etc/RTIR_Config.pm
index 8d836ef0..fb2055c5 100644
--- a/etc/RTIR_Config.pm
+++ b/etc/RTIR_Config.pm
@@ -640,6 +640,32 @@ By default RTIR enables 'httpurl_overwrite', 'ip', 'email' and 'domain'.
 
 Set(@Active_MakeClicky, qw(httpurl_overwrite ip email domain));
 
+=item C<$RTIR_ShowIncidentPlaybooks>
+
+Controls the display of a playbook portlet on incidents.
+
+When active, and the incident custom field specified by
+C<$RTIR_PlaybookCriteriaCF> matches the name of an article in the
+C<$RTIR_PlaybookClass> class, that article will be displayed in a portlet on
+the incident as guidance for the user.
+
+By default RTIR does not show this portlet.
+
+=cut
+
+Set($RTIR_ShowIncidentPlaybooks, 0);
+
+=item C<$RTIR_PlaybookClass>
+
+This is the name of the Class that the articles must be in to be found and
+displayed as a playbook when C<$RTIR_ShowIncidentPlaybooks> is set.
+
+Defaults to 'Playbook'
+
+=cut
+
+Set($RTIR_PlaybookClass, 'Playbook');
+
 =back
 
 =head1 Custom Fields
@@ -721,6 +747,17 @@ that are not included in L<Net::Domain::TLD> yet. It's true by default.
 
 Set($RTIR_StrictDomainTLD, 1);
 
+=item C<$RTIR_PlaybookCriteriaCF>
+
+This is the name of the incident custom field that will be used to look up an
+article to display when C<$RTIR_ShowIncidentPlaybooks> is set.
+
+Defaults to 'Classification'.
+
+=cut
+
+Set($RTIR_PlaybookCriteriaCF, 'Classification');
+
 =back
 
 =head1 Countermeasures
diff --git a/etc/initialdata b/etc/initialdata
index cd1b2351..f1af1e9f 100644
--- a/etc/initialdata
+++ b/etc/initialdata
@@ -740,6 +740,67 @@ for my $cf (@CustomFields) {
             Object => RT->System
         );
 
+    },
+    sub {
+        $| = 1;
+        my $CurrentUser = RT::CurrentUser->new();
+        $CurrentUser->LoadByName('RT_System');
+
+        require RT::Class;
+        my $class = RT::Class->new($CurrentUser);
+        $class->Load('Playbook');
+        unless ( $class->Id ) {
+            $RT::Logger->info("Creating 'Playbook' Article class.");
+            my ( $id, $msg ) = $class->Create(
+                Name        => 'Playbook',
+                Description => 'Incident Response Playbooks',
+                HotList     => 1
+            );
+            die $msg unless $id;
+        }
+
+        require RT::Article;
+        my $playbook = RT::CustomField->new($CurrentUser);
+        $playbook->Load('Playbook');
+        unless ($playbook->Id
+            and $playbook->LookupType eq RT::Article->CustomFieldLookupType )
+        {
+            $RT::Logger->info("Creating 'Procedures' Article custom field.");
+            my ( $id, $msg ) = $playbook->Create(
+                Name        => 'Procedures',
+                Type        => 'HTML',
+                MaxValues   => 1,
+                Description => 'Procedures to be displayed in the Playbook portlet',
+                LookupType  => RT::Article->CustomFieldLookupType,
+            );
+            die $msg unless $id;
+        }
+
+        $playbook->AddToObject($class);
+
+        my @skips = ( "Name", "Summary", "EscapeHTML", "CF-Title-" . $playbook->Id );
+
+        my $content = RT::CustomField->new($CurrentUser);
+        $content->LoadByName( Name => 'Content', LookupType => RT::Article->CustomFieldLookupType );
+        if ( $content->Id && ( $content->IsGlobal || $content->IsAdded( $class->Id ) ) ) {
+            push @skips, "CF-Title-" . $content->Id, "CF-Value-" . $content->Id;
+        }
+
+        $class->SetAttribute( Name => "Skip-$_", Content => 1 ) for @skips;
+
+        my $group = RT::Group->new($CurrentUser);
+        $group->LoadUserDefinedGroup("DutyTeam");
+        die "Can't load group" unless $group->Id;
+        $group->PrincipalObj->GrantRight( Right => $_, Object => $playbook )
+            for qw/SeeCustomField ModifyCustomField/;
+        $group->PrincipalObj->GrantRight( Right => $_, Object => $class )
+            for
+            qw/AdminClass AdminTopics CreateArticle ModifyArticle ModifyArticleTopics SeeClass ShowArticle ShowArticleHistory DeleteArticle/;
+        $group->PrincipalObj->GrantRight(
+            Right  => ShowArticlesMenu,
+            Object => RT->System
+        );
+
     },
     sub {
         my $dashboard = RT::Dashboard->new( RT->SystemUser );
diff --git a/etc/upgrade/5.0.4/content b/etc/upgrade/5.0.4/content
new file mode 100644
index 00000000..ac34fccc
--- /dev/null
+++ b/etc/upgrade/5.0.4/content
@@ -0,0 +1,68 @@
+use strict;
+use warnings;
+
+our @Final = (
+    sub {
+        $| = 1;
+        my $CurrentUser = RT::CurrentUser->new();
+        $CurrentUser->LoadByName('RT_System');
+
+        require RT::Class;
+        my $class = RT::Class->new($CurrentUser);
+        $class->Load('Playbook');
+        unless ( $class->Id ) {
+            $RT::Logger->info("Creating 'Playbook' Article class.");
+            my ( $id, $msg ) = $class->Create(
+                Name        => 'Playbook',
+                Description => 'Incident Response Playbooks',
+                HotList     => 1
+            );
+            die $msg unless $id;
+        }
+
+        require RT::Article;
+        my $playbook = RT::CustomField->new($CurrentUser);
+        $playbook->Load('Playbook');
+        unless ($playbook->Id
+            and $playbook->LookupType eq RT::Article->CustomFieldLookupType )
+        {
+            $RT::Logger->info("Creating 'Procedures' Article custom field.");
+            my ( $id, $msg ) = $playbook->Create(
+                Name        => 'Procedures',
+                Type        => 'HTML',
+                MaxValues   => 1,
+                Description => 'Procedures to be displayed in the Playbook portlet',
+                LookupType  => RT::Article->CustomFieldLookupType,
+            );
+            die $msg unless $id;
+        }
+
+        $playbook->AddToObject($class);
+
+        my @skips = ( "Name", "Summary", "EscapeHTML", "CF-Title-" . $playbook->Id );
+
+        my $content = RT::CustomField->new($CurrentUser);
+        $content->LoadByName( Name => 'Content', LookupType => RT::Article->CustomFieldLookupType );
+        if ( $content->Id && ( $content->IsGlobal || $content->IsAdded( $class->Id ) ) ) {
+            push @skips, "CF-Title-" . $content->Id, "CF-Value-" . $content->Id;
+        }
+
+        $class->SetAttribute( Name => "Skip-$_", Content => 1 ) for @skips;
+
+        my $group = RT::Group->new($CurrentUser);
+        $group->LoadUserDefinedGroup("DutyTeam");
+        die "Can't load group" unless $group->Id;
+        $group->PrincipalObj->GrantRight( Right => $_, Object => $playbook )
+            for qw/SeeCustomField ModifyCustomField/;
+        $group->PrincipalObj->GrantRight( Right => $_, Object => $class )
+            for
+            qw/AdminClass AdminTopics CreateArticle ModifyArticle ModifyArticleTopics SeeClass ShowArticle ShowArticleHistory DeleteArticle/;
+        $group->PrincipalObj->GrantRight(
+            Right  => 'ShowArticlesMenu',
+            Object => RT->System
+        );
+
+    },
+);
+
+1;
diff --git a/html/RTIR/Incident/Display.html b/html/RTIR/Incident/Display.html
index e384faa2..bc16a5cb 100644
--- a/html/RTIR/Incident/Display.html
+++ b/html/RTIR/Incident/Display.html
@@ -306,6 +306,15 @@
 
 <& /RTIR/Elements/ShowCVEDetails, Ticket => $TicketObj &>
 
+% if ( RT->Config->Get('RTIR_ShowIncidentPlaybooks') ) {
+    <& /Elements/ArticleContentAsPortlet,
+        PortletTitle   => RT->Config->Get('RTIR_PlaybookClass'),
+        ArticleObj     => $PlaybookArticleObj,
+        ContentIfEmpty => 'No documentation available',
+        TitleClass     => 'ticket-info-reminders',
+    &>
+% }
+
 % $m->callback( %ARGS, Ticket => $TicketObj, CallbackName => 'RightColumnEnd' );
   </div>
 </div>
@@ -528,6 +537,25 @@ my $attachments = $TicketObj->Attachments;
 $TicketObj->CurrentUser->AddRecentlyViewedTicket($TicketObj)
     if $TicketObj->CurrentUser->can('AddRecentlyViewedTicket');
 
+my $PlaybookArticleObj;
+
+if ( RT->Config->Get('RTIR_ShowIncidentPlaybooks') ) {
+    my $Criteria = $TicketObj->FirstCustomFieldValue( RT->Config->Get('RTIR_PlaybookCriteriaCF' ));
+
+    if ( $Criteria ) {
+        my $ArticleClass = RT::Class->new( $session{CurrentUser} );
+        $ArticleClass->LoadByCols( Name => RT->Config->Get('RTIR_PlaybookClass') );
+
+        if ( $ArticleClass->Id ) {
+            my $Articles = RT::Articles->new( $session{CurrentUser} );
+            $Articles->Limit( FIELD => "Class", VALUE => $ArticleClass->Id );
+            $Articles->Limit( FIELD => "Name", VALUE => $Criteria );
+
+            $PlaybookArticleObj = $Articles->First;
+        }
+    }
+}
+
 </%INIT>
 
 <%ARGS>

commit c4d6e5128854518ec57fea45cb480cbcf7d8f7a7
Author: Brian Conry <bconry at bestpractical.com>
Date:   Wed Jul 6 14:06:56 2022 -0500

    Change default type of Article CF Responses
    
    This change modifies the default type for new installs of the 'Response'
    field added to the Article Class 'Templates' from text to HTML.

diff --git a/docs/UPGRADING-5.0 b/docs/UPGRADING-5.0
index b7c43498..f7f16586 100644
--- a/docs/UPGRADING-5.0
+++ b/docs/UPGRADING-5.0
@@ -242,4 +242,19 @@ moving the scrip to Batch mode may restore the previous behavior.
 
 =back
 
+=head1 UPGRADING FROM 5.0.3 AND EARLIER
+
+=over 4
+
+=item * Type change for Article custom field Response
+
+The type of the article custom field "Response" has been changed for new RTIR
+installs from text to HTML.  This allows the Templates to contain HTML content
+for responses when the analyst is using the "Rich text" editor, which is the
+system default.  Accompanying this, the EscapeHTML option is now deselected by
+default for the Responses class.
+
+Neither of these changes are applied on upgrade because the content of the
+custom field may need to be tweaked after the conversion from text to HTML.
+
 =cut
diff --git a/etc/initialdata b/etc/initialdata
index 1b720a2d..cd1b2351 100644
--- a/etc/initialdata
+++ b/etc/initialdata
@@ -707,7 +707,7 @@ for my $cf (@CustomFields) {
             $RT::Logger->info("Creating 'Response' Article custom field.");
             my ( $id, $msg ) = $response->Create(
                 Name        => 'Response',
-                Type        => 'Text',
+                Type        => 'HTML',
                 MaxValues   => 1,
                 Description => 'Response to be inserted into the ticket',
                 LookupType  => RT::Article->CustomFieldLookupType,
@@ -717,7 +717,7 @@ for my $cf (@CustomFields) {
 
         $response->AddToObject($class);
 
-        my @skips = ( "Name", "Summary", "CF-Title-" . $response->Id );
+        my @skips = ( "Name", "Summary", "EscapeHTML", "CF-Title-" . $response->Id );
 
         my $content = RT::CustomField->new($CurrentUser);
         $content->LoadByName( Name => 'Content', LookupType => RT::Article->CustomFieldLookupType );

-----------------------------------------------------------------------


hooks/post-receive
-- 
rtir


More information about the rt-commit mailing list