[Rt-commit] rtir branch WIP-5.0/add-process-reference-articles created. 5.0.1-82-gc4c25416

BPS Git Server git at git.bestpractical.com
Wed Jul 13 21:43:06 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, WIP-5.0/add-process-reference-articles has been created
        at  c4c2541641e0ae0b8094ec6045bdc4f81caf8684 (commit)

- Log -----------------------------------------------------------------
commit c4c2541641e0ae0b8094ec6045bdc4f81caf8684
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 eb952f65..f0d10ef5 100644
--- a/docs/UPGRADING-5.0
+++ b/docs/UPGRADING-5.0
@@ -257,4 +257,18 @@ 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 called "Playbook", with an HTML custom field called
+"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.
+
+This portlet is not enabled by default.
+
+=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 c2ce4f7c..da27fce7 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 'Playbook' Article custom field.");
+            my ( $id, $msg ) = $playbook->Create(
+                Name        => 'Playbook',
+                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..59fabf9d
--- /dev/null
+++ b/etc/upgrade/5.0.4/content
@@ -0,0 +1,68 @@
+use strict;
+use warnings;
+
+ at 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 2940d4e92f7ec2080cee4f39563e651d6b61db99
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..eb952f65 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 * Article custom field Resposne type change
+
+The type of the Article custom field Response has been changed for new RTIR
+installes 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..c2ce4f7c 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-" . $playbook->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