View | Details | Raw Unified | Return to bug 30933
Collapse All | Expand All

(-)a/Koha/Virtualshelf.pm (+66 lines)
Lines 265-270 sub can_biblios_be_removed { Link Here
265
    # Same answer since bug 18228
265
    # Same answer since bug 18228
266
}
266
}
267
267
268
=head3 cannot_be_transferred
269
270
    $shelf->cannot_be_transferred({
271
        by => $p1, to => $p2, interface => opac|intranet|undef,
272
            # p1 and p2 are borrowernumbers
273
    });
274
275
    This routine has two main goals:
276
    [1] Decide if patron may transfer a shared list to another
277
        sharee (patron).
278
    [2] Decide if staff member may transfer a public list.
279
280
    If you pass interface, we'll check if it supports transfer too.
281
    NOTE: The explicit passing is still more reliable than via context,
282
    since we could switch interface after login in the same session.
283
284
    Returns a true value (read: error_code) when not allowed.
285
    The following error codes are possible:
286
        unauthorized_transfer, missing_by_parameter, new_owner_not_found,
287
        new_owner_has_no_share, missing_to_parameter.
288
    Otherwise returns false (zero).
289
290
=cut
291
292
sub cannot_be_transferred {
293
    my ( $self, $params ) = @_;
294
    my $to = $params->{to};
295
    my $by = $params->{by};
296
    my $interface = $params->{interface};
297
298
    # Check on interface: currently we don't support transfer shared on intranet, transfer public on OPAC
299
    if( $interface ) {
300
        return 'unauthorized_transfer'
301
            if ( $self->public && $interface eq 'opac' ) or
302
               ( $self->is_private && $interface eq 'intranet' );
303
                   # is_private call is enough here, get_shares tested below
304
    }
305
306
    my $shares = $self->public ? undef : $self->get_shares->search({ borrowernumber => { '!=' => undef } });
307
    return 'unauthorized_transfer' if $self->is_private && !$shares->count;
308
309
    if( $by ) {
310
        if( $self->public ) {
311
            my $by_patron = Koha::Patrons->find($by);
312
            return 'unauthorized_transfer'
313
                if !$by_patron || !haspermission( $by_patron->userid, { lists => 'edit_public_lists' });
314
        } else {
315
            return 'unauthorized_transfer' if !$self->can_be_managed($by);
316
        }
317
    } else {
318
        return 'missing_by_parameter';
319
    }
320
321
    if( $to ) {
322
        if( !Koha::Patrons->find($to) ) {
323
            return 'new_owner_not_found';
324
        }
325
        if( !$self->public && !$shares->search({ borrowernumber => $to })->count ) {
326
            return 'new_owner_has_no_share';
327
        }
328
    } else {
329
        return 'missing_to_parameter';
330
    }
331
    return 0; # serving as green light
332
}
333
268
=head2 Internal methods
334
=head2 Internal methods
269
335
270
=head3 _type
336
=head3 _type
(-)a/t/db_dependent/Virtualshelves.t (-2 / +44 lines)
Lines 1-7 Link Here
1
#!/usr/bin/perl
1
#!/usr/bin/perl
2
2
3
use Modern::Perl;
3
use Modern::Perl;
4
use Test::More tests => 6;
4
use Test::More tests => 7;
5
use DateTime::Duration;
5
use DateTime::Duration;
6
6
7
use C4::Context;
7
use C4::Context;
Lines 591-596 subtest 'Get shelves containing biblios' => sub { Link Here
591
    teardown();
591
    teardown();
592
};
592
};
593
593
594
subtest 'cannot_be_transferred' => sub {
595
    plan tests => 12;
596
597
    # Three patrons and a deleted one
598
    my $staff = $builder->build_object({ class => 'Koha::Patrons', value => { flags => undef } });
599
    my $listowner = $builder->build_object({ class => 'Koha::Patrons' });
600
    my $receiver = $builder->build_object({ class => 'Koha::Patrons' });
601
    my $removed_patron = $builder->build_object({ class => 'Koha::Patrons' });
602
    $removed_patron->delete;
603
604
    # Create three lists
605
    my $private_list = Koha::Virtualshelf->new({ shelfname => "A", owner => $listowner->id })->store;
606
    my $public_list = Koha::Virtualshelf->new({ shelfname => "B", public => 1, owner => $listowner->id })->store;
607
    my $shared_list = Koha::Virtualshelf->new({ shelfname => "C", owner => $listowner->id })->store;
608
    $shared_list->share("key")->accept( "key", $receiver->id );
609
610
    # Test on private list
611
    is( $private_list->cannot_be_transferred, 'unauthorized_transfer', 'Private list can never be transferred' );
612
613
    # Test on public list
614
    is( $public_list->cannot_be_transferred, 'missing_by_parameter', 'Public list, no parameters' );
615
    is( $public_list->cannot_be_transferred({ by => $staff->id, to => $receiver->id }), 'unauthorized_transfer', 'Lacks permission' );
616
    my $perms = $builder->build({ source => 'UserPermission', value  => {
617
        borrowernumber => $staff->id, module_bit => 20, code => 'edit_public_lists',
618
    }});
619
    is( $public_list->cannot_be_transferred({ by => $staff->id, to => $receiver->id }), 0, 'Minimum permission passes' );
620
    $staff->flags(1)->store;
621
    is( $public_list->cannot_be_transferred({ by => $staff->id, to => $receiver->id }), 0, 'Superlibrarian permission passes' );
622
    is( $public_list->cannot_be_transferred({ by => $staff->id, to => $receiver->id, interface => 'opac' }), 'unauthorized_transfer',
623
        'Not supported on OPAC' );
624
    is( $public_list->cannot_be_transferred({ by => $staff->id, to => $removed_patron->id }), 'new_owner_not_found', 'Removed patron cannot own' );
625
626
    # Test on shared list
627
    is( $shared_list->cannot_be_transferred({ by => $staff->id }), 'unauthorized_transfer', 'Shared list, transfer limited to owner' );
628
    is( $shared_list->cannot_be_transferred({ by => $receiver->id }), 'unauthorized_transfer', 'Shared list, transfer still limited to owner' );
629
    is( $shared_list->cannot_be_transferred({ by => $listowner->id, to => $receiver->id }), 0, 'sharee could become owner' );
630
    is( $shared_list->cannot_be_transferred({ by => $listowner->id, to => $receiver->id, interface => 'intranet' }), 'unauthorized_transfer',
631
        'Intranet not supported' );
632
    is( $shared_list->cannot_be_transferred({ by => $listowner->id, to => $staff->id }), 'new_owner_has_no_share', 'staff has no share' );
633
};
634
635
$schema->storage->txn_rollback;
636
594
sub teardown {
637
sub teardown {
595
    $dbh->do(q|DELETE FROM virtualshelfshares|);
638
    $dbh->do(q|DELETE FROM virtualshelfshares|);
596
    $dbh->do(q|DELETE FROM virtualshelfcontents|);
639
    $dbh->do(q|DELETE FROM virtualshelfcontents|);
597
- 

Return to bug 30933