1. import builtins
    
  2. import getpass
    
  3. import os
    
  4. import sys
    
  5. from datetime import date
    
  6. from io import StringIO
    
  7. from unittest import mock
    
  8. 
    
  9. from django.apps import apps
    
  10. from django.contrib.auth import get_permission_codename, management
    
  11. from django.contrib.auth.management import create_permissions, get_default_username
    
  12. from django.contrib.auth.management.commands import changepassword, createsuperuser
    
  13. from django.contrib.auth.models import Group, Permission, User
    
  14. from django.contrib.contenttypes.models import ContentType
    
  15. from django.core.management import call_command
    
  16. from django.core.management.base import CommandError
    
  17. from django.db import migrations
    
  18. from django.test import TestCase, override_settings
    
  19. from django.utils.translation import gettext_lazy as _
    
  20. 
    
  21. from .models import (
    
  22.     CustomUser,
    
  23.     CustomUserNonUniqueUsername,
    
  24.     CustomUserWithFK,
    
  25.     CustomUserWithM2M,
    
  26.     CustomUserWithUniqueConstraint,
    
  27.     Email,
    
  28.     Organization,
    
  29.     UserProxy,
    
  30. )
    
  31. 
    
  32. MOCK_INPUT_KEY_TO_PROMPTS = {
    
  33.     # @mock_inputs dict key: [expected prompt messages],
    
  34.     "bypass": ["Bypass password validation and create user anyway? [y/N]: "],
    
  35.     "email": ["Email address: "],
    
  36.     "date_of_birth": ["Date of birth: "],
    
  37.     "first_name": ["First name: "],
    
  38.     "username": [
    
  39.         "Username: ",
    
  40.         lambda: "Username (leave blank to use '%s'): " % get_default_username(),
    
  41.     ],
    
  42. }
    
  43. 
    
  44. 
    
  45. def mock_inputs(inputs):
    
  46.     """
    
  47.     Decorator to temporarily replace input/getpass to allow interactive
    
  48.     createsuperuser.
    
  49.     """
    
  50. 
    
  51.     def inner(test_func):
    
  52.         def wrapped(*args):
    
  53.             class mock_getpass:
    
  54.                 @staticmethod
    
  55.                 def getpass(prompt=b"Password: ", stream=None):
    
  56.                     if callable(inputs["password"]):
    
  57.                         return inputs["password"]()
    
  58.                     return inputs["password"]
    
  59. 
    
  60.             def mock_input(prompt):
    
  61.                 assert "__proxy__" not in prompt
    
  62.                 response = None
    
  63.                 for key, val in inputs.items():
    
  64.                     if val == "KeyboardInterrupt":
    
  65.                         raise KeyboardInterrupt
    
  66.                     # get() fallback because sometimes 'key' is the actual
    
  67.                     # prompt rather than a shortcut name.
    
  68.                     prompt_msgs = MOCK_INPUT_KEY_TO_PROMPTS.get(key, key)
    
  69.                     if isinstance(prompt_msgs, list):
    
  70.                         prompt_msgs = [
    
  71.                             msg() if callable(msg) else msg for msg in prompt_msgs
    
  72.                         ]
    
  73.                     if prompt in prompt_msgs:
    
  74.                         if callable(val):
    
  75.                             response = val()
    
  76.                         else:
    
  77.                             response = val
    
  78.                         break
    
  79.                 if response is None:
    
  80.                     raise ValueError("Mock input for %r not found." % prompt)
    
  81.                 return response
    
  82. 
    
  83.             old_getpass = createsuperuser.getpass
    
  84.             old_input = builtins.input
    
  85.             createsuperuser.getpass = mock_getpass
    
  86.             builtins.input = mock_input
    
  87.             try:
    
  88.                 test_func(*args)
    
  89.             finally:
    
  90.                 createsuperuser.getpass = old_getpass
    
  91.                 builtins.input = old_input
    
  92. 
    
  93.         return wrapped
    
  94. 
    
  95.     return inner
    
  96. 
    
  97. 
    
  98. class MockTTY:
    
  99.     """
    
  100.     A fake stdin object that pretends to be a TTY to be used in conjunction
    
  101.     with mock_inputs.
    
  102.     """
    
  103. 
    
  104.     def isatty(self):
    
  105.         return True
    
  106. 
    
  107. 
    
  108. class MockInputTests(TestCase):
    
  109.     @mock_inputs({"username": "alice"})
    
  110.     def test_input_not_found(self):
    
  111.         with self.assertRaisesMessage(
    
  112.             ValueError, "Mock input for 'Email address: ' not found."
    
  113.         ):
    
  114.             call_command("createsuperuser", stdin=MockTTY())
    
  115. 
    
  116. 
    
  117. class GetDefaultUsernameTestCase(TestCase):
    
  118.     databases = {"default", "other"}
    
  119. 
    
  120.     def setUp(self):
    
  121.         self.old_get_system_username = management.get_system_username
    
  122. 
    
  123.     def tearDown(self):
    
  124.         management.get_system_username = self.old_get_system_username
    
  125. 
    
  126.     def test_actual_implementation(self):
    
  127.         self.assertIsInstance(management.get_system_username(), str)
    
  128. 
    
  129.     def test_simple(self):
    
  130.         management.get_system_username = lambda: "joe"
    
  131.         self.assertEqual(management.get_default_username(), "joe")
    
  132. 
    
  133.     def test_existing(self):
    
  134.         User.objects.create(username="joe")
    
  135.         management.get_system_username = lambda: "joe"
    
  136.         self.assertEqual(management.get_default_username(), "")
    
  137.         self.assertEqual(management.get_default_username(check_db=False), "joe")
    
  138. 
    
  139.     def test_i18n(self):
    
  140.         # 'Julia' with accented 'u':
    
  141.         management.get_system_username = lambda: "J\xfalia"
    
  142.         self.assertEqual(management.get_default_username(), "julia")
    
  143. 
    
  144.     def test_with_database(self):
    
  145.         User.objects.create(username="joe")
    
  146.         management.get_system_username = lambda: "joe"
    
  147.         self.assertEqual(management.get_default_username(), "")
    
  148.         self.assertEqual(management.get_default_username(database="other"), "joe")
    
  149. 
    
  150.         User.objects.using("other").create(username="joe")
    
  151.         self.assertEqual(management.get_default_username(database="other"), "")
    
  152. 
    
  153. 
    
  154. @override_settings(
    
  155.     AUTH_PASSWORD_VALIDATORS=[
    
  156.         {"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"},
    
  157.     ]
    
  158. )
    
  159. class ChangepasswordManagementCommandTestCase(TestCase):
    
  160.     @classmethod
    
  161.     def setUpTestData(cls):
    
  162.         cls.user = User.objects.create_user(username="joe", password="qwerty")
    
  163. 
    
  164.     def setUp(self):
    
  165.         self.stdout = StringIO()
    
  166.         self.stderr = StringIO()
    
  167. 
    
  168.     def tearDown(self):
    
  169.         self.stdout.close()
    
  170.         self.stderr.close()
    
  171. 
    
  172.     @mock.patch.object(getpass, "getpass", return_value="password")
    
  173.     def test_get_pass(self, mock_get_pass):
    
  174.         call_command("changepassword", username="joe", stdout=self.stdout)
    
  175.         self.assertIs(User.objects.get(username="joe").check_password("password"), True)
    
  176. 
    
  177.     @mock.patch.object(getpass, "getpass", return_value="")
    
  178.     def test_get_pass_no_input(self, mock_get_pass):
    
  179.         with self.assertRaisesMessage(CommandError, "aborted"):
    
  180.             call_command("changepassword", username="joe", stdout=self.stdout)
    
  181. 
    
  182.     @mock.patch.object(changepassword.Command, "_get_pass", return_value="new_password")
    
  183.     def test_system_username(self, mock_get_pass):
    
  184.         """The system username is used if --username isn't provided."""
    
  185.         username = getpass.getuser()
    
  186.         User.objects.create_user(username=username, password="qwerty")
    
  187.         call_command("changepassword", stdout=self.stdout)
    
  188.         self.assertIs(
    
  189.             User.objects.get(username=username).check_password("new_password"), True
    
  190.         )
    
  191. 
    
  192.     def test_nonexistent_username(self):
    
  193.         with self.assertRaisesMessage(CommandError, "user 'test' does not exist"):
    
  194.             call_command("changepassword", username="test", stdout=self.stdout)
    
  195. 
    
  196.     @mock.patch.object(changepassword.Command, "_get_pass", return_value="not qwerty")
    
  197.     def test_that_changepassword_command_changes_joes_password(self, mock_get_pass):
    
  198.         "Executing the changepassword management command should change joe's password"
    
  199.         self.assertTrue(self.user.check_password("qwerty"))
    
  200. 
    
  201.         call_command("changepassword", username="joe", stdout=self.stdout)
    
  202.         command_output = self.stdout.getvalue().strip()
    
  203. 
    
  204.         self.assertEqual(
    
  205.             command_output,
    
  206.             "Changing password for user 'joe'\n"
    
  207.             "Password changed successfully for user 'joe'",
    
  208.         )
    
  209.         self.assertTrue(User.objects.get(username="joe").check_password("not qwerty"))
    
  210. 
    
  211.     @mock.patch.object(
    
  212.         changepassword.Command, "_get_pass", side_effect=lambda *args: str(args)
    
  213.     )
    
  214.     def test_that_max_tries_exits_1(self, mock_get_pass):
    
  215.         """
    
  216.         A CommandError should be thrown by handle() if the user enters in
    
  217.         mismatched passwords three times.
    
  218.         """
    
  219.         msg = "Aborting password change for user 'joe' after 3 attempts"
    
  220.         with self.assertRaisesMessage(CommandError, msg):
    
  221.             call_command(
    
  222.                 "changepassword", username="joe", stdout=self.stdout, stderr=self.stderr
    
  223.             )
    
  224. 
    
  225.     @mock.patch.object(changepassword.Command, "_get_pass", return_value="1234567890")
    
  226.     def test_password_validation(self, mock_get_pass):
    
  227.         """
    
  228.         A CommandError should be raised if the user enters in passwords which
    
  229.         fail validation three times.
    
  230.         """
    
  231.         abort_msg = "Aborting password change for user 'joe' after 3 attempts"
    
  232.         with self.assertRaisesMessage(CommandError, abort_msg):
    
  233.             call_command(
    
  234.                 "changepassword", username="joe", stdout=self.stdout, stderr=self.stderr
    
  235.             )
    
  236.         self.assertIn("This password is entirely numeric.", self.stderr.getvalue())
    
  237. 
    
  238.     @mock.patch.object(changepassword.Command, "_get_pass", return_value="not qwerty")
    
  239.     def test_that_changepassword_command_works_with_nonascii_output(
    
  240.         self, mock_get_pass
    
  241.     ):
    
  242.         """
    
  243.         #21627 -- Executing the changepassword management command should allow
    
  244.         non-ASCII characters from the User object representation.
    
  245.         """
    
  246.         # 'Julia' with accented 'u':
    
  247.         User.objects.create_user(username="J\xfalia", password="qwerty")
    
  248.         call_command("changepassword", username="J\xfalia", stdout=self.stdout)
    
  249. 
    
  250. 
    
  251. class MultiDBChangepasswordManagementCommandTestCase(TestCase):
    
  252.     databases = {"default", "other"}
    
  253. 
    
  254.     @mock.patch.object(changepassword.Command, "_get_pass", return_value="not qwerty")
    
  255.     def test_that_changepassword_command_with_database_option_uses_given_db(
    
  256.         self, mock_get_pass
    
  257.     ):
    
  258.         """
    
  259.         changepassword --database should operate on the specified DB.
    
  260.         """
    
  261.         user = User.objects.db_manager("other").create_user(
    
  262.             username="joe", password="qwerty"
    
  263.         )
    
  264.         self.assertTrue(user.check_password("qwerty"))
    
  265. 
    
  266.         out = StringIO()
    
  267.         call_command("changepassword", username="joe", database="other", stdout=out)
    
  268.         command_output = out.getvalue().strip()
    
  269. 
    
  270.         self.assertEqual(
    
  271.             command_output,
    
  272.             "Changing password for user 'joe'\n"
    
  273.             "Password changed successfully for user 'joe'",
    
  274.         )
    
  275.         self.assertTrue(
    
  276.             User.objects.using("other").get(username="joe").check_password("not qwerty")
    
  277.         )
    
  278. 
    
  279. 
    
  280. @override_settings(
    
  281.     SILENCED_SYSTEM_CHECKS=["fields.W342"],  # ForeignKey(unique=True)
    
  282.     AUTH_PASSWORD_VALIDATORS=[
    
  283.         {"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"}
    
  284.     ],
    
  285. )
    
  286. class CreatesuperuserManagementCommandTestCase(TestCase):
    
  287.     def test_no_email_argument(self):
    
  288.         new_io = StringIO()
    
  289.         with self.assertRaisesMessage(
    
  290.             CommandError, "You must use --email with --noinput."
    
  291.         ):
    
  292.             call_command(
    
  293.                 "createsuperuser", interactive=False, username="joe", stdout=new_io
    
  294.             )
    
  295. 
    
  296.     def test_basic_usage(self):
    
  297.         "Check the operation of the createsuperuser management command"
    
  298.         # We can use the management command to create a superuser
    
  299.         new_io = StringIO()
    
  300.         call_command(
    
  301.             "createsuperuser",
    
  302.             interactive=False,
    
  303.             username="joe",
    
  304.             email="[email protected]",
    
  305.             stdout=new_io,
    
  306.         )
    
  307.         command_output = new_io.getvalue().strip()
    
  308.         self.assertEqual(command_output, "Superuser created successfully.")
    
  309.         u = User.objects.get(username="joe")
    
  310.         self.assertEqual(u.email, "[email protected]")
    
  311. 
    
  312.         # created password should be unusable
    
  313.         self.assertFalse(u.has_usable_password())
    
  314. 
    
  315.     def test_non_ascii_verbose_name(self):
    
  316.         @mock_inputs(
    
  317.             {
    
  318.                 "password": "nopasswd",
    
  319.                 "Uživatel (leave blank to use '%s'): "
    
  320.                 % get_default_username(): "foo",  # username (cz)
    
  321.                 "email": "[email protected]",
    
  322.             }
    
  323.         )
    
  324.         def test(self):
    
  325.             username_field = User._meta.get_field("username")
    
  326.             old_verbose_name = username_field.verbose_name
    
  327.             username_field.verbose_name = _("u\u017eivatel")
    
  328.             new_io = StringIO()
    
  329.             try:
    
  330.                 call_command(
    
  331.                     "createsuperuser",
    
  332.                     interactive=True,
    
  333.                     stdout=new_io,
    
  334.                     stdin=MockTTY(),
    
  335.                 )
    
  336.             finally:
    
  337.                 username_field.verbose_name = old_verbose_name
    
  338. 
    
  339.             command_output = new_io.getvalue().strip()
    
  340.             self.assertEqual(command_output, "Superuser created successfully.")
    
  341. 
    
  342.         test(self)
    
  343. 
    
  344.     def test_verbosity_zero(self):
    
  345.         # We can suppress output on the management command
    
  346.         new_io = StringIO()
    
  347.         call_command(
    
  348.             "createsuperuser",
    
  349.             interactive=False,
    
  350.             username="joe2",
    
  351.             email="[email protected]",
    
  352.             verbosity=0,
    
  353.             stdout=new_io,
    
  354.         )
    
  355.         command_output = new_io.getvalue().strip()
    
  356.         self.assertEqual(command_output, "")
    
  357.         u = User.objects.get(username="joe2")
    
  358.         self.assertEqual(u.email, "[email protected]")
    
  359.         self.assertFalse(u.has_usable_password())
    
  360. 
    
  361.     def test_email_in_username(self):
    
  362.         call_command(
    
  363.             "createsuperuser",
    
  364.             interactive=False,
    
  365.             username="[email protected]",
    
  366.             email="[email protected]",
    
  367.             verbosity=0,
    
  368.         )
    
  369.         u = User._default_manager.get(username="[email protected]")
    
  370.         self.assertEqual(u.email, "[email protected]")
    
  371.         self.assertFalse(u.has_usable_password())
    
  372. 
    
  373.     @override_settings(AUTH_USER_MODEL="auth_tests.CustomUser")
    
  374.     def test_swappable_user(self):
    
  375.         "A superuser can be created when a custom user model is in use"
    
  376.         # We can use the management command to create a superuser
    
  377.         # We skip validation because the temporary substitution of the
    
  378.         # swappable User model messes with validation.
    
  379.         new_io = StringIO()
    
  380.         call_command(
    
  381.             "createsuperuser",
    
  382.             interactive=False,
    
  383.             email="[email protected]",
    
  384.             date_of_birth="1976-04-01",
    
  385.             first_name="Joe",
    
  386.             stdout=new_io,
    
  387.         )
    
  388.         command_output = new_io.getvalue().strip()
    
  389.         self.assertEqual(command_output, "Superuser created successfully.")
    
  390.         u = CustomUser._default_manager.get(email="[email protected]")
    
  391.         self.assertEqual(u.date_of_birth, date(1976, 4, 1))
    
  392. 
    
  393.         # created password should be unusable
    
  394.         self.assertFalse(u.has_usable_password())
    
  395. 
    
  396.     @override_settings(AUTH_USER_MODEL="auth_tests.CustomUser")
    
  397.     def test_swappable_user_missing_required_field(self):
    
  398.         "A Custom superuser won't be created when a required field isn't provided"
    
  399.         # We can use the management command to create a superuser
    
  400.         # We skip validation because the temporary substitution of the
    
  401.         # swappable User model messes with validation.
    
  402.         new_io = StringIO()
    
  403.         with self.assertRaisesMessage(
    
  404.             CommandError, "You must use --email with --noinput."
    
  405.         ):
    
  406.             call_command(
    
  407.                 "createsuperuser",
    
  408.                 interactive=False,
    
  409.                 stdout=new_io,
    
  410.                 stderr=new_io,
    
  411.             )
    
  412. 
    
  413.         self.assertEqual(CustomUser._default_manager.count(), 0)
    
  414. 
    
  415.     @override_settings(
    
  416.         AUTH_USER_MODEL="auth_tests.CustomUserNonUniqueUsername",
    
  417.         AUTHENTICATION_BACKENDS=["my.custom.backend"],
    
  418.     )
    
  419.     def test_swappable_user_username_non_unique(self):
    
  420.         @mock_inputs(
    
  421.             {
    
  422.                 "username": "joe",
    
  423.                 "password": "nopasswd",
    
  424.             }
    
  425.         )
    
  426.         def createsuperuser():
    
  427.             new_io = StringIO()
    
  428.             call_command(
    
  429.                 "createsuperuser",
    
  430.                 interactive=True,
    
  431.                 email="[email protected]",
    
  432.                 stdout=new_io,
    
  433.                 stdin=MockTTY(),
    
  434.             )
    
  435.             command_output = new_io.getvalue().strip()
    
  436.             self.assertEqual(command_output, "Superuser created successfully.")
    
  437. 
    
  438.         for i in range(2):
    
  439.             createsuperuser()
    
  440. 
    
  441.         users = CustomUserNonUniqueUsername.objects.filter(username="joe")
    
  442.         self.assertEqual(users.count(), 2)
    
  443. 
    
  444.     def test_skip_if_not_in_TTY(self):
    
  445.         """
    
  446.         If the command is not called from a TTY, it should be skipped and a
    
  447.         message should be displayed (#7423).
    
  448.         """
    
  449. 
    
  450.         class FakeStdin:
    
  451.             """A fake stdin object that has isatty() return False."""
    
  452. 
    
  453.             def isatty(self):
    
  454.                 return False
    
  455. 
    
  456.         out = StringIO()
    
  457.         call_command(
    
  458.             "createsuperuser",
    
  459.             stdin=FakeStdin(),
    
  460.             stdout=out,
    
  461.             interactive=True,
    
  462.         )
    
  463. 
    
  464.         self.assertEqual(User._default_manager.count(), 0)
    
  465.         self.assertIn("Superuser creation skipped", out.getvalue())
    
  466. 
    
  467.     def test_passing_stdin(self):
    
  468.         """
    
  469.         You can pass a stdin object as an option and it should be
    
  470.         available on self.stdin.
    
  471.         If no such option is passed, it defaults to sys.stdin.
    
  472.         """
    
  473.         sentinel = object()
    
  474.         command = createsuperuser.Command()
    
  475.         call_command(
    
  476.             command,
    
  477.             stdin=sentinel,
    
  478.             interactive=False,
    
  479.             verbosity=0,
    
  480.             username="janet",
    
  481.             email="[email protected]",
    
  482.         )
    
  483.         self.assertIs(command.stdin, sentinel)
    
  484. 
    
  485.         command = createsuperuser.Command()
    
  486.         call_command(
    
  487.             command,
    
  488.             interactive=False,
    
  489.             verbosity=0,
    
  490.             username="joe",
    
  491.             email="[email protected]",
    
  492.         )
    
  493.         self.assertIs(command.stdin, sys.stdin)
    
  494. 
    
  495.     @override_settings(AUTH_USER_MODEL="auth_tests.CustomUserWithFK")
    
  496.     def test_fields_with_fk(self):
    
  497.         new_io = StringIO()
    
  498.         group = Group.objects.create(name="mygroup")
    
  499.         email = Email.objects.create(email="[email protected]")
    
  500.         call_command(
    
  501.             "createsuperuser",
    
  502.             interactive=False,
    
  503.             username=email.pk,
    
  504.             email=email.email,
    
  505.             group=group.pk,
    
  506.             stdout=new_io,
    
  507.         )
    
  508.         command_output = new_io.getvalue().strip()
    
  509.         self.assertEqual(command_output, "Superuser created successfully.")
    
  510.         u = CustomUserWithFK._default_manager.get(email=email)
    
  511.         self.assertEqual(u.username, email)
    
  512.         self.assertEqual(u.group, group)
    
  513. 
    
  514.         non_existent_email = "[email protected]"
    
  515.         msg = "email instance with email %r does not exist." % non_existent_email
    
  516.         with self.assertRaisesMessage(CommandError, msg):
    
  517.             call_command(
    
  518.                 "createsuperuser",
    
  519.                 interactive=False,
    
  520.                 username=email.pk,
    
  521.                 email=non_existent_email,
    
  522.                 stdout=new_io,
    
  523.             )
    
  524. 
    
  525.     @override_settings(AUTH_USER_MODEL="auth_tests.CustomUserWithFK")
    
  526.     def test_fields_with_fk_interactive(self):
    
  527.         new_io = StringIO()
    
  528.         group = Group.objects.create(name="mygroup")
    
  529.         email = Email.objects.create(email="[email protected]")
    
  530. 
    
  531.         @mock_inputs(
    
  532.             {
    
  533.                 "password": "nopasswd",
    
  534.                 "Username (Email.id): ": email.pk,
    
  535.                 "Email (Email.email): ": email.email,
    
  536.                 "Group (Group.id): ": group.pk,
    
  537.             }
    
  538.         )
    
  539.         def test(self):
    
  540.             call_command(
    
  541.                 "createsuperuser",
    
  542.                 interactive=True,
    
  543.                 stdout=new_io,
    
  544.                 stdin=MockTTY(),
    
  545.             )
    
  546. 
    
  547.             command_output = new_io.getvalue().strip()
    
  548.             self.assertEqual(command_output, "Superuser created successfully.")
    
  549.             u = CustomUserWithFK._default_manager.get(email=email)
    
  550.             self.assertEqual(u.username, email)
    
  551.             self.assertEqual(u.group, group)
    
  552. 
    
  553.         test(self)
    
  554. 
    
  555.     @override_settings(AUTH_USER_MODEL="auth_tests.CustomUserWithFK")
    
  556.     def test_fields_with_fk_via_option_interactive(self):
    
  557.         new_io = StringIO()
    
  558.         group = Group.objects.create(name="mygroup")
    
  559.         email = Email.objects.create(email="[email protected]")
    
  560. 
    
  561.         @mock_inputs({"password": "nopasswd"})
    
  562.         def test(self):
    
  563.             call_command(
    
  564.                 "createsuperuser",
    
  565.                 interactive=True,
    
  566.                 username=email.pk,
    
  567.                 email=email.email,
    
  568.                 group=group.pk,
    
  569.                 stdout=new_io,
    
  570.                 stdin=MockTTY(),
    
  571.             )
    
  572. 
    
  573.             command_output = new_io.getvalue().strip()
    
  574.             self.assertEqual(command_output, "Superuser created successfully.")
    
  575.             u = CustomUserWithFK._default_manager.get(email=email)
    
  576.             self.assertEqual(u.username, email)
    
  577.             self.assertEqual(u.group, group)
    
  578. 
    
  579.         test(self)
    
  580. 
    
  581.     @override_settings(AUTH_USER_MODEL="auth_tests.CustomUserWithFK")
    
  582.     def test_validate_fk(self):
    
  583.         email = Email.objects.create(email="[email protected]")
    
  584.         Group.objects.all().delete()
    
  585.         nonexistent_group_id = 1
    
  586.         msg = f"group instance with id {nonexistent_group_id} does not exist."
    
  587. 
    
  588.         with self.assertRaisesMessage(CommandError, msg):
    
  589.             call_command(
    
  590.                 "createsuperuser",
    
  591.                 interactive=False,
    
  592.                 username=email.pk,
    
  593.                 email=email.email,
    
  594.                 group=nonexistent_group_id,
    
  595.                 verbosity=0,
    
  596.             )
    
  597. 
    
  598.     @override_settings(AUTH_USER_MODEL="auth_tests.CustomUserWithFK")
    
  599.     def test_validate_fk_environment_variable(self):
    
  600.         email = Email.objects.create(email="[email protected]")
    
  601.         Group.objects.all().delete()
    
  602.         nonexistent_group_id = 1
    
  603.         msg = f"group instance with id {nonexistent_group_id} does not exist."
    
  604. 
    
  605.         with mock.patch.dict(
    
  606.             os.environ,
    
  607.             {"DJANGO_SUPERUSER_GROUP": str(nonexistent_group_id)},
    
  608.         ):
    
  609.             with self.assertRaisesMessage(CommandError, msg):
    
  610.                 call_command(
    
  611.                     "createsuperuser",
    
  612.                     interactive=False,
    
  613.                     username=email.pk,
    
  614.                     email=email.email,
    
  615.                     verbosity=0,
    
  616.                 )
    
  617. 
    
  618.     @override_settings(AUTH_USER_MODEL="auth_tests.CustomUserWithFK")
    
  619.     def test_validate_fk_via_option_interactive(self):
    
  620.         email = Email.objects.create(email="[email protected]")
    
  621.         Group.objects.all().delete()
    
  622.         nonexistent_group_id = 1
    
  623.         msg = f"group instance with id {nonexistent_group_id} does not exist."
    
  624. 
    
  625.         @mock_inputs(
    
  626.             {
    
  627.                 "password": "nopasswd",
    
  628.                 "Username (Email.id): ": email.pk,
    
  629.                 "Email (Email.email): ": email.email,
    
  630.             }
    
  631.         )
    
  632.         def test(self):
    
  633.             with self.assertRaisesMessage(CommandError, msg):
    
  634.                 call_command(
    
  635.                     "createsuperuser",
    
  636.                     group=nonexistent_group_id,
    
  637.                     stdin=MockTTY(),
    
  638.                     verbosity=0,
    
  639.                 )
    
  640. 
    
  641.         test(self)
    
  642. 
    
  643.     @override_settings(AUTH_USER_MODEL="auth_tests.CustomUserWithM2m")
    
  644.     def test_fields_with_m2m(self):
    
  645.         new_io = StringIO()
    
  646.         org_id_1 = Organization.objects.create(name="Organization 1").pk
    
  647.         org_id_2 = Organization.objects.create(name="Organization 2").pk
    
  648.         call_command(
    
  649.             "createsuperuser",
    
  650.             interactive=False,
    
  651.             username="joe",
    
  652.             orgs=[org_id_1, org_id_2],
    
  653.             stdout=new_io,
    
  654.         )
    
  655.         command_output = new_io.getvalue().strip()
    
  656.         self.assertEqual(command_output, "Superuser created successfully.")
    
  657.         user = CustomUserWithM2M._default_manager.get(username="joe")
    
  658.         self.assertEqual(user.orgs.count(), 2)
    
  659. 
    
  660.     @override_settings(AUTH_USER_MODEL="auth_tests.CustomUserWithM2M")
    
  661.     def test_fields_with_m2m_interactive(self):
    
  662.         new_io = StringIO()
    
  663.         org_id_1 = Organization.objects.create(name="Organization 1").pk
    
  664.         org_id_2 = Organization.objects.create(name="Organization 2").pk
    
  665. 
    
  666.         @mock_inputs(
    
  667.             {
    
  668.                 "password": "nopasswd",
    
  669.                 "Username: ": "joe",
    
  670.                 "Orgs (Organization.id): ": "%s, %s" % (org_id_1, org_id_2),
    
  671.             }
    
  672.         )
    
  673.         def test(self):
    
  674.             call_command(
    
  675.                 "createsuperuser",
    
  676.                 interactive=True,
    
  677.                 stdout=new_io,
    
  678.                 stdin=MockTTY(),
    
  679.             )
    
  680.             command_output = new_io.getvalue().strip()
    
  681.             self.assertEqual(command_output, "Superuser created successfully.")
    
  682.             user = CustomUserWithM2M._default_manager.get(username="joe")
    
  683.             self.assertEqual(user.orgs.count(), 2)
    
  684. 
    
  685.         test(self)
    
  686. 
    
  687.     @override_settings(AUTH_USER_MODEL="auth_tests.CustomUserWithM2M")
    
  688.     def test_fields_with_m2m_interactive_blank(self):
    
  689.         new_io = StringIO()
    
  690.         org_id = Organization.objects.create(name="Organization").pk
    
  691.         entered_orgs = [str(org_id), " "]
    
  692. 
    
  693.         def return_orgs():
    
  694.             return entered_orgs.pop()
    
  695. 
    
  696.         @mock_inputs(
    
  697.             {
    
  698.                 "password": "nopasswd",
    
  699.                 "Username: ": "joe",
    
  700.                 "Orgs (Organization.id): ": return_orgs,
    
  701.             }
    
  702.         )
    
  703.         def test(self):
    
  704.             call_command(
    
  705.                 "createsuperuser",
    
  706.                 interactive=True,
    
  707.                 stdout=new_io,
    
  708.                 stderr=new_io,
    
  709.                 stdin=MockTTY(),
    
  710.             )
    
  711.             self.assertEqual(
    
  712.                 new_io.getvalue().strip(),
    
  713.                 "Error: This field cannot be blank.\n"
    
  714.                 "Superuser created successfully.",
    
  715.             )
    
  716. 
    
  717.         test(self)
    
  718. 
    
  719.     @override_settings(AUTH_USER_MODEL="auth_tests.CustomUserWithM2MThrough")
    
  720.     def test_fields_with_m2m_and_through(self):
    
  721.         msg = (
    
  722.             "Required field 'orgs' specifies a many-to-many relation through "
    
  723.             "model, which is not supported."
    
  724.         )
    
  725.         with self.assertRaisesMessage(CommandError, msg):
    
  726.             call_command("createsuperuser")
    
  727. 
    
  728.     def test_default_username(self):
    
  729.         """createsuperuser uses a default username when one isn't provided."""
    
  730.         # Get the default username before creating a user.
    
  731.         default_username = get_default_username()
    
  732.         new_io = StringIO()
    
  733.         entered_passwords = ["password", "password"]
    
  734. 
    
  735.         def return_passwords():
    
  736.             return entered_passwords.pop(0)
    
  737. 
    
  738.         @mock_inputs({"password": return_passwords, "username": "", "email": ""})
    
  739.         def test(self):
    
  740.             call_command(
    
  741.                 "createsuperuser",
    
  742.                 interactive=True,
    
  743.                 stdin=MockTTY(),
    
  744.                 stdout=new_io,
    
  745.                 stderr=new_io,
    
  746.             )
    
  747.             self.assertEqual(
    
  748.                 new_io.getvalue().strip(), "Superuser created successfully."
    
  749.             )
    
  750.             self.assertTrue(User.objects.filter(username=default_username).exists())
    
  751. 
    
  752.         test(self)
    
  753. 
    
  754.     def test_password_validation(self):
    
  755.         """
    
  756.         Creation should fail if the password fails validation.
    
  757.         """
    
  758.         new_io = StringIO()
    
  759.         entered_passwords = ["1234567890", "1234567890", "password", "password"]
    
  760. 
    
  761.         def bad_then_good_password():
    
  762.             return entered_passwords.pop(0)
    
  763. 
    
  764.         @mock_inputs(
    
  765.             {
    
  766.                 "password": bad_then_good_password,
    
  767.                 "username": "joe1234567890",
    
  768.                 "email": "",
    
  769.                 "bypass": "n",
    
  770.             }
    
  771.         )
    
  772.         def test(self):
    
  773.             call_command(
    
  774.                 "createsuperuser",
    
  775.                 interactive=True,
    
  776.                 stdin=MockTTY(),
    
  777.                 stdout=new_io,
    
  778.                 stderr=new_io,
    
  779.             )
    
  780.             self.assertEqual(
    
  781.                 new_io.getvalue().strip(),
    
  782.                 "This password is entirely numeric.\n"
    
  783.                 "Superuser created successfully.",
    
  784.             )
    
  785. 
    
  786.         test(self)
    
  787. 
    
  788.     @override_settings(
    
  789.         AUTH_PASSWORD_VALIDATORS=[
    
  790.             {
    
  791.                 "NAME": (
    
  792.                     "django.contrib.auth.password_validation."
    
  793.                     "UserAttributeSimilarityValidator"
    
  794.                 )
    
  795.             },
    
  796.         ]
    
  797.     )
    
  798.     def test_validate_password_against_username(self):
    
  799.         new_io = StringIO()
    
  800.         username = "supremelycomplex"
    
  801.         entered_passwords = [
    
  802.             username,
    
  803.             username,
    
  804.             "superduperunguessablepassword",
    
  805.             "superduperunguessablepassword",
    
  806.         ]
    
  807. 
    
  808.         def bad_then_good_password():
    
  809.             return entered_passwords.pop(0)
    
  810. 
    
  811.         @mock_inputs(
    
  812.             {
    
  813.                 "password": bad_then_good_password,
    
  814.                 "username": username,
    
  815.                 "email": "",
    
  816.                 "bypass": "n",
    
  817.             }
    
  818.         )
    
  819.         def test(self):
    
  820.             call_command(
    
  821.                 "createsuperuser",
    
  822.                 interactive=True,
    
  823.                 stdin=MockTTY(),
    
  824.                 stdout=new_io,
    
  825.                 stderr=new_io,
    
  826.             )
    
  827.             self.assertEqual(
    
  828.                 new_io.getvalue().strip(),
    
  829.                 "The password is too similar to the username.\n"
    
  830.                 "Superuser created successfully.",
    
  831.             )
    
  832. 
    
  833.         test(self)
    
  834. 
    
  835.     @override_settings(
    
  836.         AUTH_USER_MODEL="auth_tests.CustomUser",
    
  837.         AUTH_PASSWORD_VALIDATORS=[
    
  838.             {
    
  839.                 "NAME": (
    
  840.                     "django.contrib.auth.password_validation."
    
  841.                     "UserAttributeSimilarityValidator"
    
  842.                 )
    
  843.             },
    
  844.         ],
    
  845.     )
    
  846.     def test_validate_password_against_required_fields(self):
    
  847.         new_io = StringIO()
    
  848.         first_name = "josephine"
    
  849.         entered_passwords = [
    
  850.             first_name,
    
  851.             first_name,
    
  852.             "superduperunguessablepassword",
    
  853.             "superduperunguessablepassword",
    
  854.         ]
    
  855. 
    
  856.         def bad_then_good_password():
    
  857.             return entered_passwords.pop(0)
    
  858. 
    
  859.         @mock_inputs(
    
  860.             {
    
  861.                 "password": bad_then_good_password,
    
  862.                 "username": "whatever",
    
  863.                 "first_name": first_name,
    
  864.                 "date_of_birth": "1970-01-01",
    
  865.                 "email": "[email protected]",
    
  866.                 "bypass": "n",
    
  867.             }
    
  868.         )
    
  869.         def test(self):
    
  870.             call_command(
    
  871.                 "createsuperuser",
    
  872.                 interactive=True,
    
  873.                 stdin=MockTTY(),
    
  874.                 stdout=new_io,
    
  875.                 stderr=new_io,
    
  876.             )
    
  877.             self.assertEqual(
    
  878.                 new_io.getvalue().strip(),
    
  879.                 "The password is too similar to the first name.\n"
    
  880.                 "Superuser created successfully.",
    
  881.             )
    
  882. 
    
  883.         test(self)
    
  884. 
    
  885.     @override_settings(
    
  886.         AUTH_USER_MODEL="auth_tests.CustomUser",
    
  887.         AUTH_PASSWORD_VALIDATORS=[
    
  888.             {
    
  889.                 "NAME": (
    
  890.                     "django.contrib.auth.password_validation."
    
  891.                     "UserAttributeSimilarityValidator"
    
  892.                 )
    
  893.             },
    
  894.         ],
    
  895.     )
    
  896.     def test_validate_password_against_required_fields_via_option(self):
    
  897.         new_io = StringIO()
    
  898.         first_name = "josephine"
    
  899.         entered_passwords = [
    
  900.             first_name,
    
  901.             first_name,
    
  902.             "superduperunguessablepassword",
    
  903.             "superduperunguessablepassword",
    
  904.         ]
    
  905. 
    
  906.         def bad_then_good_password():
    
  907.             return entered_passwords.pop(0)
    
  908. 
    
  909.         @mock_inputs(
    
  910.             {
    
  911.                 "password": bad_then_good_password,
    
  912.                 "bypass": "n",
    
  913.             }
    
  914.         )
    
  915.         def test(self):
    
  916.             call_command(
    
  917.                 "createsuperuser",
    
  918.                 interactive=True,
    
  919.                 first_name=first_name,
    
  920.                 date_of_birth="1970-01-01",
    
  921.                 email="[email protected]",
    
  922.                 stdin=MockTTY(),
    
  923.                 stdout=new_io,
    
  924.                 stderr=new_io,
    
  925.             )
    
  926.             self.assertEqual(
    
  927.                 new_io.getvalue().strip(),
    
  928.                 "The password is too similar to the first name.\n"
    
  929.                 "Superuser created successfully.",
    
  930.             )
    
  931. 
    
  932.         test(self)
    
  933. 
    
  934.     def test_blank_username(self):
    
  935.         """Creation fails if --username is blank."""
    
  936.         new_io = StringIO()
    
  937.         with self.assertRaisesMessage(CommandError, "Username cannot be blank."):
    
  938.             call_command(
    
  939.                 "createsuperuser",
    
  940.                 username="",
    
  941.                 stdin=MockTTY(),
    
  942.                 stdout=new_io,
    
  943.                 stderr=new_io,
    
  944.             )
    
  945. 
    
  946.     def test_blank_username_non_interactive(self):
    
  947.         new_io = StringIO()
    
  948.         with self.assertRaisesMessage(CommandError, "Username cannot be blank."):
    
  949.             call_command(
    
  950.                 "createsuperuser",
    
  951.                 username="",
    
  952.                 interactive=False,
    
  953.                 stdin=MockTTY(),
    
  954.                 stdout=new_io,
    
  955.                 stderr=new_io,
    
  956.             )
    
  957. 
    
  958.     def test_password_validation_bypass(self):
    
  959.         """
    
  960.         Password validation can be bypassed by entering 'y' at the prompt.
    
  961.         """
    
  962.         new_io = StringIO()
    
  963. 
    
  964.         @mock_inputs(
    
  965.             {
    
  966.                 "password": "1234567890",
    
  967.                 "username": "joe1234567890",
    
  968.                 "email": "",
    
  969.                 "bypass": "y",
    
  970.             }
    
  971.         )
    
  972.         def test(self):
    
  973.             call_command(
    
  974.                 "createsuperuser",
    
  975.                 interactive=True,
    
  976.                 stdin=MockTTY(),
    
  977.                 stdout=new_io,
    
  978.                 stderr=new_io,
    
  979.             )
    
  980.             self.assertEqual(
    
  981.                 new_io.getvalue().strip(),
    
  982.                 "This password is entirely numeric.\n"
    
  983.                 "Superuser created successfully.",
    
  984.             )
    
  985. 
    
  986.         test(self)
    
  987. 
    
  988.     def test_invalid_username(self):
    
  989.         """Creation fails if the username fails validation."""
    
  990.         user_field = User._meta.get_field(User.USERNAME_FIELD)
    
  991.         new_io = StringIO()
    
  992.         entered_passwords = ["password", "password"]
    
  993.         # Enter an invalid (too long) username first and then a valid one.
    
  994.         invalid_username = ("x" * user_field.max_length) + "y"
    
  995.         entered_usernames = [invalid_username, "janet"]
    
  996. 
    
  997.         def return_passwords():
    
  998.             return entered_passwords.pop(0)
    
  999. 
    
  1000.         def return_usernames():
    
  1001.             return entered_usernames.pop(0)
    
  1002. 
    
  1003.         @mock_inputs(
    
  1004.             {"password": return_passwords, "username": return_usernames, "email": ""}
    
  1005.         )
    
  1006.         def test(self):
    
  1007.             call_command(
    
  1008.                 "createsuperuser",
    
  1009.                 interactive=True,
    
  1010.                 stdin=MockTTY(),
    
  1011.                 stdout=new_io,
    
  1012.                 stderr=new_io,
    
  1013.             )
    
  1014.             self.assertEqual(
    
  1015.                 new_io.getvalue().strip(),
    
  1016.                 "Error: Ensure this value has at most %s characters (it has %s).\n"
    
  1017.                 "Superuser created successfully."
    
  1018.                 % (user_field.max_length, len(invalid_username)),
    
  1019.             )
    
  1020. 
    
  1021.         test(self)
    
  1022. 
    
  1023.     @mock_inputs({"username": "KeyboardInterrupt"})
    
  1024.     def test_keyboard_interrupt(self):
    
  1025.         new_io = StringIO()
    
  1026.         with self.assertRaises(SystemExit):
    
  1027.             call_command(
    
  1028.                 "createsuperuser",
    
  1029.                 interactive=True,
    
  1030.                 stdin=MockTTY(),
    
  1031.                 stdout=new_io,
    
  1032.                 stderr=new_io,
    
  1033.             )
    
  1034.         self.assertEqual(new_io.getvalue(), "\nOperation cancelled.\n")
    
  1035. 
    
  1036.     def test_existing_username(self):
    
  1037.         """Creation fails if the username already exists."""
    
  1038.         user = User.objects.create(username="janet")
    
  1039.         new_io = StringIO()
    
  1040.         entered_passwords = ["password", "password"]
    
  1041.         # Enter the existing username first and then a new one.
    
  1042.         entered_usernames = [user.username, "joe"]
    
  1043. 
    
  1044.         def return_passwords():
    
  1045.             return entered_passwords.pop(0)
    
  1046. 
    
  1047.         def return_usernames():
    
  1048.             return entered_usernames.pop(0)
    
  1049. 
    
  1050.         @mock_inputs(
    
  1051.             {"password": return_passwords, "username": return_usernames, "email": ""}
    
  1052.         )
    
  1053.         def test(self):
    
  1054.             call_command(
    
  1055.                 "createsuperuser",
    
  1056.                 interactive=True,
    
  1057.                 stdin=MockTTY(),
    
  1058.                 stdout=new_io,
    
  1059.                 stderr=new_io,
    
  1060.             )
    
  1061.             self.assertEqual(
    
  1062.                 new_io.getvalue().strip(),
    
  1063.                 "Error: That username is already taken.\n"
    
  1064.                 "Superuser created successfully.",
    
  1065.             )
    
  1066. 
    
  1067.         test(self)
    
  1068. 
    
  1069.     @override_settings(AUTH_USER_MODEL="auth_tests.CustomUserWithUniqueConstraint")
    
  1070.     def test_existing_username_meta_unique_constraint(self):
    
  1071.         """
    
  1072.         Creation fails if the username already exists and a custom user model
    
  1073.         has UniqueConstraint.
    
  1074.         """
    
  1075.         user = CustomUserWithUniqueConstraint.objects.create(username="janet")
    
  1076.         new_io = StringIO()
    
  1077.         entered_passwords = ["password", "password"]
    
  1078.         # Enter the existing username first and then a new one.
    
  1079.         entered_usernames = [user.username, "joe"]
    
  1080. 
    
  1081.         def return_passwords():
    
  1082.             return entered_passwords.pop(0)
    
  1083. 
    
  1084.         def return_usernames():
    
  1085.             return entered_usernames.pop(0)
    
  1086. 
    
  1087.         @mock_inputs({"password": return_passwords, "username": return_usernames})
    
  1088.         def test(self):
    
  1089.             call_command(
    
  1090.                 "createsuperuser",
    
  1091.                 interactive=True,
    
  1092.                 stdin=MockTTY(),
    
  1093.                 stdout=new_io,
    
  1094.                 stderr=new_io,
    
  1095.             )
    
  1096.             self.assertEqual(
    
  1097.                 new_io.getvalue().strip(),
    
  1098.                 "Error: That username is already taken.\n"
    
  1099.                 "Superuser created successfully.",
    
  1100.             )
    
  1101. 
    
  1102.         test(self)
    
  1103. 
    
  1104.     def test_existing_username_non_interactive(self):
    
  1105.         """Creation fails if the username already exists."""
    
  1106.         User.objects.create(username="janet")
    
  1107.         new_io = StringIO()
    
  1108.         with self.assertRaisesMessage(
    
  1109.             CommandError, "Error: That username is already taken."
    
  1110.         ):
    
  1111.             call_command(
    
  1112.                 "createsuperuser",
    
  1113.                 username="janet",
    
  1114.                 email="",
    
  1115.                 interactive=False,
    
  1116.                 stdout=new_io,
    
  1117.             )
    
  1118. 
    
  1119.     def test_existing_username_provided_via_option_and_interactive(self):
    
  1120.         """call_command() gets username='janet' and interactive=True."""
    
  1121.         new_io = StringIO()
    
  1122.         entered_passwords = ["password", "password"]
    
  1123.         User.objects.create(username="janet")
    
  1124. 
    
  1125.         def return_passwords():
    
  1126.             return entered_passwords.pop(0)
    
  1127. 
    
  1128.         @mock_inputs(
    
  1129.             {
    
  1130.                 "password": return_passwords,
    
  1131.                 "username": "janet1",
    
  1132.                 "email": "[email protected]",
    
  1133.             }
    
  1134.         )
    
  1135.         def test(self):
    
  1136.             call_command(
    
  1137.                 "createsuperuser",
    
  1138.                 username="janet",
    
  1139.                 interactive=True,
    
  1140.                 stdin=MockTTY(),
    
  1141.                 stdout=new_io,
    
  1142.                 stderr=new_io,
    
  1143.             )
    
  1144.             msg = (
    
  1145.                 "Error: That username is already taken.\n"
    
  1146.                 "Superuser created successfully."
    
  1147.             )
    
  1148.             self.assertEqual(new_io.getvalue().strip(), msg)
    
  1149. 
    
  1150.         test(self)
    
  1151. 
    
  1152.     def test_validation_mismatched_passwords(self):
    
  1153.         """
    
  1154.         Creation should fail if the user enters mismatched passwords.
    
  1155.         """
    
  1156.         new_io = StringIO()
    
  1157. 
    
  1158.         # The first two passwords do not match, but the second two do match and
    
  1159.         # are valid.
    
  1160.         entered_passwords = ["password", "not password", "password2", "password2"]
    
  1161. 
    
  1162.         def mismatched_passwords_then_matched():
    
  1163.             return entered_passwords.pop(0)
    
  1164. 
    
  1165.         @mock_inputs(
    
  1166.             {
    
  1167.                 "password": mismatched_passwords_then_matched,
    
  1168.                 "username": "joe1234567890",
    
  1169.                 "email": "",
    
  1170.             }
    
  1171.         )
    
  1172.         def test(self):
    
  1173.             call_command(
    
  1174.                 "createsuperuser",
    
  1175.                 interactive=True,
    
  1176.                 stdin=MockTTY(),
    
  1177.                 stdout=new_io,
    
  1178.                 stderr=new_io,
    
  1179.             )
    
  1180.             self.assertEqual(
    
  1181.                 new_io.getvalue().strip(),
    
  1182.                 "Error: Your passwords didn't match.\n"
    
  1183.                 "Superuser created successfully.",
    
  1184.             )
    
  1185. 
    
  1186.         test(self)
    
  1187. 
    
  1188.     def test_validation_blank_password_entered(self):
    
  1189.         """
    
  1190.         Creation should fail if the user enters blank passwords.
    
  1191.         """
    
  1192.         new_io = StringIO()
    
  1193. 
    
  1194.         # The first two passwords are empty strings, but the second two are
    
  1195.         # valid.
    
  1196.         entered_passwords = ["", "", "password2", "password2"]
    
  1197. 
    
  1198.         def blank_passwords_then_valid():
    
  1199.             return entered_passwords.pop(0)
    
  1200. 
    
  1201.         @mock_inputs(
    
  1202.             {
    
  1203.                 "password": blank_passwords_then_valid,
    
  1204.                 "username": "joe1234567890",
    
  1205.                 "email": "",
    
  1206.             }
    
  1207.         )
    
  1208.         def test(self):
    
  1209.             call_command(
    
  1210.                 "createsuperuser",
    
  1211.                 interactive=True,
    
  1212.                 stdin=MockTTY(),
    
  1213.                 stdout=new_io,
    
  1214.                 stderr=new_io,
    
  1215.             )
    
  1216.             self.assertEqual(
    
  1217.                 new_io.getvalue().strip(),
    
  1218.                 "Error: Blank passwords aren't allowed.\n"
    
  1219.                 "Superuser created successfully.",
    
  1220.             )
    
  1221. 
    
  1222.         test(self)
    
  1223. 
    
  1224.     @override_settings(AUTH_USER_MODEL="auth_tests.NoPasswordUser")
    
  1225.     def test_usermodel_without_password(self):
    
  1226.         new_io = StringIO()
    
  1227.         call_command(
    
  1228.             "createsuperuser",
    
  1229.             interactive=False,
    
  1230.             stdin=MockTTY(),
    
  1231.             stdout=new_io,
    
  1232.             stderr=new_io,
    
  1233.             username="username",
    
  1234.         )
    
  1235.         self.assertEqual(new_io.getvalue().strip(), "Superuser created successfully.")
    
  1236. 
    
  1237.     @override_settings(AUTH_USER_MODEL="auth_tests.NoPasswordUser")
    
  1238.     def test_usermodel_without_password_interactive(self):
    
  1239.         new_io = StringIO()
    
  1240. 
    
  1241.         @mock_inputs({"username": "username"})
    
  1242.         def test(self):
    
  1243.             call_command(
    
  1244.                 "createsuperuser",
    
  1245.                 interactive=True,
    
  1246.                 stdin=MockTTY(),
    
  1247.                 stdout=new_io,
    
  1248.                 stderr=new_io,
    
  1249.             )
    
  1250.             self.assertEqual(
    
  1251.                 new_io.getvalue().strip(), "Superuser created successfully."
    
  1252.             )
    
  1253. 
    
  1254.         test(self)
    
  1255. 
    
  1256.     @mock.patch.dict(
    
  1257.         os.environ,
    
  1258.         {
    
  1259.             "DJANGO_SUPERUSER_PASSWORD": "test_password",
    
  1260.             "DJANGO_SUPERUSER_USERNAME": "test_superuser",
    
  1261.             "DJANGO_SUPERUSER_EMAIL": "[email protected]",
    
  1262.             "DJANGO_SUPERUSER_FIRST_NAME": "ignored_first_name",
    
  1263.         },
    
  1264.     )
    
  1265.     def test_environment_variable_non_interactive(self):
    
  1266.         call_command("createsuperuser", interactive=False, verbosity=0)
    
  1267.         user = User.objects.get(username="test_superuser")
    
  1268.         self.assertEqual(user.email, "[email protected]")
    
  1269.         self.assertTrue(user.check_password("test_password"))
    
  1270.         # Environment variables are ignored for non-required fields.
    
  1271.         self.assertEqual(user.first_name, "")
    
  1272. 
    
  1273.     @override_settings(AUTH_USER_MODEL="auth_tests.CustomUserWithM2m")
    
  1274.     def test_environment_variable_m2m_non_interactive(self):
    
  1275.         new_io = StringIO()
    
  1276.         org_id_1 = Organization.objects.create(name="Organization 1").pk
    
  1277.         org_id_2 = Organization.objects.create(name="Organization 2").pk
    
  1278.         with mock.patch.dict(
    
  1279.             os.environ,
    
  1280.             {
    
  1281.                 "DJANGO_SUPERUSER_ORGS": f"{org_id_1},{org_id_2}",
    
  1282.             },
    
  1283.         ):
    
  1284.             call_command(
    
  1285.                 "createsuperuser",
    
  1286.                 interactive=False,
    
  1287.                 username="joe",
    
  1288.                 stdout=new_io,
    
  1289.             )
    
  1290.         command_output = new_io.getvalue().strip()
    
  1291.         self.assertEqual(command_output, "Superuser created successfully.")
    
  1292.         user = CustomUserWithM2M._default_manager.get(username="joe")
    
  1293.         self.assertEqual(user.orgs.count(), 2)
    
  1294. 
    
  1295.     @mock.patch.dict(
    
  1296.         os.environ,
    
  1297.         {
    
  1298.             "DJANGO_SUPERUSER_USERNAME": "test_superuser",
    
  1299.             "DJANGO_SUPERUSER_EMAIL": "[email protected]",
    
  1300.         },
    
  1301.     )
    
  1302.     def test_ignore_environment_variable_non_interactive(self):
    
  1303.         # Environment variables are ignored in non-interactive mode, if
    
  1304.         # provided by a command line arguments.
    
  1305.         call_command(
    
  1306.             "createsuperuser",
    
  1307.             interactive=False,
    
  1308.             username="cmd_superuser",
    
  1309.             email="[email protected]",
    
  1310.             verbosity=0,
    
  1311.         )
    
  1312.         user = User.objects.get(username="cmd_superuser")
    
  1313.         self.assertEqual(user.email, "[email protected]")
    
  1314.         self.assertFalse(user.has_usable_password())
    
  1315. 
    
  1316.     @mock.patch.dict(
    
  1317.         os.environ,
    
  1318.         {
    
  1319.             "DJANGO_SUPERUSER_PASSWORD": "test_password",
    
  1320.             "DJANGO_SUPERUSER_USERNAME": "test_superuser",
    
  1321.             "DJANGO_SUPERUSER_EMAIL": "[email protected]",
    
  1322.         },
    
  1323.     )
    
  1324.     def test_ignore_environment_variable_interactive(self):
    
  1325.         # Environment variables are ignored in interactive mode.
    
  1326.         @mock_inputs({"password": "cmd_password"})
    
  1327.         def test(self):
    
  1328.             call_command(
    
  1329.                 "createsuperuser",
    
  1330.                 interactive=True,
    
  1331.                 username="cmd_superuser",
    
  1332.                 email="[email protected]",
    
  1333.                 stdin=MockTTY(),
    
  1334.                 verbosity=0,
    
  1335.             )
    
  1336.             user = User.objects.get(username="cmd_superuser")
    
  1337.             self.assertEqual(user.email, "[email protected]")
    
  1338.             self.assertTrue(user.check_password("cmd_password"))
    
  1339. 
    
  1340.         test(self)
    
  1341. 
    
  1342. 
    
  1343. class MultiDBCreatesuperuserTestCase(TestCase):
    
  1344.     databases = {"default", "other"}
    
  1345. 
    
  1346.     def test_createsuperuser_command_with_database_option(self):
    
  1347.         """
    
  1348.         createsuperuser --database should operate on the specified DB.
    
  1349.         """
    
  1350.         new_io = StringIO()
    
  1351.         call_command(
    
  1352.             "createsuperuser",
    
  1353.             interactive=False,
    
  1354.             username="joe",
    
  1355.             email="[email protected]",
    
  1356.             database="other",
    
  1357.             stdout=new_io,
    
  1358.         )
    
  1359.         command_output = new_io.getvalue().strip()
    
  1360.         self.assertEqual(command_output, "Superuser created successfully.")
    
  1361.         user = User.objects.using("other").get(username="joe")
    
  1362.         self.assertEqual(user.email, "[email protected]")
    
  1363. 
    
  1364.     def test_createsuperuser_command_suggested_username_with_database_option(self):
    
  1365.         default_username = get_default_username(database="other")
    
  1366.         qs = User.objects.using("other")
    
  1367. 
    
  1368.         @mock_inputs({"password": "nopasswd", "username": "", "email": ""})
    
  1369.         def test_other_create_with_suggested_username(self):
    
  1370.             call_command(
    
  1371.                 "createsuperuser",
    
  1372.                 interactive=True,
    
  1373.                 stdin=MockTTY(),
    
  1374.                 verbosity=0,
    
  1375.                 database="other",
    
  1376.             )
    
  1377.             self.assertIs(qs.filter(username=default_username).exists(), True)
    
  1378. 
    
  1379.         test_other_create_with_suggested_username(self)
    
  1380. 
    
  1381.         @mock_inputs({"password": "nopasswd", "Username: ": "other", "email": ""})
    
  1382.         def test_other_no_suggestion(self):
    
  1383.             call_command(
    
  1384.                 "createsuperuser",
    
  1385.                 interactive=True,
    
  1386.                 stdin=MockTTY(),
    
  1387.                 verbosity=0,
    
  1388.                 database="other",
    
  1389.             )
    
  1390.             self.assertIs(qs.filter(username="other").exists(), True)
    
  1391. 
    
  1392.         test_other_no_suggestion(self)
    
  1393. 
    
  1394. 
    
  1395. class CreatePermissionsTests(TestCase):
    
  1396.     def setUp(self):
    
  1397.         self._original_permissions = Permission._meta.permissions[:]
    
  1398.         self._original_default_permissions = Permission._meta.default_permissions
    
  1399.         self.app_config = apps.get_app_config("auth")
    
  1400. 
    
  1401.     def tearDown(self):
    
  1402.         Permission._meta.permissions = self._original_permissions
    
  1403.         Permission._meta.default_permissions = self._original_default_permissions
    
  1404.         ContentType.objects.clear_cache()
    
  1405. 
    
  1406.     def test_default_permissions(self):
    
  1407.         permission_content_type = ContentType.objects.get_by_natural_key(
    
  1408.             "auth", "permission"
    
  1409.         )
    
  1410.         Permission._meta.permissions = [
    
  1411.             ("my_custom_permission", "Some permission"),
    
  1412.         ]
    
  1413.         create_permissions(self.app_config, verbosity=0)
    
  1414. 
    
  1415.         # view/add/change/delete permission by default + custom permission
    
  1416.         self.assertEqual(
    
  1417.             Permission.objects.filter(
    
  1418.                 content_type=permission_content_type,
    
  1419.             ).count(),
    
  1420.             5,
    
  1421.         )
    
  1422. 
    
  1423.         Permission.objects.filter(content_type=permission_content_type).delete()
    
  1424.         Permission._meta.default_permissions = []
    
  1425.         create_permissions(self.app_config, verbosity=0)
    
  1426. 
    
  1427.         # custom permission only since default permissions is empty
    
  1428.         self.assertEqual(
    
  1429.             Permission.objects.filter(
    
  1430.                 content_type=permission_content_type,
    
  1431.             ).count(),
    
  1432.             1,
    
  1433.         )
    
  1434. 
    
  1435.     def test_unavailable_models(self):
    
  1436.         """
    
  1437.         #24075 - Permissions shouldn't be created or deleted if the ContentType
    
  1438.         or Permission models aren't available.
    
  1439.         """
    
  1440.         state = migrations.state.ProjectState()
    
  1441.         # Unavailable contenttypes.ContentType
    
  1442.         with self.assertNumQueries(0):
    
  1443.             create_permissions(self.app_config, verbosity=0, apps=state.apps)
    
  1444.         # Unavailable auth.Permission
    
  1445.         state = migrations.state.ProjectState(real_apps={"contenttypes"})
    
  1446.         with self.assertNumQueries(0):
    
  1447.             create_permissions(self.app_config, verbosity=0, apps=state.apps)
    
  1448. 
    
  1449.     def test_create_permissions_checks_contenttypes_created(self):
    
  1450.         """
    
  1451.         `post_migrate` handler ordering isn't guaranteed. Simulate a case
    
  1452.         where create_permissions() is called before create_contenttypes().
    
  1453.         """
    
  1454.         # Warm the manager cache.
    
  1455.         ContentType.objects.get_for_model(Group)
    
  1456.         # Apply a deletion as if e.g. a database 'flush' had been executed.
    
  1457.         ContentType.objects.filter(app_label="auth", model="group").delete()
    
  1458.         # This fails with a foreign key constraint without the fix.
    
  1459.         create_permissions(apps.get_app_config("auth"), interactive=False, verbosity=0)
    
  1460. 
    
  1461.     def test_permission_with_proxy_content_type_created(self):
    
  1462.         """
    
  1463.         A proxy model's permissions use its own content type rather than the
    
  1464.         content type of the concrete model.
    
  1465.         """
    
  1466.         opts = UserProxy._meta
    
  1467.         codename = get_permission_codename("add", opts)
    
  1468.         self.assertTrue(
    
  1469.             Permission.objects.filter(
    
  1470.                 content_type__model=opts.model_name,
    
  1471.                 content_type__app_label=opts.app_label,
    
  1472.                 codename=codename,
    
  1473.             ).exists()
    
  1474.         )