diff options
author | Marius Halden <marius.h@lden.org> | 2020-09-29 14:23:52 +0200 |
---|---|---|
committer | Marius Halden <marius.h@lden.org> | 2020-09-29 14:23:52 +0200 |
commit | a27ce1524d801d2742a2bdb6ec1da45126d64353 (patch) | |
tree | 64123c4e17dc1776aa0a7cd65ee01d49d3e7d978 /t/app/controller/auth.t | |
parent | 377bd96aab7cad3434185c30eb908c9da447fe40 (diff) | |
parent | 2773c60226b9370fe8ee00f7b205b571bb87c3b5 (diff) |
Merge tag 'v3.0.1' into fiksgatami-dev
Diffstat (limited to 't/app/controller/auth.t')
-rw-r--r-- | t/app/controller/auth.t | 171 |
1 files changed, 160 insertions, 11 deletions
diff --git a/t/app/controller/auth.t b/t/app/controller/auth.t index ffabc75f3..24deb8cab 100644 --- a/t/app/controller/auth.t +++ b/t/app/controller/auth.t @@ -1,3 +1,19 @@ +package FixMyStreet::Cobrand::Dummy; +use parent 'FixMyStreet::Cobrand::Default'; + +sub must_have_2fa { + my ($self, $user) = @_; + return 'skip' if $user->name eq 'skip'; + return 1; +} + +package FixMyStreet::Cobrand::Expiring; +use parent 'FixMyStreet::Cobrand::Default'; + +sub password_expiry { 86400 } + +package main; + use Test::MockModule; use FixMyStreet::TestMech; @@ -7,10 +23,6 @@ my $test_email = 'test@example.com'; my $test_email3 = 'newuser@example.org'; my $test_password = 'foobar123'; -END { - done_testing(); -} - $mech->get_ok('/auth'); # check that we can't reach a page that is only available to authenticated users @@ -81,7 +93,7 @@ $mech->not_logged_in_ok; # check that the user does not exist sub get_user { - FixMyStreet::App->model('DB::User')->find( { email => $test_email } ); + FixMyStreet::DB->resultset('User')->find( { email => $test_email } ); } ok !get_user(), "no user exists"; @@ -92,8 +104,10 @@ $mech->not_logged_in_ok; # visit the confirm link and check user is confirmed $mech->get_ok($link); - ok get_user(), "user created"; + my $user = get_user(); + ok $user, "user created"; is $mech->uri->path, '/my', "redirected to the 'my' section of site"; + ok $user->get_extra_metadata('last_password_change'), 'password change set'; $mech->logged_in_ok; # logout @@ -154,7 +168,7 @@ subtest "sign in with uppercase email" => sub { $mech->content_contains($test_email); $mech->content_lacks($uc_test_email); - my $count = FixMyStreet::App->model('DB::User')->search( { email => $uc_test_email } )->count; + my $count = FixMyStreet::DB->resultset('User')->search( { email => $uc_test_email } )->count; is $count, 0, "uppercase user wasn't created"; }; @@ -178,7 +192,7 @@ FixMyStreet::override_config { ok $mech->email_count_is(0); - my $count = FixMyStreet::App->model('DB::User')->search( { email => $test_email3 } )->count; + my $count = FixMyStreet::DB->resultset('User')->search( { email => $test_email3 } )->count; is $count, 0, "no user exists"; }; @@ -229,7 +243,7 @@ subtest "check logging in with token" => sub { $mech->log_out_ok; $mech->not_logged_in_ok; - my $user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } ); + my $user = FixMyStreet::DB->resultset('User')->find( { email => $test_email } ); # token needs to be 18 characters $user->set_extra_metadata('access_token', '1234567890abcdefgh'); $user->update(); @@ -281,6 +295,7 @@ subtest 'test forgotten password page' => sub { fields => { username => $test_email, password_register => 'squirblewirble' }, button => 'sign_in_by_code', }); + $mech->clear_emails_ok; }; subtest "Test two-factor authentication login" => sub { @@ -289,8 +304,7 @@ subtest "Test two-factor authentication login" => sub { my $code = $auth->code; my $wrong_code = $auth->code(undef, time() - 120); - my $user = FixMyStreet::App->model('DB::User')->find( { email => $test_email } ); - $user->is_superuser(1); + my $user = FixMyStreet::DB->resultset('User')->find( { email => $test_email } ); $user->password('password'); $user->set_extra_metadata('2fa_secret', $auth->secret32); $user->update; @@ -305,3 +319,138 @@ subtest "Test two-factor authentication login" => sub { $mech->submit_form_ok({ with_fields => { '2fa_code' => $code } }, "provide correct 2FA code" ); $mech->logged_in_ok; }; + +subtest "Test enforced two-factor authentication" => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => 'dummy', + }, sub { + my $user = FixMyStreet::DB->resultset('User')->find( { email => $test_email } ); + $user->unset_extra_metadata('2fa_secret'); + $user->update; + + $mech->get_ok('/auth'); + $mech->submit_form_ok( + { with_fields => { username => $test_email, password_sign_in => 'password' } }, + "sign in using form" ); + + $mech->content_contains('requires two-factor'); + $mech->submit_form_ok({ with_fields => { '2fa_action' => 'activate' } }, "submit 2FA activation"); + my ($token) = $mech->content =~ /name="secret32" value="([^"]*)">/; + + use Auth::GoogleAuth; + my $auth = Auth::GoogleAuth->new({ secret32 => $token }); + my $code = $auth->code; + my $wrong_code = $auth->code(undef, time() - 120); + + $mech->submit_form_ok({ with_fields => { '2fa_code' => $wrong_code } }, "provide wrong 2FA code" ); + $mech->content_contains('Try again'); + $mech->submit_form_ok({ with_fields => { '2fa_code' => $code } }, "provide correct 2FA code" ); + $mech->content_contains('successfully enabled two-factor authentication', "2FA activated"); + + $user->discard_changes(); + my $user_token = $user->get_extra_metadata('2fa_secret'); + is $token, $user_token, '2FA secret set'; + + $mech->logged_in_ok; + + $user->name('skip'); + $user->update; + $mech->get_ok('/auth'); + $mech->submit_form_ok( + { with_fields => { username => $test_email, password_sign_in => 'password' } }, + "sign in using form" ); + $mech->content_contains('<h1>Your account'); + }; +}; + +subtest "Test enforced two-factor authentication, no password yet set" => sub { + FixMyStreet::override_config { + ALLOWED_COBRANDS => 'dummy', + }, sub { + my $user = FixMyStreet::DB->resultset('User')->find( { email => $test_email } ); + $user->unset_extra_metadata('2fa_secret'); + $user->name('Test User'); + $user->update; + + $mech->clear_emails_ok; + $mech->get_ok('/auth'); + $mech->submit_form_ok({ + fields => { username => $test_email, password_register => $test_password }, + button => 'sign_in_by_code', + }, "log in by email"); + + my $link = $mech->get_link_from_email; + $mech->get_ok($link); + + $mech->content_contains('requires two-factor'); + $mech->submit_form_ok({ with_fields => { '2fa_action' => 'activate' } }, "submit 2fa activation"); + my ($token) = $mech->content =~ /name="secret32" value="([^"]*)">/; + + my $auth = Auth::GoogleAuth->new({ secret32 => $token }); + my $code = $auth->code; + $mech->submit_form_ok({ with_fields => { '2fa_code' => $code } }, "provide correct 2fa code" ); + + $user->discard_changes(); + my $user_token = $user->get_extra_metadata('2fa_secret'); + is $token, $user_token, '2FA secret set'; + + $mech->logged_in_ok; + + $mech->get_ok($link); + $mech->content_contains('Please generate a two-factor code'); + $mech->submit_form_ok({ with_fields => { '2fa_code' => $code } }, "provide correct 2FA code" ); + $mech->content_lacks('requires two-factor'); + + $user->name('skip'); + $user->update; + $mech->get_ok($link); + $mech->content_contains('Your account'); + }; +}; + +subtest "Check two-factor log in by email works" => sub { + use Auth::GoogleAuth; + my $auth = Auth::GoogleAuth->new; + my $code = $auth->code; + + my $user = FixMyStreet::DB->resultset('User')->find( { email => $test_email } ); + $user->set_extra_metadata('2fa_secret', $auth->secret32); + $user->update; + + $mech->clear_emails_ok; + $mech->get_ok('/auth'); + $mech->submit_form_ok({ + fields => { username => $test_email, password_register => $test_password }, + button => 'sign_in_by_code', + }, "log in by email"); + + my $link = $mech->get_link_from_email; + $mech->get_ok($link); + $mech->content_contains('Please generate a two-factor code'); + $mech->submit_form_ok({ with_fields => { '2fa_code' => $code } }, "provide correct 2FA code" ); + $mech->logged_in_ok; +}; + +FixMyStreet::override_config { + ALLOWED_COBRANDS => 'expiring' +}, sub { + subtest 'Password expiry' => sub { + my $user = FixMyStreet::DB->resultset('User')->find( { email => $test_email } ); + $user->set_extra_metadata('last_password_change', time() - 200000); + $user->unset_extra_metadata('2fa_secret'); + $user->update; + + $mech->get_ok('/'); + $mech->content_contains('Password expired'); + $mech->submit_form_ok( + { with_fields => { password_register => 'new-password' } }, + "fill in reset form" ); + + my $link = $mech->get_link_from_email; + $mech->clear_emails_ok; + $mech->get_ok($link); + $mech->logged_in_ok; + }; +}; + +done_testing(); |