Skip to content

Commit

Permalink
feat: show secret_key with QR code
Browse files Browse the repository at this point in the history
- streamline the setup experience for users working with
  password managers that cannot read QR codes easily.

Co-authored-by: Claude Paroz <[email protected]>
  • Loading branch information
dopry and claudep committed Oct 14, 2022
1 parent dffe9a1 commit cf4b191
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 2 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@
### Removed
- Django 2.2, 3.0, and 3.1 support

### Changed

- display the TOTP secret key alongside the QR code to streamline setup for
password managers without QR support.

## 1.14.0

### Added
Expand Down
6 changes: 6 additions & 0 deletions tests/test_views_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ def test_setup_only_generator_available(self):
# test if secret key is valid base32 and has the correct number of bytes
secret_key = response.context_data['secret_key']
self.assertEqual(len(b32decode(secret_key)), 20)
self.assertEqual(
response.context_data['otpauth_url'],
f'otpauth://totp/testserver%3A%20bouke%40example.com?secret={secret_key}&digits=6&issuer=testserver'
)
self.assertEqual(response.context_data['issuer'], 'testserver')
self.assertEqual(response.context_data['totp_digits'], 6)

response = self.client.post(
reverse('two_factor:setup'),
Expand Down
8 changes: 6 additions & 2 deletions two_factor/templates/two_factor/core/setup.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@ <h1>{% block title %}{% trans "Enable Two-Factor Authentication" %}{% endblock %
{% elif wizard.steps.current == 'generator' %}
<p>{% blocktrans trimmed %}To start using a token generator, please use your
smartphone to scan the QR code below. For example, use Google
Authenticator. Then, enter the token generated by the app.
{% endblocktrans %}</p>
Authenticator.{% endblocktrans %}</p>
<p><img src="{{ QR_URL }}" alt="QR Code" class="bg-white"/></p>
<p>{% blocktrans trimmed %}Alternatively you can use the following secret to
setup TOTP in your authenticator or password manager manually.{% endblocktrans %}</p>
<p>{% translate "TOTP Secret:" %} <a href="{{ otpauth_url }}">{{ secret_key }}</a></p>
<p>{% blocktrans %}Then, enter the token generated by the app.{% endblocktrans %}</p>

{% elif wizard.steps.current == 'sms' %}
<p>{% blocktrans trimmed %}Please enter the phone number you wish to receive the
text messages on. This number will be validated in the next step.
Expand Down
8 changes: 8 additions & 0 deletions two_factor/views/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -596,10 +596,18 @@ def get_context_data(self, form, **kwargs):
key = self.get_key('generator')
rawkey = unhexlify(key.encode('ascii'))
b32key = b32encode(rawkey).decode('utf-8')
issuer = get_current_site(self.request).name
username = self.request.user.get_username()
otpauth_url = get_otpauth_url(username, b32key, issuer)
self.request.session[self.session_key_name] = b32key
context.update({
# used in default template
'otpauth_url': otpauth_url,
'QR_URL': reverse(self.qrcode_url),
'secret_key': b32key,
# available for custom templates
'issuer': issuer,
'totp_digits': totp_digits(),
})
elif self.steps.current == 'validation':
context['device'] = self.get_device()
Expand Down

0 comments on commit cf4b191

Please sign in to comment.