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

(-)a/C4/Auth_with_ldap.pm (+94 lines)
Lines 28-33 use Koha::Patrons; Link Here
28
use Koha::AuthUtils qw( hash_password );
28
use Koha::AuthUtils qw( hash_password );
29
use Net::LDAP;
29
use Net::LDAP;
30
use Net::LDAP::Filter;
30
use Net::LDAP::Filter;
31
use Try::Tiny;
31
32
32
our (@ISA, @EXPORT_OK);
33
our (@ISA, @EXPORT_OK);
33
BEGIN {
34
BEGIN {
Lines 434-439 sub update_local { Link Here
434
    _do_changepassword($userid, $borrowerid, $password) if exists( $borrower->{'password'} );
435
    _do_changepassword($userid, $borrowerid, $password) if exists( $borrower->{'password'} );
435
}
436
}
436
437
438
# Subroutine to update a user with LDAP using its cardnumber.
439
sub updateborrower_ldap {
440
    my $patron = shift;
441
    my $cardnumber = $patron->cardnumber;
442
443
    return unless ($config{update});
444
445
    my @hosts = split(',', $prefhost);
446
    my $db = Net::LDAP->new(\@hosts, timeout => ($ldap->{timeout} || 30)) or return;
447
448
    my $cardnumber_field = $mapping{cardnumber}->{is} or die ldapserver_error("mapping for 'cardnumber'");
449
    my $filter = Net::LDAP::Filter->new("$cardnumber_field=$cardnumber") or die "Failed to create new Net::LDAP::Filter";
450
    my $res = ($config{anonymous}) ? $db->bind : $db->bind($ldapname, password=>$ldappassword);
451
    if ($res->code) {   # connection refused
452
        warn "LDAP bind failed as ldapuser " . ($ldapname || '[ANONYMOUS]') . ": " . description($res);
453
        return;
454
    }
455
    my $search = $db->search(
456
        base => $base,
457
        filter => $filter,
458
    );
459
460
    # Search error, return undef
461
    return (undef, $search->error) if $search->code;
462
463
    my $count = $search->count;
464
    if ($count == 1) {
465
        # User was found, update!
466
        my %borrower = ldap_entry_2_hash($search->shift_entry,$cardnumber);
467
468
        &update_local($patron->userid, $patron->password, $patron->borrowernumber, \%borrower);
469
470
        my $updated_patron = Koha::Patrons->find( $patron->borrowernumber );
471
        return $updated_patron;
472
    }
473
    else {
474
        return;
475
    }
476
477
}
478
479
# Subroutine to search for a user by its cardnumber through LDAP.
480
# The user is added locally if found. (We suppose this user doesn't already exist if this subroutine is called)
481
sub findcardnumber_ldap {
482
    my $cardnumber = shift;
483
484
    return unless ($config{replicate});
485
486
    my @hosts = split(',', $prefhost);
487
    my $db = Net::LDAP->new(\@hosts, timeout => ($ldap->{timeout} || 30)) or return;
488
489
    my $cardnumber_field = $mapping{cardnumber}->{is} or die ldapserver_error("mapping for 'cardnumber'");
490
    my $filter = Net::LDAP::Filter->new("$cardnumber_field=$cardnumber") or die "Failed to create new Net::LDAP::Filter";
491
    my $res = ($config{anonymous}) ? $db->bind : $db->bind($ldapname, password=>$ldappassword);
492
    if ($res->code) {   # connection refused
493
        warn "LDAP bind failed as ldapuser " . ($ldapname || '[ANONYMOUS]') . ": " . description($res);
494
        return;
495
    }
496
    my $search = $db->search(
497
        base => $base,
498
        filter => $filter,
499
    );
500
501
    # Search error, return undef
502
    return (undef, $search->error) if $search->code;
503
504
    my $count = $search->count;
505
    if ($count == 1) {
506
        # User was found, add it!
507
        my %borrower = ldap_entry_2_hash($search->shift_entry,$cardnumber);
508
509
        # Generate a random password to keep the user secure if no password was mapped
510
        my @chars = ( "A" .. "Z", "a" .. "z", 0 .. 9, qw(! @ $ % ^ & *) );
511
        $borrower{'password'} = join("", @chars[ map { rand @chars } ( 1 .. 30 ) ]) unless $borrower{'password'};
512
513
        try {
514
            my @columns = Koha::Patrons->columns;
515
            my $patron = Koha::Patron->new(
516
                {
517
                    map { exists( $borrower{$_} ) ? ( $_ => $borrower{$_} ) : () } @columns
518
                }
519
            )->store;
520
            return $patron;
521
        } catch {
522
            return (undef, $_->{msg});
523
        };
524
    }
525
    else {
526
        return;
527
    }
528
529
}
530
437
1;
531
1;
438
__END__
532
__END__
439
533
(-)a/circ/circulation.pl (+14 lines)
Lines 244-249 my $message; Link Here
244
if ($findborrower) {
244
if ($findborrower) {
245
    Koha::Plugins->call( 'patron_barcode_transform', \$findborrower );
245
    Koha::Plugins->call( 'patron_barcode_transform', \$findborrower );
246
    my $patron = Koha::Patrons->find( { cardnumber => $findborrower } );
246
    my $patron = Koha::Patrons->find( { cardnumber => $findborrower } );
247
248
    # search cardnumber on LDAP server
249
    if ( C4::Context->config('useldapserver')
250
        and ( my $search_cardnumber = C4::Context->preference("SearchCardnumberWithLDAP") ) ne "never")
251
    {
252
        my $ldap_error;
253
        if ( $patron ) {
254
            ($patron, $ldap_error) = C4::Auth_with_ldap::updateborrower_ldap($patron) if $search_cardnumber eq "always";
255
        } else {
256
            ($patron, $ldap_error) = C4::Auth_with_ldap::findcardnumber_ldap($findborrower);
257
        }
258
        $template->param(ldap_error => $ldap_error) if $ldap_error;
259
    }
260
247
    if ( $patron ) {
261
    if ( $patron ) {
248
        $borrowernumber = $patron->borrowernumber;
262
        $borrowernumber = $patron->borrowernumber;
249
    } else {
263
    } else {
(-)a/circ/request-article.pl (-4 / +19 lines)
Lines 51-60 my $biblio = Koha::Biblios->find($biblionumber); Link Here
51
output_and_exit( $cgi, $cookie, $template, 'unknown_biblio')
51
output_and_exit( $cgi, $cookie, $template, 'unknown_biblio')
52
    unless $biblio;
52
    unless $biblio;
53
53
54
my $patron =
54
my $patron = undef;
55
    $patron_id         ? Koha::Patrons->find($patron_id)
55
if ( $patron_id ) {
56
  : $patron_cardnumber ? Koha::Patrons->find( { cardnumber => $patron_cardnumber } )
56
    $patron = Koha::Patrons->find($patron_id);
57
  : undef;
57
} elsif ( $patron_cardnumber ) {
58
    $patron = Koha::Patrons->find( { cardnumber => $patron_cardnumber } );
59
60
    # search cardnumber on LDAP server
61
    if ( C4::Context->config('useldapserver')
62
        and ( my $search_cardnumber = C4::Context->preference("SearchCardnumberWithLDAP") ) ne "never")
63
    {
64
        my $ldap_error;
65
        if ( $patron ) {
66
            ($patron, $ldap_error) = C4::Auth_with_ldap::updateborrower_ldap($patron) if $search_cardnumber eq "always";
67
        } else {
68
            ($patron, $ldap_error) = C4::Auth_with_ldap::findcardnumber_ldap($patron_cardnumber);
69
        }
70
        $template->param(ldap_error => $ldap_error) if $ldap_error;
71
    }
72
}
58
73
59
if ( $op eq 'cud-create' ) {
74
if ( $op eq 'cud-create' ) {
60
    my $borrowernumber = $cgi->param('borrowernumber');
75
    my $borrowernumber = $cgi->param('borrowernumber');
(-)a/installer/data/mysql/atomicupdate/bug_11808.pl (+14 lines)
Line 0 Link Here
1
use Modern::Perl;
2
3
return {
4
    bug_number => "11808",
5
    description => "Search cardnumber on the LDAP server if one is configured and add/update user.",
6
    up => sub {
7
        my ($args) = @_;
8
        my ($dbh, $out) = @$args{qw(dbh out)};
9
        $dbh->do(q{
10
            INSERT INTO systempreferences (variable,value,explanation,options,type)
11
            VALUES('SearchCardnumberWithLDAP', 'never', 'Search for a cardnumber with LDAP when searching for a patron that does not exist locally. If the cardnumber is found via LDAP, the user is added or updated.', 'always|not_found|never', 'Choice');
12
        });
13
    },
14
};
(-)a/installer/data/mysql/mandatory/sysprefs.sql (+1 lines)
Lines 686-691 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
686
('SCOLoadCheckoutsByDefault','1','','If enabled, load the list of a patrons checkouts when they log in to the Self Checkout','YesNo'),
686
('SCOLoadCheckoutsByDefault','1','','If enabled, load the list of a patrons checkouts when they log in to the Self Checkout','YesNo'),
687
('SCOUserCSS','',NULL,'Add CSS to be included in the SCO module in an embedded <style> tag.','free'),
687
('SCOUserCSS','',NULL,'Add CSS to be included in the SCO module in an embedded <style> tag.','free'),
688
('SCOUserJS','',NULL,'Define custom javascript for inclusion in the SCO module','free'),
688
('SCOUserJS','',NULL,'Define custom javascript for inclusion in the SCO module','free'),
689
('SearchCardnumberWithLDAP', 'never', 'Search for a cardnumber with LDAP when searching for a patron that does not exist locally. If the cardnumber is found via LDAP, the user is added or updated.', 'always|not_found|never', 'Choice'),
689
('SearchEngine','Zebra','Elasticsearch|Zebra','Search Engine','Choice'),
690
('SearchEngine','Zebra','Elasticsearch|Zebra','Search Engine','Choice'),
690
('SearchLimitLibrary', 'homebranch', 'homebranch|holdingbranch|both', "When limiting search results with a library or library group, use the item's home library, or holding library, or both.", 'Choice'),
691
('SearchLimitLibrary', 'homebranch', 'homebranch|holdingbranch|both', "When limiting search results with a library or library group, use the item's home library, or holding library, or both.", 'Choice'),
691
('SearchMyLibraryFirst','0',NULL,'If ON, OPAC searches return results limited by the user\'s library by default if they are logged in','YesNo'),
692
('SearchMyLibraryFirst','0',NULL,'If ON, OPAC searches return results limited by the user\'s library by default if they are logged in','YesNo'),
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/patrons.pref (+7 lines)
Lines 211-216 Patrons: Link Here
211
         - '<br><strong>NOTE:</strong> All patron fields can be used, but to work correctly they must contain a valid email address or an empty string.'
211
         - '<br><strong>NOTE:</strong> All patron fields can be used, but to work correctly they must contain a valid email address or an empty string.'
212
         - "Valid options are the <a href='http://schema.koha-community.org/__VERSION__/tables/borrowers.html' target='blank'>database columns</a> of the borrowers table, separated by | (pipe)."
212
         - "Valid options are the <a href='http://schema.koha-community.org/__VERSION__/tables/borrowers.html' target='blank'>database columns</a> of the borrowers table, separated by | (pipe)."
213
         - "Example: email|emailpro|B_email"
213
         - "Example: email|emailpro|B_email"
214
     -
215
         - pref: SearchCardnumberWithLDAP
216
           choices:
217
               always: Always
218
               not_found: If not found locally,
219
               never: Never
220
         - "search cardnumbers on the LDAP server. If the cardnumber is found via LDAP, the user is added or updated locally. Note : This feature only works if auth_by_bind is disabled in koha-conf.xml."
214
     -
221
     -
215
         - "When <a href='/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=EmailFieldPrimary'>EmailFieldPrimary</a> is set to '<strong>selected addresses</strong>', send email to all valid email addresses in the selected fields:"
222
         - "When <a href='/cgi-bin/koha/admin/preferences.pl?op=search&searchfield=EmailFieldPrimary'>EmailFieldPrimary</a> is set to '<strong>selected addresses</strong>', send email to all valid email addresses in the selected fields:"
216
         - pref: EmailFieldSelection
223
         - pref: EmailFieldSelection
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt (+5 lines)
Lines 714-719 Link Here
714
714
715
                    [% IF ( message ) %]
715
                    [% IF ( message ) %]
716
                        [% INCLUDE 'patron-toolbar.inc' %]
716
                        [% INCLUDE 'patron-toolbar.inc' %]
717
                        [% IF (ldap_error) %]
718
                            <div class="dialog alert">
719
                                An error occured while searching for cardnumber on the LDAP server : [% ldap_error | html %]
720
                            </div>
721
                        [% END %]
717
                        <h4>No patron matched <span class="ex">[% message | html %]</span></h4>
722
                        <h4>No patron matched <span class="ex">[% message | html %]</span></h4>
718
                    [% END %]
723
                    [% END %]
719
724
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/request-article.tt (+6 lines)
Lines 94-99 Link Here
94
            <main>
94
            <main>
95
                [% INCLUDE 'messages.inc' %]
95
                [% INCLUDE 'messages.inc' %]
96
96
97
                [% IF (ldap_error) %]
98
                    <div class="dialog alert">
99
                        An error occured while searching for cardnumber on the LDAP server : [% ldap_error | html %]
100
                    </div>
101
                [% END %]
102
97
                    <h1>Request article from [% INCLUDE 'biblio-title.inc' link = 1 %]</h1>
103
                    <h1>Request article from [% INCLUDE 'biblio-title.inc' link = 1 %]</h1>
98
                    [% IF error_message %]
104
                    [% IF error_message %]
99
                        <div class="dialog alert">
105
                        <div class="dialog alert">
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/member.tt (+6 lines)
Lines 107-112 Link Here
107
                </div>
107
                </div>
108
            [% END %]
108
            [% END %]
109
109
110
            [% IF (ldap_error) %]
111
                <div class="dialog alert">
112
                    An error occured while searching for cardnumber on the LDAP server : [% ldap_error | html %]
113
                </div>
114
            [% END %]
115
110
            [% IF CAN_user_borrowers_edit_borrowers || CAN_user_tools_manage_patron_lists %]
116
            [% IF CAN_user_borrowers_edit_borrowers || CAN_user_tools_manage_patron_lists %]
111
                [% columns.unshift('checkbox') | html %]
117
                [% columns.unshift('checkbox') | html %]
112
            [% END %]
118
            [% END %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt (+17 lines)
Lines 225-230 Link Here
225
                </div>
225
                </div>
226
            [% END %]
226
            [% END %]
227
227
228
            [% IF ( messagetransfert ) %]
229
                <div class="dialog message">
230
                    <h2>Hold found for ([% nextreservtitle | html %]), please transfer</h2>
231
                    <p>Hold placed by : <strong> [% nextreservsurname | html %] [% nextreservfirstname | html %]</strong> at : <strong> [% branchname | html %] </strong>, Please transfer this item.
232
                    </p>
233
                    <form name="cancelReservewithtransfert" action="branchreserves.pl" method="post">
234
                        <input type="submit" class="button" />
235
                    </form>
236
                </div>
237
            [% END %]
238
239
            [% IF (ldap_error) %]
240
                <div class="dialog alert">
241
                    An error occured while searching for cardnumber on the LDAP server : [% ldap_error | html %]
242
                </div>
243
            [% END %]
244
228
            [% UNLESS ( multi_hold ) %]
245
            [% UNLESS ( multi_hold ) %]
229
                <h2>Place a hold on [% INCLUDE 'biblio-title.inc' link = 1 %] [% IF biblio.author %] by [% biblio.author | html %][% END %]</h2>
246
                <h2>Place a hold on [% INCLUDE 'biblio-title.inc' link = 1 %] [% IF biblio.author %] by [% biblio.author | html %][% END %]</h2>
230
            [% ELSE %]
247
            [% ELSE %]
(-)a/members/member.pl (+14 lines)
Lines 53-58 if ( $quicksearch and $searchmember && !$circsearch ) { Link Here
53
        $branchcode = $userenv->{'branch'};
53
        $branchcode = $userenv->{'branch'};
54
    }
54
    }
55
    my $patron = Koha::Patrons->find( { cardnumber => $searchmember } );
55
    my $patron = Koha::Patrons->find( { cardnumber => $searchmember } );
56
57
    # search cardnumber on LDAP server
58
    if ( C4::Context->config('useldapserver')
59
        and ( my $search_cardnumber = C4::Context->preference("SearchCardnumberWithLDAP") ) ne "never")
60
    {
61
        my $ldap_error;
62
        if ( $patron ) {
63
            ($patron, $ldap_error) = C4::Auth_with_ldap::updateborrower_ldap($patron) if $search_cardnumber eq "always";
64
        } else {
65
            ($patron, $ldap_error) = C4::Auth_with_ldap::findcardnumber_ldap($searchmember);
66
        }
67
        $template->param(ldap_error => $ldap_error) if $ldap_error;
68
    }
69
56
    if (
70
    if (
57
        $patron
71
        $patron
58
        and (  ( $branchcode and $patron->branchcode eq $branchcode )
72
        and (  ( $branchcode and $patron->branchcode eq $branchcode )
(-)a/reserve/request.pl (-1 / +14 lines)
Lines 142-147 elsif ( $op eq 'cud-cancel_bulk' ) { Link Here
142
142
143
if ($findborrower) {
143
if ($findborrower) {
144
    my $patron = Koha::Patrons->find( { cardnumber => $findborrower } );
144
    my $patron = Koha::Patrons->find( { cardnumber => $findborrower } );
145
146
    # search cardnumber on LDAP server
147
    if ( C4::Context->config('useldapserver')
148
        and ( my $search_cardnumber = C4::Context->preference("SearchCardnumberWithLDAP") ) ne "never")
149
    {
150
        my $ldap_error;
151
        if ( $patron ) {
152
            ($patron, $ldap_error) = C4::Auth_with_ldap::updateborrower_ldap($patron) if $search_cardnumber eq "always";
153
        } else {
154
            ($patron, $ldap_error) = C4::Auth_with_ldap::findcardnumber_ldap($findborrower);
155
        }
156
        $template->param(ldap_error => $ldap_error) if $ldap_error;
157
    }
158
145
    $borrowernumber_hold = $patron->borrowernumber if $patron;
159
    $borrowernumber_hold = $patron->borrowernumber if $patron;
146
}
160
}
147
161
148
- 

Return to bug 11808