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 436-441 sub update_local { Link Here
436
    _do_changepassword($userid, $borrowerid, $password) if exists( $borrower->{'password'} );
437
    _do_changepassword($userid, $borrowerid, $password) if exists( $borrower->{'password'} );
437
}
438
}
438
439
440
# Subroutine to update a user with LDAP using its cardnumber.
441
sub updateborrower_ldap {
442
    my $patron = shift;
443
    my $cardnumber = $patron->cardnumber;
444
445
    return unless ($config{update});
446
447
    my @hosts = split(',', $prefhost);
448
    my $db = Net::LDAP->new(\@hosts, timeout => ($ldap->{timeout} || 30)) or return;
449
450
    my $cardnumber_field = $mapping{cardnumber}->{is} or die ldapserver_error("mapping for 'cardnumber'");
451
    my $filter = Net::LDAP::Filter->new("$cardnumber_field=$cardnumber") or die "Failed to create new Net::LDAP::Filter";
452
    my $res = ($config{anonymous}) ? $db->bind : $db->bind($ldapname, password=>$ldappassword);
453
    if ($res->code) {   # connection refused
454
        warn "LDAP bind failed as ldapuser " . ($ldapname || '[ANONYMOUS]') . ": " . description($res);
455
        return;
456
    }
457
    my $search = $db->search(
458
        base => $base,
459
        filter => $filter,
460
    );
461
462
    # Search error, return undef
463
    return (undef, $search->error) if $search->code;
464
465
    my $count = $search->count;
466
    if ($count == 1) {
467
        # User was found, update!
468
        my %borrower = ldap_entry_2_hash($search->shift_entry,$cardnumber);
469
470
        &update_local($patron->userid, $patron->password, $patron->borrowernumber, \%borrower);
471
472
        my $updated_patron = Koha::Patrons->find( $patron->borrowernumber );
473
        return $updated_patron;
474
    }
475
    else {
476
        return;
477
    }
478
479
}
480
481
# Subroutine to search for a user by its cardnumber through LDAP.
482
# The user is added locally if found. (We suppose this user doesn't already exist if this subroutine is called)
483
sub findcardnumber_ldap {
484
    my $cardnumber = shift;
485
486
    return unless ($config{replicate});
487
488
    my @hosts = split(',', $prefhost);
489
    my $db = Net::LDAP->new(\@hosts, timeout => ($ldap->{timeout} || 30)) or return;
490
491
    my $cardnumber_field = $mapping{cardnumber}->{is} or die ldapserver_error("mapping for 'cardnumber'");
492
    my $filter = Net::LDAP::Filter->new("$cardnumber_field=$cardnumber") or die "Failed to create new Net::LDAP::Filter";
493
    my $res = ($config{anonymous}) ? $db->bind : $db->bind($ldapname, password=>$ldappassword);
494
    if ($res->code) {   # connection refused
495
        warn "LDAP bind failed as ldapuser " . ($ldapname || '[ANONYMOUS]') . ": " . description($res);
496
        return;
497
    }
498
    my $search = $db->search(
499
        base => $base,
500
        filter => $filter,
501
    );
502
503
    # Search error, return undef
504
    return (undef, $search->error) if $search->code;
505
506
    my $count = $search->count;
507
    if ($count == 1) {
508
        # User was found, add it!
509
        my %borrower = ldap_entry_2_hash($search->shift_entry,$cardnumber);
510
511
        # Generate a random password to keep the user secure if no password was mapped
512
        my @chars = ( "A" .. "Z", "a" .. "z", 0 .. 9, qw(! @ $ % ^ & *) );
513
        $borrower{'password'} = join("", @chars[ map { rand @chars } ( 1 .. 30 ) ]) unless $borrower{'password'};
514
515
        try {
516
            my @columns = Koha::Patrons->columns;
517
            my $patron = Koha::Patron->new(
518
                {
519
                    map { exists( $borrower{$_} ) ? ( $_ => $borrower{$_} ) : () } @columns
520
                }
521
            )->store;
522
            return $patron;
523
        } catch {
524
            return (undef, $_->{msg});
525
        };
526
    }
527
    else {
528
        return;
529
    }
530
531
}
532
439
1;
533
1;
440
__END__
534
__END__
441
535
(-)a/circ/circulation.pl (-1 / +15 lines)
Lines 243-249 my $message; Link Here
243
if ($findborrower) {
243
if ($findborrower) {
244
    Koha::Plugins->call( 'patron_barcode_transform', \$findborrower );
244
    Koha::Plugins->call( 'patron_barcode_transform', \$findborrower );
245
    my $patron = Koha::Patrons->find( { cardnumber => $findborrower } );
245
    my $patron = Koha::Patrons->find( { cardnumber => $findborrower } );
246
    if ($patron) {
246
247
    # search cardnumber on LDAP server
248
    if ( C4::Context->config('useldapserver')
249
        and ( my $search_cardnumber = C4::Context->preference("SearchCardnumberWithLDAP") ) ne "never")
250
    {
251
        my $ldap_error;
252
        if ( $patron ) {
253
            ($patron, $ldap_error) = C4::Auth_with_ldap::updateborrower_ldap($patron) if $search_cardnumber eq "always";
254
        } else {
255
            ($patron, $ldap_error) = C4::Auth_with_ldap::findcardnumber_ldap($findborrower);
256
        }
257
        $template->param(ldap_error => $ldap_error) if $ldap_error;
258
    }
259
260
    if ( $patron ) {
247
        $borrowernumber = $patron->borrowernumber;
261
        $borrowernumber = $patron->borrowernumber;
248
    } else {
262
    } else {
249
        print $query->redirect( "/cgi-bin/koha/members/member.pl?quicksearch=1&circsearch=1&searchmember="
263
        print $query->redirect( "/cgi-bin/koha/members/member.pl?quicksearch=1&circsearch=1&searchmember="
(-)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 699-704 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
699
('SCOLoadCheckoutsByDefault','1','','If enabled, load the list of a patrons checkouts when they log in to the Self Checkout','YesNo'),
699
('SCOLoadCheckoutsByDefault','1','','If enabled, load the list of a patrons checkouts when they log in to the Self Checkout','YesNo'),
700
('SCOUserCSS','',NULL,'Add CSS to be included in the SCO module in an embedded <style> tag.','free'),
700
('SCOUserCSS','',NULL,'Add CSS to be included in the SCO module in an embedded <style> tag.','free'),
701
('SCOUserJS','',NULL,'Define custom javascript for inclusion in the SCO module','free'),
701
('SCOUserJS','',NULL,'Define custom javascript for inclusion in the SCO module','free'),
702
('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'),
702
('SearchCancelledAndInvalidISBNandISSN','0',NULL,'Enable search for cancelled or invalid forms of ISBN/ISSN when performing ISBN/ISSN search (when using ES)','YesNo'),
703
('SearchCancelledAndInvalidISBNandISSN','0',NULL,'Enable search for cancelled or invalid forms of ISBN/ISSN when performing ISBN/ISSN search (when using ES)','YesNo'),
703
('SearchEngine','Zebra','Elasticsearch|Zebra','Search Engine','Choice'),
704
('SearchEngine','Zebra','Elasticsearch|Zebra','Search Engine','Choice'),
704
('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'),
705
('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'),
(-)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 726-731 Link Here
726
726
727
                    [% IF ( message ) %]
727
                    [% IF ( message ) %]
728
                        [% INCLUDE 'patron-toolbar.inc' %]
728
                        [% INCLUDE 'patron-toolbar.inc' %]
729
                        [% IF (ldap_error) %]
730
                            <div class="dialog alert">
731
                                An error occured while searching for cardnumber on the LDAP server : [% ldap_error | html %]
732
                            </div>
733
                        [% END %]
729
                        <h4>No patron matched <span class="ex">[% message | html %]</span></h4>
734
                        <h4>No patron matched <span class="ex">[% message | html %]</span></h4>
730
                    [% END %]
735
                    [% END %]
731
736
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/request-article.tt (+6 lines)
Lines 98-103 Link Here
98
            <main>
98
            <main>
99
                [% INCLUDE 'messages.inc' %]
99
                [% INCLUDE 'messages.inc' %]
100
100
101
                [% IF (ldap_error) %]
102
                    <div class="dialog alert">
103
                        An error occured while searching for cardnumber on the LDAP server : [% ldap_error | html %]
104
                    </div>
105
                [% END %]
106
101
                    <h1>Request article from [% INCLUDE 'biblio-title.inc' link = 1 %]</h1>
107
                    <h1>Request article from [% INCLUDE 'biblio-title.inc' link = 1 %]</h1>
102
                    [% IF error_message %]
108
                    [% IF error_message %]
103
                        <div class="alert alert-warning">
109
                        <div class="alert alert-warning">
(-)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 147-152 elsif ( $op eq 'cud-cancel_bulk' ) { Link Here
147
147
148
if ($findborrower) {
148
if ($findborrower) {
149
    my $patron = Koha::Patrons->find( { cardnumber => $findborrower } );
149
    my $patron = Koha::Patrons->find( { cardnumber => $findborrower } );
150
151
    # search cardnumber on LDAP server
152
    if ( C4::Context->config('useldapserver')
153
        and ( my $search_cardnumber = C4::Context->preference("SearchCardnumberWithLDAP") ) ne "never")
154
    {
155
        my $ldap_error;
156
        if ( $patron ) {
157
            ($patron, $ldap_error) = C4::Auth_with_ldap::updateborrower_ldap($patron) if $search_cardnumber eq "always";
158
        } else {
159
            ($patron, $ldap_error) = C4::Auth_with_ldap::findcardnumber_ldap($findborrower);
160
        }
161
        $template->param(ldap_error => $ldap_error) if $ldap_error;
162
    }
163
150
    $borrowernumber_hold = $patron->borrowernumber if $patron;
164
    $borrowernumber_hold = $patron->borrowernumber if $patron;
151
}
165
}
152
166
153
- 

Return to bug 11808