""" Create a superadmin user interactively. Run this script to add a superadmin account to your database. """ import getpass import re from database import SessionLocal from models import User, UserStatus, UserRole, Role from auth import get_password_hash from datetime import datetime, timezone import sys def validate_email(email): """Validate email format""" pattern = r'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$' return re.match(pattern, email) is not None def validate_phone(phone): """Validate phone format (simple check)""" # Remove common separators cleaned = phone.replace('-', '').replace('(', '').replace(')', '').replace(' ', '').replace('.', '') return len(cleaned) >= 10 and cleaned.isdigit() def validate_zipcode(zipcode): """Validate US zipcode format""" return len(zipcode) == 5 and zipcode.isdigit() def get_input(prompt, validator=None, required=True, default=None): """Get user input with optional validation""" while True: if default: user_input = input(f"{prompt} [{default}]: ").strip() if not user_input: return default else: user_input = input(f"{prompt}: ").strip() if not user_input and not required: return None if not user_input and required: print("āŒ This field is required. Please try again.") continue if validator and not validator(user_input): print("āŒ Invalid format. Please try again.") continue return user_input def get_password(): """Get password with confirmation and validation""" while True: password = getpass.getpass("Password (min 8 characters): ") if len(password) < 8: print("āŒ Password must be at least 8 characters long.") continue confirm = getpass.getpass("Confirm password: ") if password != confirm: print("āŒ Passwords do not match. Please try again.") continue return password def create_superadmin(): """Create a superadmin user interactively""" db = SessionLocal() try: print("\n" + "="*60) print("šŸ”§ LOAF Membership Platform - Superadmin Creation") print("="*60 + "\n") # Get user information interactively print("šŸ“ Please provide the superadmin account details:\n") email = get_input( "Email address", validator=validate_email, required=True ) # Check if user already exists existing_user = db.query(User).filter(User.email == email).first() if existing_user: print(f"\nāš ļø User with email '{email}' already exists!") print(f" Current Role: {existing_user.role.value}") print(f" Current Status: {existing_user.status.value}") update = input("\nā“ Would you like to update this user to superadmin? (yes/no): ").strip().lower() if update in ['yes', 'y']: existing_user.role = UserRole.superadmin existing_user.status = UserStatus.active existing_user.email_verified = True # Assign superadmin role in dynamic RBAC if roles table exists try: superadmin_role = db.query(Role).filter(Role.code == 'superadmin').first() if superadmin_role and not existing_user.role_id: existing_user.role_id = superadmin_role.id except Exception: pass # Roles table might not exist yet db.commit() print("āœ… User updated to superadmin successfully!") print(f" Email: {existing_user.email}") print(f" Role: {existing_user.role.value}") print(f" User ID: {existing_user.id}") else: print("āŒ Operation cancelled.") return password = get_password() print("\nšŸ‘¤ Personal Information:\n") first_name = get_input("First name", required=True) last_name = get_input("Last name", required=True) phone = get_input("Phone number", validator=validate_phone, required=True) print("\nšŸ“ Address Information:\n") address = get_input("Street address", required=True) city = get_input("City", required=True) state = get_input("State (2-letter code)", required=True, default="CA") zipcode = get_input("ZIP code", validator=validate_zipcode, required=True) print("\nšŸ“… Date of Birth (YYYY-MM-DD format):\n") while True: dob_str = get_input("Date of birth (e.g., 1990-01-15)", required=True) try: date_of_birth = datetime.strptime(dob_str, "%Y-%m-%d") break except ValueError: print("āŒ Invalid date format. Please use YYYY-MM-DD format.") # Create superadmin user print("\nā³ Creating superadmin user...") superadmin_user = User( email=email, password_hash=get_password_hash(password), first_name=first_name, last_name=last_name, phone=phone, address=address, city=city, state=state.upper(), zipcode=zipcode, date_of_birth=date_of_birth, status=UserStatus.active, role=UserRole.superadmin, email_verified=True, newsletter_subscribed=False ) db.add(superadmin_user) db.flush() # Flush to get the user ID before looking up roles # Assign superadmin role in dynamic RBAC if roles table exists try: superadmin_role = db.query(Role).filter(Role.code == 'superadmin').first() if superadmin_role: superadmin_user.role_id = superadmin_role.id print(" āœ“ Assigned dynamic superadmin role") except Exception as e: print(f" āš ļø Dynamic roles not yet set up (this is normal for fresh installs)") db.commit() db.refresh(superadmin_user) print("\n" + "="*60) print("āœ… Superadmin user created successfully!") print("="*60) print(f"\nšŸ“§ Email: {superadmin_user.email}") print(f"šŸ‘¤ Name: {superadmin_user.first_name} {superadmin_user.last_name}") print(f"šŸ”‘ Role: {superadmin_user.role.value}") print(f"šŸ†” User ID: {superadmin_user.id}") print(f"\n✨ You can now log in to the admin panel at /admin/login") print("\n" + "="*60 + "\n") except KeyboardInterrupt: print("\n\nāŒ Operation cancelled by user.") db.rollback() sys.exit(1) except Exception as e: print(f"\nāŒ Error creating superadmin user: {e}") import traceback traceback.print_exc() db.rollback() sys.exit(1) finally: db.close() if __name__ == "__main__": create_superadmin()