Merge remote-tracking branch 'upstream/24.05.x' into 24.05.x-security

Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
This commit is contained in:
Paul Derscheid 2025-05-26 22:22:20 +02:00
commit f0628f9489
No known key found for this signature in database
GPG Key ID: C25F9FD44CED595B
5 changed files with 113 additions and 121 deletions

View File

@ -92,7 +92,7 @@ sub process {
usage_data_provider_id => $ud_provider->erm_usage_data_provider_id,
file_content => $args->{file_content},
date_uploaded => POSIX::strftime( "%Y%m%d%H%M%S", localtime ),
filename => $ud_provider->name,
filename => $ud_provider->name . "_" . $ud_provider->{report_type},
}
]
);

View File

@ -159,36 +159,38 @@ my $out;
unless ( C4::Context->preference('ILS-DI') ) {
$out->{'code'} = "NotAllowed";
$out->{'message'} = "ILS-DI is disabled.";
}
# If the remote address is not allowed, redirect to 403
my @AuthorizedIPs = split( /,/, C4::Context->preference('ILS-DI:AuthorizedIPs') );
if (@AuthorizedIPs) { # If no filter set, allow access to everybody
my $authorized = 0;
foreach my $ip (@AuthorizedIPs) {
my $netmask = Net::Netmask->new2($ip);
if ( $netmask && $netmask->match( $ENV{REMOTE_ADDR} ) ) {
$authorized = 1;
last;
}
}
unless ($authorized) {
$out->{'code'} = "NotAllowed";
$out->{'message'} = "Unauthorized IP address: $ENV{REMOTE_ADDR}.";
}
} else {
$out->{'code'} = "NotAllowed";
$out->{'message'} = "Unauthorized IP address: $ENV{REMOTE_ADDR}.";
print XMLout(
$out,
noattr => 1,
nosort => 1,
xmldecl => '<?xml version="1.0" encoding="UTF-8" ?>',
RootName => "ilsdi",
SuppressEmpty => 1
);
exit 0;
# If the remote address is not allowed, redirect to 403
my @AuthorizedIPs = split( /,/, C4::Context->preference('ILS-DI:AuthorizedIPs') );
if (@AuthorizedIPs) { # If no filter set, allow access to everybody
my $authorized = 0;
foreach my $ip (@AuthorizedIPs) {
my $netmask = Net::Netmask->new2($ip);
if ( $netmask && $netmask->match( $ENV{REMOTE_ADDR} ) ) {
$authorized = 1;
last;
}
}
unless ($authorized) {
$out->{'code'} = "NotAllowed";
$out->{'message'} = "Unauthorized IP address: $ENV{REMOTE_ADDR}.";
}
} else {
$out->{'code'} = "NotAllowed";
$out->{'message'} = "Unauthorized IP address: $ENV{REMOTE_ADDR}.";
print XMLout(
$out,
noattr => 1,
nosort => 1,
xmldecl => '<?xml version="1.0" encoding="UTF-8" ?>',
RootName => "ilsdi",
SuppressEmpty => 1
);
exit 0;
}
}
my $service = $cgi->param('service') || "ilsdi";

View File

