2008-06-08 13:31:16 +08:00
|
|
|
"""
|
|
|
|
Management utility to create superusers.
|
|
|
|
"""
|
|
|
|
|
|
|
|
import getpass
|
|
|
|
import re
|
|
|
|
import sys
|
|
|
|
from optparse import make_option
|
2012-03-05 12:17:55 +08:00
|
|
|
|
2008-07-22 11:24:09 +08:00
|
|
|
from django.contrib.auth.models import User
|
2011-05-09 09:10:40 +08:00
|
|
|
from django.contrib.auth.management import get_default_username
|
Removed oldforms, validators, and related code:
* Removed `Manipulator`, `AutomaticManipulator`, and related classes.
* Removed oldforms specific bits from model fields:
* Removed `validator_list` and `core` arguments from constructors.
* Removed the methods:
* `get_manipulator_field_names`
* `get_manipulator_field_objs`
* `get_manipulator_fields`
* `get_manipulator_new_data`
* `prepare_field_objs_and_params`
* `get_follow`
* Renamed `flatten_data` method to `value_to_string` for better alignment with its use by the serialization framework, which was the only remaining code using `flatten_data`.
* Removed oldforms methods from `django.db.models.Options` class: `get_followed_related_objects`, `get_data_holders`, `get_follow`, and `has_field_type`.
* Removed oldforms-admin specific options from `django.db.models.fields.related` classes: `num_in_admin`, `min_num_in_admin`, `max_num_in_admin`, `num_extra_on_change`, and `edit_inline`.
* Serialization framework
* `Serializer.get_string_value` now calls the model fields' renamed `value_to_string` methods.
* Removed a special-casing of `models.DateTimeField` in `core.serializers.base.Serializer.get_string_value` that's handled by `django.db.models.fields.DateTimeField.value_to_string`.
* Removed `django.core.validators`:
* Moved `ValidationError` exception to `django.core.exceptions`.
* For the couple places that were using validators, brought over the necessary code to maintain the same functionality.
* Introduced a SlugField form field for validation and to compliment the SlugField model field (refs #8040).
* Removed an oldforms-style model creation hack (refs #2160).
git-svn-id: http://code.djangoproject.com/svn/django/trunk@8616 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-08-27 15:19:44 +08:00
|
|
|
from django.core import exceptions
|
2008-06-08 13:31:16 +08:00
|
|
|
from django.core.management.base import BaseCommand, CommandError
|
2012-03-05 12:17:55 +08:00
|
|
|
from django.db import DEFAULT_DB_ALIAS
|
Removed oldforms, validators, and related code:
* Removed `Manipulator`, `AutomaticManipulator`, and related classes.
* Removed oldforms specific bits from model fields:
* Removed `validator_list` and `core` arguments from constructors.
* Removed the methods:
* `get_manipulator_field_names`
* `get_manipulator_field_objs`
* `get_manipulator_fields`
* `get_manipulator_new_data`
* `prepare_field_objs_and_params`
* `get_follow`
* Renamed `flatten_data` method to `value_to_string` for better alignment with its use by the serialization framework, which was the only remaining code using `flatten_data`.
* Removed oldforms methods from `django.db.models.Options` class: `get_followed_related_objects`, `get_data_holders`, `get_follow`, and `has_field_type`.
* Removed oldforms-admin specific options from `django.db.models.fields.related` classes: `num_in_admin`, `min_num_in_admin`, `max_num_in_admin`, `num_extra_on_change`, and `edit_inline`.
* Serialization framework
* `Serializer.get_string_value` now calls the model fields' renamed `value_to_string` methods.
* Removed a special-casing of `models.DateTimeField` in `core.serializers.base.Serializer.get_string_value` that's handled by `django.db.models.fields.DateTimeField.value_to_string`.
* Removed `django.core.validators`:
* Moved `ValidationError` exception to `django.core.exceptions`.
* For the couple places that were using validators, brought over the necessary code to maintain the same functionality.
* Introduced a SlugField form field for validation and to compliment the SlugField model field (refs #8040).
* Removed an oldforms-style model creation hack (refs #2160).
git-svn-id: http://code.djangoproject.com/svn/django/trunk@8616 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-08-27 15:19:44 +08:00
|
|
|
from django.utils.translation import ugettext as _
|
2008-06-08 13:31:16 +08:00
|
|
|
|
2010-05-21 22:08:49 +08:00
|
|
|
RE_VALID_USERNAME = re.compile('[\w.@+-]+$')
|
|
|
|
|
Removed oldforms, validators, and related code:
* Removed `Manipulator`, `AutomaticManipulator`, and related classes.
* Removed oldforms specific bits from model fields:
* Removed `validator_list` and `core` arguments from constructors.
* Removed the methods:
* `get_manipulator_field_names`
* `get_manipulator_field_objs`
* `get_manipulator_fields`
* `get_manipulator_new_data`
* `prepare_field_objs_and_params`
* `get_follow`
* Renamed `flatten_data` method to `value_to_string` for better alignment with its use by the serialization framework, which was the only remaining code using `flatten_data`.
* Removed oldforms methods from `django.db.models.Options` class: `get_followed_related_objects`, `get_data_holders`, `get_follow`, and `has_field_type`.
* Removed oldforms-admin specific options from `django.db.models.fields.related` classes: `num_in_admin`, `min_num_in_admin`, `max_num_in_admin`, `num_extra_on_change`, and `edit_inline`.
* Serialization framework
* `Serializer.get_string_value` now calls the model fields' renamed `value_to_string` methods.
* Removed a special-casing of `models.DateTimeField` in `core.serializers.base.Serializer.get_string_value` that's handled by `django.db.models.fields.DateTimeField.value_to_string`.
* Removed `django.core.validators`:
* Moved `ValidationError` exception to `django.core.exceptions`.
* For the couple places that were using validators, brought over the necessary code to maintain the same functionality.
* Introduced a SlugField form field for validation and to compliment the SlugField model field (refs #8040).
* Removed an oldforms-style model creation hack (refs #2160).
git-svn-id: http://code.djangoproject.com/svn/django/trunk@8616 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-08-27 15:19:44 +08:00
|
|
|
EMAIL_RE = re.compile(
|
|
|
|
r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*" # dot-atom
|
|
|
|
r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-\011\013\014\016-\177])*"' # quoted-string
|
|
|
|
r')@(?:[A-Z0-9-]+\.)+[A-Z]{2,6}$', re.IGNORECASE) # domain
|
|
|
|
|
2012-03-05 12:17:55 +08:00
|
|
|
|
Removed oldforms, validators, and related code:
* Removed `Manipulator`, `AutomaticManipulator`, and related classes.
* Removed oldforms specific bits from model fields:
* Removed `validator_list` and `core` arguments from constructors.
* Removed the methods:
* `get_manipulator_field_names`
* `get_manipulator_field_objs`
* `get_manipulator_fields`
* `get_manipulator_new_data`
* `prepare_field_objs_and_params`
* `get_follow`
* Renamed `flatten_data` method to `value_to_string` for better alignment with its use by the serialization framework, which was the only remaining code using `flatten_data`.
* Removed oldforms methods from `django.db.models.Options` class: `get_followed_related_objects`, `get_data_holders`, `get_follow`, and `has_field_type`.
* Removed oldforms-admin specific options from `django.db.models.fields.related` classes: `num_in_admin`, `min_num_in_admin`, `max_num_in_admin`, `num_extra_on_change`, and `edit_inline`.
* Serialization framework
* `Serializer.get_string_value` now calls the model fields' renamed `value_to_string` methods.
* Removed a special-casing of `models.DateTimeField` in `core.serializers.base.Serializer.get_string_value` that's handled by `django.db.models.fields.DateTimeField.value_to_string`.
* Removed `django.core.validators`:
* Moved `ValidationError` exception to `django.core.exceptions`.
* For the couple places that were using validators, brought over the necessary code to maintain the same functionality.
* Introduced a SlugField form field for validation and to compliment the SlugField model field (refs #8040).
* Removed an oldforms-style model creation hack (refs #2160).
git-svn-id: http://code.djangoproject.com/svn/django/trunk@8616 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-08-27 15:19:44 +08:00
|
|
|
def is_valid_email(value):
|
|
|
|
if not EMAIL_RE.search(value):
|
|
|
|
raise exceptions.ValidationError(_('Enter a valid e-mail address.'))
|
2008-06-08 13:31:16 +08:00
|
|
|
|
2012-03-05 12:17:55 +08:00
|
|
|
|
2008-06-08 13:31:16 +08:00
|
|
|
class Command(BaseCommand):
|
|
|
|
option_list = BaseCommand.option_list + (
|
|
|
|
make_option('--username', dest='username', default=None,
|
|
|
|
help='Specifies the username for the superuser.'),
|
|
|
|
make_option('--email', dest='email', default=None,
|
|
|
|
help='Specifies the email address for the superuser.'),
|
|
|
|
make_option('--noinput', action='store_false', dest='interactive', default=True,
|
2010-11-18 04:28:33 +08:00
|
|
|
help=('Tells Django to NOT prompt the user for input of any kind. '
|
|
|
|
'You must use --username and --email with --noinput, and '
|
|
|
|
'superusers created with --noinput will not be able to log '
|
|
|
|
'in until they\'re given a valid password.')),
|
2012-03-05 12:17:55 +08:00
|
|
|
make_option('--database', action='store', dest='database',
|
2012-03-13 04:05:48 +08:00
|
|
|
default=DEFAULT_DB_ALIAS, help='Specifies the database to use. Default is "default".'),
|
2008-06-08 13:31:16 +08:00
|
|
|
)
|
|
|
|
help = 'Used to create a superuser.'
|
|
|
|
|
|
|
|
def handle(self, *args, **options):
|
|
|
|
username = options.get('username', None)
|
|
|
|
email = options.get('email', None)
|
|
|
|
interactive = options.get('interactive')
|
2010-10-09 11:34:08 +08:00
|
|
|
verbosity = int(options.get('verbosity', 1))
|
2012-03-05 12:17:55 +08:00
|
|
|
database = options.get('database')
|
2010-10-09 11:34:08 +08:00
|
|
|
|
2008-06-08 13:31:16 +08:00
|
|
|
# Do quick and dirty validation if --noinput
|
|
|
|
if not interactive:
|
|
|
|
if not username or not email:
|
|
|
|
raise CommandError("You must use --username and --email with --noinput.")
|
|
|
|
if not RE_VALID_USERNAME.match(username):
|
|
|
|
raise CommandError("Invalid username. Use only letters, digits, and underscores")
|
|
|
|
try:
|
Removed oldforms, validators, and related code:
* Removed `Manipulator`, `AutomaticManipulator`, and related classes.
* Removed oldforms specific bits from model fields:
* Removed `validator_list` and `core` arguments from constructors.
* Removed the methods:
* `get_manipulator_field_names`
* `get_manipulator_field_objs`
* `get_manipulator_fields`
* `get_manipulator_new_data`
* `prepare_field_objs_and_params`
* `get_follow`
* Renamed `flatten_data` method to `value_to_string` for better alignment with its use by the serialization framework, which was the only remaining code using `flatten_data`.
* Removed oldforms methods from `django.db.models.Options` class: `get_followed_related_objects`, `get_data_holders`, `get_follow`, and `has_field_type`.
* Removed oldforms-admin specific options from `django.db.models.fields.related` classes: `num_in_admin`, `min_num_in_admin`, `max_num_in_admin`, `num_extra_on_change`, and `edit_inline`.
* Serialization framework
* `Serializer.get_string_value` now calls the model fields' renamed `value_to_string` methods.
* Removed a special-casing of `models.DateTimeField` in `core.serializers.base.Serializer.get_string_value` that's handled by `django.db.models.fields.DateTimeField.value_to_string`.
* Removed `django.core.validators`:
* Moved `ValidationError` exception to `django.core.exceptions`.
* For the couple places that were using validators, brought over the necessary code to maintain the same functionality.
* Introduced a SlugField form field for validation and to compliment the SlugField model field (refs #8040).
* Removed an oldforms-style model creation hack (refs #2160).
git-svn-id: http://code.djangoproject.com/svn/django/trunk@8616 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-08-27 15:19:44 +08:00
|
|
|
is_valid_email(email)
|
|
|
|
except exceptions.ValidationError:
|
2008-06-08 13:31:16 +08:00
|
|
|
raise CommandError("Invalid email address.")
|
2008-06-09 02:18:01 +08:00
|
|
|
|
2011-02-22 19:33:04 +08:00
|
|
|
# If not provided, create the user with an unusable password
|
|
|
|
password = None
|
2008-06-08 13:31:16 +08:00
|
|
|
|
|
|
|
# Prompt for username/email/password. Enclose this whole thing in a
|
|
|
|
# try/except to trap for a keyboard interrupt and exit gracefully.
|
|
|
|
if interactive:
|
2011-05-09 09:10:40 +08:00
|
|
|
default_username = get_default_username()
|
2008-06-08 13:31:16 +08:00
|
|
|
try:
|
2010-10-09 11:34:08 +08:00
|
|
|
|
2008-06-08 13:31:16 +08:00
|
|
|
# Get a username
|
|
|
|
while 1:
|
|
|
|
if not username:
|
|
|
|
input_msg = 'Username'
|
|
|
|
if default_username:
|
2011-05-05 06:56:20 +08:00
|
|
|
input_msg += ' (leave blank to use %r)' % default_username
|
2008-06-08 13:31:16 +08:00
|
|
|
username = raw_input(input_msg + ': ')
|
|
|
|
if default_username and username == '':
|
|
|
|
username = default_username
|
|
|
|
if not RE_VALID_USERNAME.match(username):
|
2012-05-19 19:51:54 +08:00
|
|
|
self.stderr.write("Error: That username is invalid. Use only letters, digits and underscores.")
|
2008-06-08 13:31:16 +08:00
|
|
|
username = None
|
|
|
|
continue
|
|
|
|
try:
|
2012-03-05 12:17:55 +08:00
|
|
|
User.objects.using(database).get(username=username)
|
2008-06-08 13:31:16 +08:00
|
|
|
except User.DoesNotExist:
|
|
|
|
break
|
|
|
|
else:
|
2012-05-19 19:51:54 +08:00
|
|
|
self.stderr.write("Error: That username is already taken.")
|
2008-06-08 13:31:16 +08:00
|
|
|
username = None
|
2010-10-09 11:34:08 +08:00
|
|
|
|
2008-06-08 13:31:16 +08:00
|
|
|
# Get an email
|
|
|
|
while 1:
|
|
|
|
if not email:
|
|
|
|
email = raw_input('E-mail address: ')
|
|
|
|
try:
|
Removed oldforms, validators, and related code:
* Removed `Manipulator`, `AutomaticManipulator`, and related classes.
* Removed oldforms specific bits from model fields:
* Removed `validator_list` and `core` arguments from constructors.
* Removed the methods:
* `get_manipulator_field_names`
* `get_manipulator_field_objs`
* `get_manipulator_fields`
* `get_manipulator_new_data`
* `prepare_field_objs_and_params`
* `get_follow`
* Renamed `flatten_data` method to `value_to_string` for better alignment with its use by the serialization framework, which was the only remaining code using `flatten_data`.
* Removed oldforms methods from `django.db.models.Options` class: `get_followed_related_objects`, `get_data_holders`, `get_follow`, and `has_field_type`.
* Removed oldforms-admin specific options from `django.db.models.fields.related` classes: `num_in_admin`, `min_num_in_admin`, `max_num_in_admin`, `num_extra_on_change`, and `edit_inline`.
* Serialization framework
* `Serializer.get_string_value` now calls the model fields' renamed `value_to_string` methods.
* Removed a special-casing of `models.DateTimeField` in `core.serializers.base.Serializer.get_string_value` that's handled by `django.db.models.fields.DateTimeField.value_to_string`.
* Removed `django.core.validators`:
* Moved `ValidationError` exception to `django.core.exceptions`.
* For the couple places that were using validators, brought over the necessary code to maintain the same functionality.
* Introduced a SlugField form field for validation and to compliment the SlugField model field (refs #8040).
* Removed an oldforms-style model creation hack (refs #2160).
git-svn-id: http://code.djangoproject.com/svn/django/trunk@8616 bcc190cf-cafb-0310-a4f2-bffc1f526a37
2008-08-27 15:19:44 +08:00
|
|
|
is_valid_email(email)
|
|
|
|
except exceptions.ValidationError:
|
2012-05-19 19:51:54 +08:00
|
|
|
self.stderr.write("Error: That e-mail address is invalid.")
|
2008-06-08 13:31:16 +08:00
|
|
|
email = None
|
|
|
|
else:
|
|
|
|
break
|
2010-10-09 11:34:08 +08:00
|
|
|
|
2008-06-08 13:31:16 +08:00
|
|
|
# Get a password
|
|
|
|
while 1:
|
|
|
|
if not password:
|
|
|
|
password = getpass.getpass()
|
|
|
|
password2 = getpass.getpass('Password (again): ')
|
|
|
|
if password != password2:
|
2012-05-19 19:51:54 +08:00
|
|
|
self.stderr.write("Error: Your passwords didn't match.")
|
2008-06-08 13:31:16 +08:00
|
|
|
password = None
|
|
|
|
continue
|
|
|
|
if password.strip() == '':
|
2012-05-19 19:51:54 +08:00
|
|
|
self.stderr.write("Error: Blank passwords aren't allowed.")
|
2008-06-08 13:31:16 +08:00
|
|
|
password = None
|
|
|
|
continue
|
|
|
|
break
|
|
|
|
except KeyboardInterrupt:
|
2012-05-19 19:51:54 +08:00
|
|
|
self.stderr.write("\nOperation cancelled.")
|
2008-06-08 13:31:16 +08:00
|
|
|
sys.exit(1)
|
2010-10-09 11:34:08 +08:00
|
|
|
|
2012-03-05 12:17:55 +08:00
|
|
|
User.objects.db_manager(database).create_superuser(username, email, password)
|
2010-10-09 11:34:08 +08:00
|
|
|
if verbosity >= 1:
|
2012-05-19 19:51:54 +08:00
|
|
|
self.stdout.write("Superuser created successfully.")
|
2010-10-09 11:34:08 +08:00
|
|
|
|