createsuperuser.py 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. """
  2. Misago-native rehash of Django's createsuperuser command that
  3. works with double authentication fields on user model
  4. """
  5. import sys
  6. from getpass import getpass
  7. from optparse import make_option
  8. from django.contrib.auth import get_user_model
  9. from django.core.exceptions import ValidationError
  10. from django.core.management.base import BaseCommand
  11. from django.db import DEFAULT_DB_ALIAS, IntegrityError
  12. from django.utils.encoding import force_str
  13. from django.utils.six.moves import input
  14. from ...validators import validate_email, validate_password, validate_username
  15. class NotRunningInTTYException(Exception):
  16. pass
  17. class Command(BaseCommand):
  18. help = 'Used to create a superuser.'
  19. def __init__(self, *args, **kwargs):
  20. super(Command, self).__init__(*args, **kwargs)
  21. self.option_list = BaseCommand.option_list + (
  22. make_option('--username', dest='username', default=None,
  23. help='Specifies the username for the superuser.'),
  24. make_option('--email', dest='email', default=None,
  25. help='Specifies the username for the superuser.'),
  26. make_option('--password', dest='password', default=None,
  27. help='Specifies the username for the superuser.'),
  28. make_option('--noinput', action='store_false', dest='interactive',
  29. default=True,
  30. help=('Tells Miago to NOT prompt the user for input '
  31. 'of any kind. You must use --username with '
  32. '--noinput, along with an option for any other '
  33. 'required field. Superusers created with '
  34. '--noinput will not be able to log in until '
  35. 'they\'re given a valid password.')),
  36. make_option('--database', action='store', dest='database',
  37. default=DEFAULT_DB_ALIAS,
  38. help=('Specifies the database to use. '
  39. 'Default is "default".')),
  40. )
  41. def execute(self, *args, **options):
  42. self.stdin = options.get('stdin', sys.stdin) # Used for testing
  43. return super(Command, self).execute(*args, **options)
  44. def handle(self, *args, **options):
  45. username = options.get('username')
  46. email = options.get('email')
  47. password = options.get('password')
  48. interactive = options.get('interactive')
  49. verbosity = int(options.get('verbosity', 1))
  50. # Validate initial inputs
  51. if username is not None:
  52. try:
  53. username = username.strip()
  54. validate_username(username)
  55. except ValidationError as e:
  56. self.stderr.write(e.messages[0])
  57. username = None
  58. if email is not None:
  59. try:
  60. email = email.strip()
  61. validate_email(email)
  62. except ValidationError as e:
  63. self.stderr.write(e.messages[0])
  64. email = None
  65. if password is not None:
  66. try:
  67. password = password.strip()
  68. validate_password(password)
  69. except ValidationError as e:
  70. self.stderr.write(e.messages[0])
  71. password = None
  72. if not interactive:
  73. if username and email and password:
  74. # Call User manager's create_superuser using our wrapper
  75. self.create_superuser(username, email, password, verbosity)
  76. else:
  77. try:
  78. if hasattr(self.stdin, 'isatty') and not self.stdin.isatty():
  79. raise NotRunningInTTYException("Not running in a TTY")
  80. # Prompt for username/password, and any other required fields.
  81. # Enclose this whole thing in a try/except to trap for a
  82. # keyboard interrupt and exit gracefully.
  83. while not username:
  84. try:
  85. message = force_str("Enter displayed username: ")
  86. raw_value = input(message).strip()
  87. validate_username(raw_value)
  88. username = raw_value
  89. except ValidationError as e:
  90. self.stderr.write(e.messages[0])
  91. while not email:
  92. try:
  93. raw_value = input("Enter E-mail address: ").strip()
  94. validate_email(raw_value)
  95. email = raw_value
  96. except ValidationError as e:
  97. self.stderr.write(e.messages[0])
  98. while not password:
  99. try:
  100. raw_value = getpass("Enter password: ").strip()
  101. validate_password(raw_value)
  102. repeat_raw_value = getpass("Repeat password: ").strip()
  103. if raw_value != repeat_raw_value:
  104. raise ValidationError(
  105. "Entered passwords are different.")
  106. password = raw_value
  107. except ValidationError as e:
  108. self.stderr.write(e.messages[0])
  109. # Call User manager's create_superuser using our wrapper
  110. self.create_superuser(username, email, password, verbosity)
  111. except KeyboardInterrupt:
  112. self.stderr.write("\nOperation cancelled.")
  113. sys.exit(1)
  114. except NotRunningInTTYException:
  115. self.stdout.write(
  116. "Superuser creation skipped due to not running in a TTY. "
  117. "You can run `manage.py createsuperuser` in your project "
  118. "to create one manually."
  119. )
  120. def create_superuser(self, username, email, password, verbosity):
  121. try:
  122. User = get_user_model()
  123. user = User.objects.create_superuser(username, email, password,
  124. set_default_avatar=True)
  125. if verbosity >= 1:
  126. message = "Superuser #%(pk)s has been created successfully."
  127. self.stdout.write(message % {'pk': user.pk})
  128. except ValidationError as e:
  129. self.stderr.write(e.messages[0])
  130. except IntegrityError as e:
  131. self.stderr.write(e.messages[0])