From b88f98738fbbdf119f4ff001e4eccf72a77d9518 Mon Sep 17 00:00:00 2001 From: Yan Mitrofanov Date: Thu, 13 Aug 2020 13:27:00 +0300 Subject: [PATCH] Fixed #31878 -- Made createsuperuser respect --database option in default usernames. --- django/contrib/auth/management/__init__.py | 9 +++-- .../management/commands/createsuperuser.py | 2 +- tests/auth_tests/test_management.py | 40 +++++++++++++++++++ 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/django/contrib/auth/management/__init__.py b/django/contrib/auth/management/__init__.py index deda238c78d..1170cb0b20a 100644 --- a/django/contrib/auth/management/__init__.py +++ b/django/contrib/auth/management/__init__.py @@ -101,14 +101,15 @@ def get_system_username(): return result -def get_default_username(check_db=True): +def get_default_username(check_db=True, database=DEFAULT_DB_ALIAS): """ Try to determine the current system user's username to use as a default. :param check_db: If ``True``, requires that the username does not match an existing ``auth.User`` (otherwise returns an empty string). + :param database: The database where the unique check will be performed. :returns: The username, or an empty string if no username can be - determined. + determined or the suggested username is already taken. """ # This file is used in apps.py, it should not trigger models import. from django.contrib.auth import models as auth_app @@ -137,7 +138,9 @@ def get_default_username(check_db=True): # Don't return the default username if it is already taken. if check_db and default_username: try: - auth_app.User._default_manager.get(username=default_username) + auth_app.User._default_manager.db_manager(database).get( + username=default_username, + ) except auth_app.User.DoesNotExist: pass else: diff --git a/django/contrib/auth/management/commands/createsuperuser.py b/django/contrib/auth/management/commands/createsuperuser.py index 3b76477f018..3eb8abff066 100644 --- a/django/contrib/auth/management/commands/createsuperuser.py +++ b/django/contrib/auth/management/commands/createsuperuser.py @@ -97,7 +97,7 @@ class Command(BaseCommand): fake_user_data = {} if hasattr(self.stdin, 'isatty') and not self.stdin.isatty(): raise NotRunningInTTYException - default_username = get_default_username() + default_username = get_default_username(database=database) if username: error_msg = self._validate_username(username, verbose_field_name, database) if error_msg: diff --git a/tests/auth_tests/test_management.py b/tests/auth_tests/test_management.py index 6a8e623129d..517c0697da8 100644 --- a/tests/auth_tests/test_management.py +++ b/tests/auth_tests/test_management.py @@ -102,6 +102,7 @@ class MockInputTests(TestCase): class GetDefaultUsernameTestCase(TestCase): + databases = {'default', 'other'} def setUp(self): self.old_get_system_username = management.get_system_username @@ -128,6 +129,15 @@ class GetDefaultUsernameTestCase(TestCase): management.get_system_username = lambda: 'J\xfalia' self.assertEqual(management.get_default_username(), 'julia') + def test_with_database(self): + User.objects.create(username='joe') + management.get_system_username = lambda: 'joe' + self.assertEqual(management.get_default_username(), '') + self.assertEqual(management.get_default_username(database='other'), 'joe') + + User.objects.using('other').create(username='joe') + self.assertEqual(management.get_default_username(database='other'), '') + @override_settings(AUTH_PASSWORD_VALIDATORS=[ {'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator'}, @@ -1047,6 +1057,36 @@ class MultiDBCreatesuperuserTestCase(TestCase): user = User.objects.using('other').get(username='joe') self.assertEqual(user.email, 'joe@somewhere.org') + def test_createsuperuser_command_suggested_username_with_database_option(self): + default_username = get_default_username(database='other') + qs = User.objects.using('other') + + @mock_inputs({'password': 'nopasswd', 'username': '', 'email': ''}) + def test_other_create_with_suggested_username(self): + call_command( + 'createsuperuser', + interactive=True, + stdin=MockTTY(), + verbosity=0, + database='other', + ) + self.assertIs(qs.filter(username=default_username).exists(), True) + + test_other_create_with_suggested_username(self) + + @mock_inputs({'password': 'nopasswd', 'Username: ': 'other', 'email': ''}) + def test_other_no_suggestion(self): + call_command( + 'createsuperuser', + interactive=True, + stdin=MockTTY(), + verbosity=0, + database='other', + ) + self.assertIs(qs.filter(username='other').exists(), True) + + test_other_no_suggestion(self) + class CreatePermissionsTests(TestCase):