[Rt-commit] rtir branch 5.0/fix-external-tools-iframe created. 5.0.4-4-gc4f9532b

BPS Git Server git at git.bestpractical.com
Thu Jul 6 00:29:08 UTC 2023


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/fix-external-tools-iframe has been created
        at  c4f9532bde3c10662d5648a062f6a04feff4663b (commit)

- Log -----------------------------------------------------------------
commit c4f9532bde3c10662d5648a062f6a04feff4663b
Author: Ronaldo Richieri <ronaldo at bestpractical.com>
Date:   Wed Jul 5 21:28:33 2023 -0300

    Add upgrade info about Iframe Research Tool replacement

diff --git a/docs/UPGRADING-5.0 b/docs/UPGRADING-5.0
index 67ce05ed..f12c10db 100644
--- a/docs/UPGRADING-5.0
+++ b/docs/UPGRADING-5.0
@@ -289,4 +289,25 @@ list for "How Reported" to include these new values:
 
 =back
 
+=head1 UPGRADING FROM 5.0.4 AND EARLIER
+
+=over 4
+
+=item * "Iframe Research Tools" replaced with "External Research Tools"
+
+Recent versions of browsers have started blocking iframes from loading
+content from other domains. To address this, we have replaced the
+"Iframe Research Tools" with the new "External Research Tools", which get
+the content from the external site directly and render it in inline RT.
+
+The new External Research Tools are configured in a similar way as the
+Iframe Research Tools, but need some additional information to work.
+
+If you have configured different Iframe Research Tools, you will need to
+adapt the configuration to the new External Research Tools.
+
+Please check the RTIR configuration documentation for more information.
+
+=back
+
 =cut

commit 7f65d85931f57e1e12217db0f1d2017508ed3cbc
Author: Ronaldo Richieri <ronaldo at bestpractical.com>
Date:   Wed Jul 5 21:14:54 2023 -0300

    Update Documentation with External Research Tools information
    
    Iframe Research Tools are deprecated and were replaced with a set
    of External Research Tools which are rendered inline in RT.

diff --git a/etc/RTIR_Config.pm b/etc/RTIR_Config.pm
index a8be153a..93a07745 100644
--- a/etc/RTIR_Config.pm
+++ b/etc/RTIR_Config.pm
@@ -803,6 +803,48 @@ One of the research tools available in RTIR allows you to
 configure a set of search URLs that incident handlers
 can use to open searches in external tools.
 
