From ff2b951c4de87cbdba7eaaca4cb6dac39bb76d5e Mon Sep 17 00:00:00 2001 From: Olivia Reynolds Date: Tue, 28 Jul 2026 14:50:32 +0000 Subject: [PATCH] Bug 41648: Validate plugin date metadata If a plugin reports a date_authored or date_updated we can't parse, remove the invalid property from the metadata hashref and emit a warning. To test this, introduce a separate test plugin directory and test file. Having a plugin that produces warnings in the main test directory would require accounting for this warning in every existing test that loads plugins. Correspondingly, this patch also fixes an invalid date in an existing test plugin. Test plan: 1. Apply patch. 2. Run `prove -r t/db_dependent/Koha/Plugins/` and verify there are no test failures. Sponsored-by: Open Fifth Signed-off-by: David Nind Signed-off-by: Laura_Escamilla Signed-off-by: Pedro Amorim --- Koha/Plugins/Base.pm | 15 +++++ t/db_dependent/Koha/Plugins/BadPlugins.t | 67 ++++++++++++++++++++ t/lib/plugins/Koha/Plugin/BadAPIRoute.pm | 2 +- t/lib/plugins_bad/Koha/Plugin/BadMetadata.pm | 32 ++++++++++ 4 files changed, 115 insertions(+), 1 deletion(-) create mode 100755 t/db_dependent/Koha/Plugins/BadPlugins.t create mode 100644 t/lib/plugins_bad/Koha/Plugin/BadMetadata.pm diff --git a/Koha/Plugins/Base.pm b/Koha/Plugins/Base.pm index 011edc296f..c7921496be 100644 --- a/Koha/Plugins/Base.pm +++ b/Koha/Plugins/Base.pm @@ -28,6 +28,7 @@ use base qw{Module::Bundled::Files}; use C4::Context; use C4::Output qw( output_with_http_headers ); +use Koha::DateUtils qw( dt_from_string ); use Koha::Exceptions::Plugin; use Koha::Cache::Memory::Lite; @@ -209,6 +210,20 @@ sub get_metadata { #FIXME: Why another encoding issue? For metadata containing non latin characters. my $metadata = $self->{metadata}; defined( $metadata->{$_} ) && utf8::decode( $metadata->{$_} ) for keys %$metadata; + + # Validate date fields + foreach my $field (qw{date_authored date_updated}) { + my $value = $metadata->{$field}; + next unless $value; + + try { dt_from_string( $value, 'iso' ) } + catch { + my $name = $metadata->{name} // 'Unknown'; + warn "Plugin $name has invalid $field metadata"; + delete $metadata->{$field}; + } + } + return $metadata; } diff --git a/t/db_dependent/Koha/Plugins/BadPlugins.t b/t/db_dependent/Koha/Plugins/BadPlugins.t new file mode 100755 index 0000000000..43c593b6a1 --- /dev/null +++ b/t/db_dependent/Koha/Plugins/BadPlugins.t @@ -0,0 +1,67 @@ +#!/usr/bin/perl + +# 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 . + +use Modern::Perl; + +use File::Basename; +use Test::MockModule; +use Test::NoWarnings; +use Test::More tests => 5; +use Test::Warn; +use Test::Exception; + +use Koha::Database; + +use t::lib::Mocks; + +BEGIN { + # Mock pluginsdir before loading Plugins module + my $path = dirname(__FILE__) . '/../../../lib/plugins_bad'; + t::lib::Mocks::mock_config( 'pluginsdir', $path ); + + use_ok('Koha::Plugins'); + use_ok('Koha::Plugins::Handler'); + use_ok('Koha::Plugins::Base'); +} + +my $schema = Koha::Database->new->schema; + +t::lib::Mocks::mock_preference( 'SessionStorage', 'tmp' ); + +subtest 'Koha::Plugin::BadMetadata' => sub { + plan tests => 4; + + $schema->storage->txn_begin; + + # Temporarily remove any installed plugins data (FIXME not done) + Koha::Plugins->RemovePlugins; + + my $plugins = Koha::Plugins->new( { enable_plugins => 1 } ); + + warnings_are { $plugins->InstallPlugins; } + [ + 'Plugin Bad Metadata has invalid date_authored metadata', + 'Plugin Bad Metadata has invalid date_updated metadata' + ]; + + my @plugins = $plugins->GetPlugins( { metadata => { name => 'Bad Metadata' }, all => 1 } ); + is( scalar @plugins, 1 ); + + is( $plugins[0]->get_metadata()->{'date_authored'}, undef ); + is( $plugins[0]->get_metadata()->{'date_updated'}, undef ); + + $schema->storage->txn_rollback; +}; diff --git a/t/lib/plugins/Koha/Plugin/BadAPIRoute.pm b/t/lib/plugins/Koha/Plugin/BadAPIRoute.pm index 6127cb53c7..6d97dc547c 100644 --- a/t/lib/plugins/Koha/Plugin/BadAPIRoute.pm +++ b/t/lib/plugins/Koha/Plugin/BadAPIRoute.pm @@ -11,7 +11,7 @@ our $metadata = { name => 'Bad API Route Plugin', author => 'John Doe', description => 'Test plugin for bad API route', - date_authored => '2018-', + date_authored => '2018-01-01', date_updated => '2013-01-14', minimum_version => '17.11', maximum_version => undef, diff --git a/t/lib/plugins_bad/Koha/Plugin/BadMetadata.pm b/t/lib/plugins_bad/Koha/Plugin/BadMetadata.pm new file mode 100644 index 0000000000..dd2e891d46 --- /dev/null +++ b/t/lib/plugins_bad/Koha/Plugin/BadMetadata.pm @@ -0,0 +1,32 @@ +package Koha::Plugin::BadMetadata; + +use Modern::Perl; + +use base qw(Koha::Plugins::Base); + +our $VERSION = "0.0.1"; +our $metadata = { + name => 'Bad Metadata', + author => 'Jane Doe', + description => 'For testing plugin metadata validation', + date_authored => '2001/01/01', + date_updated => '2015', + minimum_version => '3.11', + maximum_version => undef, + version => $VERSION, +}; + +=head1 Methods + +=head2 new + +=cut + +sub new { + my ( $class, $args ) = @_; + $args->{'metadata'} = $metadata; + my $self = $class->SUPER::new($args); + return $self; +} + +1;