This commit is contained in:
Andrew Williamson 2019-01-09 19:18:03 +08:00 коммит произвёл GitHub
Родитель 7d01df40c2
Коммит 96d87a9391
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
6 изменённых файлов: 19 добавлений и 114 удалений

Просмотреть файл

@ -45,7 +45,7 @@ A developer is defined as a user who is listed as a developer or owner of one or
:>json string|null occupation: The occupation of the user.
:>json string|null picture_type: the image type (only 'image/png' is supported) if a user photo has been uploaded, or null otherwise.
:>json string|null picture_url: URL to a photo of the user, or null if no photo has been uploaded.
:>json string username: username chosen by the user, used in the account url. If not set will be a randomly generated string.
:>json string username: deprecated property still included for backwards compatability. Previous chosen by the user, used in the account url. If not previously set will be a randomly generated string.
@ -137,7 +137,6 @@ but not listed below are not editable and will be ignored in the patch request.
:<json string|null homepage: The user's website.
:<json string|null location: The location of the user.
:<json string|null occupation: The occupation of the user.
:<json string|null username: username to be used in the account url. The username can only contain letters, numbers, underscores or hyphens. All-number usernames are prohibited as they conflict with user-ids.
-------------------

Просмотреть файл

@ -13,8 +13,8 @@ from olympia.access import acl
from olympia.access.models import Group
from olympia.amo.templatetags.jinja_helpers import absolutify
from olympia.amo.utils import (
ImageCheck, clean_nl, has_links, slug_validator, subscribe_newsletter,
unsubscribe_newsletter, urlparams)
clean_nl, has_links, ImageCheck,
subscribe_newsletter, unsubscribe_newsletter, urlparams)
from olympia.api.utils import is_gate_active
from olympia.api.validators import OneOrMorePrintableCharacterValidator
from olympia.users import notifications
@ -83,11 +83,11 @@ class UserProfileSerializer(PublicUserProfileSerializer):
fields = PublicUserProfileSerializer.Meta.fields + (
'display_name', 'email', 'deleted', 'last_login', 'picture_upload',
'last_login_ip', 'read_dev_agreement', 'permissions',
'fxa_edit_email_url',
'fxa_edit_email_url', 'username',
)
writeable_fields = (
'biography', 'display_name', 'homepage', 'location', 'occupation',
'picture_upload', 'username',
'picture_upload',
)
read_only_fields = tuple(set(fields) - set(writeable_fields))
@ -119,30 +119,6 @@ class UserProfileSerializer(PublicUserProfileSerializer):
)
return value
def validate_username(self, value):
# All-digits usernames are disallowed since they can be confused for
# user IDs in URLs.
if value.isdigit():
raise serializers.ValidationError(
ugettext(u'Usernames cannot contain only digits.'))
slug_validator(
value, lower=False,
message=ugettext(u'Enter a valid username consisting of letters, '
u'numbers, underscores or hyphens.'))
if DeniedName.blocked(value):
raise serializers.ValidationError(
ugettext(u'This username cannot be used.'))
# Bug 858452. Remove this check when collation of the username
# column is changed to case insensitive.
if (UserProfile.objects.exclude(id=self.instance.id)
.filter(username__iexact=value).exists()):
raise serializers.ValidationError(
ugettext(u'This username is already in use.'))
return value
def validate_picture_upload(self, value):
image_check = ImageCheck(value)

Просмотреть файл