@ -23,7 +23,7 @@ use Koha::Database;
use Koha::BackgroundJobs;
use Koha::BackgroundJob::ErmSushiHarvester;
use JSON qw( decode_json );
use JSON qw( decode_json );
use File::Basename qw( dirname );
use File::Slurp;
@ -86,9 +86,6 @@ subtest 'enqueue_sushi_harvest_jobs' => sub {
$schema->storage->txn_begin;
my $patron = Koha::Patrons->search()->last;
t::lib::Mocks::mock_userenv( { number => $patron->borrowernumber } ); # Is superlibrarian
my $usage_data_provider = $builder->build_object(
{ class => 'Koha::ERM::EUsage::UsageDataProviders', value => { name => 'TestProvider' } } );

View File

@ -22,7 +22,7 @@ use Test::More tests => 2;
use Koha::Database;
use Koha::ERM::EUsage::CounterFile;
use JSON qw( decode_json );
use JSON qw( decode_json );
use File::Basename qw( dirname );
use File::Slurp;
@ -46,9 +46,6 @@ subtest 'store' => sub {
$schema->storage->txn_begin;
my $patron = Koha::Patrons->search()->last;
t::lib::Mocks::mock_userenv( { number => $patron->borrowernumber } ); # Is superlibrarian
my $usage_data_provider = $builder->build_object(
{ class => 'Koha::ERM::EUsage::UsageDataProviders', value => { name => 'TestProvider' } } );
$usage_data_provider->{report_type} = 'TR_J1';

View File

@ -50,27 +50,6 @@ subtest "monthly_report" => sub {
$schema->storage->txn_begin;
my $librarian = $builder->build_object(
{
class => 'Koha::Patrons',
value => { flags => 2**28 }
}
);
my $password = 'thePassword123';
$librarian->set_password( { password => $password, skip_validation => 1 } );
my $userid = $librarian->userid;
t::lib::Mocks::mock_userenv( { number => $userid } );
my $patron = $builder->build_object(
{
class => 'Koha::Patrons',
value => { flags => 0 }
}
);
$patron->set_password( { password => $password, skip_validation => 1 } );
my $unauth_userid = $patron->userid;
# Run a harvest to populate the database with data
my $usage_data_provider = $builder->build_object( { class => 'Koha::ERM::EUsage::UsageDataProviders' } );
my $counter_file = $sushi_counter_TR_J1->get_COUNTER_from_SUSHI;
@ -85,6 +64,26 @@ subtest "monthly_report" => sub {
]
);
my $librarian = $builder->build_object(
{
class => 'Koha::Patrons',
value => { flags => 2**28 }
}
);
my $password = 'thePassword123';
$librarian->set_password( { password => $password, skip_validation => 1 } );
my $userid = $librarian->userid;
my $patron = $builder->build_object(
{
class => 'Koha::Patrons',
value => { flags => 0 }
}
);
$patron->set_password( { password => $password, skip_validation => 1 } );
my $unauth_userid = $patron->userid;
# Unauthorized access
$t->get_ok("//$unauth_userid:$password@/api/v1/erm/eUsage/monthly_report/title")->status_is(403);
@ -149,27 +148,6 @@ subtest "yearly_report" => sub {
$schema->storage->txn_begin;
my $librarian = $builder->build_object(
{
class => 'Koha::Patrons',
value => { flags => 2**28 }
}
);
my $password = 'thePassword123';
$librarian->set_password( { password => $password, skip_validation => 1 } );
my $userid = $librarian->userid;
t::lib::Mocks::mock_userenv( { number => $userid } );
my $patron = $builder->build_object(
{
class => 'Koha::Patrons',
value => { flags => 0 }
}
);
$patron->set_password( { password => $password, skip_validation => 1 } );
my $unauth_userid = $patron->userid;
# Run a harvest to populate the database with data
my $usage_data_provider = $builder->build_object( { class => 'Koha::ERM::EUsage::UsageDataProviders' } );
my $counter_file = $sushi_counter_TR_J1->get_COUNTER_from_SUSHI;
@ -184,6 +162,26 @@ subtest "yearly_report" => sub {
]
);
my $librarian = $builder->build_object(
{
class => 'Koha::Patrons',
value => { flags => 2**28 }
}
);
my $password = 'thePassword123';
$librarian->set_password( { password => $password, skip_validation => 1 } );
my $userid = $librarian->userid;
my $patron = $builder->build_object(
{
class => 'Koha::Patrons',
value => { flags => 0 }
}
);
$patron->set_password( { password => $password, skip_validation => 1 } );
my $unauth_userid = $patron->userid;
# Unauthorized access
$t->get_ok("//$unauth_userid:$password@/api/v1/erm/eUsage/yearly_report/title")->status_is(403);
@ -239,27 +237,6 @@ subtest "metric_types_report" => sub {
$schema->storage->txn_begin;
my $librarian = $builder->build_object(
{
class => 'Koha::Patrons',
value => { flags => 2**28 }
}
);
my $password = 'thePassword123';
$librarian->set_password( { password => $password, skip_validation => 1 } );
my $userid = $librarian->userid;
t::lib::Mocks::mock_userenv( { number => $userid } );
my $patron = $builder->build_object(
{
class => 'Koha::Patrons',
value => { flags => 0 }
}
);
$patron->set_password( { password => $password, skip_validation => 1 } );
my $unauth_userid = $patron->userid;
# Run a harvest to populate the database with data
my $usage_data_provider = $builder->build_object( { class => 'Koha::ERM::EUsage::UsageDataProviders' } );
my $counter_file = $sushi_counter_TR_J1->get_COUNTER_from_SUSHI;
@ -274,6 +251,26 @@ subtest "metric_types_report" => sub {
]
);
my $librarian = $builder->build_object(
{
class => 'Koha::Patrons',
value => { flags => 2**28 }
}
);
my $password = 'thePassword123';
$librarian->set_password( { password => $password, skip_validation => 1 } );
my $userid = $librarian->userid;
my $patron = $builder->build_object(
{
class => 'Koha::Patrons',
value => { flags => 0 }
}
);
$patron->set_password( { password => $password, skip_validation => 1 } );
my $unauth_userid = $patron->userid;
# Unauthorized access
$t->get_ok("//$unauth_userid:$password@/api/v1/erm/eUsage/metric_types_report/title")->status_is(403);
@ -335,27 +332,6 @@ subtest "provider_rollup_report" => sub {
$schema->storage->txn_begin;
my $librarian = $builder->build_object(
{
class => 'Koha::Patrons',
value => { flags => 2**28 }
}
);
my $password = 'thePassword123';
$librarian->set_password( { password => $password, skip_validation => 1 } );
my $userid = $librarian->userid;
t::lib::Mocks::mock_userenv( { number => $userid } );
my $patron = $builder->build_object(
{
class => 'Koha::Patrons',
value => { flags => 0 }
}
);
$patron->set_password( { password => $password, skip_validation => 1 } );
my $unauth_userid = $patron->userid;
# Run a harvest to populate the database with data
my $usage_data_provider = $builder->build_object( { class => 'Koha::ERM::EUsage::UsageDataProviders' } );
my $counter_file = $sushi_counter_TR_J1->get_COUNTER_from_SUSHI;
@ -370,6 +346,26 @@ subtest "provider_rollup_report" => sub {
]
);
my $librarian = $builder->build_object(
{
class => 'Koha::Patrons',
value => { flags => 2**28 }
}
);
my $password = 'thePassword123';
$librarian->set_password( { password => $password, skip_validation => 1 } );
my $userid = $librarian->userid;
my $patron = $builder->build_object(
{
class => 'Koha::Patrons',
value => { flags => 0 }
}
);
$patron->set_password( { password => $password, skip_validation => 1 } );
my $unauth_userid = $patron->userid;
# Unauthorized access
$t->get_ok("//$unauth_userid:$password@/api/v1/erm/eUsage/provider_rollup_report/title")->status_is(403);