authentic/src/authentic2/forms/registration.py

156 lines
6.2 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# authentic2 - versatile identity manager
# Copyright (C) 2010-2019 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import re
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.utils.translation import ugettext
from django.utils.translation import ugettext_lazy as _
from authentic2.a2_rbac.models import OrganizationalUnit
from authentic2.forms.fields import CheckPasswordField, NewPasswordField
from .. import app_settings, models
from . import profile as profile_forms
from .fields import ValidatedEmailField
from .honeypot import HoneypotForm
User = get_user_model()
class RegistrationForm(HoneypotForm):
error_css_class = 'form-field-error'
required_css_class = 'form-field-required'
email = ValidatedEmailField(label=_('Email'))
def __init__(self, *args, **kwargs):
super(RegistrationForm, self).__init__(*args, **kwargs)
attributes = {a.name: a for a in models.Attribute.objects.all()}
for field in app_settings.A2_PRE_REGISTRATION_FIELDS:
if field in ('first_name', 'last_name'):
self.fields[field] = User._meta.get_field(field).formfield()
elif field in attributes:
self.fields[field] = attributes[field].get_form_field()
self.fields[field].required = True
def clean_email(self):
email = self.cleaned_data['email']
for email_pattern in app_settings.A2_REGISTRATION_EMAIL_BLACKLIST:
if not email_pattern.startswith('^'):
email_pattern = '^' + email_pattern
if not email_pattern.endswith('$'):
email_pattern += '$'
if re.match(email_pattern, email):
raise ValidationError(ugettext('You cannot register with this email.'))
return email
validate_name = RegexValidator(
r'[0-9_!¡?÷?¿/\\+=@#$%ˆ&*(){}|~<>;:[\]]',
message=_('Special characters are not allowed.'),
inverse_match=True,
)
class RegistrationCompletionFormNoPassword(profile_forms.BaseUserForm):
error_css_class = 'form-field-error'
required_css_class = 'form-field-required'
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
if 'first_name' in self.fields:
self.fields['first_name'].validators.append(validate_name)
if 'last_name' in self.fields:
self.fields['last_name'].validators.append(validate_name)
def clean_username(self):
if self.cleaned_data.get('username'):
username = self.cleaned_data['username']
username_is_unique = app_settings.A2_REGISTRATION_USERNAME_IS_UNIQUE
if app_settings.A2_REGISTRATION_REALM:
username += '@' + app_settings.A2_REGISTRATION_REALM
if 'ou' in self.data:
ou = OrganizationalUnit.objects.get(pk=self.data['ou'])
username_is_unique |= ou.username_is_unique
if username_is_unique:
exist = False
try:
User.objects.get(username=username)
except User.DoesNotExist:
pass
except User.MultipleObjectsReturned:
exist = True
else:
exist = True
if exist:
raise ValidationError(
_('This username is already in ' 'use. Please supply a different username.')
)
return username
def clean_email(self):
if self.cleaned_data.get('email'):
email = self.cleaned_data['email']
if app_settings.A2_REGISTRATION_EMAIL_IS_UNIQUE:
exist = False
try:
User.objects.get(email__iexact=email)
except User.DoesNotExist:
pass
except User.MultipleObjectsReturned:
exist = True
else:
exist = True
if exist:
raise ValidationError(
_('This email address is already in ' 'use. Please supply a different email address.')
)
return BaseUserManager.normalize_email(email)
def save(self, commit=True):
self.instance.email_verified = True
self.instance.is_active = True
user = super(RegistrationCompletionFormNoPassword, self).save(commit=commit)
if commit and app_settings.A2_REGISTRATION_GROUPS:
groups = []
for name in app_settings.A2_REGISTRATION_GROUPS:
group, created = Group.objects.get_or_create(name=name)
groups.append(group)
user.groups = groups
return user
class RegistrationCompletionForm(RegistrationCompletionFormNoPassword):
password1 = NewPasswordField(label=_('Password'))
password2 = CheckPasswordField(label=_("Password (again)"))
def clean(self):
"""
Verifiy that the values entered into the two password fields
match. Note that an error here will end up in
``non_field_errors()`` because it doesn't apply to a single
field.
"""
if 'password1' in self.cleaned_data and 'password2' in self.cleaned_data:
if self.cleaned_data['password1'] != self.cleaned_data['password2']:
raise ValidationError(_("The two password fields didn't match."))
self.instance.set_password(self.cleaned_data['password1'])
return self.cleaned_data