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 433-438 sub update_local { Link Here
433
    _do_changepassword($userid, $borrowerid, $password) if exists( $borrower->{'password'} );
434
    _do_changepassword($userid, $borrowerid, $password) if exists( $borrower->{'password'} );
434
}
435
}
435
436
437
# Subroutine to update a user with LDAP using its cardnumber.
438
sub updateborrower_ldap {
439
    my $patron = shift;
440
    my $cardnumber = $patron->cardnumber;
441
442
    return unless ($config{update});
443
444
    my @hosts = split(',', $prefhost);
445
    my $db = Net::LDAP->new(\@hosts, timeout => ($ldap->{timeout} || 30)) or return;
446
447
    my $cardnumber_field = $mapping{cardnumber}->{is} or die ldapserver_error("mapping for 'cardnumber'");
448
    my $filter = Net::LDAP::Filter->new("$cardnumber_field=$cardnumber") or die "Failed to create new Net::LDAP::Filter";
449
    my $res = ($config{anonymous}) ? $db->bind : $db->bind($ldapname, password=>$ldappassword);
450
    if ($res->code) {   # connection refused
451
        warn "LDAP bind failed as ldapuser " . ($ldapname || '[ANONYMOUS]') . ": " . description($res);
452
        return;
453
    }
454
    my $search = $db->search(
455
        base => $base,
456
        filter => $filter,
457
    );
458
459
    # Search error, return undef
460
    return (undef, $search->error) if $search->code;
461
462
    my $count = $search->count;
463
    if ($count == 1) {
464
        # User was found, update!
465
        my %borrower = ldap_entry_2_hash($search->shift_entry,$cardnumber);
466
467
        &update_local($patron->userid, $patron->password, $patron->borrowernumber, \%borrower);
468
469
        my $updated_patron = Koha::Patrons->find( $patron->borrowernumber );
470
        return $updated_patron;
471
    }
472
    else {
473
        return;
474
    }
475
476
}
477
478
# Subroutine to search for a user by its cardnumber through LDAP.
479
# The user is added locally if found. (We suppose this user doesn't already exist if this subroutine is called)
480
sub findcardnumber_ldap {
481
    my $cardnumber = shift;
482
483
    return unless ($config{replicate});
484
485
    my @hosts = split(',', $prefhost);
486
    my $db = Net::LDAP->new(\@hosts, timeout => ($ldap->{timeout} || 30)) or return;
487
488
    my $cardnumber_field = $mapping{cardnumber}->{is} or die ldapserver_error("mapping for 'cardnumber'");
489
    my $filter = Net::LDAP::Filter->new("$cardnumber_field=$cardnumber") or die "Failed to create new Net::LDAP::Filter";
490
    my $res = ($config{anonymous}) ? $db->bind : $db->bind($ldapname, password=>$ldappassword);
491
    if ($res->code) {   # connection refused
492
        warn "LDAP bind failed as ldapuser " . ($ldapname || '[ANONYMOUS]') . ": " . description($res);
493
        return;
494
    }
495
    my $search = $db->search(
496
        base => $base,
497
        filter => $filter,
498
    );
499
500
    # Search error, return undef
501
    return (undef, $search->error) if $search->code;
502
503
    my $count = $search->count;
504
    if ($count == 1) {
505
        # User was found, add it!
506
        my %borrower = ldap_entry_2_hash($search->shift_entry,$cardnumber);
507
508
        # Generate a random password to keep the user secure if no password was mapped
509
        my @chars = ( "A" .. "Z", "a" .. "z", 0 .. 9, qw(! @ $ % ^ & *) );
510
        $borrower{'password'} = join("", @chars[ map { rand @chars } ( 1 .. 30 ) ]) unless $borrower{'password'};
511
512
        try {
513
            my @columns = Koha::Patrons->columns;
514
            my $patron = Koha::Patron->new(
515
                {
516
                    map { exists( $borrower{$_} ) ? ( $_ => $borrower{$_} ) : () } @columns
517
                }
518
            )->store;
519
            return $patron;
520
        } catch {
521
            return (undef, $_->{msg});
522
        };
523
    }
524
    else {
525
        return;
526
    }
527
528
}
529
436
1;
530
1;
437
__END__
531
__END__
438
532
(-)a/circ/circulation.pl (+14 lines)
Lines 220-225 my $message; Link Here
220
if ($findborrower) {
220
if ($findborrower) {
221
    Koha::Plugins->call( 'patron_barcode_transform', \$findborrower );
221
    Koha::Plugins->call( 'patron_barcode_transform', \$findborrower );
222
    my $patron = Koha::Patrons->find( { cardnumber => $findborrower } );
222
    my $patron = Koha::Patrons->find( { cardnumber => $findborrower } );
223
224
    # search cardnumber on LDAP server
225
    if ( C4::Context->config('useldapserver')
226
        and ( my $search_cardnumber = C4::Context->preference("SearchCardnumberWithLDAP") ) ne "never")
227
    {
228
        my $ldap_error;
229
        if ( $patron ) {
230
            ($patron, $ldap_error) = C4::Auth_with_ldap::updateborrower_ldap($patron) if $search_cardnumber eq "always";
231
        } else {
232
            ($patron, $ldap_error) = C4::Auth_with_ldap::findcardnumber_ldap($findborrower);
233
        }
234
        $template->param(ldap_error => $ldap_error) if $ldap_error;
235
    }
236
223
    if ( $patron ) {
237
    if ( $patron ) {
224
        $borrowernumber = $patron->borrowernumber;
238
        $borrowernumber = $patron->borrowernumber;
225
    } else {
239
    } 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 ( $action eq 'create' ) {
74
if ( $action eq '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 636-641 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
636
('SCOMainUserBlock','','70|10','Add a block of HTML that will display on the self checkout screen','Textarea'),
636
('SCOMainUserBlock','','70|10','Add a block of HTML that will display on the self checkout screen','Textarea'),
637
('SCOUserCSS','',NULL,'Add CSS to be included in the SCO module in an embedded <style> tag.','free'),
637
('SCOUserCSS','',NULL,'Add CSS to be included in the SCO module in an embedded <style> tag.','free'),
638
('SCOUserJS','',NULL,'Define custom javascript for inclusion in the SCO module','free'),
638
('SCOUserJS','',NULL,'Define custom javascript for inclusion in the SCO module','free'),
639
('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'),
639
('SearchEngine','Zebra','Elasticsearch|Zebra','Search Engine','Choice'),
640
('SearchEngine','Zebra','Elasticsearch|Zebra','Search Engine','Choice'),
640
('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'),
641
('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'),
641
('SearchMyLibraryFirst','0',NULL,'If ON, OPAC searches return results limited by the user\'s library by default if they are logged in','YesNo'),
642
('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 183-188 Patrons: Link Here
183
               cardnumber: cardnumber as
183
               cardnumber: cardnumber as
184
               "OFF": first valid
184
               "OFF": first valid
185
         - "patron email address for sending out emails."
185
         - "patron email address for sending out emails."
186
     -
187
         - pref: SearchCardnumberWithLDAP
188
           choices:
189
               always: Always
190
               not_found: If not found locally,
191
               never: Never
192
         - "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."
186
     -
193
     -
187
         - pref: TalkingTechItivaPhoneNotification
194
         - pref: TalkingTechItivaPhoneNotification
188
           choices:
195
           choices:
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt (+5 lines)
Lines 623-628 Link Here
623
623
624
                    [% IF ( message ) %]
624
                    [% IF ( message ) %]
625
                        [% INCLUDE 'patron-toolbar.inc' %]
625
                        [% INCLUDE 'patron-toolbar.inc' %]
626
                        [% IF (ldap_error) %]
627
                            <div class="dialog alert">
628
                                An error occured while searching for cardnumber on the LDAP server : [% ldap_error | html %]
629
                            </div>
630
                        [% END %]
626
                        <h4>No patron matched <span class="ex">[% message | html %]</span></h4>
631
                        <h4>No patron matched <span class="ex">[% message | html %]</span></h4>
627
                    [% END %]
632
                    [% END %]
628
633
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/request-article.tt (+6 lines)
Lines 95-100 Link Here
95
        <div class="col-sm-10 col-sm-push-2">
95
        <div class="col-sm-10 col-sm-push-2">
96
            <main>
96
            <main>
97
97
98
                [% IF (ldap_error) %]
99
                    <div class="dialog alert">
100
                        An error occured while searching for cardnumber on the LDAP server : [% ldap_error | html %]
101
                    </div>
102
                [% END %]
103
98
                    <h1>Request article from [% INCLUDE 'biblio-title.inc' link = 1 %]</h1>
104
                    <h1>Request article from [% INCLUDE 'biblio-title.inc' link = 1 %]</h1>
99
                    [% IF error_message %]
105
                    [% IF error_message %]
100
                        <div class="dialog alert">
106
                        <div class="dialog alert">
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/member.tt (+6 lines)
Lines 106-111 Link Here
106
                </div>
106
                </div>
107
            [% END %]
107
            [% END %]
108
108
109
            [% IF (ldap_error) %]
110
                <div class="dialog alert">
111
                    An error occured while searching for cardnumber on the LDAP server : [% ldap_error | html %]
112
                </div>
113
            [% END %]
114
109
            [% IF CAN_user_borrowers_edit_borrowers || CAN_user_tools_manage_patron_lists %]
115
            [% IF CAN_user_borrowers_edit_borrowers || CAN_user_tools_manage_patron_lists %]
110
                [% columns.unshift('checkbox') | html %]
116
                [% columns.unshift('checkbox') | html %]
111
            [% END %]
117
            [% END %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt (+6 lines)
Lines 189-194 Link Here
189
                </div>
189
                </div>
190
            [% END %]
190
            [% END %]
191
191
192
            [% IF (ldap_error) %]
193
                <div class="dialog alert">
194
                    An error occured while searching for cardnumber on the LDAP server : [% ldap_error | html %]
195
                </div>
196
            [% END %]
197
192
            [% UNLESS ( multi_hold ) %]
198
            [% UNLESS ( multi_hold ) %]
193
                <h2>Place a hold on [% INCLUDE 'biblio-title.inc' link = 1 %] [% IF biblio.author %] by [% biblio.author | html %][% END %]</h2>
199
                <h2>Place a hold on [% INCLUDE 'biblio-title.inc' link = 1 %] [% IF biblio.author %] by [% biblio.author | html %][% END %]</h2>
194
            [% ELSE %]
200
            [% 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 ( $action eq 'cancelBulk' ) { 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