Skip to content

Commit

Permalink
Add setting to allow generating a different number of backup tokens (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
jduar authored Nov 13, 2023
1 parent 2672450 commit b9c2903
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 1 deletion.
8 changes: 8 additions & 0 deletions allauth_2fa/app_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ def REQUIRE_OTP_ON_DEVICE_REMOVAL(self) -> bool:
True,
)

@property
def BACKUP_TOKENS_NUMBER(self) -> int:
return getattr(
settings,
"ALLAUTH_2FA_BACKUP_TOKENS_NUMBER",
3,
)


_app_settings = _AppSettings()

Expand Down
2 changes: 1 addition & 1 deletion allauth_2fa/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ def get_context_data(self, **kwargs):
def post(self, request, *args, **kwargs):
static_device, _ = request.user.staticdevice_set.get_or_create(name="backup")
static_device.token_set.all().delete()
for _ in range(3):
for _ in range(app_settings.BACKUP_TOKENS_NUMBER):
static_device.token_set.create(token=StaticToken.random_token())
self.reveal_tokens = True
return self.get(request, *args, **kwargs)
7 changes: 7 additions & 0 deletions docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,10 @@ Possible keys (and default values):
* ``authenticate``: :class:`allauth_2fa.forms.TOTPAuthenticateForm`
* ``setup``: :class:`allauth_2fa.forms.TOTPDeviceForm`
* ``remove``: :class:`allauth_2fa.forms.TOTPDeviceRemoveForm`

``ALLAUTH_2FA_BACKUP_TOKENS_NUMBER``
----------------------------------

Sets the number of generated backup tokens.

Defaults to ``3``.
18 changes: 18 additions & 0 deletions tests/test_allauth_2fa.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
]

TWO_FACTOR_AUTH_URL = reverse_lazy("two-factor-authenticate")
TWO_FACTOR_BACKUP_TOKENS_URL = reverse_lazy("two-factor-backup-tokens")
TWO_FACTOR_SETUP_URL = reverse_lazy("two-factor-setup")
LOGIN_URL = reverse_lazy("account_login")
JOHN_CREDENTIALS = {"login": "john", "password": "doe"}
Expand Down Expand Up @@ -321,6 +322,23 @@ def test_not_configured_redirect(client, john):
assertRedirects(resp, TWO_FACTOR_SETUP_URL, fetch_redirect_response=False)


def test_backup_tokens_number(client, john_with_totp):
"""Tests that the configured number of tokens is sent."""
user, totp_device, static_device = john_with_totp
login(client, expected_redirect_url=TWO_FACTOR_AUTH_URL)
do_totp_authentication(
client,
totp_device=totp_device,
expected_redirect_url=settings.LOGIN_REDIRECT_URL,
)
resp = client.post(TWO_FACTOR_BACKUP_TOKENS_URL)
assert len(resp.context_data["backup_tokens"]) == 3

with override_settings(ALLAUTH_2FA_BACKUP_TOKENS_NUMBER=10):
resp = client.post(TWO_FACTOR_BACKUP_TOKENS_URL)
assert len(resp.context_data["backup_tokens"]) == 10


class Require2FA(BaseRequire2FAMiddleware):
def require_2fa(self, request):
return True
Expand Down

0 comments on commit b9c2903

Please sign in to comment.