forked from openwebwork/webwork2
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
450 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
136 changes: 136 additions & 0 deletions
136
lib/WeBWorK/ContentGenerator/TwoFactorAuthentication.pm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
################################################################################ | ||
# WeBWorK Online Homework Delivery System | ||
# Copyright © 2000-2023 The WeBWorK Project, https://github.com/openwebwork | ||
# | ||
# This program is free software; you can redistribute it and/or modify it under | ||
# the terms of either: (a) the GNU General Public License as published by the | ||
# Free Software Foundation; either version 2, or (at your option) any later | ||
# version, or (b) the "Artistic License" which comes with this package. | ||
# | ||
# This program is distributed in the hope that it will be useful, but WITHOUT | ||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | ||
# FOR A PARTICULAR PURPOSE. See either the GNU General Public License or the | ||
# Artistic License for more details. | ||
################################################################################ | ||
|
||
package WeBWorK::ContentGenerator::TwoFactorAuthentication; | ||
use Mojo::Base 'WeBWorK::ContentGenerator::Login', -signatures; | ||
|
||
=head1 NAME | ||
WeBWorK::ContentGenerator::TwoFactorAuthentication - display the two factor authentication form. | ||
=cut | ||
|
||
use Imager::QRCode; | ||
use Imager::Color; | ||
use Email::Stuffer; | ||
use Mojo::Util qw(b64_encode); | ||
|
||
use WeBWorK::Utils::TOTP; | ||
use WeBWorK::Utils qw(createEmailSenderTransportSMTP); | ||
|
||
sub pre_header_initialize ($c) { | ||
my $ce = $c->ce; | ||
|
||
# Preserve the form data posted to the requested URI | ||
my @fields_to_print = | ||
grep { !m/^(user|passwd|key|force_passwd_authen|otp_code|verify_otp|cancel_otp_verification)$/ } $c->param; | ||
push(@fields_to_print, 'user', 'key') if $ce->{session_management_via} ne 'session_cookie'; | ||
$c->stash->{hidden_fields} = @fields_to_print ? $c->hidden_fields(@fields_to_print) : ''; | ||
|
||
# Make sure these are defined for the template. | ||
$c->stash->{otp_link} = ''; | ||
$c->stash->{otp_qrcode} = ''; | ||
$c->stash->{authen_error} = ''; | ||
|
||
# Note that this user has already authenticated with username and password, | ||
# so this and the $user below should exist. | ||
my $password = $c->db->getPassword($c->authen->{user_id}); | ||
|
||
if (!$password->otp_secret) { | ||
my $totp = | ||
WeBWorK::Utils::TOTP->new( | ||
$c->authen->session->{otp_secret} ? (secret => $c->authen->session->{otp_secret}) : ()); | ||
$c->authen->session(otp_secret => $totp->secret); | ||
|
||
my $otp_link = $totp->generate_otp($c->authen->{user_id}, $ce->{courseName}); | ||
Imager::QRCode->new( | ||
size => 4, | ||
margin => 3, | ||
level => 'L', | ||
casesensitive => 1, | ||
lightcolor => Imager::Color->new(255, 255, 255, 0), | ||
darkcolor => Imager::Color->new(0, 0, 0), | ||
)->plot($otp_link)->write(data => \(my $img_data), type => 'png'); | ||
|
||
my $user = $c->db->getUser($c->authen->{user_id}); | ||
|
||
if ($ce->{twoFA}{email_sender} && (my $recipient = $user->email_address)) { | ||
return if $c->authen->session->{otp_setup_email_sent}; | ||
|
||
my $mail = | ||
Email::Stuffer->to($recipient)->from($ce->{twoFA}{email_sender}) | ||
->subject($c->maketext('Setup One-Time Password Authentication'))->html_body( | ||
$c->c( | ||
$c->tag( | ||
'p', | ||
$c->maketext( | ||
'To set up one-time password generation, scan the attached QR code with an ' | ||
. 'authenticator app (such as Google Authenticator, Microsoft Authenticator, ' | ||
. 'Twilio Authy, etc.) installed on a mobile device.' | ||
) | ||
), | ||
$c->tag( | ||
'p', | ||
sub { | ||
$c->maketext( | ||
'Alternately, after installing an authenticator app on a mobile device, ' | ||
. 'open this email on that device, and click <a href="[_1]">here</a>.', | ||
$otp_link | ||
); | ||
} | ||
), | ||
$c->tag( | ||
'p', | ||
$c->maketext( | ||
'Once the authenticator app is set up, return to the login page in WeBWorK and ' | ||
. 'enter the code it shows. Remember that the attached QR code and link above are ' | ||
. 'only valid as long as the page that you were visiting when this email was sent ' | ||
. 'is still open.' | ||
) | ||
), | ||
$c->tag( | ||
'p', | ||
$c->maketext( | ||
'This email should be deleted once you have completely signed in the first time.') | ||
) | ||
)->join('')->to_string | ||
)->attach($img_data, content_type => 'image/png', filename => 'QRCode.png') | ||
->header('X-Remote-Host' => $c->tx->remote_address || 'UNKNOWN') | ||
->transport(createEmailSenderTransportSMTP($ce)); | ||
|
||
eval { $mail->send_or_die({ | ||
$ce->{mail}{set_return_path} ? (from => $ce->{mail}{set_return_path}) : () }); }; | ||
|
||
if ($@) { | ||
$c->log->error('The following error occured while attempting to send the one-time password ' | ||
. 'generation setup email for "' | ||
. $c->authen->{user_id} . '":' | ||
. ref($@) ? $@->message : $@); | ||
$c->log->error('The user will be shown the information directly in the web page.'); | ||
$c->stash->{otp_link} = $otp_link; | ||
$c->stash->{otp_qrcode} = $img_data; | ||
} else { | ||
$c->authen->session->{otp_setup_email_sent} = 1; | ||
} | ||
} else { | ||
$c->stash->{otp_link} = $otp_link; | ||
$c->stash->{otp_qrcode} = $img_data; | ||
} | ||
} | ||
|
||
return; | ||
} | ||
|
||
1; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.