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."))