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

(-)a/C4/Auth.pm (-15 / +20 lines)
Lines 1965-1987 sub checkpw { Link Here
1965
    my $shib_login = $shib ? get_login_shib() : undef;
1965
    my $shib_login = $shib ? get_login_shib() : undef;
1966
1966
1967
    my @return;
1967
    my @return;
1968
    my $patron;
1969
    if ( defined $userid ) {
1970
        $patron = Koha::Patrons->find( { userid     => $userid } );
1971
        $patron = Koha::Patrons->find( { cardnumber => $userid } ) unless $patron;
1972
    }
1973
    my $check_internal_as_fallback = 0;
1968
    my $check_internal_as_fallback = 0;
1974
    my $passwd_ok                  = 0;
1969
    my $passwd_ok                  = 0;
1970
    my $patron;
1971
1975
1972
1976
    # Note: checkpw_* routines returns:
1973
    # Note: checkpw_* routines returns:
1977
    # 1 if auth is ok
1974
    # 1 if auth is ok
1978
    # 0 if auth is nok
1975
    # 0 if auth is nok
1979
    # -1 if user bind failed (LDAP only)
1976
    # -1 if user bind failed (LDAP only)
1980
1977
1981
    if ( $patron and ( $patron->account_locked ) ) {
1978
    if ( $ldap && defined($password) ) {
1982
1983
        # Nothing to check, account is locked
1984
    } elsif ( $ldap && defined($password) ) {
1985
        my ( $retval, $retcard, $retuserid );
1979
        my ( $retval, $retcard, $retuserid );
1986
        ( $retval, $retcard, $retuserid, $patron ) = checkpw_ldap(@_);    # EXTERNAL AUTH
1980
        ( $retval, $retcard, $retuserid, $patron ) = checkpw_ldap(@_);    # EXTERNAL AUTH
1987
        if ( $retval == 1 ) {
1981
        if ( $retval == 1 ) {
Lines 1995-2001 sub checkpw { Link Here
1995
        # In case of a CAS authentication, we use the ticket instead of the password
1989
        # In case of a CAS authentication, we use the ticket instead of the password
1996
        my $ticket = $query->param('ticket');
1990
        my $ticket = $query->param('ticket');
1997
        $query->delete('ticket');                                         # remove ticket to come back to original URL
1991
        $query->delete('ticket');                                         # remove ticket to come back to original URL
1998
        my ( $retval, $retcard, $retuserid, $cas_ticket, $patron ) =
1992
        my ( $retval, $retcard, $retuserid, $cas_ticket );
1993
        ( $retval, $retcard, $retuserid, $cas_ticket, $patron ) =
1999
            checkpw_cas( $ticket, $query, $type );                        # EXTERNAL AUTH
1994
            checkpw_cas( $ticket, $query, $type );                        # EXTERNAL AUTH
2000
        if ($retval) {
1995
        if ($retval) {
2001
            @return = ( $retval, $retcard, $retuserid, $patron, $cas_ticket );
1996
            @return = ( $retval, $retcard, $retuserid, $patron, $cas_ticket );
Lines 2016-2022 sub checkpw { Link Here
2016
2011
2017
        # Then, we check if it matches a valid koha user
2012
        # Then, we check if it matches a valid koha user
2018
        if ($shib_login) {
2013
        if ($shib_login) {
2019
            my ( $retval, $retcard, $retuserid, $patron ) =
2014
            my ( $retval, $retcard, $retuserid );
2015
            ( $retval, $retcard, $retuserid, $patron ) =
2020
                C4::Auth_with_shibboleth::checkpw_shib($shib_login);    # EXTERNAL AUTH
2016
                C4::Auth_with_shibboleth::checkpw_shib($shib_login);    # EXTERNAL AUTH
2021
            if ($retval) {
2017
            if ($retval) {
2022
                @return = ( $retval, $retcard, $retuserid, $patron );
2018
                @return = ( $retval, $retcard, $retuserid, $patron );
Lines 2027-2046 sub checkpw { Link Here
2027
        $check_internal_as_fallback = 1;
2023
        $check_internal_as_fallback = 1;
2028
    }
2024
    }
2029
2025
2026
    if ( $check_internal_as_fallback ){
2030
    # INTERNAL AUTH
2027
    # INTERNAL AUTH
2031
    if ($check_internal_as_fallback) {
2032
        @return = checkpw_internal( $userid, $password, $no_set_userenv );
2028
        @return = checkpw_internal( $userid, $password, $no_set_userenv );
2033
        push( @return, $patron );
2034
        $passwd_ok = 1 if $return[0] > 0;    # 1 or 2
2029
        $passwd_ok = 1 if $return[0] > 0;    # 1 or 2
2030
        $patron = Koha::Patrons->find({ cardnumber => $return[1] }) if $passwd_ok;
2031
        push @return, $patron if $patron;
2032
    }
2033
2034
     if ( defined $userid && !$patron ) {
2035
        $patron = Koha::Patrons->find( { userid     => $userid } );
2036
        $patron = Koha::Patrons->find( { cardnumber => $userid } ) unless $patron;
2037
        push @return, $patron if $check_internal_as_fallback;
2035
    }
2038
    }
2036
2039
2037
    if ($patron) {
2040
    if ($patron) {
2038
        if ($passwd_ok) {
2041
        if( $patron->account_locked ){
2042
            @return = ();
2043
        } elsif ($passwd_ok) {
2039
            $patron->update( { login_attempts => 0 } );
2044
            $patron->update( { login_attempts => 0 } );
2040
            if ( $patron->password_expired ) {
2045
            if ( $patron->password_expired ) {
2041
                @return = ( -2, $patron );
2046
                @return = ( -2, $patron );
2042
            }
2047
            }
2043
        } elsif ( !$patron->account_locked ) {
2048
        } else {
2044
            $patron->update( { login_attempts => $patron->login_attempts + 1 } );
2049
            $patron->update( { login_attempts => $patron->login_attempts + 1 } );
2045
        }
2050
        }
2046
    }
2051
    }
(-)a/t/db_dependent/Auth.t (-2 / +27 lines)
Lines 7-13 use CGI qw ( -utf8 ); Link Here
7
use Test::MockObject;
7
use Test::MockObject;
8
use Test::MockModule;
8
use Test::MockModule;
9
use List::MoreUtils qw/all any none/;
9
use List::MoreUtils qw/all any none/;
10
use Test::More tests => 21;
10
use Test::More tests => 22;
11
use Test::Warn;
11
use Test::Warn;
12
use t::lib::Mocks;
12
use t::lib::Mocks;
13
use t::lib::TestBuilder;
13
use t::lib::TestBuilder;
Lines 458-464 subtest 'checkpw lockout tests' => sub { Link Here
458
    ( $checkpw, undef, undef ) = checkpw( $patron->userid, $password, undef, undef, 1 );
458
    ( $checkpw, undef, undef ) = checkpw( $patron->userid, $password, undef, undef, 1 );
459
    is( $checkpw, undef, 'checkpw returns undef with right password when account locked' );
459
    is( $checkpw, undef, 'checkpw returns undef with right password when account locked' );
460
    ( $checkpw, undef, undef ) = checkpw( $patron->cardnumber, $password, undef, undef, 1 );
460
    ( $checkpw, undef, undef ) = checkpw( $patron->cardnumber, $password, undef, undef, 1 );
461
    is( $checkpw, undef, 'checkpw returns undefwith right password when logging in via cardnumber if account locked' );
461
    is( $checkpw, undef, 'checkpw returns undef with right password when logging in via cardnumber if account locked' );
462
462
463
};
463
};
464
464
Lines 1442-1447 subtest 'AutoSelfCheckAllowed' => sub { Link Here
1442
    is( $loggedinuser,                           $sco_patron->id );
1442
    is( $loggedinuser,                           $sco_patron->id );
1443
};
1443
};
1444
1444
1445
subtest 'checkpw for users with shared cardnumber / userid ' => sub {
1446
1447
    plan tests => 8;
1448
1449
    t::lib::Mocks::mock_preference( 'RequireStrongPassword', 0 );
1450
    my $library = $builder->build_object( { class => 'Koha::Libraries' } );
1451
    my $patron_1  = $builder->build_object( { class => 'Koha::Patrons' } );
1452
    $patron_1->set_password( { password => "OnePassword" } );
1453
    my $patron_2  = $builder->build_object( { class => 'Koha::Patrons', value => { userid => $patron_1->cardnumber } } );
1454
    $patron_2->set_password( { password => "PasswordTwo" } );
1455
1456
    my ( $checkpw, $cardnumber, $userid, $patron ) = checkpw( $patron_1->cardnumber, "OnePassword", undef, undef, 1 );
1457
    ok( $checkpw, 'checkpw returns true for right password when logging in via cardnumber' );
1458
    is( $cardnumber, $patron_1->cardnumber, 'checkpw returns correct cardnumber' );
1459
    is( $userid, $patron_1->userid, 'checkpw returns correct userid' );
1460
    is( $patron->id, $patron_1->id, 'checkpw returns correct patron' );
1461
1462
    ( $checkpw, $cardnumber, $userid, $patron ) = checkpw( $patron_2->userid, "PasswordTwo", undef, undef, 1 );
1463
    ok( $checkpw, 'checkpw returns true for right password when logging in via userid' );
1464
    is( $cardnumber, $patron_2->cardnumber, 'checkpw returns correct cardnumber' );
1465
    is( $userid, $patron_2->userid, 'checkpw returns correct userid' );
1466
    is( $patron->id, $patron_2->id, 'checkpw returns correct patron' );
1467
1468
};
1469
1445
sub set_weak_password {
1470
sub set_weak_password {
1446
    my ($patron) = @_;
1471
    my ($patron) = @_;
1447
    my $password = 'password';
1472
    my $password = 'password';
(-)a/t/db_dependent/api/v1/password_validation.t (-2 / +60 lines)
Lines 18-24 Link Here
18
18
19
use Modern::Perl;
19
use Modern::Perl;
20
20
21
use Test::More tests => 5;
21
use Test::More tests => 6;
22
use Test::Mojo;
22
use Test::Mojo;
23
23
24
use t::lib::TestBuilder;
24
use t::lib::TestBuilder;
Lines 239-242 subtest 'password validation - expired password' => sub { Link Here
239
    $schema->storage->txn_rollback;
239
    $schema->storage->txn_rollback;
240
};
240
};
241
241
242
subtest 'password validation - users with shared cardnumber / userid' => sub {
243
244
    plan tests => 12;
245
246
    $schema->storage->txn_begin;
247
248
    my $patron_1 = $builder->build_object(
249
        {
250
            class => 'Koha::Patrons',
251
            value => { }
252
        }
253
    );
254
    my $patron_password_1 = 'thePassword123';
255
    $patron_1->set_password( { password => $patron_password_1, skip_validation => 1 } );
256
257
    my $patron_2 = $builder->build_object(
258
        {
259
            class => 'Koha::Patrons',
260
            value => { userid => $patron_1->cardnumber }
261
        }
262
    );
263
    my $patron_password_2 = 'thePassword345';
264
    $patron_2->set_password( { password => $patron_password_2, skip_validation => 1 } );
265
266
    my $json = {
267
        identifier => $patron_1->cardnumber,
268
        password   => $patron_password_1,
269
    };
270
271
    $t->post_ok( "//$userid:$password@/api/v1/auth/password/validation" => json => $json )->status_is(201)
272
        ->json_is({ cardnumber => $patron_1->cardnumber, patron_id => $patron_1->borrowernumber, userid => $patron_1->userid} );
273
274
    $json = {
275
        identifier => $patron_2->userid,
276
        password   => $patron_password_2,
277
    };
278
279
    $t->post_ok( "//$userid:$password@/api/v1/auth/password/validation" => json => $json )->status_is(201)
280
        ->json_is({ cardnumber => $patron_2->cardnumber, patron_id => $patron_2->borrowernumber, userid => $patron_2->userid} );
281
282
    my $json = {
283
        userid => $patron_1->cardnumber,
284
        password   => $patron_password_1,
285
    };
286
287
    $t->post_ok( "//$userid:$password@/api/v1/auth/password/validation" => json => $json )->status_is(201)
288
        ->json_is({ cardnumber => $patron_1->cardnumber, patron_id => $patron_1->borrowernumber, userid => $patron_1->userid} );
289
290
    $json = {
291
        userid => $patron_2->userid,
292
        password   => $patron_password_2,
293
    };
294
295
    $t->post_ok( "//$userid:$password@/api/v1/auth/password/validation" => json => $json )->status_is(201)
296
        ->json_is({ cardnumber => $patron_2->cardnumber, patron_id => $patron_2->borrowernumber, userid => $patron_2->userid} );
297
298
    $schema->storage->txn_rollback;
299
};
300
242
$schema->storage->txn_rollback;
301
$schema->storage->txn_rollback;
243
- 

Return to bug 36575