146 lines
5.2 KiB
Python
146 lines
5.2 KiB
Python
"""
|
|
Role Permissions Migration Script (Phase 3)
|
|
|
|
This script migrates role_permissions from the legacy role enum to the new dynamic role system.
|
|
For each role_permission, it maps the current role enum value to the corresponding role_id.
|
|
|
|
Usage:
|
|
python migrate_role_permissions_to_dynamic_roles.py
|
|
|
|
Environment Variables:
|
|
DATABASE_URL - PostgreSQL connection string
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
from sqlalchemy import create_engine
|
|
from sqlalchemy.orm import sessionmaker
|
|
from database import Base
|
|
from models import RolePermission, Role, UserRole
|
|
from dotenv import load_dotenv
|
|
|
|
# Load environment variables
|
|
load_dotenv()
|
|
|
|
# Database connection
|
|
DATABASE_URL = os.getenv("DATABASE_URL")
|
|
if not DATABASE_URL:
|
|
print("Error: DATABASE_URL environment variable not set")
|
|
sys.exit(1)
|
|
|
|
engine = create_engine(DATABASE_URL)
|
|
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
|
|
|
|
|
def migrate_role_permissions():
|
|
"""Migrate role_permissions from enum role to role_id"""
|
|
db = SessionLocal()
|
|
|
|
try:
|
|
print("🚀 Starting role_permissions migration (Phase 3)...")
|
|
print("="*60)
|
|
|
|
# Step 1: Load all roles into a map
|
|
print("\n📋 Loading roles from database...")
|
|
roles = db.query(Role).all()
|
|
role_map = {role.code: role for role in roles}
|
|
|
|
print(f"✓ Loaded {len(roles)} roles:")
|
|
for role in roles:
|
|
print(f" • {role.name} ({role.code}) - ID: {role.id}")
|
|
|
|
# Step 2: Get all role_permissions
|
|
print("\n🔐 Loading role_permissions...")
|
|
role_permissions = db.query(RolePermission).all()
|
|
print(f"✓ Found {len(role_permissions)} role_permission records to migrate")
|
|
|
|
if not role_permissions:
|
|
print("\n✅ No role_permissions to migrate!")
|
|
return
|
|
|
|
# Step 3: Check if any role_permissions already have role_id set
|
|
perms_with_role_id = [rp for rp in role_permissions if rp.role_id is not None]
|
|
if perms_with_role_id:
|
|
print(f"\n⚠️ Warning: {len(perms_with_role_id)} role_permissions already have role_id set")
|
|
response = input("Do you want to re-migrate these records? (yes/no): ")
|
|
if response.lower() != 'yes':
|
|
print("Skipping role_permissions that already have role_id set...")
|
|
role_permissions = [rp for rp in role_permissions if rp.role_id is None]
|
|
print(f"Will migrate {len(role_permissions)} role_permissions without role_id")
|
|
|
|
if not role_permissions:
|
|
print("\n✅ No role_permissions to migrate!")
|
|
return
|
|
|
|
# Step 4: Migrate role_permissions
|
|
print(f"\n🔄 Migrating {len(role_permissions)} role_permission records...")
|
|
|
|
migration_stats = {
|
|
UserRole.guest: 0,
|
|
UserRole.member: 0,
|
|
UserRole.admin: 0,
|
|
UserRole.superadmin: 0
|
|
}
|
|
|
|
for rp in role_permissions:
|
|
# Get the enum role code (e.g., "guest", "member", "admin", "superadmin")
|
|
role_code = rp.role.value
|
|
|
|
# Find the matching role in the roles table
|
|
if role_code not in role_map:
|
|
print(f" ⚠️ Warning: No matching role found for '{role_code}' (permission_id: {rp.permission_id})")
|
|
continue
|
|
|
|
# Set the role_id
|
|
rp.role_id = role_map[role_code].id
|
|
migration_stats[rp.role] = migration_stats.get(rp.role, 0) + 1
|
|
|
|
# Commit all changes
|
|
db.commit()
|
|
print(f"✓ Migrated {len(role_permissions)} role_permission records")
|
|
|
|
# Step 5: Display migration summary
|
|
print("\n" + "="*60)
|
|
print("📊 Migration Summary:")
|
|
print("="*60)
|
|
print("\nRole permissions migrated by role:")
|
|
for role_enum, count in migration_stats.items():
|
|
if count > 0:
|
|
print(f" • {role_enum.value}: {count} permissions")
|
|
|
|
# Step 6: Verify migration
|
|
print("\n🔍 Verifying migration...")
|
|
perms_without_role_id = db.query(RolePermission).filter(RolePermission.role_id == None).count()
|
|
perms_with_role_id = db.query(RolePermission).filter(RolePermission.role_id != None).count()
|
|
|
|
print(f" • Role permissions with role_id: {perms_with_role_id}")
|
|
print(f" • Role permissions without role_id: {perms_without_role_id}")
|
|
|
|
if perms_without_role_id > 0:
|
|
print(f"\n⚠️ Warning: {perms_without_role_id} role_permissions still don't have role_id set!")
|
|
else:
|
|
print("\n✅ All role_permissions successfully migrated!")
|
|
|
|
print("\n" + "="*60)
|
|
print("✅ Role permissions migration completed successfully!")
|
|
print("="*60)
|
|
|
|
print("\n📝 Next Steps:")
|
|
print(" 1. Update auth.py to use dynamic roles")
|
|
print(" 2. Update server.py role checks")
|
|
print(" 3. Verify system still works with new roles")
|
|
print(" 4. In Phase 4, remove legacy enum columns")
|
|
|
|
except Exception as e:
|
|
db.rollback()
|
|
print(f"\n❌ Error migrating role_permissions: {str(e)}")
|
|
import traceback
|
|
traceback.print_exc()
|
|
raise
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
migrate_role_permissions()
|