550 lines
16 KiB
Python
550 lines
16 KiB
Python
"""
|
|
Permission Seeding Script
|
|
|
|
This script populates the database with 60+ granular permissions for RBAC.
|
|
Permissions are organized into 9 modules: users, events, subscriptions,
|
|
financials, newsletters, bylaws, gallery, settings, and permissions.
|
|
|
|
Usage:
|
|
python permissions_seed.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 Permission, RolePermission, 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)
|
|
|
|
# ============================================================
|
|
# Permission Definitions
|
|
# ============================================================
|
|
|
|
PERMISSIONS = [
|
|
# ========== USERS MODULE ==========
|
|
{
|
|
"code": "users.view",
|
|
"name": "View Users",
|
|
"description": "View user list and user profiles",
|
|
"module": "users"
|
|
},
|
|
{
|
|
"code": "users.create",
|
|
"name": "Create Users",
|
|
"description": "Create new users and send invitations",
|
|
"module": "users"
|
|
},
|
|
{
|
|
"code": "users.edit",
|
|
"name": "Edit Users",
|
|
"description": "Edit user profiles and information",
|
|
"module": "users"
|
|
},
|
|
{
|
|
"code": "users.delete",
|
|
"name": "Delete Users",
|
|
"description": "Delete user accounts",
|
|
"module": "users"
|
|
},
|
|
{
|
|
"code": "users.status",
|
|
"name": "Change User Status",
|
|
"description": "Change user status (active, inactive, etc.)",
|
|
"module": "users"
|
|
},
|
|
{
|
|
"code": "users.approve",
|
|
"name": "Approve/Validate Users",
|
|
"description": "Approve or validate user applications",
|
|
"module": "users"
|
|
},
|
|
{
|
|
"code": "users.export",
|
|
"name": "Export Users",
|
|
"description": "Export user data to CSV",
|
|
"module": "users"
|
|
},
|
|
{
|
|
"code": "users.import",
|
|
"name": "Import Users",
|
|
"description": "Import users from CSV",
|
|
"module": "users"
|
|
},
|
|
{
|
|
"code": "users.reset_password",
|
|
"name": "Reset User Password",
|
|
"description": "Reset user passwords via email",
|
|
"module": "users"
|
|
},
|
|
{
|
|
"code": "users.resend_verification",
|
|
"name": "Resend Verification Email",
|
|
"description": "Resend email verification links",
|
|
"module": "users"
|
|
},
|
|
|
|
# ========== EVENTS MODULE ==========
|
|
{
|
|
"code": "events.view",
|
|
"name": "View Events",
|
|
"description": "View event list and event details",
|
|
"module": "events"
|
|
},
|
|
{
|
|
"code": "events.create",
|
|
"name": "Create Events",
|
|
"description": "Create new events",
|
|
"module": "events"
|
|
},
|
|
{
|
|
"code": "events.edit",
|
|
"name": "Edit Events",
|
|
"description": "Edit existing events",
|
|
"module": "events"
|
|
},
|
|
{
|
|
"code": "events.delete",
|
|
"name": "Delete Events",
|
|
"description": "Delete events",
|
|
"module": "events"
|
|
},
|
|
{
|
|
"code": "events.publish",
|
|
"name": "Publish Events",
|
|
"description": "Publish or unpublish events",
|
|
"module": "events"
|
|
},
|
|
{
|
|
"code": "events.attendance",
|
|
"name": "Mark Event Attendance",
|
|
"description": "Mark user attendance for events",
|
|
"module": "events"
|
|
},
|
|
{
|
|
"code": "events.rsvps",
|
|
"name": "View Event RSVPs",
|
|
"description": "View and manage event RSVPs",
|
|
"module": "events"
|
|
},
|
|
{
|
|
"code": "events.calendar_export",
|
|
"name": "Export Event Calendar",
|
|
"description": "Export events to iCal format",
|
|
"module": "events"
|
|
},
|
|
|
|
# ========== SUBSCRIPTIONS MODULE ==========
|
|
{
|
|
"code": "subscriptions.view",
|
|
"name": "View Subscriptions",
|
|
"description": "View subscription list and details",
|
|
"module": "subscriptions"
|
|
},
|
|
{
|
|
"code": "subscriptions.create",
|
|
"name": "Create Subscriptions",
|
|
"description": "Create manual subscriptions for users",
|
|
"module": "subscriptions"
|
|
},
|
|
{
|
|
"code": "subscriptions.edit",
|
|
"name": "Edit Subscriptions",
|
|
"description": "Edit subscription details",
|
|
"module": "subscriptions"
|
|
},
|
|
{
|
|
"code": "subscriptions.cancel",
|
|
"name": "Cancel Subscriptions",
|
|
"description": "Cancel user subscriptions",
|
|
"module": "subscriptions"
|
|
},
|
|
{
|
|
"code": "subscriptions.activate",
|
|
"name": "Activate Subscriptions",
|
|
"description": "Manually activate subscriptions",
|
|
"module": "subscriptions"
|
|
},
|
|
{
|
|
"code": "subscriptions.plans",
|
|
"name": "Manage Subscription Plans",
|
|
"description": "Create and edit subscription plans",
|
|
"module": "subscriptions"
|
|
},
|
|
|
|
# ========== FINANCIALS MODULE ==========
|
|
{
|
|
"code": "financials.view",
|
|
"name": "View Financial Reports",
|
|
"description": "View financial reports and dashboards",
|
|
"module": "financials"
|
|
},
|
|
{
|
|
"code": "financials.create",
|
|
"name": "Create Financial Reports",
|
|
"description": "Upload and create financial reports",
|
|
"module": "financials"
|
|
},
|
|
{
|
|
"code": "financials.edit",
|
|
"name": "Edit Financial Reports",
|
|
"description": "Edit existing financial reports",
|
|
"module": "financials"
|
|
},
|
|
{
|
|
"code": "financials.delete",
|
|
"name": "Delete Financial Reports",
|
|
"description": "Delete financial reports",
|
|
"module": "financials"
|
|
},
|
|
{
|
|
"code": "financials.export",
|
|
"name": "Export Financial Data",
|
|
"description": "Export financial data to CSV/PDF",
|
|
"module": "financials"
|
|
},
|
|
{
|
|
"code": "financials.payments",
|
|
"name": "View Payment Details",
|
|
"description": "View detailed payment information",
|
|
"module": "financials"
|
|
},
|
|
|
|
# ========== NEWSLETTERS MODULE ==========
|
|
{
|
|
"code": "newsletters.view",
|
|
"name": "View Newsletters",
|
|
"description": "View newsletter archives",
|
|
"module": "newsletters"
|
|
},
|
|
{
|
|
"code": "newsletters.create",
|
|
"name": "Create Newsletters",
|
|
"description": "Upload and create newsletters",
|
|
"module": "newsletters"
|
|
},
|
|
{
|
|
"code": "newsletters.edit",
|
|
"name": "Edit Newsletters",
|
|
"description": "Edit existing newsletters",
|
|
"module": "newsletters"
|
|
},
|
|
{
|
|
"code": "newsletters.delete",
|
|
"name": "Delete Newsletters",
|
|
"description": "Delete newsletter archives",
|
|
"module": "newsletters"
|
|
},
|
|
{
|
|
"code": "newsletters.send",
|
|
"name": "Send Newsletters",
|
|
"description": "Send newsletter emails to subscribers",
|
|
"module": "newsletters"
|
|
},
|
|
{
|
|
"code": "newsletters.subscribers",
|
|
"name": "Manage Newsletter Subscribers",
|
|
"description": "View and manage newsletter subscribers",
|
|
"module": "newsletters"
|
|
},
|
|
|
|
# ========== BYLAWS MODULE ==========
|
|
{
|
|
"code": "bylaws.view",
|
|
"name": "View Bylaws",
|
|
"description": "View organization bylaws documents",
|
|
"module": "bylaws"
|
|
},
|
|
{
|
|
"code": "bylaws.create",
|
|
"name": "Create Bylaws",
|
|
"description": "Upload new bylaws documents",
|
|
"module": "bylaws"
|
|
},
|
|
{
|
|
"code": "bylaws.edit",
|
|
"name": "Edit Bylaws",
|
|
"description": "Edit existing bylaws documents",
|
|
"module": "bylaws"
|
|
},
|
|
{
|
|
"code": "bylaws.delete",
|
|
"name": "Delete Bylaws",
|
|
"description": "Delete bylaws documents",
|
|
"module": "bylaws"
|
|
},
|
|
{
|
|
"code": "bylaws.publish",
|
|
"name": "Publish Bylaws",
|
|
"description": "Mark bylaws as current/published version",
|
|
"module": "bylaws"
|
|
},
|
|
|
|
# ========== GALLERY MODULE ==========
|
|
{
|
|
"code": "gallery.view",
|
|
"name": "View Event Gallery",
|
|
"description": "View event gallery photos",
|
|
"module": "gallery"
|
|
},
|
|
{
|
|
"code": "gallery.upload",
|
|
"name": "Upload Photos",
|
|
"description": "Upload photos to event galleries",
|
|
"module": "gallery"
|
|
},
|
|
{
|
|
"code": "gallery.edit",
|
|
"name": "Edit Photos",
|
|
"description": "Edit photo captions and details",
|
|
"module": "gallery"
|
|
},
|
|
{
|
|
"code": "gallery.delete",
|
|
"name": "Delete Photos",
|
|
"description": "Delete photos from galleries",
|
|
"module": "gallery"
|
|
},
|
|
{
|
|
"code": "gallery.moderate",
|
|
"name": "Moderate Gallery Content",
|
|
"description": "Approve/reject uploaded photos",
|
|
"module": "gallery"
|
|
},
|
|
|
|
# ========== SETTINGS MODULE ==========
|
|
{
|
|
"code": "settings.view",
|
|
"name": "View Settings",
|
|
"description": "View application settings",
|
|
"module": "settings"
|
|
},
|
|
{
|
|
"code": "settings.edit",
|
|
"name": "Edit Settings",
|
|
"description": "Edit application settings",
|
|
"module": "settings"
|
|
},
|
|
{
|
|
"code": "settings.email_templates",
|
|
"name": "Manage Email Templates",
|
|
"description": "Edit email templates and notifications",
|
|
"module": "settings"
|
|
},
|
|
{
|
|
"code": "settings.storage",
|
|
"name": "Manage Storage",
|
|
"description": "View and manage storage usage",
|
|
"module": "settings"
|
|
},
|
|
{
|
|
"code": "settings.backup",
|
|
"name": "Backup & Restore",
|
|
"description": "Create and restore database backups",
|
|
"module": "settings"
|
|
},
|
|
{
|
|
"code": "settings.logs",
|
|
"name": "View System Logs",
|
|
"description": "View application and audit logs",
|
|
"module": "settings"
|
|
},
|
|
|
|
# ========== PERMISSIONS MODULE (SUPERADMIN ONLY) ==========
|
|
{
|
|
"code": "permissions.view",
|
|
"name": "View Permissions",
|
|
"description": "View permission definitions and assignments",
|
|
"module": "permissions"
|
|
},
|
|
{
|
|
"code": "permissions.assign",
|
|
"name": "Assign Permissions",
|
|
"description": "Assign permissions to roles (SUPERADMIN ONLY)",
|
|
"module": "permissions"
|
|
},
|
|
{
|
|
"code": "permissions.manage_roles",
|
|
"name": "Manage Roles",
|
|
"description": "Create and manage user roles",
|
|
"module": "permissions"
|
|
},
|
|
{
|
|
"code": "permissions.audit",
|
|
"name": "View Permission Audit Log",
|
|
"description": "View permission change audit logs",
|
|
"module": "permissions"
|
|
},
|
|
]
|
|
|
|
# Default permission assignments for each role
|
|
DEFAULT_ROLE_PERMISSIONS = {
|
|
UserRole.guest: [], # Guests have no admin permissions
|
|
|
|
UserRole.member: [
|
|
# Members can view public content
|
|
"events.view",
|
|
"events.rsvps",
|
|
"events.calendar_export",
|
|
"newsletters.view",
|
|
"bylaws.view",
|
|
"gallery.view",
|
|
],
|
|
|
|
UserRole.admin: [
|
|
# Admins have most permissions except RBAC management
|
|
"users.view",
|
|
"users.create",
|
|
"users.edit",
|
|
"users.status",
|
|
"users.approve",
|
|
"users.export",
|
|
"users.import",
|
|
"users.reset_password",
|
|
"users.resend_verification",
|
|
"events.view",
|
|
"events.create",
|
|
"events.edit",
|
|
"events.delete",
|
|
"events.publish",
|
|
"events.attendance",
|
|
"events.rsvps",
|
|
"events.calendar_export",
|
|
"subscriptions.view",
|
|
"subscriptions.create",
|
|
"subscriptions.edit",
|
|
"subscriptions.cancel",
|
|
"subscriptions.activate",
|
|
"subscriptions.plans",
|
|
"financials.view",
|
|
"financials.create",
|
|
"financials.edit",
|
|
"financials.delete",
|
|
"financials.export",
|
|
"financials.payments",
|
|
"newsletters.view",
|
|
"newsletters.create",
|
|
"newsletters.edit",
|
|
"newsletters.delete",
|
|
"newsletters.send",
|
|
"newsletters.subscribers",
|
|
"bylaws.view",
|
|
"bylaws.create",
|
|
"bylaws.edit",
|
|
"bylaws.delete",
|
|
"bylaws.publish",
|
|
"gallery.view",
|
|
"gallery.upload",
|
|
"gallery.edit",
|
|
"gallery.delete",
|
|
"gallery.moderate",
|
|
"settings.view",
|
|
"settings.edit",
|
|
"settings.email_templates",
|
|
"settings.storage",
|
|
"settings.logs",
|
|
],
|
|
|
|
# Superadmin gets all permissions automatically in code,
|
|
# so we don't need to explicitly assign them
|
|
UserRole.superadmin: []
|
|
}
|
|
|
|
|
|
def seed_permissions():
|
|
"""Seed permissions and default role assignments"""
|
|
db = SessionLocal()
|
|
|
|
try:
|
|
print("🌱 Starting permission seeding...")
|
|
|
|
# Step 1: Clear existing permissions and role_permissions
|
|
print("\n📦 Clearing existing permissions and role assignments...")
|
|
db.query(RolePermission).delete()
|
|
db.query(Permission).delete()
|
|
db.commit()
|
|
print("✓ Cleared existing data")
|
|
|
|
# Step 2: Create permissions
|
|
print(f"\n📝 Creating {len(PERMISSIONS)} permissions...")
|
|
permission_map = {} # Map code to permission object
|
|
|
|
for perm_data in PERMISSIONS:
|
|
permission = Permission(
|
|
code=perm_data["code"],
|
|
name=perm_data["name"],
|
|
description=perm_data["description"],
|
|
module=perm_data["module"]
|
|
)
|
|
db.add(permission)
|
|
permission_map[perm_data["code"]] = permission
|
|
|
|
db.commit()
|
|
print(f"✓ Created {len(PERMISSIONS)} permissions")
|
|
|
|
# Step 3: Assign default permissions to roles
|
|
print("\n🔐 Assigning default permissions to roles...")
|
|
|
|
for role, permission_codes in DEFAULT_ROLE_PERMISSIONS.items():
|
|
if not permission_codes:
|
|
print(f" • {role.value}: No default permissions (handled in code)")
|
|
continue
|
|
|
|
for code in permission_codes:
|
|
if code not in permission_map:
|
|
print(f" ⚠️ Warning: Permission '{code}' not found for role {role.value}")
|
|
continue
|
|
|
|
role_permission = RolePermission(
|
|
role=role,
|
|
permission_id=permission_map[code].id
|
|
)
|
|
db.add(role_permission)
|
|
|
|
db.commit()
|
|
print(f" ✓ {role.value}: Assigned {len(permission_codes)} permissions")
|
|
|
|
# Step 4: Summary
|
|
print("\n" + "="*60)
|
|
print("📊 Seeding Summary:")
|
|
print("="*60)
|
|
|
|
# Count permissions by module
|
|
modules = {}
|
|
for perm in PERMISSIONS:
|
|
module = perm["module"]
|
|
modules[module] = modules.get(module, 0) + 1
|
|
|
|
print("\nPermissions by module:")
|
|
for module, count in sorted(modules.items()):
|
|
print(f" • {module.capitalize()}: {count} permissions")
|
|
|
|
print(f"\nTotal permissions: {len(PERMISSIONS)}")
|
|
print("\n✅ Permission seeding completed successfully!")
|
|
|
|
except Exception as e:
|
|
db.rollback()
|
|
print(f"\n❌ Error seeding permissions: {str(e)}")
|
|
raise
|
|
finally:
|
|
db.close()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
seed_permissions()
|