mirror of
https://github.com/pretix/pretix.git
synced 2025-12-18 16:12:26 +00:00
Compare commits
1 Commits
re-add-mis
...
recovery-c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
45bff138d7 |
@@ -57,6 +57,7 @@ from django.views.decorators.csrf import csrf_exempt
|
||||
from django.views.decorators.http import require_http_methods
|
||||
from django.views.generic import TemplateView
|
||||
from django_otp import match_token
|
||||
from django_otp.plugins.otp_static.models import StaticDevice
|
||||
from webauthn.helpers import generate_challenge
|
||||
|
||||
from pretix.base.auth import get_auth_backends
|
||||
@@ -538,6 +539,10 @@ class Login2FAView(TemplateView):
|
||||
break
|
||||
else:
|
||||
valid = match_token(self.user, token)
|
||||
if isinstance(valid, StaticDevice):
|
||||
self.user.send_security_notice([
|
||||
_("A recovery code for two-factor authentification was used to log in.")
|
||||
])
|
||||
|
||||
if valid:
|
||||
logger.info(f"Backend login successful for user {self.user.pk} with 2FA.")
|
||||
|
||||
@@ -165,6 +165,9 @@ class UserEmergencyTokenView(AdministratorPermissionRequiredMixin, RecentAuthent
|
||||
d, __ = StaticDevice.objects.get_or_create(user=self.object, name='emergency')
|
||||
token = d.token_set.create(token=get_random_string(length=12, allowed_chars='1234567890'))
|
||||
self.object.log_action('pretix.user.settings.2fa.emergency', user=self.request.user)
|
||||
self.object.send_security_notice([
|
||||
_('A two-factor emergency code has been generated by a system administrator.')
|
||||
])
|
||||
|
||||
messages.success(request, _(
|
||||
'The emergency token for this user is "{token}". It can only be used once. Please make sure to transmit '
|
||||
|
||||
@@ -42,8 +42,10 @@ from django.contrib.auth.tokens import (
|
||||
)
|
||||
from django.core import mail as djmail
|
||||
from django.test import RequestFactory, TestCase, override_settings
|
||||
from django.utils.crypto import get_random_string
|
||||
from django.utils.timezone import now
|
||||
from django_otp.oath import TOTP
|
||||
from django_otp.plugins.otp_static.models import StaticDevice
|
||||
from django_otp.plugins.otp_totp.models import TOTPDevice
|
||||
from webauthn.authentication.verify_authentication_response import (
|
||||
VerifiedAuthentication,
|
||||
@@ -492,6 +494,20 @@ class Login2FAFormTest(TestCase):
|
||||
|
||||
m.undo()
|
||||
|
||||
def test_recovery_code_valid(self):
|
||||
djmail.outbox = []
|
||||
d, __ = StaticDevice.objects.get_or_create(user=self.user, name='emergency')
|
||||
token = d.token_set.create(token=get_random_string(length=12, allowed_chars='1234567890'))
|
||||
|
||||
response = self.client.get('/control/login/2fa')
|
||||
assert 'token' in response.content.decode()
|
||||
response = self.client.post('/control/login/2fa', {
|
||||
'token': token.token,
|
||||
})
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertIn('/control/', response['Location'])
|
||||
assert "recovery code" in djmail.outbox[0].body
|
||||
|
||||
|
||||
class FakeRedis(object):
|
||||
def get_redis_connection(self, connection_string):
|
||||
|
||||
Reference in New Issue
Block a user