authentik.tenants.migrations.0001_initial

  1# Generated by Django 4.2.7 on 2023-11-15 10:53
  2
  3import uuid
  4
  5import django.db.models.deletion
  6from django.db import migrations, models
  7from django_tenants.utils import get_tenant_base_schema
  8
  9import authentik.lib.utils.time
 10import authentik.tenants.models
 11from authentik.lib.config import CONFIG
 12
 13
 14def create_default_tenant(apps, schema_editor):
 15    db_alias = schema_editor.connection.alias
 16
 17    Tenant = apps.get_model("authentik_tenants", "Tenant")
 18    Tenant.objects.using(db_alias).create(
 19        schema_name=CONFIG.get("postgresql.default_schema", "public"),
 20        name="Default",
 21        ready=True,
 22        avatars=CONFIG.get("avatars", "gravatar,initials"),
 23        default_user_change_name=CONFIG.get_bool("default_user_change_name", True),
 24        default_user_change_email=CONFIG.get_bool("default_user_change_email", False),
 25        default_user_change_username=CONFIG.get_bool("default_user_change_username", False),
 26        footer_links=CONFIG.get("footer_links", default=[]),
 27        gdpr_compliance=CONFIG.get_bool("gdpr_compliance", True),
 28        impersonation=CONFIG.get_bool("impersonation", True),
 29    )
 30
 31
 32class Migration(migrations.Migration):
 33    initial = True
 34
 35    dependencies = []
 36
 37    operations = [
 38        migrations.CreateModel(
 39            name="Tenant",
 40            fields=[
 41                (
 42                    "schema_name",
 43                    models.CharField(
 44                        db_index=True,
 45                        max_length=63,
 46                        unique=True,
 47                        validators=[authentik.tenants.models._validate_schema_name],
 48                    ),
 49                ),
 50                (
 51                    "tenant_uuid",
 52                    models.UUIDField(
 53                        default=uuid.uuid4, editable=False, primary_key=True, serialize=False
 54                    ),
 55                ),
 56                ("name", models.TextField()),
 57                ("ready", models.BooleanField(default=False)),
 58                (
 59                    "avatars",
 60                    models.TextField(
 61                        default="gravatar,initials",
 62                        help_text="Configure how authentik should show avatars for users.",
 63                    ),
 64                ),
 65                (
 66                    "default_user_change_name",
 67                    models.BooleanField(
 68                        default=True, help_text="Enable the ability for users to change their name."
 69                    ),
 70                ),
 71                (
 72                    "default_user_change_email",
 73                    models.BooleanField(
 74                        default=False,
 75                        help_text="Enable the ability for users to change their email address.",
 76                    ),
 77                ),
 78                (
 79                    "default_user_change_username",
 80                    models.BooleanField(
 81                        default=False,
 82                        help_text="Enable the ability for users to change their username.",
 83                    ),
 84                ),
 85                (
 86                    "event_retention",
 87                    models.TextField(
 88                        default="days=365",
 89                        help_text="Events will be deleted after this duration.(Format: weeks=3;days=2;hours=3,seconds=2).",
 90                        validators=[authentik.lib.utils.time.timedelta_string_validator],
 91                    ),
 92                ),
 93                (
 94                    "footer_links",
 95                    models.JSONField(
 96                        blank=True,
 97                        default=list,
 98                        help_text="The option configures the footer links on the flow executor pages.",
 99                    ),
100                ),
101                (
102                    "gdpr_compliance",
103                    models.BooleanField(
104                        default=True,
105                        help_text="When enabled, all the events caused by a user will be deleted upon the user's deletion.",
106                    ),
107                ),
108                (
109                    "impersonation",
110                    models.BooleanField(
111                        default=True, help_text="Globally enable/disable impersonation."
112                    ),
113                ),
114            ],
115            options={
116                "verbose_name": "Tenant",
117                "verbose_name_plural": "Tenants",
118            },
119        ),
120        migrations.CreateModel(
121            name="Domain",
122            fields=[
123                (
124                    "id",
125                    models.AutoField(
126                        auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
127                    ),
128                ),
129                ("domain", models.CharField(db_index=True, max_length=253, unique=True)),
130                ("is_primary", models.BooleanField(db_index=True, default=True)),
131                (
132                    "tenant",
133                    models.ForeignKey(
134                        on_delete=django.db.models.deletion.CASCADE,
135                        related_name="domains",
136                        to="authentik_tenants.tenant",
137                    ),
138                ),
139            ],
140            options={
141                "verbose_name": "Domain",
142                "verbose_name_plural": "Domains",
143            },
144        ),
145        migrations.RunPython(code=create_default_tenant, reverse_code=migrations.RunPython.noop),
146        migrations.RunSQL(
147            sql=f"CREATE SCHEMA IF NOT EXISTS {get_tenant_base_schema()};",
148            reverse_sql=f"DROP SCHEMA IF EXISTS {get_tenant_base_schema()};",
149        ),
150    ]
def create_default_tenant(apps, schema_editor):
15def create_default_tenant(apps, schema_editor):
16    db_alias = schema_editor.connection.alias
17
18    Tenant = apps.get_model("authentik_tenants", "Tenant")
19    Tenant.objects.using(db_alias).create(
20        schema_name=CONFIG.get("postgresql.default_schema", "public"),
21        name="Default",
22        ready=True,
23        avatars=CONFIG.get("avatars", "gravatar,initials"),
24        default_user_change_name=CONFIG.get_bool("default_user_change_name", True),
25        default_user_change_email=CONFIG.get_bool("default_user_change_email", False),
26        default_user_change_username=CONFIG.get_bool("default_user_change_username", False),
27        footer_links=CONFIG.get("footer_links", default=[]),
28        gdpr_compliance=CONFIG.get_bool("gdpr_compliance", True),
29        impersonation=CONFIG.get_bool("impersonation", True),
30    )
class Migration(django.db.migrations.migration.Migration):
 33class Migration(migrations.Migration):
 34    initial = True
 35
 36    dependencies = []
 37
 38    operations = [
 39        migrations.CreateModel(
 40            name="Tenant",
 41            fields=[
 42                (
 43                    "schema_name",
 44                    models.CharField(
 45                        db_index=True,
 46                        max_length=63,
 47                        unique=True,
 48                        validators=[authentik.tenants.models._validate_schema_name],
 49                    ),
 50                ),
 51                (
 52                    "tenant_uuid",
 53                    models.UUIDField(
 54                        default=uuid.uuid4, editable=False, primary_key=True, serialize=False
 55                    ),
 56                ),
 57                ("name", models.TextField()),
 58                ("ready", models.BooleanField(default=False)),
 59                (
 60                    "avatars",
 61                    models.TextField(
 62                        default="gravatar,initials",
 63                        help_text="Configure how authentik should show avatars for users.",
 64                    ),
 65                ),
 66                (
 67                    "default_user_change_name",
 68                    models.BooleanField(
 69                        default=True, help_text="Enable the ability for users to change their name."
 70                    ),
 71                ),
 72                (
 73                    "default_user_change_email",
 74                    models.BooleanField(
 75                        default=False,
 76                        help_text="Enable the ability for users to change their email address.",
 77                    ),
 78                ),
 79                (
 80                    "default_user_change_username",
 81                    models.BooleanField(
 82                        default=False,
 83                        help_text="Enable the ability for users to change their username.",
 84                    ),
 85                ),
 86                (
 87                    "event_retention",
 88                    models.TextField(
 89                        default="days=365",
 90                        help_text="Events will be deleted after this duration.(Format: weeks=3;days=2;hours=3,seconds=2).",
 91                        validators=[authentik.lib.utils.time.timedelta_string_validator],
 92                    ),
 93                ),
 94                (
 95                    "footer_links",
 96                    models.JSONField(
 97                        blank=True,
 98                        default=list,
 99                        help_text="The option configures the footer links on the flow executor pages.",
100                    ),
101                ),
102                (
103                    "gdpr_compliance",
104                    models.BooleanField(
105                        default=True,
106                        help_text="When enabled, all the events caused by a user will be deleted upon the user's deletion.",
107                    ),
108                ),
109                (
110                    "impersonation",
111                    models.BooleanField(
112                        default=True, help_text="Globally enable/disable impersonation."
113                    ),
114                ),
115            ],
116            options={
117                "verbose_name": "Tenant",
118                "verbose_name_plural": "Tenants",
119            },
120        ),
121        migrations.CreateModel(
122            name="Domain",
123            fields=[
124                (
125                    "id",
126                    models.AutoField(
127                        auto_created=True, primary_key=True, serialize=False, verbose_name="ID"
128                    ),
129                ),
130                ("domain", models.CharField(db_index=True, max_length=253, unique=True)),
131                ("is_primary", models.BooleanField(db_index=True, default=True)),
132                (
133                    "tenant",
134                    models.ForeignKey(
135                        on_delete=django.db.models.deletion.CASCADE,
136                        related_name="domains",
137                        to="authentik_tenants.tenant",
138                    ),
139                ),
140            ],
141            options={
142                "verbose_name": "Domain",
143                "verbose_name_plural": "Domains",
144            },
145        ),
146        migrations.RunPython(code=create_default_tenant, reverse_code=migrations.RunPython.noop),
147        migrations.RunSQL(
148            sql=f"CREATE SCHEMA IF NOT EXISTS {get_tenant_base_schema()};",
149            reverse_sql=f"DROP SCHEMA IF EXISTS {get_tenant_base_schema()};",
150        ),
151    ]

