From 66659dfe517ed79914e2807b3a70ae89ee1a7a0b Mon Sep 17 00:00:00 2001 From: Gergely Polonkai Date: Tue, 10 Jul 2018 15:33:57 +0200 Subject: [PATCH] Make registration show an error message on username or email reuse --- calsocial/forms.py | 68 +++++++++++++++++++++++++-- calsocial/templates/registration.html | 1 + 2 files changed, 66 insertions(+), 3 deletions(-) diff --git a/calsocial/forms.py b/calsocial/forms.py index 509c152..da72b2a 100644 --- a/calsocial/forms.py +++ b/calsocial/forms.py @@ -23,16 +23,78 @@ from flask_wtf import FlaskForm import pytz from wtforms import BooleanField, PasswordField, SelectField, StringField from wtforms.ext.dateutil.fields import DateTimeField -from wtforms.validators import DataRequired, Email, ValidationError +from wtforms.validators import DataRequired, Email, StopValidation, ValidationError from wtforms.widgets import TextArea +class UsernameAvailable(object): # pylint: disable=too-few-public-methods + """Checks if a username is available + """ + + def __init__(self, message=None): + self.message = message + + def __call__(self, form, field): + from sqlalchemy.orm.exc import NoResultFound + + from calsocial.models import User + + # If there is no data, we don’t raise an error; it’s not the task of this validator to + # check the validity of the username + if not field.data: + return + + try: + User.query.filter(User.username == field.data).one() + except NoResultFound: + return + + if self.message is None: + message = field.gettext('This username is not available') + else: + message = self.message + + field.errors[:] = [] + raise StopValidation(message) + + +class EmailAvailable(object): # pylint: disable=too-few-public-methods + """Checks if an email address is available + """ + + def __init__(self, message=None): + self.message = message + + def __call__(self, form, field): + from sqlalchemy.orm.exc import NoResultFound + + from calsocial.models import User + + # If there is no data, we don’t raise an error; it’s not the task of this validator to + # check the validity of the username + if not field.data: + return + + try: + User.query.filter(User.email == field.data).one() + except NoResultFound: + return + + if self.message is None: + message = field.gettext('This email address can not be used') + else: + message = self.message + + field.errors[:] = [] + raise StopValidation(message) + + class RegistrationForm(FlaskForm): """Registration form """ - username = StringField(_('Username'), validators=[DataRequired()]) - email = StringField(_('Email address'), validators=[Email()]) + username = StringField(_('Username'), validators=[DataRequired(), UsernameAvailable()]) + email = StringField(_('Email address'), validators=[Email(), EmailAvailable()]) password = PasswordField(_('Password'), validators=[DataRequired()]) password_retype = PasswordField(_('Password, once more'), validators=[DataRequired()]) diff --git a/calsocial/templates/registration.html b/calsocial/templates/registration.html index cb1a69c..95f3977 100644 --- a/calsocial/templates/registration.html +++ b/calsocial/templates/registration.html @@ -2,6 +2,7 @@ {% block content %}
+ {{ form.errors }} {{ form.hidden_tag() }} {{ form.username.errors }}