mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 14:31:08 -05:00
153 lines
6.9 KiB
Python
153 lines
6.9 KiB
Python
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)}")
|