Add optional support for Unicode usernames

Refactoring: Use format with named variables
This commit is contained in:
Omar Al-Ithawi
2017-03-20 19:13:28 +02:00
parent e6c94400d1
commit 1b46c3e646
16 changed files with 423 additions and 42 deletions

View File

@@ -12,7 +12,7 @@ USERNAME_MAX_LENGTH = 30
# The minimum and maximum length for the email account field
EMAIL_MIN_LENGTH = 3
EMAIL_MAX_LENGTH = 254
EMAIL_MAX_LENGTH = 254 # Limit per RFCs is 254
# The minimum and maximum length for the password account field
PASSWORD_MIN_LENGTH = 2

View File

@@ -1,18 +1,19 @@
"""
Programmatic integration point for User API Accounts sub-application
"""
from django.utils.translation import ugettext as _
from django.utils.translation import override as override_language, ugettext as _
from django.db import transaction, IntegrityError
import datetime
from pytz import UTC
from django.core.exceptions import ObjectDoesNotExist
from django.conf import settings
from django.core.validators import validate_email, validate_slug, ValidationError
from django.core.validators import validate_email, ValidationError
from django.http import HttpResponseForbidden
from openedx.core.djangoapps.user_api.preferences.api import update_user_preferences
from openedx.core.djangoapps.user_api.errors import PreferenceValidationError
from student.models import User, UserProfile, Registration
from student import forms as student_forms
from student import views as student_views
from util.model_utils import emit_setting_changed_event
@@ -449,11 +450,12 @@ def _validate_username(username):
)
)
try:
validate_slug(username)
except ValidationError:
raise AccountUsernameInvalid(
u"Username '{username}' must contain only A-Z, a-z, 0-9, -, or _ characters"
)
with override_language('en'):
# `validate_username` provides a proper localized message, however the API needs only the English
# message by convention.
student_forms.validate_username(username)
except ValidationError as error:
raise AccountUsernameInvalid(error.message)
def _validate_password(password, username):

View File

@@ -460,3 +460,34 @@ class AccountCreationActivationAndPasswordChangeTest(TestCase):
"""
response = create_account(self.USERNAME, self.PASSWORD, self.EMAIL)
self.assertEqual(response.status_code, 403)
@attr(shard=2)
@ddt.ddt
class AccountCreationUnicodeUsernameTest(TestCase):
"""
Test cases to cover the account initialization workflow
"""
PASSWORD = u'unicode-user-password'
EMAIL = u'unicode-user-username@example.com'
UNICODE_USERNAMES = [
u'Enchanté',
u'username_with_@',
u'username with spaces',
u'eastern_arabic_numbers_١٢٣',
]
@ddt.data(*UNICODE_USERNAMES)
def test_unicode_usernames(self, unicode_username):
with patch.dict(settings.FEATURES, {'ENABLE_UNICODE_USERNAME': False}):
with self.assertRaises(AccountUsernameInvalid):
create_account(unicode_username, self.PASSWORD, self.EMAIL) # Feature is disabled, therefore invalid.
with patch.dict(settings.FEATURES, {'ENABLE_UNICODE_USERNAME': True}):
try:
create_account(unicode_username, self.PASSWORD, self.EMAIL)
except AccountUsernameInvalid:
self.fail(u'The API should accept Unicode username `{unicode_username}`.'.format(
unicode_username=unicode_username,
))