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 |
- |
|
|