diff options
Diffstat (limited to 'perllib/Catalyst/Authentication')
-rw-r--r-- | perllib/Catalyst/Authentication/Credential/2FA.pm | 47 |
1 files changed, 45 insertions, 2 deletions
diff --git a/perllib/Catalyst/Authentication/Credential/2FA.pm b/perllib/Catalyst/Authentication/Credential/2FA.pm index 9f22fed11..8b6771037 100644 --- a/perllib/Catalyst/Authentication/Credential/2FA.pm +++ b/perllib/Catalyst/Authentication/Credential/2FA.pm @@ -21,11 +21,54 @@ sub authenticate { my $user_obj = $realm->find_user($userfindauthinfo, $c); if (ref($user_obj)) { - # We don't care unless user has a 2FA secret - return $user_obj unless $user_obj->get_extra_metadata('2fa_secret'); + + # We don't care unless user has a 2FA secret, or the cobrand mandates it + return $user_obj unless $user_obj->has_2fa || $c->cobrand->call_hook('must_have_2fa', $user_obj); $c->stash->{token} = $c->get_param('token'); + if (!$user_obj->has_2fa) { + $c->stash->{template} = 'auth/2fa/intro.html'; + my $action = $c->get_param('2fa_action') || ''; + + my $secret; + if ($action eq 'confirm') { + $secret = $c->get_param('secret32'); + if ($c->check_2fa($secret)) { + $user_obj->set_extra_metadata('2fa_secret' => $secret); + $user_obj->update; + if ($c->stash->{token}) { + my $token = $c->forward('/tokens/load_auth_token', [ $c->stash->{token}, '2fa' ]); + # Will contain a detach_to and report/update data + $c->stash($token->data); + } else { + $c->stash->{stage} = 'success'; + $c->stash->{detach_to} = '/auth/two_factor_setup_success'; + } + return $user_obj; + } else { + $action = 'activate'; # Incorrect code, reshow + } + } + + if ($action eq 'activate') { + my $auth = Auth::GoogleAuth->new; + $c->stash->{qr_code} = $auth->qr_code($secret, $user_obj->email, 'FixMyStreet'); + $c->stash->{secret32} = $auth->secret32; + $c->stash->{stage} = 'activate'; + } + + if ($c->stash->{tfa_data}) { + my $token = $c->model("DB::Token")->create( { + scope => '2fa', + data => $c->stash->{tfa_data}, + }); + $c->stash->{token} = $token->token; + } + + $c->detach; + } + if ($c->check_2fa($user_obj->has_2fa)) { if ($c->stash->{token}) { my $token = $c->forward('/tokens/load_auth_token', [ $c->stash->{token}, '2fa' ]); |