The base class for all migrations.

Migration files will import this from django.db.migrations.Migration and subclass it as a class called Migration. It will have one or more of the following attributes:

  • operations: A list of Operation instances, probably from django.db.migrations.operations
  • dependencies: A list of tuples of (app_path, migration_name)
  • run_before: A list of tuples of (app_path, migration_name)
  • replaces: A list of migration_names

Note that all migrations come out of migrations and into the Loader or Graph as instances, having been initialized with their app label and name.

initial = True
dependencies = []
operations = [<CreateModel name='Tenant', fields=[('schema_name', <django.db.models.fields.CharField>), ('tenant_uuid', <django.db.models.fields.UUIDField>), ('name', <django.db.models.fields.TextField>), ('ready', <django.db.models.fields.BooleanField>), ('avatars', <django.db.models.fields.TextField>), ('default_user_change_name', <django.db.models.fields.BooleanField>), ('default_user_change_email', <django.db.models.fields.BooleanField>), ('default_user_change_username', <django.db.models.fields.BooleanField>), ('event_retention', <django.db.models.fields.TextField>), ('footer_links', <django.db.models.fields.json.JSONField>), ('gdpr_compliance', <django.db.models.fields.BooleanField>), ('impersonation', <django.db.models.fields.BooleanField>)], options={'verbose_name': 'Tenant', 'verbose_name_plural': 'Tenants'}>, <CreateModel name='Domain', fields=[('id', <django.db.models.fields.AutoField>), ('domain', <django.db.models.fields.CharField>), ('is_primary', <django.db.models.fields.BooleanField>), ('tenant', <django.db.models.fields.related.ForeignKey>)], options={'verbose_name': 'Domain', 'verbose_name_plural': 'Domains'}>, <RunPython code=<function create_default_tenant>, reverse_code=<function RunPython.noop>>, <RunSQL sql='CREATE SCHEMA IF NOT EXISTS template;', reverse_sql='DROP SCHEMA IF EXISTS template;'>]