Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
D
django
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
django
Commits
9935f97c
Kaydet (Commit)
9935f97c
authored
Nis 22, 2016
tarafından
Claude Paroz
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Refs #21379 -- Normalized unicode username inputs
üst
526575c6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
56 additions
and
2 deletions
+56
-2
base_user.py
django/contrib/auth/base_user.py
+7
-1
forms.py
django/contrib/auth/forms.py
+10
-1
models.py
django/contrib/auth/models.py
+1
-0
customizing.txt
docs/topics/auth/customizing.txt
+8
-0
test_basic.py
tests/auth_tests/test_basic.py
+7
-0
test_forms.py
tests/auth_tests/test_forms.py
+23
-0
No files found.
django/contrib/auth/base_user.py
Dosyayı görüntüle @
9935f97c
...
...
@@ -4,6 +4,8 @@ not in INSTALLED_APPS.
"""
from
__future__
import
unicode_literals
import
unicodedata
from
django.contrib.auth
import
password_validation
from
django.contrib.auth.hashers
import
(
check_password
,
is_password_usable
,
make_password
,
...
...
@@ -11,7 +13,7 @@ from django.contrib.auth.hashers import (
from
django.db
import
models
from
django.utils.crypto
import
get_random_string
,
salted_hmac
from
django.utils.deprecation
import
CallableFalse
,
CallableTrue
from
django.utils.encoding
import
python_2_unicode_compatible
from
django.utils.encoding
import
force_text
,
python_2_unicode_compatible
from
django.utils.translation
import
ugettext_lazy
as
_
...
...
@@ -31,6 +33,10 @@ class BaseUserManager(models.Manager):
email
=
'@'
.
join
([
email_name
,
domain_part
.
lower
()])
return
email
@classmethod
def
normalize_username
(
cls
,
username
):
return
unicodedata
.
normalize
(
'NFKC'
,
force_text
(
username
))
def
make_random_password
(
self
,
length
=
10
,
allowed_chars
=
'abcdefghjkmnpqrstuvwxyz'
'ABCDEFGHJKLMNPQRSTUVWXYZ'
...
...
django/contrib/auth/forms.py
Dosyayı görüntüle @
9935f97c
from
__future__
import
unicode_literals
import
unicodedata
from
django
import
forms
from
django.contrib.auth
import
(
authenticate
,
get_user_model
,
password_validation
,
...
...
@@ -60,6 +62,11 @@ class ReadOnlyPasswordHashField(forms.Field):
return
False
class
UsernameField
(
forms
.
CharField
):
def
to_python
(
self
,
value
):
return
unicodedata
.
normalize
(
'NFKC'
,
super
(
UsernameField
,
self
)
.
to_python
(
value
))
class
UserCreationForm
(
forms
.
ModelForm
):
"""
A form that creates a user, with no privileges, from the given username and
...
...
@@ -83,6 +90,7 @@ class UserCreationForm(forms.ModelForm):
class
Meta
:
model
=
User
fields
=
(
"username"
,)
field_classes
=
{
'username'
:
UsernameField
}
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
UserCreationForm
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
...
...
@@ -121,6 +129,7 @@ class UserChangeForm(forms.ModelForm):
class
Meta
:
model
=
User
fields
=
'__all__'
field_classes
=
{
'username'
:
UsernameField
}
def
__init__
(
self
,
*
args
,
**
kwargs
):
super
(
UserChangeForm
,
self
)
.
__init__
(
*
args
,
**
kwargs
)
...
...
@@ -140,7 +149,7 @@ class AuthenticationForm(forms.Form):
Base class for authenticating users. Extend this to get a form that accepts
username/password logins.
"""
username
=
forms
.
Char
Field
(
username
=
Username
Field
(
max_length
=
254
,
widget
=
forms
.
TextInput
(
attrs
=
{
'autofocus'
:
''
}),
)
...
...
django/contrib/auth/models.py
Dosyayı görüntüle @
9935f97c
...
...
@@ -145,6 +145,7 @@ class UserManager(BaseUserManager):
if
not
username
:
raise
ValueError
(
'The given username must be set'
)
email
=
self
.
normalize_email
(
email
)
username
=
self
.
normalize_username
(
username
)
user
=
self
.
model
(
username
=
username
,
email
=
email
,
**
extra_fields
)
user
.
set_password
(
password
)
user
.
save
(
using
=
self
.
_db
)
...
...
docs/topics/auth/customizing.txt
Dosyayı görüntüle @
9935f97c
...
...
@@ -726,6 +726,14 @@ utility methods:
Normalizes email addresses by lowercasing the domain portion of the
email address.
.. classmethod:: models.BaseUserManager.normalize_username(email)
.. versionadded:: 1.10
Applies NFKC Unicode normalization to usernames so that visually
identical characters with different Unicode code points are considered
identical.
.. method:: models.BaseUserManager.get_by_natural_key(username)
Retrieves a user instance using the contents of the field
...
...
tests/auth_tests/test_basic.py
Dosyayı görüntüle @
9935f97c
...
...
@@ -7,6 +7,7 @@ from django.apps import apps
from
django.contrib.auth
import
get_user_model
from
django.contrib.auth.models
import
AnonymousUser
,
User
from
django.core.exceptions
import
ImproperlyConfigured
from
django.db
import
IntegrityError
from
django.dispatch
import
receiver
from
django.test
import
TestCase
,
override_settings
from
django.test.signals
import
setting_changed
...
...
@@ -60,6 +61,12 @@ class BasicTestCase(TestCase):
def
test_unicode_username
(
self
):
User
.
objects
.
create_user
(
'jörg'
)
User
.
objects
.
create_user
(
'Григорий'
)
# Two equivalent unicode normalized usernames should be duplicates
omega_username
=
'iamtheΩ'
# U+03A9 GREEK CAPITAL LETTER OMEGA
ohm_username
=
'iamtheΩ'
# U+2126 OHM SIGN
User
.
objects
.
create_user
(
ohm_username
)
with
self
.
assertRaises
(
IntegrityError
):
User
.
objects
.
create_user
(
omega_username
)
def
test_is_anonymous_authenticated_method_deprecation
(
self
):
deprecation_message
=
(
...
...
tests/auth_tests/test_forms.py
Dosyayı görüntüle @
9935f97c
...
...
@@ -3,6 +3,7 @@ from __future__ import unicode_literals
import
datetime
import
re
from
unittest
import
skipIf
from
django
import
forms
from
django.contrib.auth.forms
import
(
...
...
@@ -118,6 +119,28 @@ class UserCreationFormTest(TestDataMixin, TestCase):
else
:
self
.
assertFalse
(
form
.
is_valid
())
@skipIf
(
six
.
PY2
,
"Python 2 doesn't support unicode usernames by default."
)
def
test_duplicate_normalized_unicode
(
self
):
"""
To prevent almost identical usernames, visually identical but differing
by their unicode code points only, Unicode NFKC normalization should
make appear them equal to Django.
"""
omega_username
=
'iamtheΩ'
# U+03A9 GREEK CAPITAL LETTER OMEGA
ohm_username
=
'iamtheΩ'
# U+2126 OHM SIGN
self
.
assertNotEqual
(
omega_username
,
ohm_username
)
User
.
objects
.
create_user
(
username
=
omega_username
,
password
=
'pwd'
)
data
=
{
'username'
:
ohm_username
,
'password1'
:
'pwd2'
,
'password2'
:
'pwd2'
,
}
form
=
UserCreationForm
(
data
)
self
.
assertFalse
(
form
.
is_valid
())
self
.
assertEqual
(
form
.
errors
[
'username'
],
[
"A user with that username already exists."
]
)
@override_settings
(
AUTH_PASSWORD_VALIDATORS
=
[
{
'NAME'
:
'django.contrib.auth.password_validation.UserAttributeSimilarityValidator'
},
{
'NAME'
:
'django.contrib.auth.password_validation.MinimumLengthValidator'
,
'OPTIONS'
:
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment