diff --git a/flask_security/forms.py b/flask_security/forms.py index bacf118..b021fb6 100644 --- a/flask_security/forms.py +++ b/flask_security/forms.py @@ -21,6 +21,14 @@ from .exceptions import UserNotFoundError _datastore = LocalProxy(lambda: app.extensions['security'].datastore) +def unique_user_email(form, field): + try: + _datastore.find_user(email=field.data) + raise ValidationError('%s is already associated with an account' % field.data) + except UserNotFoundError: + pass + + def valid_user_email(form, field): try: _datastore.find_user(email=field.data) @@ -41,6 +49,13 @@ class UserEmailFormMixin(): valid_user_email]) +class UniqueEmailFormMixin(): + email = TextField("Email Address", + validators=[Required(message="Email not provided"), + Email(message="Invalid email address"), + unique_user_email]) + + class PasswordFormMixin(): password = PasswordField("Password", validators=[Required(message="Password not provided")]) @@ -102,7 +117,7 @@ class LoginForm(Form, EmailFormMixin, PasswordFormMixin): class RegisterForm(Form, - EmailFormMixin, + UniqueEmailFormMixin, PasswordFormMixin, PasswordConfirmFormMixin): """The default register form""" diff --git a/tests/functional_tests.py b/tests/functional_tests.py index b913c64..f8d3ef3 100644 --- a/tests/functional_tests.py +++ b/tests/functional_tests.py @@ -237,9 +237,16 @@ class ConfiguredSecurityTests(SecurityTest): password='password', password_confirm='password') - r = self.client.post('/register', data=data, follow_redirects=True) + r = self._post('/register', data=data, follow_redirects=True) self.assertIn('Post Register', r.data) + def test_register_existing_email(self): + data = dict(email='matt@lp.com', + password='password', + password_confirm='password') + r = self._post('/register', data=data, follow_redirects=True) + self.assertIn('matt@lp.com is already associated with an account', r.data) + def test_unauthorized(self): self.authenticate("joe@lp.com", endpoint="/custom_auth") r = self._get("/admin", follow_redirects=True)