from django.db.models.signals import post_save, pre_save from django.dispatch import receiver from django.contrib.auth.models import Group from django.db import transaction from django.core.files import File from django.core.files.temp import NamedTemporaryFile import requests from .models import User, UserProfile, EmailVerification @receiver(post_save, sender=User) def create_user_profile(sender, instance, created, **kwargs): """Create UserProfile for new users""" try: if created: # Create profile profile = UserProfile.objects.create(user=instance) # If user has a social account with avatar, download it social_account = instance.socialaccount_set.first() if social_account: extra_data = social_account.extra_data avatar_url = None if social_account.provider == 'google': avatar_url = extra_data.get('picture') elif social_account.provider == 'discord': avatar = extra_data.get('avatar') discord_id = extra_data.get('id') if avatar: avatar_url = f'https://cdn.discordapp.com/avatars/{discord_id}/{avatar}.png' if avatar_url: try: response = requests.get(avatar_url) if response.status_code == 200: img_temp = NamedTemporaryFile(delete=True) img_temp.write(response.content) img_temp.flush() file_name = f"avatar_{instance.username}.png" profile.avatar.save( file_name, File(img_temp), save=True ) except Exception as e: print(f"Error downloading avatar for user {instance.username}: {str(e)}") except Exception as e: print(f"Error creating profile for user {instance.username}: {str(e)}") @receiver(post_save, sender=User) def save_user_profile(sender, instance, **kwargs): """Ensure UserProfile exists and is saved""" try: if not hasattr(instance, 'profile'): UserProfile.objects.create(user=instance) instance.profile.save() except Exception as e: print(f"Error saving profile for user {instance.username}: {str(e)}") @receiver(pre_save, sender=User) def sync_user_role_with_groups(sender, instance, **kwargs): """Sync user role with Django groups""" if instance.pk: # Only for existing users try: old_instance = User.objects.get(pk=instance.pk) if old_instance.role != instance.role: # Role has changed, update groups with transaction.atomic(): # Remove from old role group if exists if old_instance.role != User.Roles.USER: old_group = Group.objects.filter(name=old_instance.role).first() if old_group: instance.groups.remove(old_group) # Add to new role group if instance.role != User.Roles.USER: new_group, _ = Group.objects.get_or_create(name=instance.role) instance.groups.add(new_group) # Special handling for superuser role if instance.role == User.Roles.SUPERUSER: instance.is_superuser = True instance.is_staff = True elif old_instance.role == User.Roles.SUPERUSER: # If removing superuser role, remove superuser status instance.is_superuser = False if instance.role not in [User.Roles.ADMIN, User.Roles.MODERATOR]: instance.is_staff = False # Handle staff status for admin and moderator roles if instance.role in [User.Roles.ADMIN, User.Roles.MODERATOR]: instance.is_staff = True elif old_instance.role in [User.Roles.ADMIN, User.Roles.MODERATOR]: # If removing admin/moderator role, remove staff status if instance.role not in [User.Roles.SUPERUSER]: instance.is_staff = False except User.DoesNotExist: pass except Exception as e: print(f"Error syncing role with groups for user {instance.username}: {str(e)}") def create_default_groups(): """ Create default groups with appropriate permissions. Call this in a migration or management command. """ try: from django.contrib.auth.models import Permission from django.contrib.contenttypes.models import ContentType # Create Moderator group moderator_group, _ = Group.objects.get_or_create(name=User.Roles.MODERATOR) moderator_permissions = [ # Review moderation permissions 'change_review', 'delete_review', 'change_reviewreport', 'delete_reviewreport', # Edit moderation permissions 'change_parkedit', 'delete_parkedit', 'change_rideedit', 'delete_rideedit', 'change_companyedit', 'delete_companyedit', 'change_manufactureredit', 'delete_manufactureredit', ] # Create Admin group admin_group, _ = Group.objects.get_or_create(name=User.Roles.ADMIN) admin_permissions = moderator_permissions + [ # User management permissions 'change_user', 'delete_user', # Content management permissions 'add_park', 'change_park', 'delete_park', 'add_ride', 'change_ride', 'delete_ride', 'add_company', 'change_company', 'delete_company', 'add_manufacturer', 'change_manufacturer', 'delete_manufacturer', ] # Assign permissions to groups for codename in moderator_permissions: try: perm = Permission.objects.get(codename=codename) moderator_group.permissions.add(perm) except Permission.DoesNotExist: print(f"Permission not found: {codename}") for codename in admin_permissions: try: perm = Permission.objects.get(codename=codename) admin_group.permissions.add(perm) except Permission.DoesNotExist: print(f"Permission not found: {codename}") except Exception as e: print(f"Error creating default groups: {str(e)}")