Bug 29873: Create QR code
authorMarcel de Rooy <m.de.rooy@rijksmuseum.nl>
Thu, 13 Jan 2022 14:27:36 +0000 (14:27 +0000)
committerFridolin Somers <fridolin.somers@biblibre.com>
Mon, 2 May 2022 21:22:58 +0000 (11:22 -1000)
Instead of using deprecated Google Charts API, and exposing our
secret in a GET parameter, we generate QR data ourselves.

Test plan:
[1] Enable two factor authentication in the prefs.
[2] Login in staff. Go to account. Select Manage 2FA.
[3] Verify that QR code is displayed.
[4] Register the QR in your authenticator app and test 2FA
    by logging in again.

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Tested with Google Authenticator and FreeOTP.

Bug 29873: (follow-up) Rename qr_dataurl

As requested by a QA team member.
We're moving to qr_code as method name. This is the same name as
the method in the underlying base class.
Apart from one sed statement, changing to self->SUPER on one line.

Test plan:
Can you still register, logout and login?

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Bug 29873: (follow-up) Switch to GD

We do not need a new module, we could use GD instead.

Signed-off-by: Marcel de Rooy <m.de.rooy@rijksmuseum.nl>
Signed-off-by: Martin Renvoize <martin.renvoize@ptfs-europe.com>
Signed-off-by: Jonathan Druart <jonathan.druart@bugs.koha-community.org>
Signed-off-by: Fridolin Somers <fridolin.somers@biblibre.com>
Koha/Auth/TwoFactorAuth.pm
koha-tmpl/intranet-tmpl/prog/en/modules/members/two_factor_auth.tt
members/two_factor_auth.pl

index 81ddf06..e2cff44 100644 (file)
@@ -17,6 +17,8 @@ package Koha::Auth::TwoFactorAuth;
 
 use Modern::Perl;
 use Auth::GoogleAuth;
+use GD::Barcode;
+use MIME::Base64 qw( encode_base64 );
 
 use base qw( Auth::GoogleAuth );
 
@@ -66,4 +68,24 @@ sub new {
     );
 }
 
+=head3 qr_code
+
+    my $image_src = $auth->qr_code;
+
+    Replacement for (unsafer) Auth::GoogleAuth::qr_code.
+    Returns the data URL to fill the src attribute of the
+    image tag on the registration form.
+
+=cut
+
+sub qr_code {
+    my ( $self ) = @_;
+
+    my $otpauth = $self->SUPER::qr_code( undef, undef, undef, 1);
+        # no need to pass secret, key and issuer again
+    my $qrcode = GD::Barcode->new( 'QRcode', $otpauth, { Ecc => 'M', Version => 8, ModuleSize => 4 } );
+    my $data = $qrcode->plot->png;
+    return "data:image/png;base64,". encode_base64( $data, q{} ); # does not contain newlines
+}
+
 1;
index cddac9f..feb86b9 100644 (file)
@@ -55,7 +55,7 @@
                             <ol>
                                 <li>
                                     <label for="qr_code">QR code: </label>
-                                    <img id="qr_code" src="[% qr_code_url | $raw %]" />
+                                    <img id="qr_code" src="[% qr_code | $raw %]" />
                                 </li>
                                 <li>
                                     <label for="pin_code">Pin code: </label>
index d5157df..b874a6f 100755 (executable)
@@ -86,14 +86,12 @@ if ( $op eq 'enable-2FA' ) {
     my $auth = Koha::Auth::TwoFactorAuth->new(
         { patron => $logged_in_user, secret => $secret } );
 
-    my $qr_code_url =
-      $auth->qr_code( undef, $auth->key_id, $auth->issuer ); # no need to pass secret32
-
     $template->param(
         issuer      => $auth->issuer,
         key_id      => $auth->key_id,
+        qr_code  => $auth->qr_code,
         secret32    => $auth->secret32,
-        qr_code_url => $qr_code_url,
+            # IMPORTANT: get secret32 after qr_code call !
     );
     $auth->clear;
     $op = 'register';