Fixed #19725 -- Made createsuperuser handle non-ascii prompts
Thanks Michisu for the report.
This commit is contained in:
parent
fb606e10ac
commit
55c585f1c7
|
@ -11,6 +11,7 @@ from django.contrib.auth.management import get_default_username
|
||||||
from django.core import exceptions
|
from django.core import exceptions
|
||||||
from django.core.management.base import BaseCommand, CommandError
|
from django.core.management.base import BaseCommand, CommandError
|
||||||
from django.db import DEFAULT_DB_ALIAS
|
from django.db import DEFAULT_DB_ALIAS
|
||||||
|
from django.utils.encoding import force_str
|
||||||
from django.utils.six.moves import input
|
from django.utils.six.moves import input
|
||||||
from django.utils.text import capfirst
|
from django.utils.text import capfirst
|
||||||
|
|
||||||
|
@ -83,8 +84,9 @@ class Command(BaseCommand):
|
||||||
if not username:
|
if not username:
|
||||||
input_msg = capfirst(self.username_field.verbose_name)
|
input_msg = capfirst(self.username_field.verbose_name)
|
||||||
if default_username:
|
if default_username:
|
||||||
input_msg += " (leave blank to use '%s')" % default_username
|
input_msg = "%s (leave blank to use '%s')" % (
|
||||||
raw_value = input(input_msg + ': ')
|
input_msg, default_username)
|
||||||
|
raw_value = input(force_str('%s: ' % input_msg))
|
||||||
|
|
||||||
if default_username and raw_value == '':
|
if default_username and raw_value == '':
|
||||||
raw_value = default_username
|
raw_value = default_username
|
||||||
|
@ -107,7 +109,7 @@ class Command(BaseCommand):
|
||||||
field = self.UserModel._meta.get_field(field_name)
|
field = self.UserModel._meta.get_field(field_name)
|
||||||
user_data[field_name] = options.get(field_name)
|
user_data[field_name] = options.get(field_name)
|
||||||
while user_data[field_name] is None:
|
while user_data[field_name] is None:
|
||||||
raw_value = input(capfirst(field.verbose_name + ': '))
|
raw_value = input(force_str('%s: ' % capfirst(field.verbose_name)))
|
||||||
try:
|
try:
|
||||||
user_data[field_name] = field.clean(raw_value, None)
|
user_data[field_name] = field.clean(raw_value, None)
|
||||||
except exceptions.ValidationError as e:
|
except exceptions.ValidationError as e:
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import locale
|
import locale
|
||||||
|
|
||||||
from django.contrib.auth import get_user_model
|
from django.contrib.auth import get_user_model
|
||||||
|
@ -12,6 +15,37 @@ from django.test.utils import override_settings
|
||||||
from django.utils.six import StringIO
|
from django.utils.six import StringIO
|
||||||
|
|
||||||
|
|
||||||
|
def mock_inputs(inputs):
|
||||||
|
"""
|
||||||
|
Decorator to temporarily replace input/getpass to allow interactive
|
||||||
|
createsuperuser.
|
||||||
|
"""
|
||||||
|
def inner(test_func):
|
||||||
|
def wrapped(*args):
|
||||||
|
class mock_getpass:
|
||||||
|
pass
|
||||||
|
mock_getpass.getpass = staticmethod(lambda p=None: inputs['password'])
|
||||||
|
|
||||||
|
def mock_input(prompt):
|
||||||
|
# prompt should be encoded in Python 2. This line will raise an
|
||||||
|
# Exception if prompt contains unencoded non-ascii on Python 2.
|
||||||
|
prompt = str(prompt)
|
||||||
|
if str('leave blank to use') in prompt:
|
||||||
|
return inputs['username']
|
||||||
|
|
||||||
|
old_getpass = createsuperuser.getpass
|
||||||
|
old_input = createsuperuser.input
|
||||||
|
createsuperuser.getpass = mock_getpass
|
||||||
|
createsuperuser.input = mock_input
|
||||||
|
try:
|
||||||
|
test_func(*args)
|
||||||
|
finally:
|
||||||
|
createsuperuser.getpass = old_getpass
|
||||||
|
createsuperuser.input = old_input
|
||||||
|
return wrapped
|
||||||
|
return inner
|
||||||
|
|
||||||
|
|
||||||
@skipIfCustomUser
|
@skipIfCustomUser
|
||||||
class BasicTestCase(TestCase):
|
class BasicTestCase(TestCase):
|
||||||
def test_user(self):
|
def test_user(self):
|
||||||
|
@ -103,17 +137,17 @@ class BasicTestCase(TestCase):
|
||||||
self.assertEqual(u.email, 'joe2@somewhere.org')
|
self.assertEqual(u.email, 'joe2@somewhere.org')
|
||||||
self.assertFalse(u.has_usable_password())
|
self.assertFalse(u.has_usable_password())
|
||||||
|
|
||||||
new_io = StringIO()
|
|
||||||
call_command("createsuperuser",
|
call_command("createsuperuser",
|
||||||
interactive=False,
|
interactive=False,
|
||||||
username="joe+admin@somewhere.org",
|
username="joe+admin@somewhere.org",
|
||||||
email="joe@somewhere.org",
|
email="joe@somewhere.org",
|
||||||
stdout=new_io
|
verbosity=0
|
||||||
)
|
)
|
||||||
u = User.objects.get(username="joe+admin@somewhere.org")
|
u = User.objects.get(username="joe+admin@somewhere.org")
|
||||||
self.assertEqual(u.email, 'joe@somewhere.org')
|
self.assertEqual(u.email, 'joe@somewhere.org')
|
||||||
self.assertFalse(u.has_usable_password())
|
self.assertFalse(u.has_usable_password())
|
||||||
|
|
||||||
|
@mock_inputs({'password': "nopasswd"})
|
||||||
def test_createsuperuser_nolocale(self):
|
def test_createsuperuser_nolocale(self):
|
||||||
"""
|
"""
|
||||||
Check that createsuperuser does not break when no locale is set. See
|
Check that createsuperuser does not break when no locale is set. See
|
||||||
|
@ -121,39 +155,47 @@ class BasicTestCase(TestCase):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
old_getdefaultlocale = locale.getdefaultlocale
|
old_getdefaultlocale = locale.getdefaultlocale
|
||||||
old_getpass = createsuperuser.getpass
|
|
||||||
try:
|
try:
|
||||||
# Temporarily remove locale information
|
# Temporarily remove locale information
|
||||||
locale.getdefaultlocale = lambda: (None, None)
|
locale.getdefaultlocale = lambda: (None, None)
|
||||||
|
|
||||||
# Temporarily replace getpass to allow interactive code to be used
|
|
||||||
# non-interactively
|
|
||||||
class mock_getpass:
|
|
||||||
pass
|
|
||||||
mock_getpass.getpass = staticmethod(lambda p=None: "nopasswd")
|
|
||||||
createsuperuser.getpass = mock_getpass
|
|
||||||
|
|
||||||
# Call the command in this new environment
|
# Call the command in this new environment
|
||||||
new_io = StringIO()
|
|
||||||
call_command("createsuperuser",
|
call_command("createsuperuser",
|
||||||
interactive=True,
|
interactive=True,
|
||||||
username="nolocale@somewhere.org",
|
username="nolocale@somewhere.org",
|
||||||
email="nolocale@somewhere.org",
|
email="nolocale@somewhere.org",
|
||||||
stdout=new_io
|
verbosity=0
|
||||||
)
|
)
|
||||||
|
|
||||||
except TypeError:
|
except TypeError:
|
||||||
self.fail("createsuperuser fails if the OS provides no information about the current locale")
|
self.fail("createsuperuser fails if the OS provides no information about the current locale")
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
# Re-apply locale and getpass information
|
# Re-apply locale information
|
||||||
createsuperuser.getpass = old_getpass
|
|
||||||
locale.getdefaultlocale = old_getdefaultlocale
|
locale.getdefaultlocale = old_getdefaultlocale
|
||||||
|
|
||||||
# If we were successful, a user should have been created
|
# If we were successful, a user should have been created
|
||||||
u = User.objects.get(username="nolocale@somewhere.org")
|
u = User.objects.get(username="nolocale@somewhere.org")
|
||||||
self.assertEqual(u.email, 'nolocale@somewhere.org')
|
self.assertEqual(u.email, 'nolocale@somewhere.org')
|
||||||
|
|
||||||
|
@mock_inputs({'password': "nopasswd", 'username': 'foo'})
|
||||||
|
def test_createsuperuser_non_ascii_verbose_name(self):
|
||||||
|
username_field = User._meta.get_field('username')
|
||||||
|
old_verbose_name = username_field.verbose_name
|
||||||
|
username_field.verbose_name = 'uživatel'
|
||||||
|
new_io = StringIO()
|
||||||
|
try:
|
||||||
|
call_command("createsuperuser",
|
||||||
|
interactive=True,
|
||||||
|
email="nolocale@somewhere.org",
|
||||||
|
stdout=new_io
|
||||||
|
)
|
||||||
|
finally:
|
||||||
|
username_field.verbose_name = old_verbose_name
|
||||||
|
|
||||||
|
command_output = new_io.getvalue().strip()
|
||||||
|
self.assertEqual(command_output, 'Superuser created successfully.')
|
||||||
|
|
||||||
def test_get_user_model(self):
|
def test_get_user_model(self):
|
||||||
"The current user model can be retrieved"
|
"The current user model can be retrieved"
|
||||||
self.assertEqual(get_user_model(), User)
|
self.assertEqual(get_user_model(), User)
|
||||||
|
|
Loading…
Reference in New Issue