123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475 |
- import getpass
- from django.contrib.auth import get_user_model
- from django.contrib.auth.password_validation import validate_password
- from django.core.exceptions import ValidationError
- from django.core.management.base import BaseCommand, CommandError
- from django.db import DEFAULT_DB_ALIAS
- UserModel = get_user_model()
- class Command(BaseCommand):
- help = "Change a user's password for django.contrib.auth."
- requires_migrations_checks = True
- requires_system_checks = False
- def _get_pass(self, prompt="Password: "):
- p = getpass.getpass(prompt=prompt)
- if not p:
- raise CommandError("aborted")
- return p
- def add_arguments(self, parser):
- parser.add_argument(
- 'username', nargs='?',
- help='Username to change password for; by default, it\'s the current username.',
- )
- parser.add_argument(
- '--database',
- default=DEFAULT_DB_ALIAS,
- help='Specifies the database to use. Default is "default".',
- )
- def handle(self, *args, **options):
- if options['username']:
- username = options['username']
- else:
- username = getpass.getuser()
- try:
- u = UserModel._default_manager.using(options['database']).get(**{
- UserModel.USERNAME_FIELD: username
- })
- except UserModel.DoesNotExist:
- raise CommandError("user '%s' does not exist" % username)
- self.stdout.write("Changing password for user '%s'\n" % u)
- MAX_TRIES = 3
- count = 0
- p1, p2 = 1, 2 # To make them initially mismatch.
- password_validated = False
- while (p1 != p2 or not password_validated) and count < MAX_TRIES:
- p1 = self._get_pass()
- p2 = self._get_pass("Password (again): ")
- if p1 != p2:
- self.stdout.write("Passwords do not match. Please try again.\n")
- count += 1
- # Don't validate passwords that don't match.
- continue
- try:
- validate_password(p2, u)
- except ValidationError as err:
- self.stderr.write('\n'.join(err.messages))
- count += 1
- else:
- password_validated = True
- if count == MAX_TRIES:
- raise CommandError("Aborting password change for user '%s' after %s attempts" % (u, count))
- u.set_password(p1)
- u.save()
- return "Password changed successfully for user '%s'" % u
|