From 63ffc0b28fc758164f0aea6b4a6ba162a0bd03b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1s=20Cohen=20Arazi?= Date: Mon, 24 Aug 2026 14:57:08 -0300 Subject: [PATCH] Bug 43375: Regression tests This patch adds a regression test demonstrating that the OAuth userinfo_url response parsing fails when the Content-Type header contains extra parameters beyond charset (e.g. Microsoft Graph API returns application/json;odata.metadata=minimal;odata.streaming=true). The strict regex in _get_data_and_patron only matches Content-Type values with an optional ;charset=... suffix, causing valid JSON responses to be silently misinterpreted as URL-encoded form data. Test plan: 1. Apply this patch 2. Run: $ ktd --shell k$ prove t/db_dependent/Koha/Auth/Client/OAuth.t => FAIL: New subtest fails - email is undef, patron not found 3. Sign off :-D Signed-off-by: David Nind Signed-off-by: Pedro Amorim --- t/db_dependent/Koha/Auth/Client/OAuth.t | 104 +++++++++++++++++++++++- 1 file changed, 102 insertions(+), 2 deletions(-) diff --git a/t/db_dependent/Koha/Auth/Client/OAuth.t b/t/db_dependent/Koha/Auth/Client/OAuth.t index 0cca7126a2..3f7f075ca2 100755 --- a/t/db_dependent/Koha/Auth/Client/OAuth.t +++ b/t/db_dependent/Koha/Auth/Client/OAuth.t @@ -1,4 +1,4 @@ -#!/usr/bin/perl +#!/usr/bin/env perl # Copyright 2025 Koha Development Team # @@ -19,7 +19,7 @@ use Modern::Perl; -use Test::More tests => 4; +use Test::More tests => 5; use Test::MockModule; use Test::NoWarnings; @@ -255,3 +255,103 @@ subtest '_get_data_and_patron() no patron found tests' => sub { $schema->storage->txn_rollback; }; + +subtest '_get_data_and_patron() userinfo_url with extra Content-Type params (bug 43375)' => sub { + plan tests => 2; + + $schema->storage->txn_begin; + + my $client = Koha::Auth::Client::OAuth->new; + + # Create test patron + my $patron = $builder->build_object( + { + class => 'Koha::Patrons', + value => { email => 'graph@example.com' } + } + ); + + # Create provider with email matchpoint + my $provider = $builder->build_object( + { + class => 'Koha::Auth::Identity::Providers', + value => { + matchpoint => 'email', + mapping => encode_json( + { + email => 'mail', + firstname => 'givenName', + surname => 'surname', + } + ) + } + } + ); + + # Mock UserAgent - simulate Microsoft Graph API response + # Content-Type: application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8 + my $ua_mock = Test::MockModule->new('Mojo::UserAgent'); + my $tx_mock = Test::MockModule->new('Mojo::Transaction::HTTP'); + my $res_mock = Test::MockModule->new('Mojo::Message::Response'); + my $headers_mock = Test::MockModule->new('Mojo::Headers'); + + $headers_mock->mock( + 'content_type', + sub { + 'application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8'; + } + ); + $res_mock->mock( 'code', sub { '200' } ); + $res_mock->mock( + 'json', + sub { + return { + mail => 'graph@example.com', + givenName => 'Azure', + surname => 'User', + }; + } + ); + $res_mock->mock( + 'headers', + sub { + my $headers = {}; + bless $headers, 'Mojo::Headers'; + return $headers; + } + ); + + $tx_mock->mock( + 'res', + sub { + my $res = {}; + bless $res, 'Mojo::Message::Response'; + return $res; + } + ); + + $ua_mock->mock( + 'get', + sub { + my $tx = {}; + bless $tx, 'Mojo::Transaction::HTTP'; + return $tx; + } + ); + + my $data = { access_token => 'ms_graph_token' }; + my $config = { userinfo_url => 'https://graph.microsoft.com/v1.0/me' }; + + my ( $mapped_data, $found_patron ) = $client->_get_data_and_patron( + { + provider => $provider, + data => $data, + config => $config + } + ); + + is( $mapped_data->{email}, 'graph@example.com', 'Email mapped from MS Graph response with OData Content-Type' ); + is( $found_patron->id, $patron->id, 'Patron found despite extra Content-Type parameters' ); + + $schema->storage->txn_rollback; +};