You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

changepassword.py 2.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import getpass
  2. from django.contrib.auth import get_user_model
  3. from django.contrib.auth.password_validation import validate_password
  4. from django.core.exceptions import ValidationError
  5. from django.core.management.base import BaseCommand, CommandError
  6. from django.db import DEFAULT_DB_ALIAS
  7. UserModel = get_user_model()
  8. class Command(BaseCommand):
  9. help = "Change a user's password for django.contrib.auth."
  10. requires_migrations_checks = True
  11. requires_system_checks = False
  12. def _get_pass(self, prompt="Password: "):
  13. p = getpass.getpass(prompt=prompt)
  14. if not p:
  15. raise CommandError("aborted")
  16. return p
  17. def add_arguments(self, parser):
  18. parser.add_argument(
  19. 'username', nargs='?',
  20. help='Username to change password for; by default, it\'s the current username.',
  21. )
  22. parser.add_argument(
  23. '--database',
  24. default=DEFAULT_DB_ALIAS,
  25. help='Specifies the database to use. Default is "default".',
  26. )
  27. def handle(self, *args, **options):
  28. if options['username']:
  29. username = options['username']
  30. else:
  31. username = getpass.getuser()
  32. try:
  33. u = UserModel._default_manager.using(options['database']).get(**{
  34. UserModel.USERNAME_FIELD: username
  35. })
  36. except UserModel.DoesNotExist:
  37. raise CommandError("user '%s' does not exist" % username)
  38. self.stdout.write("Changing password for user '%s'\n" % u)
  39. MAX_TRIES = 3
  40. count = 0
  41. p1, p2 = 1, 2 # To make them initially mismatch.
  42. password_validated = False
  43. while (p1 != p2 or not password_validated) and count < MAX_TRIES:
  44. p1 = self._get_pass()
  45. p2 = self._get_pass("Password (again): ")
  46. if p1 != p2:
  47. self.stdout.write("Passwords do not match. Please try again.\n")
  48. count += 1
  49. # Don't validate passwords that don't match.
  50. continue
  51. try:
  52. validate_password(p2, u)
  53. except ValidationError as err:
  54. self.stderr.write('\n'.join(err.messages))
  55. count += 1
  56. else:
  57. password_validated = True
  58. if count == MAX_TRIES:
  59. raise CommandError("Aborting password change for user '%s' after %s attempts" % (u, count))
  60. u.set_password(p1)
  61. u.save()
  62. return "Password changed successfully for user '%s'" % u