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

(-)a/C4/Auth.pm (-15 / +20 lines)
Lines 1982-2004 sub checkpw { Link Here
1982
    my $shib_login = $shib ? get_login_shib() : undef;
1982
    my $shib_login = $shib ? get_login_shib() : undef;
1983
1983
1984
    my @return;
1984
    my @return;
1985
    my $patron;
1986
    if ( defined $userid ) {
1987
        $patron = Koha::Patrons->find( { userid     => $userid } );
1988
        $patron = Koha::Patrons->find( { cardnumber => $userid } ) unless $patron;
1989
    }
1990
    my $check_internal_as_fallback = 0;
1985
    my $check_internal_as_fallback = 0;
1991
    my $passwd_ok                  = 0;
1986
    my $passwd_ok                  = 0;
1987
    my $patron;
1988
1992
1989
1993
    # Note: checkpw_* routines returns:
1990
    # Note: checkpw_* routines returns:
1994
    # 1 if auth is ok
1991
    # 1 if auth is ok
1995
    # 0 if auth is nok
1992
    # 0 if auth is nok
1996
    # -1 if user bind failed (LDAP only)
1993
    # -1 if user bind failed (LDAP only)
1997
1994
1998
    if ( $patron and ( $patron->account_locked ) ) {
1995
    if ( $ldap && defined($password) ) {
1999
2000
        # Nothing to check, account is locked
2001
    } elsif ( $ldap && defined($password) ) {
2002
        my ( $retval, $retcard, $retuserid );
1996
        my ( $retval, $retcard, $retuserid );
2003
        ( $retval, $retcard, $retuserid, $patron ) = checkpw_ldap(@_);    # EXTERNAL AUTH
1997
        ( $retval, $retcard, $retuserid, $patron ) = checkpw_ldap(@_);    # EXTERNAL AUTH
2004
        if ( $retval == 1 ) {
1998
        if ( $retval == 1 ) {
Lines 2012-2018 sub checkpw { Link Here
2012
        # In case of a CAS authentication, we use the ticket instead of the password
2006
        # In case of a CAS authentication, we use the ticket instead of the password
2013
        my $ticket = $query->param('ticket');
2007
        my $ticket = $query->param('ticket');
2014
        $query->delete('ticket');                                         # remove ticket to come back to original URL
2008
        $query->delete('ticket');                                         # remove ticket to come back to original URL
2015
        my ( $retval, $retcard, $retuserid, $cas_ticket, $patron ) =
2009
        my ( $retval, $retcard, $retuserid, $cas_ticket );
2010
        ( $retval, $retcard, $retuserid, $cas_ticket, $patron ) =
2016
            checkpw_cas( $ticket, $query, $type );                        # EXTERNAL AUTH
2011
            checkpw_cas( $ticket, $query, $type );                        # EXTERNAL AUTH
2017
        if ($retval) {
2012
        if ($retval) {
2018
            @return = ( $retval, $retcard, $retuserid, $patron, $cas_ticket );
2013
            @return = ( $retval, $retcard, $retuserid, $patron, $cas_ticket );
Lines 2033-2039 sub checkpw { Link Here
2033
2028
2034
        # Then, we check if it matches a valid koha user
2029
        # Then, we check if it matches a valid koha user
2035
        if ($shib_login) {
2030
        if ($shib_login) {
2036
            my ( $retval, $retcard, $retuserid, $patron ) =
2031
            my ( $retval, $retcard, $retuserid );
2032
            ( $retval, $retcard, $retuserid, $patron ) =
2037
                C4::Auth_with_shibboleth::checkpw_shib($shib_login);    # EXTERNAL AUTH
2033
                C4::Auth_with_shibboleth::checkpw_shib($shib_login);    # EXTERNAL AUTH
2038
            if ($retval) {
2034
            if ($retval) {
2039
                @return = ( $retval, $retcard, $retuserid, $patron );
2035
                @return = ( $retval, $retcard, $retuserid, $patron );
Lines 2044-2063 sub checkpw { Link Here
2044
        $check_internal_as_fallback = 1;
2040
        $check_internal_as_fallback = 1;
2045
    }
2041
    }
2046
2042
2043
    if ( $check_internal_as_fallback ){
2047
    # INTERNAL AUTH
2044
    # INTERNAL AUTH
2048
    if ($check_internal_as_fallback) {
2049
        @return = checkpw_internal( $userid, $password, $no_set_userenv );
2045
        @return = checkpw_internal( $userid, $password, $no_set_userenv );
2050
        push( @return, $patron );
2051
        $passwd_ok = 1 if $return[0] > 0;    # 1 or 2
2046
        $passwd_ok = 1 if $return[0] > 0;    # 1 or 2
2047
        $patron = Koha::Patrons->find({ cardnumber => $return[1] }) if $passwd_ok;
2048
        push @return, $patron if $patron;
2049
    }
2050
2051
     if ( defined $userid && !$patron ) {
2052
        $patron = Koha::Patrons->find( { userid     => $userid } );
2053
        $patron = Koha::Patrons->find( { cardnumber => $userid } ) unless $patron;
2054
        push @return, $patron if $check_internal_as_fallback;
2052
    }
2055
    }
2053
2056
2054
    if ($patron) {
2057
    if ($patron) {
2055
        if ($passwd_ok) {
2058
        if( $patron->account_locked ){
2059
            @return = ();
2060
        } elsif ($passwd_ok) {
2056
            $patron->update( { login_attempts => 0 } );
2061
            $patron->update( { login_attempts => 0 } );
2057
            if ( $patron->password_expired ) {
2062
            if ( $patron->password_expired ) {
2058
                @return = ( -2, $patron );
2063
                @return = ( -2, $patron );
2059
            }
2064
            }
2060
        } elsif ( !$patron->account_locked ) {
2065
        } else {
2061
            $patron->update( { login_attempts => $patron->login_attempts + 1 } );
2066
            $patron->update( { login_attempts => $patron->login_attempts + 1 } );
2062
        }
2067
        }
2063
    }
2068
    }
(-)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 => 22;
10
use Test::More tests => 23;
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 1565-1570 subtest 'AutoSelfCheckAllowed' => sub { Link Here
1565
    is( $loggedinuser,                           $sco_patron->id );
1565
    is( $loggedinuser,                           $sco_patron->id );
1566
};
1566
};
1567
1567
1568
subtest 'checkpw for users with shared cardnumber / userid ' => sub {
1569
1570
    plan tests => 8;
1571
1572
    t::lib::Mocks::mock_preference( 'RequireStrongPassword', 0 );
1573
    my $library = $builder->build_object( { class => 'Koha::Libraries' } );
1574
    my $patron_1  = $builder->build_object( { class => 'Koha::Patrons' } );
1575
    $patron_1->set_password( { password => "OnePassword" } );
1576
    my $patron_2  = $builder->build_object( { class => 'Koha::Patrons', value => { userid => $patron_1->cardnumber } } );
1577
    $patron_2->set_password( { password => "PasswordTwo" } );
1578
1579
    my ( $checkpw, $cardnumber, $userid, $patron ) = checkpw( $patron_1->cardnumber, "OnePassword", undef, undef, 1 );
1580
    ok( $checkpw, 'checkpw returns true for right password when logging in via cardnumber' );
1581
    is( $cardnumber, $patron_1->cardnumber, 'checkpw returns correct cardnumber' );
1582
    is( $userid, $patron_1->userid, 'checkpw returns correct userid' );
1583
    is( $patron->id, $patron_1->id, 'checkpw returns correct patron' );
1584
1585
    ( $checkpw, $cardnumber, $userid, $patron ) = checkpw( $patron_2->userid, "PasswordTwo", undef, undef, 1 );
1586
    ok( $checkpw, 'checkpw returns true for right password when logging in via userid' );
1587
    is( $cardnumber, $patron_2->cardnumber, 'checkpw returns correct cardnumber' );
1588
    is( $userid, $patron_2->userid, 'checkpw returns correct userid' );
1589
    is( $patron->id, $patron_2->id, 'checkpw returns correct patron' );
1590
1591
};
1592
1568
sub set_weak_password {
1593
sub set_weak_password {
1569
    my ($patron) = @_;
1594
    my ($patron) = @_;
1570
    my $password = 'password';
1595
    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