Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: validate usernames with Django's rules #7124

Draft
wants to merge 5 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 40 additions & 11 deletions ietf/ietfauth/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
from django.core.exceptions import ValidationError
from django.db import models
from django.contrib.auth.models import User
from django.contrib.auth.validators import ASCIIUsernameValidator

import debug # pyflakes:ignore

Expand All @@ -20,16 +21,35 @@
from .widgets import PasswordStrengthInput, PasswordConfirmationInput


class UsernameEmailValidator(ASCIIUsernameValidator):
message=(
'This value may contain only unaccented lowercase letters (a-z), '
'digits (0-9), and the special characters "@", ".", "+", "-", and "_".'
)

def __call__(self, value):
if value.lower() != value:
raise forms.ValidationError(
(
"The supplied address contained uppercase letters. "
"Please use a lowercase email address."
),
code="invalid_case",
params={"value": value},
)
super().__call__(value)


validate_username_email = UsernameEmailValidator()


class UsernameEmailField(forms.EmailField):
"""Email that is suitable for a username"""
default_validators = forms.EmailField.default_validators + [validate_username_email]


class RegistrationForm(forms.Form):
email = forms.EmailField(label="Your email (lowercase)")

def clean_email(self):
email = self.cleaned_data.get('email', '')
if not email:
return email
if email.lower() != email:
raise forms.ValidationError('The supplied address contained uppercase letters. Please use a lowercase email address.')
return email
email = UsernameEmailField(label="Your email (lowercase)")
rjsparks marked this conversation as resolved.
Show resolved Hide resolved


class PasswordForm(forms.Form):
Expand Down Expand Up @@ -230,10 +250,19 @@ def __init__(self, user, *args, **kwargs):
assert isinstance(user, User)
super(ChangeUsernameForm, self).__init__(*args, **kwargs)
self.user = user
emails = user.person.email_set.filter(active=True)
choices = [ (email.address, email.address) for email in emails ]
choices = [(email.address, email.address) for email in self._allowed_emails(user)]
self.fields['username'] = forms.ChoiceField(choices=choices)

@staticmethod
def _allowed_emails(user):
for email in user.person.email_set.filter(active=True):
try:
validate_username_email(email.address)
except ValidationError:
pass
else:
yield email

def clean_password(self):
password = self.cleaned_data['password']
if not self.user.check_password(password):
Expand Down
3 changes: 3 additions & 0 deletions ietf/templates/registration/change_username.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ <h1>Change username</h1>
email address, then please first
<a href="{% url 'ietf.ietfauth.views.profile' %}">edit your profile</a>
to add that email address to the active email addresses for your account.
Usernames are restricted to alphanumeric characters and the characters
"@", ".", "+", "-", and "_". Email addresses with other characters may
not be chosen as a username.
</div>
<form method="post" class="my-3">
{% csrf_token %}
Expand Down
4 changes: 3 additions & 1 deletion ietf/templates/registration/create.html
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,9 @@ <h1>Account creation</h1>
</div>
</div>
<p class="my-3">
Otherwise, please enter your email address in order to create your datatracker account.
Otherwise, please enter your email address in order to create your datatracker account. This email
address will be used as your datatracker username and must consist only of alphanumeric characters
and the symbols "@", ".", "+", "-", and "_".
</p>
<form method="post">
{% csrf_token %}
Expand Down
Loading