Bug 12758: Introduce Koha::XSLT::HTTPS

This module now fetches a https stylesheet and returns it as a
string to Base. (As a workaround waiting for a real solution
in the underlying libraries.)

The module can be extended to resolve includes but this requires
parsing the xslt code.

Test plan:
[1] Run t/Koha_XSLT_HTTPS.t

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>

Signed-off-by: David Nind <david@davidnind.com>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
Signed-off-by: Tomas Cohen Arazi <tomascohen@theke.io>
This commit is contained in:
Marcel de Rooy 2022-06-29 12:16:46 +00:00 committed by Tomas Cohen Arazi
parent 1ea56fb092
commit 2d2e93e66e
No known key found for this signature in database
GPG Key ID: 0A272EA1B2F3C15F
3 changed files with 191 additions and 0 deletions

50
Koha/Exceptions/XSLT.pm Normal file
View File

@ -0,0 +1,50 @@
package Koha::Exceptions::XSLT;
# Copyright 2022 Rijksmuseum, Koha Development Team
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Koha is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Koha; if not, see <http://www.gnu.org/licenses>.
=head1 NAME
Koha::Exceptions::XSLT;
=head1 SYNOPSIS
Koha::Exceptions::XSLT::MissingFilename->throw;
=head1 DESCRIPTION
Defines a few exceptions for Koha::XSLT:: modules
=cut
use Modern::Perl;
use Koha::Exception;
use Exception::Class (
'Koha::Exceptions::XSLT' => {
isa => 'Koha::Exception',
},
'Koha::Exceptions::XSLT::MissingFilename' => {
isa => 'Koha::Exceptions::XSLT',
description => 'File name required',
},
'Koha::Exceptions::XSLT::FetchFailed' => {
isa => 'Koha::Exceptions::XSLT',
description => 'Fetching xslt file failed',
},
);
1;

82
Koha/XSLT/HTTPS.pm Normal file
View File

@ -0,0 +1,82 @@
package Koha::XSLT::HTTPS;
# Copyright 2022 Rijksmuseum
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Koha is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Koha; if not, see <http://www.gnu.org/licenses>.
=head1 NAME
Koha::XSLT::HTTPS - Helper module to resolve issues with https stylesheets
=head1 SYNOPSIS
Koha::XSLT::HTTPS->load( $filename );
=head1 DESCRIPTION
This module collects the contents of https XSLT styleheets where
libxml2/libxslt fail to do so. This should be considered as a
temporary workaround.
A similar problem comes up with xslt include files. The module could
be extended to resolve these issues too. What holds me back now, is
the fact that we need to parse the whole xslt code.
=cut
use Modern::Perl;
use LWP::UserAgent;
use Koha::Exceptions::XSLT;
=head1 METHODS
=head2 load
Koha::XSLT::HTTPS->load( $filename );
=cut
sub load {
my ( $class, $filename ) = @_;
Koha::Exceptions::XSLT::MissingFilename->throw if !$filename;
return { location => $filename } if $filename !~ /^https:\/\//;
my $ua = LWP::UserAgent->new( ssl_opts => { verify_hostname => 0 } );
my $resp = $ua->get( $filename );
if( $resp->is_success ) {
my $contents = $resp->decoded_content;
# $contents = $self->_resolve_includes( $contents );
return { string => $contents };
}
Koha::Exceptions::XSLT::FetchFailed->throw;
}
sub _resolve_includes {
# We could parse the code for includes/imports, fetch them and change refs
my ( $self, $code ) = @_;
# TODO Extend it
return $code;
}
1;
=head1 AUTHOR
Marcel de Rooy, Rijksmuseum Amsterdam, The Netherlands
=cut

59
t/Koha_XSLT_HTTPS.t Executable file
View File

@ -0,0 +1,59 @@
#!/usr/bin/perl
# Copyright 2022 Rijksmuseum
#
# This file is part of Koha.
#
# Koha is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# Koha is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Koha; if not, see <http://www.gnu.org/licenses>.
use Modern::Perl;
use Test::Exception;
use Test::MockModule;
use Test::MockObject;
use Test::More tests => 1;
use Koha::XSLT::HTTPS;
subtest 'load' => sub {
plan tests => 9;
# Mock the LWP stuff
my $lwp_object = Test::MockObject->new;
my $response = Test::MockObject->new;
$response->mock( 'is_success', sub { return 0 } );
$lwp_object->mock( 'get', sub { return $response; } );
my $lwp_mod = Test::MockModule->new( 'LWP::UserAgent' );
$lwp_mod->mock( 'new', sub { return $lwp_object } );
# Trivial bad input
throws_ok { Koha::XSLT::HTTPS->load; } 'Koha::Exceptions::XSLT::MissingFilename', 'No filename';
throws_ok { Koha::XSLT::HTTPS->load(q{}); } 'Koha::Exceptions::XSLT::MissingFilename', 'Empty filename';
my $result = Koha::XSLT::HTTPS->load('filename.xsl');
is( ref($result), 'HASH', 'Should return hash' );
is( exists $result->{location}, 1, 'Hash key location found' );
is( $result->{location}, 'filename.xsl', 'Value for location key' );
# Mock returns no success
throws_ok { Koha::XSLT::HTTPS->load('https://myfavoritexsltsite.com/test1.xsl'); }
'Koha::Exceptions::XSLT::FetchFailed', 'Fetch failed';
# Mock returns 'code'
$response->mock( 'is_success', sub { return 1 } );
$response->mock( 'decoded_content', sub { return 'supposed_xslt_code' } );
$result = Koha::XSLT::HTTPS->load('https://myfavoritexsltsite.com/test2.xsl');
is( ref($result), 'HASH', 'Should return hash' );
is( exists $result->{string}, 1, 'Hash key string found' );
is( $result->{string}, 'supposed_xslt_code', 'Value for string key' );
}