# Generated by Django 6.0 on 2026-02-08 06:03

import django.core.validators
import django.db.models.deletion
from django.conf import settings
from django.db import migrations, models


class Migration(migrations.Migration):

    initial = True

    dependencies = [
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
    ]

    operations = [
        migrations.CreateModel(
            name='AllowedCountry',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('code', models.CharField(choices=[('AF', 'Afghanistan'), ('AL', 'Albania'), ('DZ', 'Algeria'), ('AO', 'Angola'), ('AR', 'Argentina'), ('AM', 'Armenia'), ('AU', 'Australia'), ('AT', 'Austria'), ('AZ', 'Azerbaijan'), ('BH', 'Bahrain'), ('BD', 'Bangladesh'), ('BY', 'Belarus'), ('BE', 'Belgium'), ('BR', 'Brazil'), ('BG', 'Bulgaria'), ('KH', 'Cambodia'), ('CA', 'Canada'), ('CN', 'China'), ('CO', 'Colombia'), ('HR', 'Croatia'), ('CU', 'Cuba'), ('CY', 'Cyprus'), ('CZ', 'Czech Republic'), ('DK', 'Denmark'), ('EG', 'Egypt'), ('EE', 'Estonia'), ('ET', 'Ethiopia'), ('FI', 'Finland'), ('FR', 'France'), ('GE', 'Georgia'), ('DE', 'Germany'), ('GH', 'Ghana'), ('GR', 'Greece'), ('HK', 'Hong Kong'), ('HU', 'Hungary'), ('IN', 'India'), ('ID', 'Indonesia'), ('IR', 'Iran'), ('IQ', 'Iraq'), ('IE', 'Ireland'), ('IL', 'Israel'), ('IT', 'Italy'), ('JP', 'Japan'), ('JO', 'Jordan'), ('KZ', 'Kazakhstan'), ('KE', 'Kenya'), ('KP', 'North Korea'), ('KR', 'South Korea'), ('KW', 'Kuwait'), ('LV', 'Latvia'), ('LB', 'Lebanon'), ('LY', 'Libya'), ('LT', 'Lithuania'), ('MY', 'Malaysia'), ('MX', 'Mexico'), ('MA', 'Morocco'), ('MM', 'Myanmar'), ('NL', 'Netherlands'), ('NZ', 'New Zealand'), ('NG', 'Nigeria'), ('NO', 'Norway'), ('OM', 'Oman'), ('PK', 'Pakistan'), ('PS', 'Palestine'), ('PH', 'Philippines'), ('PL', 'Poland'), ('PT', 'Portugal'), ('QA', 'Qatar'), ('RO', 'Romania'), ('RU', 'Russia'), ('SA', 'Saudi Arabia'), ('RS', 'Serbia'), ('SG', 'Singapore'), ('SK', 'Slovakia'), ('SI', 'Slovenia'), ('ZA', 'South Africa'), ('ES', 'Spain'), ('SD', 'Sudan'), ('SE', 'Sweden'), ('CH', 'Switzerland'), ('SY', 'Syria'), ('TW', 'Taiwan'), ('TH', 'Thailand'), ('TN', 'Tunisia'), ('TR', 'Turkey'), ('UA', 'Ukraine'), ('AE', 'United Arab Emirates'), ('GB', 'United Kingdom'), ('US', 'United States'), ('VE', 'Venezuela'), ('VN', 'Vietnam'), ('YE', 'Yemen'), ('ZW', 'Zimbabwe')], db_index=True, help_text='ISO 3166-1 alpha-2 country code', max_length=2, unique=True)),
                ('name', models.CharField(blank=True, max_length=100)),
                ('is_active', models.BooleanField(db_index=True, default=True)),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
            ],
            options={
                'verbose_name': 'Allowed Country',
                'verbose_name_plural': 'Allowed Countries',
                'db_table': 'security_allowed_country',
                'ordering': ['name'],
            },
        ),
        migrations.CreateModel(
            name='BlockedCountry',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('code', models.CharField(choices=[('AF', 'Afghanistan'), ('AL', 'Albania'), ('DZ', 'Algeria'), ('AO', 'Angola'), ('AR', 'Argentina'), ('AM', 'Armenia'), ('AU', 'Australia'), ('AT', 'Austria'), ('AZ', 'Azerbaijan'), ('BH', 'Bahrain'), ('BD', 'Bangladesh'), ('BY', 'Belarus'), ('BE', 'Belgium'), ('BR', 'Brazil'), ('BG', 'Bulgaria'), ('KH', 'Cambodia'), ('CA', 'Canada'), ('CN', 'China'), ('CO', 'Colombia'), ('HR', 'Croatia'), ('CU', 'Cuba'), ('CY', 'Cyprus'), ('CZ', 'Czech Republic'), ('DK', 'Denmark'), ('EG', 'Egypt'), ('EE', 'Estonia'), ('ET', 'Ethiopia'), ('FI', 'Finland'), ('FR', 'France'), ('GE', 'Georgia'), ('DE', 'Germany'), ('GH', 'Ghana'), ('GR', 'Greece'), ('HK', 'Hong Kong'), ('HU', 'Hungary'), ('IN', 'India'), ('ID', 'Indonesia'), ('IR', 'Iran'), ('IQ', 'Iraq'), ('IE', 'Ireland'), ('IL', 'Israel'), ('IT', 'Italy'), ('JP', 'Japan'), ('JO', 'Jordan'), ('KZ', 'Kazakhstan'), ('KE', 'Kenya'), ('KP', 'North Korea'), ('KR', 'South Korea'), ('KW', 'Kuwait'), ('LV', 'Latvia'), ('LB', 'Lebanon'), ('LY', 'Libya'), ('LT', 'Lithuania'), ('MY', 'Malaysia'), ('MX', 'Mexico'), ('MA', 'Morocco'), ('MM', 'Myanmar'), ('NL', 'Netherlands'), ('NZ', 'New Zealand'), ('NG', 'Nigeria'), ('NO', 'Norway'), ('OM', 'Oman'), ('PK', 'Pakistan'), ('PS', 'Palestine'), ('PH', 'Philippines'), ('PL', 'Poland'), ('PT', 'Portugal'), ('QA', 'Qatar'), ('RO', 'Romania'), ('RU', 'Russia'), ('SA', 'Saudi Arabia'), ('RS', 'Serbia'), ('SG', 'Singapore'), ('SK', 'Slovakia'), ('SI', 'Slovenia'), ('ZA', 'South Africa'), ('ES', 'Spain'), ('SD', 'Sudan'), ('SE', 'Sweden'), ('CH', 'Switzerland'), ('SY', 'Syria'), ('TW', 'Taiwan'), ('TH', 'Thailand'), ('TN', 'Tunisia'), ('TR', 'Turkey'), ('UA', 'Ukraine'), ('AE', 'United Arab Emirates'), ('GB', 'United Kingdom'), ('US', 'United States'), ('VE', 'Venezuela'), ('VN', 'Vietnam'), ('YE', 'Yemen'), ('ZW', 'Zimbabwe')], db_index=True, help_text='ISO 3166-1 alpha-2 country code', max_length=2, unique=True)),
                ('name', models.CharField(blank=True, max_length=100)),
                ('reason', models.TextField(blank=True, help_text='Reason for blocking')),
                ('is_active', models.BooleanField(db_index=True, default=True)),
                ('is_auto_blocked', models.BooleanField(default=False, help_text='Automatically blocked due to high attack volume')),
                ('attack_count', models.PositiveIntegerField(default=0, help_text='Number of attacks from this country')),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
            ],
            options={
                'verbose_name': 'Blocked Country',
                'verbose_name_plural': 'Blocked Countries',
                'db_table': 'security_blocked_country',
                'ordering': ['name'],
            },
        ),
        migrations.CreateModel(
            name='BlockedUserAgent',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('pattern', models.CharField(db_index=True, help_text='User agent pattern to block', max_length=500, unique=True)),
                ('block_type', models.CharField(choices=[('exact', 'Exact Match'), ('contains', 'Contains'), ('regex', 'Regex Pattern')], default='contains', max_length=20)),
                ('category', models.CharField(choices=[('bot', 'Bad Bot'), ('scraper', 'Scraper'), ('spam', 'Spam Bot'), ('attack', 'Attack Tool'), ('custom', 'Custom')], default='bot', max_length=20)),
                ('description', models.CharField(blank=True, max_length=255)),
                ('is_active', models.BooleanField(db_index=True, default=True)),
                ('is_auto_synced', models.BooleanField(default=False, help_text='Automatically synced from public list')),
                ('block_count', models.PositiveIntegerField(default=0, help_text='Times this pattern blocked')),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
            ],
            options={
                'verbose_name': 'Blocked User Agent',
                'verbose_name_plural': 'Blocked User Agents',
                'db_table': 'security_blocked_user_agent',
                'ordering': ['-block_count', 'pattern'],
            },
        ),
        migrations.CreateModel(
            name='SecuritySettings',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('auto_block_ip_threshold', models.PositiveIntegerField(default=10, help_text='Block IP after this many security events in the time window')),
                ('auto_block_ip_window_hours', models.PositiveIntegerField(default=1, help_text='Time window (hours) for IP auto-block threshold')),
                ('auto_block_ip_duration_hours', models.PositiveIntegerField(default=24, help_text='How long to auto-block an IP (hours). 0 = permanent')),
                ('max_login_attempts', models.PositiveIntegerField(default=5, help_text='Maximum failed login attempts before account lockout (1-100)', validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(100)])),
                ('auto_block_country_threshold', models.PositiveIntegerField(default=100, help_text='Consider auto-blocking country after this many attacks')),
                ('auto_block_country_window_hours', models.PositiveIntegerField(default=24, help_text='Time window (hours) for country auto-block threshold')),
                ('auto_block_country_enabled', models.BooleanField(default=False, help_text='Auto-block countries (requires manual review)')),
                ('alert_on_new_country', models.BooleanField(default=True, help_text='Flag login as suspicious when from new country')),
                ('alert_on_new_ip', models.BooleanField(default=False, help_text='Flag login as suspicious when from new IP')),
                ('max_countries_per_day', models.PositiveIntegerField(default=3, help_text='Flag as suspicious if user logs in from more countries in a day')),
                ('sync_disposable_domains', models.BooleanField(default=True, help_text='Auto-sync disposable email domain list')),
                ('sync_bad_bots', models.BooleanField(default=True, help_text='Auto-sync bad bot user agent list')),
                ('last_sync_at', models.DateTimeField(blank=True, null=True)),
                ('notify_on_auto_block', models.BooleanField(default=True, help_text='Send notification when IP/country is auto-blocked')),
                ('notification_email', models.EmailField(blank=True, help_text='Email for security notifications', max_length=254)),
                ('telegram_notifications', models.BooleanField(default=False, help_text='Send Telegram notifications')),
                ('country_blocking_enabled', models.BooleanField(default=True)),
                ('country_whitelist_mode', models.BooleanField(default=False, help_text='If enabled, only allowed countries can access')),
                ('ip_blocking_enabled', models.BooleanField(default=True)),
                ('email_blocking_enabled', models.BooleanField(default=True)),
                ('domain_blocking_enabled', models.BooleanField(default=True)),
                ('user_agent_blocking_enabled', models.BooleanField(default=True)),
                ('login_history_enabled', models.BooleanField(default=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
            ],
            options={
                'verbose_name': 'Security Settings',
                'verbose_name_plural': 'Security Settings',
                'db_table': 'security_settings',
            },
        ),
        migrations.CreateModel(
            name='WhitelistedIP',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('ip_address', models.GenericIPAddressField(db_index=True, help_text='IP address to whitelist (IPv4 or IPv6)', unique=True)),
                ('description', models.CharField(blank=True, help_text='e.g., Office IP, VPN, Load Balancer', max_length=255)),
                ('is_active', models.BooleanField(db_index=True, default=True)),
                ('created_by', models.CharField(blank=True, help_text='Who added this', max_length=100)),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
            ],
            options={
                'verbose_name': 'Whitelisted IP',
                'verbose_name_plural': 'Whitelisted IPs',
                'db_table': 'security_whitelisted_ip',
                'ordering': ['-created_at'],
            },
        ),
        migrations.CreateModel(
            name='BlockedDomain',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('domain', models.CharField(db_index=True, help_text='Domain to block (e.g., tempmail.com)', max_length=255, unique=True)),
                ('domain_type', models.CharField(choices=[('disposable', 'Disposable Email'), ('spam', 'Known Spam Domain'), ('competitor', 'Competitor Domain'), ('custom', 'Custom Block')], default='disposable', max_length=20)),
                ('reason', models.TextField(blank=True, help_text='Reason for blocking')),
                ('is_active', models.BooleanField(db_index=True, default=True)),
                ('is_auto_synced', models.BooleanField(default=False, help_text='Automatically synced from public list')),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
            ],
            options={
                'verbose_name': 'Blocked Domain',
                'verbose_name_plural': 'Blocked Domains',
                'db_table': 'security_blocked_domain',
                'ordering': ['domain'],
                'indexes': [models.Index(fields=['domain', 'is_active'], name='security_bl_domain_5f4de5_idx')],
            },
        ),
        migrations.CreateModel(
            name='BlockedEmail',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('email', models.EmailField(db_index=True, help_text='Email address to block from registration and login', max_length=254, unique=True, validators=[django.core.validators.EmailValidator()])),
                ('reason', models.TextField(blank=True, help_text='Reason for blocking this email address')),
                ('is_active', models.BooleanField(db_index=True, default=True)),
                ('is_auto_blocked', models.BooleanField(default=False, help_text='Automatically blocked (disposable email, etc.)')),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
            ],
            options={
                'verbose_name': 'Blocked Email',
                'verbose_name_plural': 'Blocked Emails',
                'db_table': 'security_blocked_email',
                'ordering': ['-created_at'],
                'indexes': [models.Index(fields=['email'], name='sec_blocked_email_idx')],
            },
        ),
        migrations.CreateModel(
            name='BlockedIP',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('ip_address', models.GenericIPAddressField(db_index=True, help_text='IP address to block (IPv4 or IPv6)', unique=True)),
                ('reason', models.TextField(blank=True, help_text='Reason for blocking')),
                ('is_active', models.BooleanField(db_index=True, default=True)),
                ('is_auto_blocked', models.BooleanField(default=False, help_text='Automatically blocked due to suspicious activity')),
                ('block_count', models.PositiveIntegerField(default=0, help_text='Number of times this IP triggered security rules')),
                ('expires_at', models.DateTimeField(blank=True, db_index=True, help_text='Leave empty for permanent block', null=True)),
                ('country_code', models.CharField(blank=True, help_text='Detected country', max_length=2)),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
            ],
            options={
                'verbose_name': 'Blocked IP',
                'verbose_name_plural': 'Blocked IPs',
                'db_table': 'security_blocked_ip',
                'ordering': ['-created_at'],
                'indexes': [models.Index(fields=['ip_address', 'is_active'], name='security_bl_ip_addr_40cac8_idx'), models.Index(fields=['-created_at'], name='security_bl_created_107e38_idx')],
            },
        ),
        migrations.CreateModel(
            name='RateLimitRule',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('name', models.CharField(help_text='Rule name for identification', max_length=100)),
                ('path_pattern', models.CharField(db_index=True, help_text='URL path pattern (e.g., /api/v1/auth/, /api/v1/chat/)', max_length=255)),
                ('rate', models.CharField(choices=[('1/m', '1 per minute'), ('5/m', '5 per minute'), ('10/m', '10 per minute'), ('30/m', '30 per minute'), ('60/m', '60 per minute'), ('100/m', '100 per minute'), ('5/h', '5 per hour'), ('10/h', '10 per hour'), ('50/h', '50 per hour'), ('100/h', '100 per hour'), ('500/h', '500 per hour'), ('1000/h', '1000 per hour'), ('1000/d', '1000 per day'), ('5000/d', '5000 per day')], default='100/m', max_length=20)),
                ('method', models.CharField(choices=[('ALL', 'All Methods'), ('GET', 'GET'), ('POST', 'POST'), ('PUT', 'PUT'), ('PATCH', 'PATCH'), ('DELETE', 'DELETE')], default='ALL', max_length=10)),
                ('is_active', models.BooleanField(db_index=True, default=True)),
                ('block_count', models.PositiveIntegerField(default=0, help_text='Times this rule triggered')),
                ('created_at', models.DateTimeField(auto_now_add=True)),
                ('updated_at', models.DateTimeField(auto_now=True)),
            ],
            options={
                'verbose_name': 'Rate Limit Rule',
                'verbose_name_plural': 'Rate Limit Rules',
                'db_table': 'security_rate_limit_rule',
                'ordering': ['path_pattern'],
                'unique_together': {('path_pattern', 'method')},
            },
        ),
        migrations.CreateModel(
            name='SecurityLog',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('ip_address', models.GenericIPAddressField(db_index=True)),
                ('country_code', models.CharField(blank=True, db_index=True, max_length=2)),
                ('action', models.CharField(choices=[('COUNTRY_BLOCK', 'Blocked by Country'), ('COUNTRY_WHITELIST_BLOCK', 'Blocked - Country Not in Whitelist'), ('IP_BLOCK', 'Blocked by IP'), ('EMAIL_BLOCK', 'Blocked by Email'), ('DOMAIN_BLOCK', 'Blocked by Domain'), ('USER_AGENT_BLOCK', 'Blocked by User Agent'), ('RATE_LIMIT', 'Rate Limited'), ('AXES_LOCK', 'Login Locked (Axes)'), ('SUSPICIOUS_LOGIN', 'Suspicious Login Detected'), ('AUTO_BLOCK_IP', 'IP Auto-Blocked'), ('AUTO_BLOCK_COUNTRY', 'Country Auto-Blocked')], db_index=True, max_length=30)),
                ('severity', models.CharField(choices=[('low', 'Low'), ('medium', 'Medium'), ('high', 'High'), ('critical', 'Critical')], default='medium', max_length=10)),
                ('path', models.CharField(max_length=500)),
                ('method', models.CharField(blank=True, max_length=10)),
                ('user_agent', models.TextField(blank=True)),
                ('details', models.TextField(blank=True)),
                ('user_email', models.EmailField(blank=True, help_text='If login attempt, the email used', max_length=254)),
                ('created_at', models.DateTimeField(auto_now_add=True, db_index=True)),
            ],
            options={
                'verbose_name': 'Security Log',
                'verbose_name_plural': 'Security Logs',
                'db_table': 'security_security_log',
                'ordering': ['-created_at'],
                'indexes': [models.Index(fields=['-created_at'], name='security_se_created_f226dd_idx'), models.Index(fields=['ip_address', '-created_at'], name='security_se_ip_addr_9cb7f7_idx'), models.Index(fields=['action', '-created_at'], name='security_se_action_9d58e2_idx'), models.Index(fields=['country_code', '-created_at'], name='security_se_country_cc5584_idx')],
            },
        ),
        migrations.CreateModel(
            name='LoginHistory',
            fields=[
                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
                ('ip_address', models.GenericIPAddressField(db_index=True)),
                ('country_code', models.CharField(blank=True, db_index=True, max_length=2)),
                ('city', models.CharField(blank=True, max_length=100)),
                ('user_agent', models.TextField(blank=True)),
                ('device_type', models.CharField(blank=True, help_text='mobile, desktop, tablet', max_length=50)),
                ('browser', models.CharField(blank=True, max_length=100)),
                ('os', models.CharField(blank=True, max_length=100)),
                ('is_suspicious', models.BooleanField(db_index=True, default=False, help_text='Flagged as suspicious (new country, rapid IP change, etc.)')),
                ('suspicious_reason', models.CharField(blank=True, max_length=255)),
                ('session_key', models.CharField(blank=True, db_index=True, max_length=255)),
                ('created_at', models.DateTimeField(auto_now_add=True, db_index=True)),
                ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='login_history', to=settings.AUTH_USER_MODEL)),
            ],
            options={
                'verbose_name': 'Login History',
                'verbose_name_plural': 'Login History',
                'db_table': 'security_login_history',
                'ordering': ['-created_at'],
                'indexes': [models.Index(fields=['user', '-created_at'], name='security_lo_user_id_980aa9_idx'), models.Index(fields=['ip_address', '-created_at'], name='security_lo_ip_addr_50e28c_idx'), models.Index(fields=['country_code', '-created_at'], name='security_lo_country_9d3d7c_idx')],
            },
        ),
    ]
