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
34
Lines 443-448 sub update_local { Link Here
443
    _do_changepassword( $userid, $borrowerid, $password ) if exists( $borrower->{'password'} );
444
    _do_changepassword( $userid, $borrowerid, $password ) if exists( $borrower->{'password'} );
444
}
445
}
445
446
447
# Subroutine to update a user with LDAP using its cardnumber.
448
sub updateborrower_ldap {
449
    my $patron = shift;
450
    my $cardnumber = $patron->cardnumber;
451
452
    return unless ($config{update});
453
454
    my @hosts = split(',', $prefhost);
455
    my $db = Net::LDAP->new(\@hosts, timeout => ($ldap->{timeout} || 30)) or return;
456
457
    my $cardnumber_field = $mapping{cardnumber}->{is} or die ldapserver_error("mapping for 'cardnumber'");
458
    my $filter = Net::LDAP::Filter->new("$cardnumber_field=$cardnumber") or die "Failed to create new Net::LDAP::Filter";
459
    my $res = ($config{anonymous}) ? $db->bind : $db->bind($ldapname, password=>$ldappassword);
460
    if ($res->code) {   # connection refused
461
        warn "LDAP bind failed as ldapuser " . ($ldapname || '[ANONYMOUS]') . ": " . description($res);
462
        return;
463
    }
464
    my $search = $db->search(
465
        base => $base,
466
        filter => $filter,
467
    );
468
469
    # Search error, return undef
470
    return (undef, $search->error) if $search->code;
471
472
    my $count = $search->count;
473
    if ($count == 1) {
474
        # User was found, update!
475
        my %borrower = ldap_entry_2_hash($search->shift_entry,$cardnumber);
476
477
        &update_local($patron->userid, $patron->password, $patron->borrowernumber, \%borrower);
478
479
        my $updated_patron = Koha::Patrons->find( $patron->borrowernumber );
480
        return $updated_patron;
481
    }
482
    else {
483
        return;
484
    }
485
486
}
487
488
# Subroutine to search for a user by its cardnumber through LDAP.
489
# The user is added locally if found. (We suppose this user doesn't already exist if this subroutine is called)
490
sub findcardnumber_ldap {
491
    my $cardnumber = shift;
492
493
    return unless ($config{replicate});
494
495
    my @hosts = split(',', $prefhost);
496
    my $db = Net::LDAP->new(\@hosts, timeout => ($ldap->{timeout} || 30)) or return;
497
498
    my $cardnumber_field = $mapping{cardnumber}->{is} or die ldapserver_error("mapping for 'cardnumber'");
499
    my $filter = Net::LDAP::Filter->new("$cardnumber_field=$cardnumber") or die "Failed to create new Net::LDAP::Filter";
500
    my $res = ($config{anonymous}) ? $db->bind : $db->bind($ldapname, password=>$ldappassword);
501
    if ($res->code) {   # connection refused
502
        warn "LDAP bind failed as ldapuser " . ($ldapname || '[ANONYMOUS]') . ": " . description($res);
503
        return;
504
    }
505
    my $search = $db->search(
506
        base => $base,
507
        filter => $filter,
508
    );
509
510
    # Search error, return undef
511
    return (undef, $search->error) if $search->code;
512
513
    my $count = $search->count;
514
    if ($count == 1) {
515
        # User was found, add it!
516
        my %borrower = ldap_entry_2_hash($search->shift_entry,$cardnumber);
517
518
        # Generate a random password to keep the user secure if no password was mapped
519
        my @chars = ( "A" .. "Z", "a" .. "z", 0 .. 9, qw(! @ $ % ^ & *) );
520
        $borrower{'password'} = join("", @chars[ map { rand @chars } ( 1 .. 30 ) ]) unless $borrower{'password'};
521
522
        try {
523
            my @columns = Koha::Patrons->columns;
524
            my $patron = Koha::Patron->new(
525
                {
526
                    map { exists( $borrower{$_} ) ? ( $_ => $borrower{$_} ) : () } @columns
527
                }
528
            )->store;
529
            return $patron;
530
        } catch {
531
            return (undef, $_->{msg});
532
        };
533
    }
534
    else {
535
        return;
536
    }
537
538
}
539
446
1;
540
1;
447
__END__
541
__END__
448
542
(-)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 702-707 INSERT INTO systempreferences ( `variable`, `value`, `options`, `explanation`, ` Link Here
702
('SCOLoadCheckoutsByDefault','1','','If enabled, load the list of a patrons checkouts when they log in to the Self Checkout','YesNo'),
702
('SCOLoadCheckoutsByDefault','1','','If enabled, load the list of a patrons checkouts when they log in to the Self Checkout','YesNo'),
703
('SCOUserCSS','',NULL,'Add CSS to be included in the SCO module in an embedded <style> tag.','free'),
703
('SCOUserCSS','',NULL,'Add CSS to be included in the SCO module in an embedded <style> tag.','free'),
704
('SCOUserJS','',NULL,'Define custom javascript for inclusion in the SCO module','free'),
704
('SCOUserJS','',NULL,'Define custom javascript for inclusion in the SCO module','free'),
705
('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'),
705
('SearchCancelledAndInvalidISBNandISSN','0',NULL,'Enable search for cancelled or invalid forms of ISBN/ISSN when performing ISBN/ISSN search (when using ES)','YesNo'),
706
('SearchCancelledAndInvalidISBNandISSN','0',NULL,'Enable search for cancelled or invalid forms of ISBN/ISSN when performing ISBN/ISSN search (when using ES)','YesNo'),
706
('SearchEngine','Zebra','Elasticsearch|Zebra','Search Engine','Choice'),
707
('SearchEngine','Zebra','Elasticsearch|Zebra','Search Engine','Choice'),
707
('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'),
708
('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 213-218 Patrons: Link Here
213
         - '<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.'
213
         - '<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.'
214
         - "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)."
214
         - "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)."
215
         - "Example: email|emailpro|B_email"
215
         - "Example: email|emailpro|B_email"
216
     -
217
         - pref: SearchCardnumberWithLDAP
218
           choices:
219
               always: Always
220
               not_found: If not found locally,
221
               never: Never
222
         - "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."
216
     -
223
     -
217
         - "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:"
224
         - "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:"
218
         - pref: EmailFieldSelection
225
         - pref: EmailFieldSelection
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/circulation.tt (+5 lines)
Lines 765-770 Link Here
765
765
766
    [% IF ( message ) %]
766
    [% IF ( message ) %]
767
        [% INCLUDE 'patron-toolbar.inc' %]
767
        [% INCLUDE 'patron-toolbar.inc' %]
768
        [% IF (ldap_error) %]
769
            <div class="dialog alert">
770
                An error occured while searching for cardnumber on the LDAP server : [% ldap_error | html %]
771
            </div>
772
        [% END %]
768
        <h4>No patron matched <span class="ex">[% message | html %]</span></h4>
773
        <h4>No patron matched <span class="ex">[% message | html %]</span></h4>
769
    [% END %]
774
    [% END %]
770
775
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/circ/request-article.tt (+7 lines)
Lines 94-99 Link Here
94
[% END #/ WRAPPER sub-header.inc %]
94
[% END #/ WRAPPER sub-header.inc %]
95
95
96
[% WRAPPER 'main-container.inc' aside='biblio-view-menu' %]
96
[% WRAPPER 'main-container.inc' aside='biblio-view-menu' %]
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
97
    <h1>Request article from [% INCLUDE 'biblio-title.inc' link = 1 %]</h1>
104
    <h1>Request article from [% INCLUDE 'biblio-title.inc' link = 1 %]</h1>
98
    [% IF error_message %]
105
    [% IF error_message %]
99
        <div class="alert alert-warning">
106
        <div class="alert alert-warning">
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/members/member.tt (+6 lines)
Lines 115-120 Link Here
115
                        </div>
115
                        </div>
116
                    [% END %]
116
                    [% END %]
117
117
118
                    [% IF (ldap_error) %]
119
                        <div class="dialog alert">
120
                            An error occured while searching for cardnumber on the LDAP server : [% ldap_error | html %]
121
                        </div>
122
                    [% END %]
123
118
                    [% IF CAN_user_borrowers_edit_borrowers || CAN_user_tools_manage_patron_lists %]
124
                    [% IF CAN_user_borrowers_edit_borrowers || CAN_user_tools_manage_patron_lists %]
119
                        [% columns.unshift('checkbox') | html %]
125
                        [% columns.unshift('checkbox') | html %]
120
                    [% END %]
126
                    [% END %]
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/reserve/request.tt (+17 lines)
Lines 221-226 Link Here
221
        </div>
221
        </div>
222
    [% END %]
222
    [% END %]
223
223
224
    [% IF ( messagetransfert ) %]
225
        <div class="dialog message">
226
            <h2>Hold found for ([% nextreservtitle | html %]), please transfer</h2>
227
            <p>Hold placed by : <strong> [% nextreservsurname | html %] [% nextreservfirstname | html %]</strong> at : <strong> [% branchname | html %] </strong>, Please transfer this item.
228
            </p>
229
            <form name="cancelReservewithtransfert" action="branchreserves.pl" method="post">
230
                <input type="submit" class="button" />
231
            </form>
232
        </div>
233
    [% END %]
234
235
    [% IF (ldap_error) %]
236
        <div class="dialog alert">
237
            An error occured while searching for cardnumber on the LDAP server : [% ldap_error | html %]
238
        </div>
239
    [% END %]
240
224
    [% UNLESS ( multi_hold ) %]
241
    [% UNLESS ( multi_hold ) %]
225
        <h2>Place a hold on [% INCLUDE 'biblio-title.inc' link = 1 %] [% IF biblio.author %]by [% biblio.author | html %][% END %]</h2>
242
        <h2>Place a hold on [% INCLUDE 'biblio-title.inc' link = 1 %] [% IF biblio.author %]by [% biblio.author | html %][% END %]</h2>
226
    [% ELSE %]
243
    [% 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 143-148 if ( $op eq 'cud-move' ) { Link Here
143
143
144
if ($findborrower) {
144
if ($findborrower) {
145
    my $patron = Koha::Patrons->find( { cardnumber => $findborrower } );
145
    my $patron = Koha::Patrons->find( { cardnumber => $findborrower } );
146
147
    # search cardnumber on LDAP server
148
    if ( C4::Context->config('useldapserver')
149
        and ( my $search_cardnumber = C4::Context->preference("SearchCardnumberWithLDAP") ) ne "never")
150
    {
151
        my $ldap_error;
152
        if ( $patron ) {
153
            ($patron, $ldap_error) = C4::Auth_with_ldap::updateborrower_ldap($patron) if $search_cardnumber eq "always";
154
        } else {
155
            ($patron, $ldap_error) = C4::Auth_with_ldap::findcardnumber_ldap($findborrower);
156
        }
157
        $template->param(ldap_error => $ldap_error) if $ldap_error;
158
    }
159
146
    $borrowernumber_hold = $patron->borrowernumber if $patron;
160
    $borrowernumber_hold = $patron->borrowernumber if $patron;
147
}
161
}
148
162
149
- 

Return to bug 11808