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.
 
 
 
 

55 lines
2.0 KiB

import secrets
from django.core.management.base import BaseCommand
from django.db.models import Q
from apps.account.models import User
class Command(BaseCommand):
help = 'Sets a new plain/hashed password and encrypts it for active users who lack an encrypted password.'
def add_arguments(self, parser):
parser.add_argument(
'--password',
type=str,
help='Specific password to set for all matched users. If not provided, a random 8-character password will be generated for each user.'
)
parser.add_argument(
'--dry-run',
action='store_true',
help='Run the command without saving changes to the database.'
)
def handle(self, *args, **options):
password_input = options['password']
dry_run = options['dry_run']
# Find active users without an encrypted password
users = User.objects.filter(
Q(password_enc='') | Q(password_enc__isnull=True),
is_active=True
)
if not users.exists():
self.stdout.write(self.style.SUCCESS("No active users found without an encrypted password."))
return
self.stdout.write(f"Found {users.count()} active users without an encrypted password.")
updated_count = 0
for user in users:
# Generate or use the provided password
new_password = password_input if password_input else secrets.token_urlsafe(6)[:8]
self.stdout.write(f"User: {user.email or user.fullname} (ID: {user.id}) -> Password: {new_password}")
if not dry_run:
user.set_password(new_password)
user.set_plain_password(new_password)
user.save()
updated_count += 1
if dry_run:
self.stdout.write(self.style.WARNING(f"[DRY-RUN] Would have updated {updated_count} users."))
else:
self.stdout.write(self.style.SUCCESS(f"Successfully updated {updated_count} users."))