users: Verify full names explicitly in account registration.

I believe this completes the project of ensuring that our recent work
on limiting what characters can appears in users' full names covers
the entire codebase.
This commit is contained in:
Tim Abbott
2017-02-07 20:04:14 -08:00
parent 56cecc4891
commit 84b18f865a
5 changed files with 60 additions and 3 deletions

View File

@@ -13,6 +13,8 @@ from jinja2 import Markup as mark_safe
from zerver.lib.actions import do_change_password, is_inactive, user_email_is_unique
from zerver.lib.name_restrictions import is_reserved_subdomain, is_disposable_domain
from zerver.lib.request import JsonableError
from zerver.lib.users import check_full_name
from zerver.lib.utils import get_subdomain, check_subdomain
from zerver.models import Realm, get_user_profile_by_email, UserProfile, \
get_realm_by_email_domain, get_realm, \
@@ -69,6 +71,13 @@ class RegistrationForm(forms.Form):
if settings.TERMS_OF_SERVICE:
terms = forms.BooleanField(required=True)
def clean_full_name(self):
# type: () -> Text
try:
return check_full_name(self.cleaned_data['full_name'])
except JsonableError as e:
raise ValidationError(e.error)
def clean_realm_subdomain(self):
# type: () -> str
if settings.REALMS_HAVE_SUBDOMAINS:

View File

@@ -195,8 +195,8 @@ class ZulipTestCase(TestCase):
def submit_reg_form_for_user(self, email, password, realm_name="Zulip Test",
realm_subdomain="zuliptest", realm_org_type=Realm.COMMUNITY,
from_confirmation='', **kwargs):
# type: (Text, Text, Optional[Text], Optional[Text], int, Optional[Text], **Any) -> HttpResponse
from_confirmation='', full_name=None, **kwargs):
# type: (Text, Text, Optional[Text], Optional[Text], int, Optional[Text], Optional[Text], **Any) -> HttpResponse
"""
Stage two of the two-step registration process.
@@ -205,8 +205,11 @@ class ZulipTestCase(TestCase):
You can pass the HTTP_HOST variable for subdomains via kwargs.
"""
if full_name is None:
full_name = email.replace("@", "_")
return self.client_post('/accounts/register/',
{'full_name': email, 'password': password,
{'full_name': full_name,
'password': password,
'realm_name': realm_name,
'realm_subdomain': realm_subdomain,
'key': find_key_by_email(email),

View File

@@ -1338,6 +1338,20 @@ class TestLDAP(ZulipTestCase):
self.assertEqual(user_profile.email, email)
self.assertEqual(user_profile.full_name, 'Full Name')
@override_settings(AUTHENTICATION_BACKENDS=('zproject.backends.ZulipLDAPAuthBackend',))
def test_get_or_create_user_when_user_has_invalid_name(self):
# type: () -> None
class _LDAPUser(object):
attrs = {'fn': ['<invalid name>'], 'sn': ['Short Name']}
ldap_user_attr_map = {'full_name': 'fn', 'short_name': 'sn'}
with self.settings(AUTH_LDAP_USER_ATTR_MAP=ldap_user_attr_map):
backend = self.backend
email = 'nonexisting@zulip.com'
with self.assertRaisesRegex(Exception, "Invalid characters in name!"):
backend.get_or_create_user(email, _LDAPUser())
@override_settings(AUTHENTICATION_BACKENDS=('zproject.backends.ZulipLDAPAuthBackend',))
def test_get_or_create_user_when_realm_is_deactivated(self):
# type: () -> None

View File

@@ -894,6 +894,31 @@ class UserSignUpTest(ZulipTestCase):
from django.core.mail import outbox
outbox.pop()
def test_signup_invalid_name(self):
# type: () -> None
"""
Check if the default language of new user is the default language
of the realm.
"""
email = "newguy@zulip.com"
password = "newpassword"
result = self.client_post('/accounts/home/', {'email': email})
self.assertEqual(result.status_code, 302)
self.assertTrue(result["Location"].endswith(
"/accounts/send_confirm/%s" % (email,)))
result = self.client_get(result["Location"])
self.assert_in_response("Check your email so we can get started.", result)
# Visit the confirmation link.
confirmation_url = self.get_confirmation_url_from_outbox(email)
result = self.client_get(confirmation_url)
self.assertEqual(result.status_code, 200)
# Pick a password and agree to the ToS.
result = self.submit_reg_form_for_user(email, password, full_name="<invalid>")
self.assert_in_success_response("Invalid characters in name!", result)
def test_unique_completely_open_domain(self):
# type: () -> None
password = "test"

View File

@@ -21,6 +21,8 @@ from social_core.backends.github import GithubOAuth2, GithubOrganizationOAuth2,
GithubTeamOAuth2
from social_core.exceptions import AuthFailed
from django.contrib.auth import authenticate
from zerver.lib.users import check_full_name
from zerver.lib.request import JsonableError
from zerver.lib.utils import check_subdomain, get_subdomain
def pad_method_dict(method_dict):
@@ -364,6 +366,10 @@ class ZulipLDAPAuthBackend(ZulipLDAPAuthBackendBase):
full_name_attr = settings.AUTH_LDAP_USER_ATTR_MAP["full_name"]
short_name = full_name = ldap_user.attrs[full_name_attr][0]
try:
full_name = check_full_name(full_name)
except JsonableError as e:
raise ZulipLDAPException(e.error)
if "short_name" in settings.AUTH_LDAP_USER_ATTR_MAP:
short_name_attr = settings.AUTH_LDAP_USER_ATTR_MAP["short_name"]
short_name = ldap_user.attrs[short_name_attr][0]