Made createsuperuser more robust when getting current OS username.
Under some versions of OS X, failure in getting the default system locale during the syncdb operation of the auth app were causing hard to diagnose problems afterwards. No solution based on getpreferredencoding() was chosen because it has its own problems with certain combinations of Python and OS X versions (e.g. http://bugs.python.org/issue6202). Thanks prestonsimmons for the report and prestonsimmons and willhardy for the initial patch. Fixes #16017.
This commit is contained in:
parent
6e4c984098
commit
4c934f3921
|
@ -84,14 +84,17 @@ def get_system_username():
|
|||
:returns: The username as a unicode string, or an empty string if the
|
||||
username could not be determined.
|
||||
"""
|
||||
try:
|
||||
return getpass.getuser().decode(locale.getdefaultlocale()[1])
|
||||
except (ImportError, KeyError, UnicodeDecodeError):
|
||||
# KeyError will be raised by os.getpwuid() (called by getuser())
|
||||
# if there is no corresponding entry in the /etc/passwd file
|
||||
# (a very restricted chroot environment, for example).
|
||||
# UnicodeDecodeError - preventive treatment for non-latin Windows.
|
||||
return ''
|
||||
default_locale = locale.getdefaultlocale()[1]
|
||||
if default_locale:
|
||||
try:
|
||||
return getpass.getuser().decode(default_locale)
|
||||
except (ImportError, KeyError, UnicodeDecodeError):
|
||||
# KeyError will be raised by os.getpwuid() (called by getuser())
|
||||
# if there is no corresponding entry in the /etc/passwd file
|
||||
# (a very restricted chroot environment, for example).
|
||||
# UnicodeDecodeError - preventive treatment for non-latin Windows.
|
||||
pass
|
||||
return ''
|
||||
|
||||
|
||||
def get_default_username(check_db=True):
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
import locale
|
||||
import traceback
|
||||
|
||||
from django.contrib.auth.management.commands import createsuperuser
|
||||
from django.contrib.auth.models import User, AnonymousUser
|
||||
from django.core.management import call_command
|
||||
from django.test import TestCase
|
||||
from django.utils.six import StringIO
|
||||
from django.utils.unittest import skipUnless
|
||||
|
||||
try:
|
||||
import crypt as crypt_module
|
||||
except ImportError:
|
||||
crypt_module = None
|
||||
|
||||
|
||||
class BasicTestCase(TestCase):
|
||||
|
@ -111,3 +109,37 @@ class BasicTestCase(TestCase):
|
|||
u = User.objects.get(username="joe+admin@somewhere.org")
|
||||
self.assertEqual(u.email, 'joe@somewhere.org')
|
||||
self.assertFalse(u.has_usable_password())
|
||||
|
||||
def test_createsuperuser_nolocale(self):
|
||||
"""
|
||||
Check that createsuperuser does not break when no locale is set. See
|
||||
ticket #16017.
|
||||
"""
|
||||
|
||||
old_getdefaultlocale = locale.getdefaultlocale
|
||||
old_getpass = createsuperuser.getpass
|
||||
try:
|
||||
# Temporarily remove locale information
|
||||
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
|
||||
new_io = StringIO()
|
||||
call_command("createsuperuser", interactive=True, username="nolocale@somewhere.org", email="nolocale@somewhere.org", stdout=new_io)
|
||||
|
||||
except TypeError as e:
|
||||
self.fail("createsuperuser fails if the OS provides no information about the current locale")
|
||||
|
||||
finally:
|
||||
# Re-apply locale and getpass information
|
||||
createsuperuser.getpass = old_getpass
|
||||
locale.getdefaultlocale = old_getdefaultlocale
|
||||
|
||||
# If we were successful, a user should have been created
|
||||
u = User.objects.get(username="nolocale@somewhere.org")
|
||||
self.assertEqual(u.email, 'nolocale@somewhere.org')
|
||||
|
|
Loading…
Reference in New Issue