diff --git a/django/contrib/auth/management/commands/createsuperuser.py b/django/contrib/auth/management/commands/createsuperuser.py index 7e19ef9955..3a16c58b3d 100644 --- a/django/contrib/auth/management/commands/createsuperuser.py +++ b/django/contrib/auth/management/commands/createsuperuser.py @@ -163,7 +163,9 @@ class Command(BaseCommand): validate_password(password2, self.UserModel(**fake_user_data)) except exceptions.ValidationError as err: self.stderr.write('\n'.join(err.messages)) - password = None + response = input('Bypass password validation and create user anyway? [y/N]: ') + if response.lower() != 'y': + password = None except KeyboardInterrupt: self.stderr.write("\nOperation cancelled.") diff --git a/docs/releases/2.1.txt b/docs/releases/2.1.txt index 22768e2f1b..2135e1a958 100644 --- a/docs/releases/2.1.txt +++ b/docs/releases/2.1.txt @@ -42,7 +42,8 @@ Minor features :mod:`django.contrib.auth` ~~~~~~~~~~~~~~~~~~~~~~~~~~ -* ... +* :djadmin:`createsuperuser` now gives a prompt to allow bypassing the + :setting:`AUTH_PASSWORD_VALIDATORS` checks. :mod:`django.contrib.contenttypes` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/tests/auth_tests/test_management.py b/tests/auth_tests/test_management.py index 539ac84424..4e60333c9d 100644 --- a/tests/auth_tests/test_management.py +++ b/tests/auth_tests/test_management.py @@ -27,6 +27,7 @@ from .models import ( MOCK_INPUT_KEY_TO_PROMPTS = { # @mock_inputs dict key: [expected prompt messages], + 'bypass': ['Bypass password validation and create user anyway? [y/N]: '], 'email': ['Email address: '], 'username': ['Username: ', lambda: "Username (leave blank to use '%s'): " % get_default_username()], } @@ -531,6 +532,7 @@ class CreatesuperuserManagementCommandTestCase(TestCase): 'password': bad_then_good_password, 'username': 'joe1234567890', 'email': '', + 'bypass': 'n', }) def test(self): call_command( @@ -564,6 +566,34 @@ class CreatesuperuserManagementCommandTestCase(TestCase): test(self) + def test_password_validation_bypass(self): + """ + Password validation can be bypassed by entering 'y' at the prompt. + """ + new_io = StringIO() + + @mock_inputs({ + 'password': '1234567890', + 'username': 'joe1234567890', + 'email': '', + 'bypass': 'y', + }) + def test(self): + call_command( + 'createsuperuser', + interactive=True, + stdin=MockTTY(), + stdout=new_io, + stderr=new_io, + ) + self.assertEqual( + new_io.getvalue().strip(), + 'This password is entirely numeric.\n' + 'Superuser created successfully.' + ) + + test(self) + def test_invalid_username(self): """Creation fails if the username fails validation.""" user_field = User._meta.get_field(User.USERNAME_FIELD)