From b58ba08263501b3efe69edc9efac8ed664434e9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Cohen=20Arazi?= Date: Mon, 13 Oct 2025 11:23:04 -0300 Subject: [PATCH] Bug 37711: (follow-up) Fix AuthClient plugin database upgrade handling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The AuthClient template plugin was causing 500 errors during database upgrades when the identity_providers schema was out of sync. The plugin tried to query the new 'auto_register_opac' column before the database schema was updated, creating a chicken-egg problem. This patch wraps the database query in Try::Tiny to handle schema mismatches gracefully during upgrades, allowing the upgrade process to continue without crashing the authentication interface. Test plan: 1. On main, apply all bug 37711 patches BUT THIS ONE 2. Simulate an upgrade by: * Edit Koha.pm so it points to the next version * Move the atomicupdate file to the right number in db_revs 3. Restart everything: $ ktd --shell k$ restart_all 4. Access http://kohadev-intra.localhost => FAIL: You get a 500! With a stack trace! 5. Apply this patch 6. Repeat 3 and 4 => SUCCESS: No 500 error, redirects to installer 7. Proceed with the upgrade: => SUCCESS: It works as it should 8. Run tests: k$ prove -v t/db_dependent/Template/Plugin/AuthClient.t => SUCCESS: All tests pass 9. Sign off :-D Signed-off-by: Tomás Cohen Arazi --- Koha/Template/Plugin/AuthClient.pm | 45 +++++++---- t/db_dependent/Template/Plugin/AuthClient.t | 86 +++++++++++++++++++++ 2 files changed, 114 insertions(+), 17 deletions(-) create mode 100755 t/db_dependent/Template/Plugin/AuthClient.t diff --git a/Koha/Template/Plugin/AuthClient.pm b/Koha/Template/Plugin/AuthClient.pm index 1cacbd41b23..7b28a3facd4 100644 --- a/Koha/Template/Plugin/AuthClient.pm +++ b/Koha/Template/Plugin/AuthClient.pm @@ -20,9 +20,11 @@ package Koha::Template::Plugin::AuthClient; use Modern::Perl; use Template::Plugin; -use base qw( Template::Plugin ); +use base qw( Template::Plugin ); +use Try::Tiny qw( catch try ); use Koha::Auth::Identity::Providers; +use Koha::Logger; =head1 NAME @@ -49,26 +51,35 @@ sub get_providers { $interface = 'staff' if $interface eq 'intranet'; - my $providers = - Koha::Auth::Identity::Providers->search( { "domains.allow_$interface" => 1 }, { prefetch => 'domains' } ); - my $base_url = ( $interface eq 'staff' ) ? "/api/v1/oauth/login" : "/api/v1/public/oauth/login"; - my @urls; - while ( my $provider = $providers->next ) { + # Handle database upgrade state where schema might be out of sync + try { + my $providers = + Koha::Auth::Identity::Providers->search( { "domains.allow_$interface" => 1 }, { prefetch => 'domains' } ); + my $base_url = ( $interface eq 'staff' ) ? "/api/v1/oauth/login" : "/api/v1/public/oauth/login"; + + while ( my $provider = $providers->next ) { + + my $code = $provider->code; + + if ( $provider->protocol eq 'OIDC' || $provider->protocol eq 'OAuth' ) { + push @urls, + { + code => $code, + description => $provider->description, + icon_url => $provider->icon_url, + url => "$base_url/$code/$interface", + }; + } + } + } catch { - my $code = $provider->code; + # If database query fails (e.g., during upgrade), return empty array + Koha::Logger->get->warn("AuthClient: Unable to load identity providers (database may need upgrade): $_"); + @urls = (); + }; - if ( $provider->protocol eq 'OIDC' || $provider->protocol eq 'OAuth' ) { - push @urls, - { - code => $code, - description => $provider->description, - icon_url => $provider->icon_url, - url => "$base_url/$code/$interface", - }; - } - } return \@urls; } diff --git a/t/db_dependent/Template/Plugin/AuthClient.t b/t/db_dependent/Template/Plugin/AuthClient.t new file mode 100755 index 00000000000..48171ad5978 --- /dev/null +++ b/t/db_dependent/Template/Plugin/AuthClient.t @@ -0,0 +1,86 @@ +#!/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 Test::More tests => 3; +use Test::Exception; +use Test::MockModule; +use Test::NoWarnings; + +use t::lib::TestBuilder; +use t::lib::Mocks::Logger; + +BEGIN { + use_ok('Koha::Template::Plugin::AuthClient'); +} + +my $schema = Koha::Database->new->schema; +my $builder = t::lib::TestBuilder->new; +my $logger = t::lib::Mocks::Logger->new(); + +subtest 'get_providers() tests' => sub { + + plan tests => 2; + + subtest 'Normal operation' => sub { + + plan tests => 2; + + $schema->storage->txn_begin; + + my $plugin = Koha::Template::Plugin::AuthClient->new(); + my $providers; + + lives_ok { + $providers = $plugin->get_providers('staff'); + } + 'get_providers executes without error'; + + is( ref($providers), 'ARRAY', 'Returns array reference' ); + + $schema->storage->txn_rollback; + }; + + subtest 'Database error handling' => sub { + + plan tests => 2; + + $schema->storage->txn_begin; + $logger->clear(); + + # Mock search to simulate database schema mismatch + my $mock = Test::MockModule->new('Koha::Auth::Identity::Providers'); + $mock->mock( + 'search', + sub { + die "DBD::mysql::st execute failed: Unknown column 'domains.auto_register_opac' in 'field list'"; + } + ); + + my $plugin = Koha::Template::Plugin::AuthClient->new(); + my $providers; + + lives_ok { + $providers = $plugin->get_providers('staff'); + } + 'get_providers handles database errors gracefully'; + + $logger->warn_like( qr/AuthClient: Unable to load identity providers/, 'Logs warning about database issue' ); + + $schema->storage->txn_rollback; + }; +}; -- 2.51.0