aboutsummaryrefslogtreecommitdiffstats
path: root/t/app/controller/auth.t
diff options
context:
space:
mode:
authorMarius Halden <marius.h@lden.org>2020-09-29 14:23:52 +0200
committerMarius Halden <marius.h@lden.org>2020-09-29 14:23:52 +0200
commita27ce1524d801d2742a2bdb6ec1da45126d64353 (patch)
tree64123c4e17dc1776aa0a7cd65ee01d49d3e7d978 /t/app/controller/auth.t
parent377bd96aab7cad3434185c30eb908c9da447fe40 (diff)
parent2773c60226b9370fe8ee00f7b205b571bb87c3b5 (diff)
Merge tag 'v3.0.1' into fiksgatami-dev
Diffstat (limited to 't/app/controller/auth.t')
-rw-r--r--t/app/controller/auth.t171
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();