import os import django # Set up Django environment os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'hospital_management.settings') django.setup() import random from datetime import datetime, timedelta, timezone from django.contrib.auth.hashers import make_password from django.utils import timezone as django_timezone from accounts.models import User, TwoFactorDevice, SocialAccount, UserSession, PasswordHistory from core.models import Tenant import uuid import secrets # Saudi-specific data constants SAUDI_FIRST_NAMES_MALE = [ 'Mohammed', 'Abdullah', 'Ahmed', 'Omar', 'Ali', 'Hassan', 'Khalid', 'Faisal', 'Saad', 'Fahd', 'Bandar', 'Turki', 'Nasser', 'Saud', 'Abdulrahman', 'Abdulaziz', 'Salman', 'Waleed', 'Majid', 'Rayan', 'Yazeed', 'Mansour', 'Osama', 'Tariq', 'Adel', 'Nawaf', 'Sultan', 'Mishaal', 'Badr', 'Ziad' ] SAUDI_FIRST_NAMES_FEMALE = [ 'Fatima', 'Aisha', 'Maryam', 'Khadija', 'Sarah', 'Noura', 'Hala', 'Reem', 'Lina', 'Dana', 'Rana', 'Nada', 'Layla', 'Amira', 'Zahra', 'Yasmin', 'Dina', 'Noor', 'Rahma', 'Salma', 'Lama', 'Ghada', 'Rania', 'Maha', 'Wedad', 'Najla', 'Shahd', 'Jood', 'Rand', 'Malak' ] SAUDI_FAMILY_NAMES = [ 'Al-Rashid', 'Al-Harbi', 'Al-Qahtani', 'Al-Dosari', 'Al-Otaibi', 'Al-Mutairi', 'Al-Shammari', 'Al-Zahrani', 'Al-Ghamdi', 'Al-Maliki', 'Al-Subai', 'Al-Jubayr', 'Al-Faisal', 'Al-Saud', 'Al-Thani', 'Al-Maktoum', 'Al-Sabah', 'Al-Khalifa', 'Bin-Laden', 'Al-Rajhi', 'Al-Sudairy', 'Al-Shaalan', 'Al-Kabeer', 'Al-Ajmi', 'Al-Anzi', 'Al-Dawsari', 'Al-Shamrani', 'Al-Balawi', 'Al-Juhani', 'Al-Sulami' ] SAUDI_MIDDLE_NAMES = [ 'bin Ahmed', 'bin Mohammed', 'bin Abdullah', 'bin Omar', 'bin Ali', 'bin Hassan', 'bin Khalid', 'bin Faisal', 'bin Saad', 'bin Fahd', 'bin Abdulaziz', 'bin Salman' ] SAUDI_CITIES = [ 'Riyadh', 'Jeddah', 'Mecca', 'Medina', 'Dammam', 'Khobar', 'Dhahran', 'Taif', 'Tabuk', 'Buraidah', 'Khamis Mushait', 'Hofuf', 'Mubarraz', 'Jubail', 'Yanbu', 'Abha', 'Najran', 'Jazan', 'Hail', 'Arar' ] SAUDI_PROVINCES = [ 'Riyadh Province', 'Makkah Province', 'Eastern Province', 'Asir Province', 'Jazan Province', 'Medina Province', 'Qassim Province', 'Tabuk Province', 'Hail Province', 'Northern Borders Province', 'Najran Province', 'Al Bahah Province' ] SAUDI_JOB_TITLES = { 'PHYSICIAN': ['Consultant Physician', 'Senior Physician', 'Staff Physician', 'Resident Physician', 'Chief Medical Officer'], 'NURSE': ['Head Nurse', 'Senior Nurse', 'Staff Nurse', 'Charge Nurse', 'Clinical Nurse Specialist'], 'PHARMACIST': ['Clinical Pharmacist', 'Staff Pharmacist', 'Pharmacy Manager', 'Pharmaceutical Consultant'], 'ADMIN': ['Medical Director', 'Hospital Administrator', 'Department Manager', 'Operations Manager'], 'LAB_TECH': ['Senior Lab Technician', 'Medical Laboratory Scientist', 'Lab Supervisor'], 'RAD_TECH': ['Senior Radiologic Technologist', 'CT Technologist', 'MRI Technologist'], 'RADIOLOGIST': ['Consultant Radiologist', 'Senior Radiologist', 'Interventional Radiologist'] } SAUDI_DEPARTMENTS = [ 'Internal Medicine', 'Cardiology', 'Orthopedics', 'Neurology', 'Oncology', 'Pediatrics', 'Emergency Medicine', 'Radiology', 'Laboratory Medicine', 'Pharmacy', 'Surgery', 'Obstetrics and Gynecology', 'Dermatology', 'Ophthalmology', 'ENT', 'Anesthesiology', 'Pathology', 'Psychiatry' ] # Saudi Medical License Formats SAUDI_LICENSE_PREFIXES = ['MOH', 'SCFHS', 'SMLE', 'SFH'] def generate_saudi_phone(): """Generate Saudi phone number""" area_codes = ['11', '12', '13', '14', '16', '17'] # Major Saudi area codes return f"+966-{random.choice(area_codes)}-{random.randint(100, 999)}-{random.randint(1000, 9999)}" def generate_saudi_mobile(): """Generate Saudi mobile number""" mobile_prefixes = ['50', '53', '54', '55', '56', '57', '58', '59'] # Saudi mobile prefixes return f"+966-{random.choice(mobile_prefixes)}-{random.randint(100, 999)}-{random.randint(1000, 9999)}" def generate_saudi_license(): """Generate Saudi medical license number""" prefix = random.choice(SAUDI_LICENSE_PREFIXES) return f"{prefix}-{random.randint(100000, 999999)}" def generate_saudi_employee_id(tenant_name, role): """Generate Saudi employee ID""" tenant_code = ''.join([c for c in tenant_name.upper() if c.isalpha()])[:3] role_code = role[:3].upper() return f"{tenant_code}-{role_code}-{random.randint(1000, 9999)}" def create_saudi_users(tenants, users_per_tenant=50): """Create Saudi healthcare users""" users = [] role_distribution = { 'PHYSICIAN': 0.15, 'NURSE': 0.25, 'PHARMACIST': 0.08, 'LAB_TECH': 0.10, 'RAD_TECH': 0.08, 'RADIOLOGIST': 0.05, 'ADMIN': 0.07, 'MEDICAL_ASSISTANT': 0.12, 'CLERICAL': 0.10 } for tenant in tenants: tenant_users = [] for role, percentage in role_distribution.items(): user_count = max(1, int(users_per_tenant * percentage)) for i in range(user_count): # Determine gender for Arabic naming is_male = random.choice([True, False]) first_name = random.choice(SAUDI_FIRST_NAMES_MALE if is_male else SAUDI_FIRST_NAMES_FEMALE) last_name = random.choice(SAUDI_FAMILY_NAMES) middle_name = random.choice(SAUDI_MIDDLE_NAMES) if random.choice([True, False]) else None # Generate username username = f"{first_name.lower()}.{last_name.lower().replace('-', '').replace('al', '')}" counter = 1 original_username = username while User.objects.filter(username=username).exists(): username = f"{original_username}{counter}" counter += 1 # Generate email email = f"{username}@{tenant.name.lower().replace(' ', '').replace('-', '')}.sa" # Professional information department = random.choice(SAUDI_DEPARTMENTS) job_title = random.choice(SAUDI_JOB_TITLES.get(role, [f"{role.replace('_', ' ').title()}"])) # License information for medical professionals license_number = None license_state = None license_expiry = None npi_number = None if role in ['PHYSICIAN', 'NURSE', 'PHARMACIST', 'RADIOLOGIST']: license_number = generate_saudi_license() license_state = random.choice(SAUDI_PROVINCES) license_expiry = django_timezone.now().date() + timedelta(days=random.randint(365, 1095)) if role == 'PHYSICIAN': npi_number = f"SA{random.randint(1000000, 9999999)}" user = User.objects.create( username=username, email=email, first_name=first_name, last_name=last_name, middle_name=middle_name, preferred_name=first_name if random.choice([True, False]) else None, tenant=tenant, # Contact information phone_number=generate_saudi_phone(), mobile_number=generate_saudi_mobile(), # Professional information employee_id=generate_saudi_employee_id(tenant.name, role), department=department, job_title=job_title, role=role, # License information license_number=license_number, license_state=license_state, license_expiry=license_expiry, npi_number=npi_number, # Security settings force_password_change=random.choice([True, False]), password_expires_at=django_timezone.now() + timedelta(days=random.randint(90, 365)), failed_login_attempts=random.randint(0, 2), two_factor_enabled=random.choice([True, False]) if role in ['PHYSICIAN', 'ADMIN', 'PHARMACIST'] else False, # Session settings max_concurrent_sessions=random.choice([1, 2, 3, 5]), session_timeout_minutes=random.choice([30, 60, 120, 240]), # Preferences user_timezone='Asia/Riyadh', language=random.choice(['ar', 'en', 'ar_SA']), theme=random.choice(['LIGHT', 'DARK', 'AUTO']), # Status is_verified=True, is_approved=True, approval_date=django_timezone.now() - timedelta(days=random.randint(1, 180)), is_active=True, is_staff=role in ['ADMIN', 'SUPER_ADMIN'], is_superuser=role == 'SUPER_ADMIN', # Metadata created_at=django_timezone.now() - timedelta(days=random.randint(1, 365)), updated_at=django_timezone.now() - timedelta(days=random.randint(0, 30)), last_password_change=django_timezone.now() - timedelta(days=random.randint(1, 90)), date_joined=django_timezone.now() - timedelta(days=random.randint(1, 365)) ) # Set password user.set_password('Hospital@123') # Default password user.save() users.append(user) tenant_users.append(user) # Set approval relationships admin_users = [u for u in tenant_users if u.role in ['ADMIN', 'SUPER_ADMIN']] if admin_users: approver = random.choice(admin_users) for user in tenant_users: if user != approver and user.role != 'SUPER_ADMIN': user.approved_by = approver user.save() print(f"Created {len(tenant_users)} users for {tenant.name}") return users def create_saudi_two_factor_devices(users): """Create two-factor authentication devices for Saudi users""" devices = [] device_types = ['TOTP', 'SMS', 'EMAIL'] device_names = { 'TOTP': ['Google Authenticator', 'Microsoft Authenticator', 'Authy', 'LastPass Authenticator'], 'SMS': ['Primary Mobile', 'Work Mobile', 'Emergency Contact'], 'EMAIL': ['Work Email', 'Personal Email', 'Backup Email'] } for user in users: if user.two_factor_enabled: # Create 1-3 devices per user device_count = random.randint(1, 3) for _ in range(device_count): device_type = random.choice(device_types) device_data = { 'user': user, 'device_id': uuid.uuid4(), 'name': random.choice(device_names[device_type]), 'device_type': device_type, 'is_active': True, 'is_verified': True, 'verified_at': django_timezone.now() - timedelta(days=random.randint(1, 30)), 'last_used_at': django_timezone.now() - timedelta(hours=random.randint(1, 168)), 'usage_count': random.randint(5, 100), 'created_at': django_timezone.now() - timedelta(days=random.randint(1, 60)) } if device_type == 'TOTP': device_data['secret_key'] = secrets.token_urlsafe(32) elif device_type == 'SMS': device_data['phone_number'] = user.mobile_number elif device_type == 'EMAIL': device_data['email_address'] = user.email device = TwoFactorDevice.objects.create(**device_data) devices.append(device) print(f"Created {len(devices)} two-factor devices") return devices def create_saudi_social_accounts(users): """Create social authentication accounts for Saudi users""" social_accounts = [] # Common providers in Saudi Arabia providers = ['GOOGLE', 'MICROSOFT', 'APPLE', 'LINKEDIN'] for user in users: # 30% chance of having social accounts if random.choice([True, False, False, False]): provider = random.choice(providers) social_account = SocialAccount.objects.create( user=user, provider=provider, provider_id=f"{provider.lower()}_{random.randint(100000000, 999999999)}", provider_email=user.email, display_name=user.get_full_name(), profile_url=f"https://{provider.lower()}.com/profile/{user.username}", avatar_url=f"https://{provider.lower()}.com/avatar/{user.username}.jpg", access_token=secrets.token_urlsafe(64), refresh_token=secrets.token_urlsafe(64), token_expires_at=django_timezone.now() + timedelta(hours=1), is_active=True, created_at=django_timezone.now() - timedelta(days=random.randint(1, 180)), last_login_at=django_timezone.now() - timedelta(hours=random.randint(1, 48)) ) social_accounts.append(social_account) print(f"Created {len(social_accounts)} social accounts") return social_accounts def create_saudi_user_sessions(users): """Create user sessions for Saudi healthcare users""" sessions = [] saudi_ips = [ '37.99.', '37.200.', '31.9.', '31.173.', '188.161.', '185.84.', '188.245.', '217.9.', '82.205.', '5.63.' ] browsers = [ 'Chrome 120.0.0.0', 'Safari 17.1.2', 'Firefox 121.0.0', 'Edge 120.0.0.0', 'Chrome Mobile 120.0.0.0', 'Safari Mobile 17.1.2' ] operating_systems = [ 'Windows 11', 'Windows 10', 'macOS 14.0', 'iOS 17.1.2', 'Android 14', 'Ubuntu 22.04' ] device_types = ['DESKTOP', 'MOBILE', 'TABLET'] login_methods = ['PASSWORD', 'TWO_FACTOR', 'SOCIAL', 'SSO'] for user in users: # Create 1-5 sessions per user session_count = random.randint(1, 5) for i in range(session_count): ip_prefix = random.choice(saudi_ips) ip_address = f"{ip_prefix}{random.randint(1, 255)}.{random.randint(1, 255)}" session_start = django_timezone.now() - timedelta(hours=random.randint(1, 720)) is_active = i == 0 and random.choice([True, True, False]) # Most recent session likely active session = UserSession.objects.create( user=user, session_key=f"session_{secrets.token_urlsafe(20)}", session_id=uuid.uuid4(), ip_address=ip_address, user_agent=f"Mozilla/5.0 (compatible; HospitalSystem/1.0; {random.choice(browsers)})", device_type=random.choice(device_types), browser=random.choice(browsers), operating_system=random.choice(operating_systems), country='Saudi Arabia', region=random.choice(SAUDI_PROVINCES), city=random.choice(SAUDI_CITIES), is_active=is_active, login_method=random.choice(login_methods), created_at=session_start, last_activity_at=session_start + timedelta(minutes=random.randint(1, 480)), expires_at=session_start + timedelta(hours=user.session_timeout_minutes // 60), ended_at=None if is_active else session_start + timedelta(hours=random.randint(1, 8)) ) sessions.append(session) print(f"Created {len(sessions)} user sessions") return sessions def create_saudi_password_history(users): """Create password history for Saudi users""" password_history = [] passwords = ['Hospital@123', 'Medical@456', 'Health@789', 'Saudi@2024', 'Secure@Pass'] for user in users: # Create 1-5 password history entries per user history_count = random.randint(1, 5) for i in range(history_count): password = random.choice(passwords) history_entry = PasswordHistory.objects.create( user=user, password_hash=make_password(password), created_at=django_timezone.now() - timedelta(days=random.randint(30 * i, 30 * (i + 1))) ) password_history.append(history_entry) print(f"Created {len(password_history)} password history entries") return password_history def main(): """Main function to generate all Saudi accounts data""" print("Starting Saudi Healthcare Accounts Data Generation...") # Get existing tenants tenants = list(Tenant.objects.all()) if not tenants: print("āŒ No tenants found. Please run the core data generator first.") return # Create users print("\n1. Creating Saudi Healthcare Users...") users = create_saudi_users(tenants, 40) # 40 users per tenant # Create two-factor devices print("\n2. Creating Two-Factor Authentication Devices...") devices = create_saudi_two_factor_devices(users) # Create social accounts print("\n3. Creating Social Authentication Accounts...") social_accounts = create_saudi_social_accounts(users) # Create user sessions print("\n4. Creating User Sessions...") sessions = create_saudi_user_sessions(users) # Create password history print("\n5. Creating Password History...") password_history = create_saudi_password_history(users) print(f"\nāœ… Saudi Healthcare Accounts Data Generation Complete!") print(f"šŸ“Š Summary:") print(f" - Users: {len(users)}") print(f" - Two-Factor Devices: {len(devices)}") print(f" - Social Accounts: {len(social_accounts)}") print(f" - User Sessions: {len(sessions)}") print(f" - Password History Entries: {len(password_history)}") # Role distribution summary role_counts = {} for user in users: role_counts[user.role] = role_counts.get(user.role, 0) + 1 print(f"\nšŸ‘„ User Role Distribution:") for role, count in sorted(role_counts.items()): print(f" - {role.replace('_', ' ').title()}: {count}") return { 'users': users, 'devices': devices, 'social_accounts': social_accounts, 'sessions': sessions, 'password_history': password_history } if __name__ == "__main__": main()