# Generated by Django 5.2.17 on 2026-09-24 14:10 import django.db.models.deletion from django.conf import settings from django.db import migrations, models class Migration(migrations.Migration): initial = True dependencies = [ ("tenancy", "0001_initial"), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name="ALTCHAChallenge", fields=[ ("challenge_id", models.CharField(max_length=64, primary_key=True, serialize=False)), ("salt", models.CharField(max_length=32)), ("difficulty", models.IntegerField(default=10000)), ("expires_at", models.DateTimeField(db_index=True)), ("is_verified", models.BooleanField(default=False)), ], options={ "db_table": "security_altcha_challenge", }, ), migrations.CreateModel( name="TwoFactorConfig", fields=[ ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), ("is_enabled", models.BooleanField(default=False)), ("is_configured", models.BooleanField(default=False)), ( "method", models.CharField( choices=[("totp", "TOTP"), ("email", "Email"), ("both", "Both")], default="totp", max_length=10 ), ), ("secret_key_encrypted", models.CharField(blank=True, max_length=500, null=True)), ("recovery_codes_encrypted", models.TextField(blank=True, null=True)), ("email_verified", models.BooleanField(default=False)), ("email_code", models.CharField(blank=True, max_length=6, null=True)), ("email_code_expires_at", models.DateTimeField(blank=True, null=True)), ( "user", models.OneToOneField( on_delete=django.db.models.deletion.CASCADE, related_name="two_factor_config", to=settings.AUTH_USER_MODEL, ), ), ], options={ "db_table": "security_two_factor_config", }, ), migrations.CreateModel( name="APIKey", fields=[ ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), ("name", models.CharField(max_length=200)), ("prefix", models.CharField(help_text="First 8 characters visible in UI", max_length=12)), ("key_hash", models.CharField(help_text="PBKDF2 hash of the full secret", max_length=255)), ("scopes", models.JSONField(default=list, help_text='["read:users", "write:billing"]')), ("is_active", models.BooleanField(default=True)), ("expires_at", models.DateTimeField(blank=True, null=True)), ("last_used_at", models.DateTimeField(blank=True, null=True)), ( "created_by", models.ForeignKey( null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL ), ), ( "rotated_from", models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to="infrasynth_security.apikey", ), ), ( "tenant", models.ForeignKey( editable=False, on_delete=django.db.models.deletion.CASCADE, related_name="+", to="tenancy.tenant", ), ), ], options={ "db_table": "security_api_key", "constraints": [ models.UniqueConstraint(fields=("tenant", "prefix"), name="uniq_api_key_prefix_per_tenant") ], }, ), migrations.CreateModel( name="Grant", fields=[ ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), ("codename", models.CharField(db_index=True, max_length=200)), ("reason", models.TextField(blank=True)), ("expires_at", models.DateTimeField(blank=True, null=True)), ( "granted_by", models.ForeignKey( null=True, on_delete=django.db.models.deletion.SET_NULL, related_name="grants_given", to=settings.AUTH_USER_MODEL, ), ), ( "tenant", models.ForeignKey( editable=False, on_delete=django.db.models.deletion.CASCADE, related_name="+", to="tenancy.tenant", ), ), ( "user", models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, related_name="direct_grants", to=settings.AUTH_USER_MODEL, ), ), ], options={ "db_table": "security_grant", "constraints": [ models.UniqueConstraint(fields=("tenant", "user", "codename"), name="uniq_grant_per_tenant_user") ], }, ), migrations.CreateModel( name="Revoke", fields=[ ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), ("codename", models.CharField(db_index=True, max_length=200)), ("reason", models.TextField(blank=True)), ( "revoked_by", models.ForeignKey( null=True, on_delete=django.db.models.deletion.SET_NULL, related_name="revokes_given", to=settings.AUTH_USER_MODEL, ), ), ( "tenant", models.ForeignKey( editable=False, on_delete=django.db.models.deletion.CASCADE, related_name="+", to="tenancy.tenant", ), ), ( "user", models.ForeignKey( on_delete=django.db.models.deletion.CASCADE, related_name="direct_revokes", to=settings.AUTH_USER_MODEL, ), ), ], options={ "db_table": "security_revoke", "constraints": [ models.UniqueConstraint(fields=("tenant", "user", "codename"), name="uniq_revoke_per_tenant_user") ], }, ), migrations.CreateModel( name="Role", fields=[ ("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")), ("name", models.CharField(max_length=100)), ("slug", models.SlugField(max_length=100)), ("description", models.TextField(blank=True)), ("permissions", models.JSONField(default=list, help_text="List of permission codenames")), ("is_system", models.BooleanField(default=False, help_text="System roles cannot be deleted")), ( "tenant", models.ForeignKey( blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name="+", to="tenancy.tenant", ), ), ( "users", models.ManyToManyField( blank=True, help_text="Users assigned this role", related_name="roles", to=settings.AUTH_USER_MODEL, ), ), ], options={ "db_table": "security_role", "constraints": [ models.UniqueConstraint(fields=("tenant", "slug"), name="uniq_role_slug_per_tenant"), models.UniqueConstraint( condition=models.Q(("tenant__isnull", True)), fields=("slug",), name="uniq_global_role_slug" ), ], }, ), ]