Bug 41602: (follow-up) Add a validation step for filtering

When there is a filter with the "status" param, we add a validation step
to secure the use of such a filter.

Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Lisette Scheer <lisette@bywatersolutions.com>
Signed-off-by: Pedro Amorim <pedro.amorim@openfifth.co.uk>
This commit is contained in:
Baptiste Wojtkowski 2026-05-15 12:45:55 +00:00 committed by Pedro Amorim
parent 134fe95444
commit dcbcea80e4
No known key found for this signature in database
GPG Key ID: 06B75BA7F3894D55
2 changed files with 59 additions and 2 deletions

View File

@ -691,13 +691,47 @@ sub _process_params {
}
}
=head3 _validate_params
Verify is the input provided with _status is valid.
Since we have to tweak the search for researches involving the _status parameter, if the search involves a _status, we need to check that the provided hashref is compatible with the use case.
An hashref is compatible if it is not nested or if the lonely level of nesting is under a "-and" parameter
=cut
sub _validate_params {
my ( $clean_params, $custom_attrs ) = @_;
return 1 unless exists $custom_attrs->{_status};
if ( ref($clean_params) eq 'HASH' ) {
if ( grep { $_ eq '-and' } keys %$clean_params ) {
my $and_hashref = $clean_params->{'-and'};
if ( ref($and_hashref) eq 'HASH' && !grep { ref( $and_hashref->{$_} ) eq 'HASH' } keys %$and_hashref ) {
return 1;
}
}
return 1 unless grep { ref( $clean_params->{$_} ) eq 'HASH' } keys %$clean_params;
}
return 0;
}
sub search {
my ( $self, $params, $attributes ) = @_;
my ( $custom_attrs, $clean_params ) = _extract_custom_attrs($params);
$params = $clean_params;
unless ( _validate_params( $clean_params, $custom_attrs ) ) {
Koha::Exceptions::BadParameter->throw(
error => "Filtering on status is only implemented for -and search",
);
}
$params = $clean_params;
my $status = $custom_attrs->{_status};
if ($status) {
if ( $status eq 'checked_out' ) {
$self = $self->filter_by_checked_out( { onsite_checkout => 0 } );

View File

@ -75,7 +75,7 @@ is( $retrieved_item_1->barcode, $new_item_1->barcode, 'Find a item by id should
subtest 'search' => sub {
plan tests => 16;
plan tests => 18;
$schema->storage->txn_begin;
my $patron = $builder->build_object( { class => 'Koha::Patrons' } );
@ -102,6 +102,29 @@ subtest 'search' => sub {
{ -and => { _status => 'available', biblionumber => $biblio->biblionumber } },
);
is( $available_items->count, 2, "Filtered to 2 available items - works when _status is in nested structure" );
throws_ok {
$available_items = Koha::Items->search(
{ -or => { _status => 'available', biblionumber => $biblio->biblionumber } },
);
}
'Koha::Exceptions::BadParameter',
"Filtered to 3 available items - returns an error when _status is in nested structure using or";
throws_ok {
$available_items = Koha::Items->search(
{
-and => {
_status => 'available',
-and => {
biblionumber => $biblio->biblionumber,
biblionumber => $biblio->biblionumber
}
},
}
);
}
'Koha::Exceptions::BadParameter',
"Filtered to 3 available items - returns an error when _status is in nested structure with more than one level";
my $item_3 = $builder->build_sample_item(
{