diff --git a/src/pretix/control/templates/pretixcontrol/user/2fa_confirm_totp.html b/src/pretix/control/templates/pretixcontrol/user/2fa_confirm_totp.html index ab6bbbfcb..86cb186e6 100644 --- a/src/pretix/control/templates/pretixcontrol/user/2fa_confirm_totp.html +++ b/src/pretix/control/templates/pretixcontrol/user/2fa_confirm_totp.html @@ -77,7 +77,11 @@ +
+ diff --git a/src/pretix/control/templates/pretixcontrol/user/2fa_confirm_u2f.html b/src/pretix/control/templates/pretixcontrol/user/2fa_confirm_u2f.html index 4fd720fde..896507392 100644 --- a/src/pretix/control/templates/pretixcontrol/user/2fa_confirm_u2f.html +++ b/src/pretix/control/templates/pretixcontrol/user/2fa_confirm_u2f.html @@ -13,6 +13,12 @@
{% csrf_token %} +

+ +

@@ -22,6 +28,7 @@ {% compress js %} diff --git a/src/pretix/control/views/user.py b/src/pretix/control/views/user.py index b043ef38a..44f375683 100644 --- a/src/pretix/control/views/user.py +++ b/src/pretix/control/views/user.py @@ -243,9 +243,18 @@ class User2FADeviceConfirmU2FView(RecentAuthenticationRequiredMixin, TemplateVie 'devicetype': 'u2f', 'name': self.device.name, }) - self.request.user.send_security_notice([ + notices = [ _('A new two-factor authentication device has been added to your account.') - ]) + ] + activate = request.POST.get('activate', '') + if activate == 'on' and not self.request.user.require_2fa: + self.request.user.require_2fa = True + self.request.user.save() + self.request.user.log_action('pretix.user.settings.2fa.enabled', user=self.request.user) + notices.append( + _('Two-factor authentication has been enabled.') + ) + self.request.user.send_security_notice(notices) note = '' if not self.request.user.require_2fa: @@ -284,6 +293,7 @@ class User2FADeviceConfirmTOTPView(RecentAuthenticationRequiredMixin, TemplateVi def post(self, request, *args, **kwargs): token = request.POST.get('token', '') + activate = request.POST.get('activate', '') if self.device.verify_token(token): self.device.confirmed = True self.device.save() @@ -292,9 +302,17 @@ class User2FADeviceConfirmTOTPView(RecentAuthenticationRequiredMixin, TemplateVi 'name': self.device.name, 'devicetype': 'totp' }) - self.request.user.send_security_notice([ + notices = [ _('A new two-factor authentication device has been added to your account.') - ]) + ] + if activate == 'on' and not self.request.user.require_2fa: + self.request.user.require_2fa = True + self.request.user.save() + self.request.user.log_action('pretix.user.settings.2fa.enabled', user=self.request.user) + notices.append( + _('Two-factor authentication has been enabled.') + ) + self.request.user.send_security_notice(notices) note = '' if not self.request.user.require_2fa: diff --git a/src/tests/control/test_user.py b/src/tests/control/test_user.py index d54a47eba..9884db86b 100644 --- a/src/tests/control/test_user.py +++ b/src/tests/control/test_user.py @@ -222,11 +222,14 @@ class UserSettings2FATest(SoupTest): totp = TOTP(d.bin_key, d.step, d.t0, d.digits, d.drift) totp.time = time.time() r = self.client.post('/control/settings/2fa/totp/{}/confirm'.format(d.pk), { - 'token': str(totp.token()) + 'token': str(totp.token()), + 'activate': 'on' }, follow=True) d.refresh_from_db() assert d.confirmed assert 'alert-success' in r.rendered_content + self.user.refresh_from_db() + assert self.user.require_2fa def test_confirm_totp_failed(self): self.client.post('/control/settings/2fa/add', { @@ -271,11 +274,14 @@ class UserSettings2FATest(SoupTest): d = U2FDevice.objects.first() r = self.client.post('/control/settings/2fa/u2f/{}/confirm'.format(d.pk), { - 'token': 'FOO' + 'token': 'FOO', + 'activate': 'on' }, follow=True) d.refresh_from_db() assert d.confirmed assert 'alert-success' in r.rendered_content + self.user.refresh_from_db() + assert self.user.require_2fa m.undo()