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 3 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
29 changes: 26 additions & 3 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,8 +21,21 @@
from .widgets import PasswordStrengthInput, PasswordConfirmationInput


validate_username_email = ASCIIUsernameValidator(
message=(
"This value may contain only unaccented lowercase a-z "
"and uppercase A-Z letters, numbers, and @/./+/-/_ characters."
)
)


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)")
email = UsernameEmailField(label="Your email (lowercase)")
rjsparks marked this conversation as resolved.
Show resolved Hide resolved

def clean_email(self):
email = self.cleaned_data.get('email', '')
Expand Down Expand Up @@ -230,10 +244,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