mirror of
https://github.com/pacnpal/thrillwiki_django_no_react.git
synced 2025-12-20 09:31:09 -05:00
Add initial migration for moderation app and resolve seed command issues
- Created an empty migration file for the moderation app to enable migrations. - Documented the resolution of the seed command failure due to missing moderation tables. - Identified and fixed a VARCHAR(10) constraint violation in the User model during seed data generation. - Updated role assignment in the seed command to comply with the field length constraint.
This commit is contained in:
@@ -186,7 +186,7 @@ class CustomUserAdmin(UserAdmin):
|
||||
def save_model(self, request, obj, form, change):
|
||||
creating = not obj.pk
|
||||
super().save_model(request, obj, form, change)
|
||||
if creating and obj.role != User.Roles.USER:
|
||||
if creating and obj.role != "USER":
|
||||
# Ensure new user with role gets added to appropriate group
|
||||
group = Group.objects.filter(name=obj.role).first()
|
||||
if group:
|
||||
|
||||
@@ -15,17 +15,17 @@ class Command(BaseCommand):
|
||||
create_default_groups()
|
||||
|
||||
# Sync existing users with groups based on their roles
|
||||
users = User.objects.exclude(role=User.Roles.USER)
|
||||
users = User.objects.exclude(role="USER")
|
||||
for user in users:
|
||||
group = Group.objects.filter(name=user.role).first()
|
||||
if group:
|
||||
user.groups.add(group)
|
||||
|
||||
# Update staff/superuser status based on role
|
||||
if user.role == User.Roles.SUPERUSER:
|
||||
if user.role == "SUPERUSER":
|
||||
user.is_superuser = True
|
||||
user.is_staff = True
|
||||
elif user.role in [User.Roles.ADMIN, User.Roles.MODERATOR]:
|
||||
elif user.role in ["ADMIN", "MODERATOR"]:
|
||||
user.is_staff = True
|
||||
user.save()
|
||||
|
||||
|
||||
@@ -121,10 +121,6 @@ class User(AbstractUser):
|
||||
"""Get the user's display name, falling back to username if not set"""
|
||||
if self.display_name:
|
||||
return self.display_name
|
||||
# Fallback to profile display_name for backward compatibility
|
||||
profile = getattr(self, "profile", None)
|
||||
if profile and profile.display_name:
|
||||
return profile.display_name
|
||||
return self.username
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
@@ -635,4 +631,6 @@ class NotificationPreference(TrackedModel):
|
||||
def create_notification_preference(sender, instance, created, **kwargs):
|
||||
"""Create notification preferences when a new user is created."""
|
||||
if created:
|
||||
NotificationPreference.objects.create(user=instance)
|
||||
NotificationPreference.objects.get_or_create(user=instance)
|
||||
|
||||
# Signal moved to signals.py to avoid duplication
|
||||
|
||||
@@ -31,7 +31,7 @@ class UserDeletionService:
|
||||
"is_active": False,
|
||||
"is_staff": False,
|
||||
"is_superuser": False,
|
||||
"role": User.Roles.USER,
|
||||
"role": "USER",
|
||||
"is_banned": True,
|
||||
"ban_reason": "System placeholder for deleted users",
|
||||
"ban_date": timezone.now(),
|
||||
@@ -178,7 +178,7 @@ class UserDeletionService:
|
||||
return False, "Superuser accounts cannot be deleted for security reasons. Please contact system administrator or remove superuser privileges first."
|
||||
|
||||
# Check if user has critical admin role
|
||||
if user.role == User.Roles.ADMIN and user.is_staff:
|
||||
if user.role == "ADMIN" and user.is_staff:
|
||||
return False, "Admin accounts with staff privileges cannot be deleted. Please remove admin privileges first or contact system administrator."
|
||||
|
||||
# Add any other business rules here
|
||||
|
||||
@@ -10,59 +10,41 @@ from .models import User, UserProfile
|
||||
|
||||
@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, timeout=60)
|
||||
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:
|
||||
# Try to get existing profile first
|
||||
"""Create UserProfile for new users - unified signal handler"""
|
||||
if created:
|
||||
try:
|
||||
profile = instance.profile
|
||||
profile.save()
|
||||
except UserProfile.DoesNotExist:
|
||||
# Profile doesn't exist, create it
|
||||
UserProfile.objects.create(user=instance)
|
||||
except Exception as e:
|
||||
print(f"Error saving profile for user {instance.username}: {str(e)}")
|
||||
# Use get_or_create to prevent duplicates
|
||||
profile, profile_created = UserProfile.objects.get_or_create(user=instance)
|
||||
|
||||
if profile_created:
|
||||
# If user has a social account with avatar, download it
|
||||
try:
|
||||
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:
|
||||
response = requests.get(avatar_url, timeout=60)
|
||||
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(pre_save, sender=User)
|
||||
@@ -75,43 +57,43 @@ def sync_user_role_with_groups(sender, instance, **kwargs):
|
||||
# Role has changed, update groups
|
||||
with transaction.atomic():
|
||||
# Remove from old role group if exists
|
||||
if old_instance.role != User.Roles.USER:
|
||||
if old_instance.role != "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:
|
||||
if instance.role != "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:
|
||||
if instance.role == "SUPERUSER":
|
||||
instance.is_superuser = True
|
||||
instance.is_staff = True
|
||||
elif old_instance.role == User.Roles.SUPERUSER:
|
||||
elif old_instance.role == "SUPERUSER":
|
||||
# If removing superuser role, remove superuser
|
||||
# status
|
||||
instance.is_superuser = False
|
||||
if instance.role not in [
|
||||
User.Roles.ADMIN,
|
||||
User.Roles.MODERATOR,
|
||||
"ADMIN",
|
||||
"MODERATOR",
|
||||
]:
|
||||
instance.is_staff = False
|
||||
|
||||
# Handle staff status for admin and moderator roles
|
||||
if instance.role in [
|
||||
User.Roles.ADMIN,
|
||||
User.Roles.MODERATOR,
|
||||
"ADMIN",
|
||||
"MODERATOR",
|
||||
]:
|
||||
instance.is_staff = True
|
||||
elif old_instance.role in [
|
||||
User.Roles.ADMIN,
|
||||
User.Roles.MODERATOR,
|
||||
"ADMIN",
|
||||
"MODERATOR",
|
||||
]:
|
||||
# If removing admin/moderator role, remove staff
|
||||
# status
|
||||
if instance.role not in [User.Roles.SUPERUSER]:
|
||||
if instance.role not in ["SUPERUSER"]:
|
||||
instance.is_staff = False
|
||||
except User.DoesNotExist:
|
||||
pass
|
||||
@@ -130,7 +112,7 @@ def create_default_groups():
|
||||
from django.contrib.auth.models import Permission
|
||||
|
||||
# Create Moderator group
|
||||
moderator_group, _ = Group.objects.get_or_create(name=User.Roles.MODERATOR)
|
||||
moderator_group, _ = Group.objects.get_or_create(name="MODERATOR")
|
||||
moderator_permissions = [
|
||||
# Review moderation permissions
|
||||
"change_review",
|
||||
@@ -149,7 +131,7 @@ def create_default_groups():
|
||||
]
|
||||
|
||||
# Create Admin group
|
||||
admin_group, _ = Group.objects.get_or_create(name=User.Roles.ADMIN)
|
||||
admin_group, _ = Group.objects.get_or_create(name="ADMIN")
|
||||
admin_permissions = moderator_permissions + [
|
||||
# User management permissions
|
||||
"change_user",
|
||||
|
||||
@@ -109,7 +109,7 @@ class SignalsTestCase(TestCase):
|
||||
|
||||
create_default_groups()
|
||||
|
||||
moderator_group = Group.objects.get(name=User.Roles.MODERATOR)
|
||||
moderator_group = Group.objects.get(name="MODERATOR")
|
||||
self.assertIsNotNone(moderator_group)
|
||||
self.assertTrue(
|
||||
moderator_group.permissions.filter(codename="change_review").exists()
|
||||
@@ -118,7 +118,7 @@ class SignalsTestCase(TestCase):
|
||||
moderator_group.permissions.filter(codename="change_user").exists()
|
||||
)
|
||||
|
||||
admin_group = Group.objects.get(name=User.Roles.ADMIN)
|
||||
admin_group = Group.objects.get(name="ADMIN")
|
||||
self.assertIsNotNone(admin_group)
|
||||
self.assertTrue(
|
||||
admin_group.permissions.filter(codename="change_review").exists()
|
||||
|
||||
@@ -42,7 +42,7 @@ class UserDeletionServiceTest(TestCase):
|
||||
self.assertEqual(deleted_user.email, "deleted@thrillwiki.com")
|
||||
self.assertFalse(deleted_user.is_active)
|
||||
self.assertTrue(deleted_user.is_banned)
|
||||
self.assertEqual(deleted_user.role, User.Roles.USER)
|
||||
self.assertEqual(deleted_user.role, "USER")
|
||||
|
||||
# Check profile was created
|
||||
self.assertTrue(hasattr(deleted_user, "profile"))
|
||||
|
||||
Reference in New Issue
Block a user