registration: provide a more user-friendly input code form (#72604)

This commit is contained in:
Paul Marillonnet 2022-12-19 16:43:39 +01:00
parent 38e12e840c
commit 0443245e1e
5 changed files with 24 additions and 2 deletions

View File

@ -16,6 +16,7 @@
import re
from django.conf import settings
from django.contrib.auth import get_user_model
from django.contrib.auth.models import BaseUserManager, Group
from django.core.exceptions import ValidationError
@ -195,4 +196,8 @@ class RegistrationCompletionForm(RegistrationCompletionFormNoPassword):
class InputRegistrationCodeForm(Form):
registration_code = CharField()
registration_code = CharField(
label=_('Registration code'),
help_text=_('The registration code you received by SMS.'),
max_length=settings.SMS_CODE_LENGTH,
)

View File

@ -815,6 +815,7 @@ class APIClient(models.Model):
class SMSCode(models.Model):
CODE_DURATION = 120
KIND_REGISTRATION = 'registration'
KIND_PASSWORD_LOST = 'password-lost'
value = models.CharField(
@ -838,8 +839,10 @@ class SMSCode(models.Model):
cls.objects.filter(expires__lte=now).delete()
@classmethod
def create(cls, phone, kind=None, expires=None, duration=120):
def create(cls, phone, kind=None, expires=None, duration=None):
if not kind:
kind = cls.KIND_REGISTRATION
if not duration:
duration = cls.CODE_DURATION
expires = expires or (timezone.now() + datetime.timedelta(seconds=duration))
return cls.objects.create(kind=kind, phone=phone, expires=expires)

View File

@ -8,6 +8,13 @@
{% block content %}
<form method="post" action=".">
<p>{% blocktrans trimmed %}Input your account activation code.{% endblocktrans %}</p>
<p>
{% blocktrans count counter=duration %}
Your code is valid for the next minute.
{% plural %}
Your code is valid for the next {{ duration }} minutes.
{% endblocktrans %}
</p>
{% csrf_token %}
{{ form }}
<div class="buttons">

View File

@ -1252,6 +1252,11 @@ class InputRegistrationCodeView(cbv.ValidateCSRFMixin, FormView):
return HttpResponseBadRequest(_('Invalid account activation code'))
return super().dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)
ctx['duration'] = models.SMSCode.CODE_DURATION // 60
return ctx
def post(self, request, *args, **kwargs):
if 'cancel' in request.POST:
self.code.delete()

View File

@ -1072,6 +1072,8 @@ def test_phone_registration(app, db, settings):
assert body['message'].startswith('Your code is')
code = SMSCode.objects.get()
assert body['message'][-code_length:] == code.value
assert ("Your code is valid for the next %s minute" % (SMSCode.CODE_DURATION // 60)) in resp.text
assert "The registration code you received by SMS." in resp.text
resp.form.set('registration_code', code.value)
resp = resp.form.submit().follow()
assert Token.objects.count() == 1