From 224fa0bc7de05f3f269e7fd41b66154b82a2e87f Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Tue, 12 Oct 2021 06:21:14 +0200 Subject: [PATCH] [4.0.x] Refs #29628, Refs #33178 -- Made createsuperuser validate password against required fields passed in options. Backport of da266b3c5ca4bb7581d7a3cc51bc820e78cf64f0 from main --- .../management/commands/createsuperuser.py | 6 +-- tests/auth_tests/test_management.py | 40 +++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/django/contrib/auth/management/commands/createsuperuser.py b/django/contrib/auth/management/commands/createsuperuser.py index 61b4061252..6ab0e5a3b9 100644 --- a/django/contrib/auth/management/commands/createsuperuser.py +++ b/django/contrib/auth/management/commands/createsuperuser.py @@ -134,13 +134,13 @@ class Command(BaseCommand): self.stderr.write('Error: This field cannot be blank.') continue user_data[field_name] = [pk.strip() for pk in input_value.split(',')] - if not field.many_to_many: - fake_user_data[field_name] = input_value - # Wrap any foreign keys in fake model instances if field.many_to_one: fake_user_data[field_name] = field.remote_field.model(input_value) + if not field.many_to_many and field_name not in fake_user_data: + fake_user_data[field_name] = user_data[field_name] + # Prompt for a password if the model has one. while PASSWORD_FIELD in user_data and user_data[PASSWORD_FIELD] is None: password = getpass.getpass() diff --git a/tests/auth_tests/test_management.py b/tests/auth_tests/test_management.py index 8a4e23952c..575975fd90 100644 --- a/tests/auth_tests/test_management.py +++ b/tests/auth_tests/test_management.py @@ -713,6 +713,46 @@ class CreatesuperuserManagementCommandTestCase(TestCase): test(self) + @override_settings( + AUTH_USER_MODEL='auth_tests.CustomUser', + AUTH_PASSWORD_VALIDATORS=[ + {'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator'}, + ] + ) + def test_validate_password_against_required_fields_via_option(self): + new_io = StringIO() + first_name = 'josephine' + entered_passwords = [ + first_name, first_name, + 'superduperunguessablepassword', 'superduperunguessablepassword', + ] + + def bad_then_good_password(): + return entered_passwords.pop(0) + + @mock_inputs({ + 'password': bad_then_good_password, + 'bypass': 'n', + }) + def test(self): + call_command( + 'createsuperuser', + interactive=True, + first_name=first_name, + date_of_birth='1970-01-01', + email='joey@example.com', + stdin=MockTTY(), + stdout=new_io, + stderr=new_io, + ) + self.assertEqual( + new_io.getvalue().strip(), + 'The password is too similar to the first name.\n' + 'Superuser created successfully.' + ) + + test(self) + def test_blank_username(self): """Creation fails if --username is blank.""" new_io = StringIO()