@ -1037,7 +1037,6 @@ class TestAccountViewSetUpdate(TestCase):
'homepage': 'http://bob-loblaw-law-web.blog',
'location': 'law office',
'occupation': 'lawyer',
'username': 'bob',
}
def setUp(self):
@ -1087,15 +1086,19 @@ class TestAccountViewSetUpdate(TestCase):
def test_read_only_fields(self):
self.client.login_api(self.user)
existing_username = self.user.username
original = self.client.get(self.url).content
# Try to patch a field that can't be patched.
response = self.patch(data={'last_login_ip': '666.666.666.666'})
response = self.patch(data={
'last_login_ip': '666.666.666.666', 'username': 'new_username'})
assert response.status_code == 200
assert response.content == original
self.user = self.user.reload()
# Confirm field hasn't been updated.
assert json.loads(response.content)['last_login_ip'] == ''
assert self.user.last_login_ip == ''
assert json.loads(response.content)['username'] == existing_username
assert self.user.username == existing_username
def test_biography_no_links(self):
self.client.login_api(self.user)
@ -1105,21 +1108,6 @@ class TestAccountViewSetUpdate(TestCase):
assert json.loads(response.content) == {
'biography': ['No links are allowed.']}
def test_username_valid(self):
self.client.login_api(self.user)
response = self.patch(
data={'username': '123456'})
assert response.status_code == 400
assert json.loads(response.content) == {
'username': ['Usernames cannot contain only digits.']}
response = self.patch(
data={'username': u'£^@'})
assert response.status_code == 400
assert json.loads(response.content) == {
'username': [u'Enter a valid username consisting of letters, '
u'numbers, underscores or hyphens.']}
def test_display_name_validation(self):
self.client.login_api(self.user)
response = self.patch(

Просмотреть файл

@ -15,8 +15,9 @@ from olympia.accounts.views import fxa_error_message
from olympia.activity.models import ActivityLog
from olympia.amo.fields import HttpHttpsOnlyURLField
from olympia.amo.utils import (
ImageCheck, clean_nl, fetch_subscribed_newsletters, has_links,
slug_validator, subscribe_newsletter, unsubscribe_newsletter)
clean_nl, has_links, ImageCheck,
fetch_subscribed_newsletters, subscribe_newsletter,
unsubscribe_newsletter)
from olympia.users import notifications
from . import tasks
@ -63,7 +64,6 @@ LOGIN_HELP_URL = (
class UserEditForm(forms.ModelForm):
username = forms.CharField(max_length=50, required=False)
display_name = forms.CharField(label=_(u'Display Name'), max_length=50,
required=False)
location = forms.CharField(label=_(u'Location'), max_length=100,
@ -148,44 +148,11 @@ class UserEditForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = (
'username', 'email', 'display_name', 'location', 'occupation',
'email', 'display_name', 'location', 'occupation',
'homepage', 'photo', 'biography', 'display_collections',
'notifications',
)
def clean_username(self):
name = self.cleaned_data['username']
if not name:
if self.instance.has_anonymous_username:
name = self.instance.username
else:
name = self.instance.anonymize_username()
# All-digits usernames are disallowed since they can be
# confused for user IDs in URLs. (See bug 862121.)
if name.isdigit():
raise forms.ValidationError(
ugettext('Usernames cannot contain only digits.'))
slug_validator(
name, lower=False,
message=ugettext(
'Enter a valid username consisting of letters, numbers, '
'underscores or hyphens.'))
if DeniedName.blocked(name):
raise forms.ValidationError(
ugettext('This username cannot be used.'))
# FIXME: Bug 858452. Remove this check when collation of the username
# column is changed to case insensitive.
if (UserProfile.objects.exclude(id=self.instance.id)
.filter(username__iexact=name).exists()):
raise forms.ValidationError(
ugettext('This username is already in use.'))
return name
def clean_display_name(self):
name = self.cleaned_data['display_name']
if DeniedName.blocked(name):

Просмотреть файл

@ -34,11 +34,6 @@ data-default-locale="{{ request.LANG|lower }}"
{%- endtrans %}
</p>
<ul class="formfields">
<li{% if form.username.errors %} class="error"{% endif %}>
<label for="id_username">{{ _('Username') }}</label>
{{ form.username }}
{{ form.username.errors }}
</li>
<li>
<label for="id_email">
{{ _('Email Address') }}

Просмотреть файл

@ -66,26 +66,9 @@ class TestUserEditForm(UserFormBase):
self.client.login(email='jbalogh@mozilla.com')
self.url = reverse('users.edit')
def test_no_username_or_display_name(self):
assert not self.user.has_anonymous_username
data = {'username': '',
'email': 'jbalogh@mozilla.com'}
response = self.client.post(self.url, data)
self.assertNoFormErrors(response)
assert self.user.reload().has_anonymous_username
def test_change_username(self):
assert self.user.username != 'new-username'
data = {'username': 'new-username',
'email': 'jbalogh@mozilla.com'}
response = self.client.post(self.url, data)
self.assertNoFormErrors(response)
assert self.user.reload().username == 'new-username'
def test_cannot_change_display_name_to_denied_ones(self):
assert self.user.display_name != 'Mozilla'
data = {'username': 'new-username',
'display_name': 'IE6Fan',
data = {'display_name': 'IE6Fan',
'email': 'jbalogh@mozilla.com'}
response = self.client.post(self.url, data)
msg = "This display name cannot be used."
@ -93,8 +76,7 @@ class TestUserEditForm(UserFormBase):
assert self.user.reload().display_name != 'IE6Fan'
def test_display_name_length(self):
data = {'username': 'new-username',
'display_name': 'a' * 51,
data = {'display_name': 'a' * 51,
'email': 'jbalogh@mozilla.com'}
response = self.client.post(self.url, data)
msg = 'Ensure this value has at most 50 characters (it has 51).'
@ -117,8 +99,7 @@ class TestUserEditForm(UserFormBase):
the auto-generated value does not change."""
username = self.user.anonymize_username()
self.user.save()
data = {'username': '',
'email': 'jbalogh@mozilla.com'}
data = {'email': 'jbalogh@mozilla.com'}
response = self.client.post(self.url, data)
self.assertNoFormErrors(response)
assert self.user.reload().username == username
@ -139,9 +120,8 @@ class TestUserEditForm(UserFormBase):
self.assertContains(r, 'Profile Updated')
def test_long_data(self):
data = {'username': 'jbalogh',
'email': 'jbalogh@mozilla.com'}
for field, length in (('username', 50), ('display_name', 50),
data = {'email': 'jbalogh@mozilla.com'}
for field, length in (('display_name', 50),
('location', 100), ('occupation', 100)):
data[field] = 'x' * (length + 1)
r = self.client.post(self.url, data, follow=True)