+    Set($RTIRExternalResearchToolConfig, {
+        1 => {
+            FriendlyName => 'Google',
+            URL => 'https://encrypted.google.com/search?q=__SearchTerm__',
+            UserAgent => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0',
+            ContentXPaths => [
+                qw{//div[@role='main']//div[@data-async-context]//div[@jscontroller]//a[@jsname]},
+                ...
+            ],
+            ScrubberRules => {
+                a => {
+                    'href' => sub {
+                    ...
+                    },
+                },
+                '*' => 1,
+                'h1' => 0,
+                ...
+            },
+        },
+    });
+
+The C<URL> key is required and should contain the URL to the search
+tool you want to use.  The C<__SearchTerm__> placeholder will be
+replaced with the search term entered by the user.
+
+The C<FriendlyName> key will be used to label the search tool in the UI.
+
+The C<UserAgent> key is optional and will be used to set the User-Agent
+header when making requests to the search tool.
+
+The C<ContentXPaths> key is optional and should contain an array of
+XPath expressions that will be used to extract the search results from
+the response.  If this key is not provided, the entire response body will
+be displayed.
+
+The C<ScrubberRules> key is optional and should contain a hash of
+scrubber rules that will be used to clean up the search results.  The
+scrubber rules are defined using the L<HTML::Scrubber> syntax.  If this
+key is not provided, all HTML elements will be allowed, but with no
+attributes.
+
 =cut
 
 Set($RTIRExternalResearchToolConfig, {

commit 801ebd2cd31e11273259010e75cbe13d6c48f355
Author: Ronaldo Richieri <ronaldo at bestpractical.com>
Date:   Mon Jul 3 17:40:56 2023 -0300

    Remove Iframe research tools and add them as External tools
    
    Iframe research tools are not supported by modern browsers. We are
    replacing them with External tools, which will call the research tools
    from the RT server.

diff --git a/Makefile.PL b/Makefile.PL
index d86f3b28..3631ecdd 100644
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -30,6 +30,8 @@ requires('DBIx::SearchBuilder', 1.61);
 requires('Regexp::Common');
 # queries parsing
 requires('Parse::BooleanLogic');
+# Parse websites with External Tools
+requires('HTML::TreeBuilder::XPath');
 
 # Domain searching
 requires('Net::Domain::TLD');
diff --git a/etc/RTIR_Config.pm b/etc/RTIR_Config.pm
index be018fe0..a8be153a 100644
--- a/etc/RTIR_Config.pm
+++ b/etc/RTIR_Config.pm
@@ -795,27 +795,91 @@ using the following mason components:
 
 =cut
 
-Set( @RTIRResearchTools, (qw(Traceroute Whois Iframe)));
+Set( @RTIRResearchTools, (qw(Traceroute Whois External)));
 
-=item C<$RTIRIframeResearchToolConfig>
+=item C<$RTIRExternalResearchToolConfig>
 
 One of the research tools available in RTIR allows you to
 configure a set of search URLs that incident handlers
-can use to open searches in IFRAMES.
-
-Entries are keyed by integer in the order you'd like to see
-them in the dropdown on the research page. Each entry consists
-of a hashref containing "FriendlyName" and "URL". The URLs will
-be evaluated to replace __SearchTerm__ with the user's current
-search term.
+can use to open searches in external tools.
 
 =cut
 
-Set($RTIRIframeResearchToolConfig, {
-    1 => { FriendlyName => 'Google', URL => 'https://encrypted.google.com/search?q=__SearchTerm__' },
-    2 => { FriendlyName => 'CVE', URL => 'http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=__SearchTerm__'},
-    3 => { FriendlyName => 'McAfee SiteAdvisor', URL => 'http://www.siteadvisor.com/sites/__SearchTerm__'}
-} );
+Set($RTIRExternalResearchToolConfig, {
+    1 => {
+        FriendlyName => 'Google',
+        URL => 'https://encrypted.google.com/search?q=__SearchTerm__',
+        UserAgent => 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0',
+        ContentXPaths => [
+            qw{//div[@role='main']//div[@data-async-context]//div[@jscontroller]//a[@jsname]},
+            qw{//div[@role='main']//div[@data-async-context]//div[@jscontroller]//div[@data-sncf]/div},
+        ],
+        ScrubberRules => {
+            a => {
+                'href' => sub {
+                    my ($obj, $tag, $attr, $value) = @_;
+                    if ($value =~ m{translate.google.com}) {
+                        return;
+                    } elsif ($value !~ m{^http}) {
+                        return;
+                    }
+                    return $value;
+                },
+                'target' => 1,
+            },
+            '*' => 1,
+            'h1' => 0,
+            'h2' => 0,
+            'span' => 0,
+            'img' => 0,
+            'cite' => 0,
+            'div' => {
+                'style' => sub {
+                    my ($obj, $tag, $attr, $value) = @_;
+                    if ($value =~ m{webkit}) {
+                        return;
+                    }
+                    return 'margin-bottom: 2.5em;';
+                },
+            },
+
+        },
+    },
+    2 => {
+        FriendlyName => 'CVE',
+        URL => 'http://cve.mitre.org/cgi-bin/cvekey.cgi?keyword=__SearchTerm__',
+        ContentXPaths => [
+            qw{//div[@id='CenterPane']/div[@class='smaller']},
+            qw{//div[@id='CenterPane']/h2},
+            qw{//div[@id='CenterPane']/div[@id='TableWithRules']/table},
+        ],
+        ScrubberRules => {
+            a => {
+                'href' => sub {
+                    my ($obj, $tag, $attr, $value) = @_;
+                    if ($value =~ m{^/cgi-bin/cvename.cgi\?name\=}) {
+                        return 'https://cve.mitre.org'.$value;
+                    }
+                    return;
+                },
+                'target' => 1,
+            },
+            '*' =>  {
+                style => 1,
+                width => 1,
+                cellpadding => 1,
+                cellspacing => 1,
+            }
+        },
+    },
+    3 => {
+        FriendlyName => 'McAfee SiteAdvisor',
+        URL => 'http://www.siteadvisor.com/sites/__SearchTerm__',
+        ContentXPaths => [
+            qw{//div[@class='content']},
+        ],
+    }
+});
 
 =item C<$TracerouteCommand>
 
diff --git a/html/RTIR/Tools/Elements/ToolFormIframe b/html/RTIR/Tools/Elements/ToolFormExternal
similarity index 96%
rename from html/RTIR/Tools/Elements/ToolFormIframe
rename to html/RTIR/Tools/Elements/ToolFormExternal
index 6b5326cb..a774ae3b 100644
--- a/html/RTIR/Tools/Elements/ToolFormIframe
+++ b/html/RTIR/Tools/Elements/ToolFormExternal
@@ -78,6 +78,6 @@ $ResearchTool => ''
 </%args>
 <%INIT>
 my $unique_id = time().rand();
-$m->notes(rtir_research_iframe_id => $unique_id);
-my $research_tools = RT->Config->Get('RTIRIframeResearchToolConfig');
+$m->notes(rtir_research_external_id => $unique_id);
+my $research_tools = RT->Config->Get('RTIRExternalResearchToolConfig');
 </%INIT>
diff --git a/html/RTIR/Tools/Elements/ToolResultsIframe b/html/RTIR/Tools/Elements/ToolResultsExternal
similarity index 59%
rename from html/RTIR/Tools/Elements/ToolResultsIframe
rename to html/RTIR/Tools/Elements/ToolResultsExternal
index 323f11c0..f3bed770 100644
--- a/html/RTIR/Tools/Elements/ToolResultsIframe
+++ b/html/RTIR/Tools/Elements/ToolResultsExternal
@@ -45,20 +45,23 @@
 %# those contributions and any derivatives thereof.
 %#
 %# END BPS TAGGED BLOCK }}}
-<h2><%loc($research_tools->{$ResearchTool}->{FriendlyName})%></h2>
-<iframe 
-    src="<%$url%>" 
-    name="rtir_research_<%$m->notes('rtir_research_iframe_id')%>" 
-    style="width: 100%; height: 70%;"></iframe>
+<hr/>
+<h2 id="externalresultstitle"><a href="<% $url %>" target="_blank"><%loc($research_tools->{$ResearchTool}->{FriendlyName})%></a></h2>
+
+<div id="externalresults">
+% if ($q) {
+    <% $out |n %>
+% } else {
+    <% loc("No value informed") %>
+%}
+</div>
 <%args>
 $q =>  undef
-$TicketType => undef
-$TicketObj => undef
 $ResearchTool => undef
 </%args>
 <%init>
 return unless ($ResearchTool);
-my $research_tools = RT->Config->Get('RTIRIframeResearchToolConfig');
+my $research_tools = RT->Config->Get('RTIRExternalResearchToolConfig');
 if (!$research_tools->{$ResearchTool}->{URL}) {
     $RT::Logger->error(
         "Couldn't find a URL for RTIR research tool $ResearchTool. You should check your RTIRIframeResearchToolConfig");
@@ -66,4 +69,47 @@ if (!$research_tools->{$ResearchTool}->{URL}) {
 }
 my $url = $research_tools->{$ResearchTool}->{URL};
 $url =~ s/__SearchTerm__/$q/g;
+
+my $out;
+
+if ($q) {
+    use LWP::UserAgent;
+    use HTML::TreeBuilder::XPath;
+
+    my $ua       = LWP::UserAgent->new( env_proxy => 1 );
+    $ua->default_header('Content-Type' => 'text/html; charset=UTF-8');
+    $ua->default_header('Accept' => 'text/html; charset=UTF-8');
+
+    if ($research_tools->{$ResearchTool}->{UserAgent}) {
+        $ua->agent( $research_tools->{$ResearchTool}->{UserAgent} );
+    };
+
+    my $response = $ua->get($url);
+
+    # Check if there is content
+    if ( $response->is_success ) {
+        my $tree = HTML::TreeBuilder::XPath->new_from_content(
+            $response->decoded_content(charset => 'utf-8') );
+        my @contents = $tree->findnodes(
+            join( '|',
+                @{ $research_tools->{$ResearchTool}->{ContentXPaths} || ['//body'] } )
+        );
+        # Find all anchors with href
+        my @anchors = $tree->look_down(_tag => 'a', href => qr/.+/);
+        foreach my $anchor (@anchors) {
+            # Upgrade target attribute to _blank
+            $anchor->attr('target', '_blank');
+        }
+
+        foreach my $content (@contents) {
+            $out .= $content->as_HTML('<>&');
+        }
+
+        $out = RT::IR::Web::ScrubHtmlExternalTools( $out,
+            $research_tools->{$ResearchTool}->{ScrubberRules} );
+    } else {
+        $out = 'Error: ' . $response->status_line;
+    }
+
+}
 </%init>
diff --git a/lib/RT/IR/Web.pm b/lib/RT/IR/Web.pm
index 6f0e10b7..82cd44b2 100644
--- a/lib/RT/IR/Web.pm
+++ b/lib/RT/IR/Web.pm
@@ -94,5 +94,22 @@ sub RTIRDefaultSearchParams {
 }
 
 package RT::IR::Web;
+
+sub ScrubHtmlExternalTools {
+    my ($html, $ScrubberRules) = @_;
+    my $scrubber = HTML::Scrubber->new( script => 0 );
+    my %rules;
+    if ( $ScrubberRules ) {
+        %rules = %$ScrubberRules;
+    } else {
+        %rules = ( '*' => 1 );
+    }
+    $scrubber->rules(
+        %rules,
+    );
+    my $scrubbed_html = $scrubber->scrub($html);
+    return $scrubbed_html;
+}
+
 RT::Base->_ImportOverlays();
 1;
diff --git a/static/css/rtir-styles.css b/static/css/rtir-styles.css
index 6f5bcfde..baca5ae7 100644
--- a/static/css/rtir-styles.css
+++ b/static/css/rtir-styles.css
@@ -193,6 +193,22 @@ body.rtir .titlebox.external-feeds tr.evenline+.evenline .collection-as-table {
     padding-bottom: 0.7rem;
 }
 
+body.rtir #externalresultstitle {
+    margin-top: 15px;
+    margin-bottom: 15px;
+}
+
+body.rtir #externalresults {
+    font-size: 1em;
+}
+
+body.rtir #externalresults h1,
+body.rtir #externalresults h2,
+body.rtir #externalresults h3 {
+    font-size: 1em;
+}
+
+
 /* elevator-dark styles for rtir */
 
 .rtir.darkmode .clickylink a.button {

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


hooks/post-receive
-- 
rtir


More information about the rt-commit mailing list