add a page for users to input their sms registration code (#69223)
This commit is contained in:
parent
e35275fe45
commit
26f9d2098d
|
@ -20,11 +20,12 @@ from django.contrib.auth import get_user_model
|
|||
from django.contrib.auth.models import BaseUserManager, Group
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.core.validators import RegexValidator
|
||||
from django.forms import Form
|
||||
from django.utils.translation import gettext
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from authentic2.a2_rbac.models import OrganizationalUnit
|
||||
from authentic2.forms.fields import CheckPasswordField, NewPasswordField
|
||||
from authentic2.forms.fields import CharField, CheckPasswordField, NewPasswordField
|
||||
from authentic2.passwords import get_min_password_strength
|
||||
|
||||
from .. import app_settings, models
|
||||
|
@ -191,3 +192,7 @@ class RegistrationCompletionForm(RegistrationCompletionFormNoPassword):
|
|||
raise ValidationError(_("The two password fields didn't match."))
|
||||
self.instance.set_password(self.cleaned_data['password1'])
|
||||
return self.cleaned_data
|
||||
|
||||
|
||||
class InputRegistrationCodeForm(Form):
|
||||
registration_code = CharField()
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
{% extends "authentic2/base-page.html" %}
|
||||
{% load i18n gadjo %}
|
||||
|
||||
{% block page-title %}
|
||||
{{ view.title }}
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<form method="post" action=".">
|
||||
<p>{% blocktrans trimmed %}Input your account activation code.{% endblocktrans %}</p>
|
||||
{% csrf_token %}
|
||||
{{ form }}
|
||||
<div class="buttons">
|
||||
<button class="submit-button">{% trans 'Submit' %}</button>
|
||||
<button class="cancel-button" name="cancel" formnovalidate>{% trans "Cancel" %}</button>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -114,6 +114,11 @@ urlpatterns = [
|
|||
TemplateView.as_view(template_name='registration/registration_closed.html'),
|
||||
name='registration_disallowed',
|
||||
),
|
||||
re_path(
|
||||
'^register/input_code/(?P<token>[A-Za-z0-9_ -]+)/$',
|
||||
views.input_registration_code,
|
||||
name='input_registration_code',
|
||||
),
|
||||
# Password reset
|
||||
re_path(
|
||||
r'^password/reset/confirm/(?P<token>[A-Za-z0-9_ -]+)/$',
|
||||
|
|
|
@ -1203,6 +1203,62 @@ class BaseRegistrationView(HomeURLMixin, FormView):
|
|||
return context
|
||||
|
||||
|
||||
class InputRegistrationCodeView(cbv.ValidateCSRFMixin, FormView):
|
||||
template_name = 'registration/sms_input_registration_code.html'
|
||||
form_class = registration_forms.InputRegistrationCodeForm
|
||||
success_url = '/accounts/'
|
||||
title = _('Account activation')
|
||||
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
token = kwargs.get('token')
|
||||
try:
|
||||
self.code = models.SMSCode.objects.get(url_token=token)
|
||||
except models.SMSCode.DoesNotExist:
|
||||
return HttpResponseBadRequest(_('Invalid account activation request'))
|
||||
if not self.code.sent:
|
||||
return HttpResponseBadRequest(_('Invalid account activation code'))
|
||||
return super().dispatch(request, *args, **kwargs)
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
if 'cancel' in request.POST:
|
||||
self.code.delete()
|
||||
return utils_misc.redirect(request, reverse('auth_homepage'))
|
||||
return super().post(request, *args, **kwargs)
|
||||
|
||||
@atomic(savepoint=False)
|
||||
def form_valid(self, form):
|
||||
super().form_valid(form)
|
||||
registration_code = form.cleaned_data.pop('registration_code')
|
||||
if self.code.value != registration_code:
|
||||
# TODO ratelimit on erroneous code inputs(?)
|
||||
# (code expires after 120 seconds)
|
||||
form.add_error('registration_code', _('Wrong registration code.'))
|
||||
return self.form_invalid(form)
|
||||
if self.code.expires < timezone.now():
|
||||
form.add_error('registration_code', _('The code has expired.'))
|
||||
return self.form_invalid(form)
|
||||
Lock.lock_identifier(self.code.phone)
|
||||
content = {
|
||||
# TODO missing ou registration management
|
||||
'authentication_method': 'phone',
|
||||
'phone': self.code.phone,
|
||||
}
|
||||
# create token to process final account activation and user-defined attributes
|
||||
token = models.Token.create(
|
||||
kind='registration',
|
||||
content=content,
|
||||
duration=120,
|
||||
)
|
||||
return utils_misc.redirect(
|
||||
# TODO next_url management throughout account creation process
|
||||
self.request,
|
||||
reverse('registration_activate', kwargs={'registration_token': token.uuid}),
|
||||
)
|
||||
|
||||
|
||||
input_registration_code = InputRegistrationCodeView.as_view()
|
||||
|
||||
|
||||
class RegistrationView(cbv.ValidateCSRFMixin, BaseRegistrationView):
|
||||
pass
|
||||
|
||||
|
|
Loading…
Reference in New Issue