|
Lines 20-25
use C4::Members;
Link Here
|
| 20 |
use Koha::AuthUtils qw/hash_password/; |
20 |
use Koha::AuthUtils qw/hash_password/; |
| 21 |
use Koha::Database; |
21 |
use Koha::Database; |
| 22 |
use Koha::Patrons; |
22 |
use Koha::Patrons; |
|
|
23 |
use Koha::Auth::TwoFactorAuth; |
| 23 |
|
24 |
|
| 24 |
BEGIN { |
25 |
BEGIN { |
| 25 |
use_ok('C4::Auth', qw( checkauth haspermission track_login_daily checkpw get_template_and_user checkpw_hash )); |
26 |
use_ok('C4::Auth', qw( checkauth haspermission track_login_daily checkpw get_template_and_user checkpw_hash )); |
|
Lines 38-44
$schema->storage->txn_begin;
Link Here
|
| 38 |
|
39 |
|
| 39 |
subtest 'checkauth() tests' => sub { |
40 |
subtest 'checkauth() tests' => sub { |
| 40 |
|
41 |
|
| 41 |
plan tests => 4; |
42 |
plan tests => 5; |
| 42 |
|
43 |
|
| 43 |
my $patron = $builder->build_object({ class => 'Koha::Patrons', value => { flags => undef } }); |
44 |
my $patron = $builder->build_object({ class => 'Koha::Patrons', value => { flags => undef } }); |
| 44 |
|
45 |
|
|
Lines 108-113
subtest 'checkauth() tests' => sub {
Link Here
|
| 108 |
is( $userid, undef, 'If librarian user is used and password with GET, they should not be logged in' ); |
109 |
is( $userid, undef, 'If librarian user is used and password with GET, they should not be logged in' ); |
| 109 |
}; |
110 |
}; |
| 110 |
|
111 |
|
|
|
112 |
subtest 'Two-factor authentication' => sub { |
| 113 |
|
| 114 |
my $patron = $builder->build_object( |
| 115 |
{ class => 'Koha::Patrons', value => { flags => 1 } } ); |
| 116 |
my $password = 'password'; |
| 117 |
$patron->set_password( { password => $password } ); |
| 118 |
$cgi = Test::MockObject->new(); |
| 119 |
|
| 120 |
my $otp_token; |
| 121 |
our ( $logout, $sessionID, $verified ); |
| 122 |
$cgi->mock( |
| 123 |
'param', |
| 124 |
sub { |
| 125 |
my ( $self, $param ) = @_; |
| 126 |
if ( $param eq 'userid' ) { return $patron->userid; } |
| 127 |
elsif ( $param eq 'password' ) { return $password; } |
| 128 |
elsif ( $param eq 'otp_token' ) { return $otp_token; } |
| 129 |
elsif ( $param eq 'logout.x' ) { return $logout; } |
| 130 |
else { return; } |
| 131 |
} |
| 132 |
); |
| 133 |
$cgi->mock( 'request_method', sub { return 'POST' } ); |
| 134 |
$cgi->mock( 'cookie', sub { return $sessionID } ); |
| 135 |
|
| 136 |
my $two_factor_auth = Test::MockModule->new( 'Koha::Auth::TwoFactorAuth' ); |
| 137 |
$two_factor_auth->mock( 'verify', sub {$verified} ); |
| 138 |
|
| 139 |
my ( $userid, $cookie, $flags ); |
| 140 |
( $userid, $cookie, $sessionID, $flags ) = C4::Auth::checkauth( $cgi, 'authrequired', undef, 'intranet' ); |
| 141 |
|
| 142 |
sub logout { |
| 143 |
my $cgi = shift; |
| 144 |
$logout = 1; |
| 145 |
undef $sessionID; |
| 146 |
C4::Auth::checkauth( $cgi, 'authrequired', undef, 'intranet' ); |
| 147 |
$logout = 0; |
| 148 |
} |
| 149 |
|
| 150 |
t::lib::Mocks::mock_preference( 'TwoFactorAuthentication', 0 ); |
| 151 |
$patron->auth_method('password')->store; |
| 152 |
( $userid, $cookie, $sessionID, $flags ) = C4::Auth::checkauth( $cgi, 'authrequired', undef, 'intranet' ); |
| 153 |
is( $userid, $patron->userid, 'Succesful login' ); |
| 154 |
is( C4::Auth::get_session($sessionID)->param('waiting-for-2FA'), undef, 'Second auth not required' ); |
| 155 |
logout($cgi); |
| 156 |
|
| 157 |
$patron->auth_method('two-factor')->store; |
| 158 |
( $userid, $cookie, $sessionID, $flags ) = C4::Auth::checkauth( $cgi, 'authrequired', undef, 'intranet' ); |
| 159 |
is( $userid, $patron->userid, 'Succesful login' ); |
| 160 |
is( C4::Auth::get_session($sessionID)->param('waiting-for-2FA'), undef, 'Second auth not required' ); |
| 161 |
logout($cgi); |
| 162 |
|
| 163 |
t::lib::Mocks::mock_preference( 'TwoFactorAuthentication', 1 ); |
| 164 |
$patron->auth_method('password')->store; |
| 165 |
( $userid, $cookie, $sessionID, $flags ) = C4::Auth::checkauth( $cgi, 'authrequired', undef, 'intranet' ); |
| 166 |
is( $userid, $patron->userid, 'Succesful login' ); |
| 167 |
is( C4::Auth::get_session($sessionID)->param('waiting-for-2FA'), undef, 'Second auth not required' ); |
| 168 |
logout($cgi); |
| 169 |
|
| 170 |
$patron->auth_method('two-factor')->store; |
| 171 |
( $userid, $cookie, $sessionID, $flags ) = C4::Auth::checkauth( $cgi, 'authrequired', undef, 'intranet' ); |
| 172 |
is( $userid, $patron->userid, 'Succesful login' ); |
| 173 |
my $session = C4::Auth::get_session($sessionID); |
| 174 |
is( C4::Auth::get_session($sessionID)->param('waiting-for-2FA'), 1, 'Second auth required' ); |
| 175 |
|
| 176 |
# Wrong OTP token |
| 177 |
$otp_token = "wrong"; |
| 178 |
$verified = 0; |
| 179 |
$patron->auth_method('two-factor')->store; |
| 180 |
( $userid, $cookie, $sessionID, $flags ) = C4::Auth::checkauth( $cgi, 'authrequired', undef, 'intranet' ); |
| 181 |
is( $userid, $patron->userid, 'Succesful login' ); |
| 182 |
is( C4::Auth::get_session($sessionID)->param('waiting-for-2FA'), 1, 'Second auth still required after wrong OTP token' ); |
| 183 |
|
| 184 |
$otp_token = "good"; |
| 185 |
$verified = 1; |
| 186 |
( $userid, $cookie, $sessionID, $flags ) = C4::Auth::checkauth( $cgi, 'authrequired', undef, 'intranet' ); |
| 187 |
is( $userid, $patron->userid, 'Succesful login' ); |
| 188 |
is( C4::Auth::get_session($sessionID)->param('waiting-for-2FA'), 0, 'Second auth no longer required if OTP token has been verified' ); |
| 189 |
|
| 190 |
}; |
| 191 |
|
| 111 |
C4::Context->_new_userenv; # For next tests |
192 |
C4::Context->_new_userenv; # For next tests |
| 112 |
|
193 |
|
| 113 |
}; |
194 |
}; |
| 114 |
- |
|
|