From 4acd2659510e1eb989981af8cf01c5e2ffa648ac Mon Sep 17 00:00:00 2001 From: Sindre Stephansen Date: Wed, 18 Mar 2020 23:11:16 +0100 Subject: [PATCH] Add QR image to set up authenticator --- src/app/requirements.txt | 1 + src/app/templates/verify.html | 5 +++-- src/app/views/register.py | 17 +++++++++++++++-- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/app/requirements.txt b/src/app/requirements.txt index 86478ce..9b130fc 100755 --- a/src/app/requirements.txt +++ b/src/app/requirements.txt @@ -2,3 +2,4 @@ web.py==0.40 mysql-connector-python==8.0.5 python-dotenv bcrypt +qrcode[pil] diff --git a/src/app/templates/verify.html b/src/app/templates/verify.html index ff776f5..b11b32c 100644 --- a/src/app/templates/verify.html +++ b/src/app/templates/verify.html @@ -1,4 +1,4 @@ -$def with (nav, success, secret, message) +$def with (nav, success, secret, qr, message) Beelance2 @@ -16,8 +16,9 @@ $def with (nav, success, secret, message) $if success:

We require two-factor authentication on this site.

-

Please enter the following code into your authenticator: $secret

+

Please scan the QR code, or enter the following code into your authenticator: $secret

This code will only be displayed once.

+ diff --git a/src/app/views/register.py b/src/app/views/register.py index 0303c4b..7d15669 100755 --- a/src/app/views/register.py +++ b/src/app/views/register.py @@ -1,10 +1,13 @@ import web +import io +import base64 from views.forms import register_form from views.utils import (get_nav_bar, csrf_protected, password_weakness, get_render, sendmail, hash_password, generate_authenticator_secret) from uuid import uuid4 import models.register import models.user +import qrcode import logging import re @@ -100,8 +103,18 @@ class Verify: if token and userid is not None: models.user.verify_user(userid) + models.user.set_token(userid, "") + username = models.user.get_user_name_by_id(userid) secret = generate_authenticator_secret() + + # Generate a base64 QR image + qr_url = "otpauth://totp/beelance.com:{}?secret={}&issuer=beelance.com".format(username, secret) + qr_img = qrcode.make(qr_url) + with io.BytesIO() as stream: + qr_img.save(stream) + img = base64.b64encode(stream.getvalue()).decode('UTF-8') + models.user.set_authenticator_secret(userid, secret) - return render.verify(nav, True, secret, "Your email has been verified.") + return render.verify(nav, True, secret, img, "Your email has been verified.") else: - return render.verify(nav, True, secret, "Invalid token. Please try again.") + return render.verify(nav, False, "", "", "Invalid token. Please try again.")