authentik.sources.saml.migrations.0001_squashed_0009_auto_20210301_0949

  1# Generated by Django 3.2.8 on 2021-10-11 15:55
  2
  3import django.db.models.deletion
  4from django.apps.registry import Apps
  5from django.db import migrations, models
  6from django.db.backends.base.schema import BaseDatabaseSchemaEditor
  7
  8import authentik.lib.utils.time
  9from authentik.common.saml import constants
 10
 11
 12def update_algorithms(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
 13    db_alias = schema_editor.connection.alias
 14
 15    SAMLSource = apps.get_model("authentik_sources_saml", "SAMLSource")
 16    signature_translation_map = {
 17        "rsa-sha1": constants.RSA_SHA1,
 18        "rsa-sha256": constants.RSA_SHA256,
 19        "ecdsa-sha256": constants.RSA_SHA256,
 20        "dsa-sha1": constants.DSA_SHA1,
 21    }
 22    digest_translation_map = {
 23        "sha1": constants.SHA1,
 24        "sha256": constants.SHA256,
 25    }
 26
 27    for source in SAMLSource.objects.using(db_alias).all():
 28        source.signature_algorithm = signature_translation_map.get(
 29            source.signature_algorithm, constants.RSA_SHA256
 30        )
 31        source.digest_algorithm = digest_translation_map.get(
 32            source.digest_algorithm, constants.SHA256
 33        )
 34        source.save()
 35
 36
 37class Migration(migrations.Migration):
 38    replaces = [
 39        ("authentik_sources_saml", "0001_initial"),
 40        ("authentik_sources_saml", "0002_auto_20200523_2329"),
 41        ("authentik_sources_saml", "0003_auto_20200624_1957"),
 42        ("authentik_sources_saml", "0004_auto_20200708_1207"),
 43        ("authentik_sources_saml", "0005_samlsource_name_id_policy"),
 44        ("authentik_sources_saml", "0006_samlsource_allow_idp_initiated"),
 45        ("authentik_sources_saml", "0007_auto_20201112_1055"),
 46        ("authentik_sources_saml", "0008_auto_20201112_2016"),
 47        ("authentik_sources_saml", "0009_auto_20210301_0949"),
 48    ]
 49
 50    initial = True
 51
 52    dependencies = [
 53        ("authentik_core", "0001_initial"),
 54        ("authentik_crypto", "0002_create_self_signed_kp"),
 55        ("authentik_crypto", "0001_initial"),
 56    ]
 57
 58    operations = [
 59        migrations.CreateModel(
 60            name="SAMLSource",
 61            fields=[
 62                (
 63                    "source_ptr",
 64                    models.OneToOneField(
 65                        auto_created=True,
 66                        on_delete=django.db.models.deletion.CASCADE,
 67                        parent_link=True,
 68                        primary_key=True,
 69                        serialize=False,
 70                        to="authentik_core.source",
 71                    ),
 72                ),
 73                (
 74                    "issuer",
 75                    models.TextField(
 76                        blank=True,
 77                        default=None,
 78                        help_text="Also known as Entity ID. Defaults the Metadata URL.",
 79                        verbose_name="Issuer",
 80                    ),
 81                ),
 82                (
 83                    "sso_url",
 84                    models.URLField(
 85                        help_text="URL that the initial Login request is sent to.",
 86                        verbose_name="SSO URL",
 87                    ),
 88                ),
 89                (
 90                    "slo_url",
 91                    models.URLField(
 92                        blank=True,
 93                        default=None,
 94                        help_text="Optional URL if your IDP supports Single-Logout.",
 95                        null=True,
 96                        verbose_name="SLO URL",
 97                    ),
 98                ),
 99                (
100                    "signing_kp",
101                    models.ForeignKey(
102                        blank=True,
103                        default=None,
104                        help_text=(
105                            "Keypair which is used to sign outgoing requests. Leave empty to"
106                            " disable signing."
107                        ),
108                        null=True,
109                        on_delete=django.db.models.deletion.SET_DEFAULT,
110                        to="authentik_crypto.certificatekeypair",
111                        verbose_name="Signing Keypair",
112                    ),
113                ),
114                (
115                    "binding_type",
116                    models.CharField(
117                        choices=[
118                            ("REDIRECT", "Redirect Binding"),
119                            ("POST", "POST Binding"),
120                            ("POST_AUTO", "POST Binding with auto-confirmation"),
121                        ],
122                        default="REDIRECT",
123                        max_length=100,
124                    ),
125                ),
126                (
127                    "temporary_user_delete_after",
128                    models.TextField(
129                        default="days=1",
130                        help_text=(
131                            "Time offset when temporary users should be deleted. This only applies"
132                            " if your IDP uses the NameID Format 'transient', and the user doesn't"
133                            " log out manually. (Format: hours=1;minutes=2;seconds=3)."
134                        ),
135                        validators=[authentik.lib.utils.time.timedelta_string_validator],
136                        verbose_name="Delete temporary users after",
137                    ),
138                ),
139                (
140                    "name_id_policy",
141                    models.TextField(
142                        choices=[
143                            ("urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", "Email"),
144                            ("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", "Persistent"),
145                            ("urn:oasis:names:tc:SAML:2.0:nameid-format:X509SubjectName", "X509"),
146                            (
147                                "urn:oasis:names:tc:SAML:2.0:nameid-format:WindowsDomainQualifiedName",
148                                "Windows",
149                            ),
150                            ("urn:oasis:names:tc:SAML:2.0:nameid-format:transient", "Transient"),
151                        ],
152                        default="urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
153                        help_text=(
154                            "NameID Policy sent to the IdP. Can be unset, in which case no Policy"
155                            " is sent."
156                        ),
157                    ),
158                ),
159                (
160                    "allow_idp_initiated",
161                    models.BooleanField(
162                        default=False,
163                        help_text=(
164                            "Allows authentication flows initiated by the IdP. This can be a"
165                            " security risk, as no validation of the request ID is done."
166                        ),
167                    ),
168                ),
169                (
170                    "digest_algorithm",
171                    models.CharField(
172                        choices=[
173                            ("http://www.w3.org/2000/09/xmldsig#sha1", "SHA1"),
174                            ("http://www.w3.org/2001/04/xmlenc#sha256", "SHA256"),
175                            ("http://www.w3.org/2001/04/xmldsig-more#sha384", "SHA384"),
176                            ("http://www.w3.org/2001/04/xmlenc#sha512", "SHA512"),
177                        ],
178                        default="http://www.w3.org/2001/04/xmlenc#sha256",
179                        max_length=50,
180                    ),
181                ),
182                (
183                    "signature_algorithm",
184                    models.CharField(
185                        choices=[
186                            ("http://www.w3.org/2000/09/xmldsig#rsa-sha1", "RSA-SHA1"),
187                            ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", "RSA-SHA256"),
188                            ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha384", "RSA-SHA384"),
189                            ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha512", "RSA-SHA512"),
190                            ("http://www.w3.org/2000/09/xmldsig#dsa-sha1", "DSA-SHA1"),
191                        ],
192                        default="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256",
193                        max_length=50,
194                    ),
195                ),
196            ],
197            options={
198                "verbose_name": "SAML Source",
199                "verbose_name_plural": "SAML Sources",
200            },
201            bases=("authentik_core.source",),
202        ),
203        migrations.RunPython(
204            code=update_algorithms,
205        ),
206        migrations.AlterField(
207            model_name="samlsource",
208            name="name_id_policy",
209            field=models.TextField(
210                choices=[
211                    ("urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", "Email"),
212                    ("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", "Persistent"),
213                    ("urn:oasis:names:tc:SAML:2.0:nameid-format:X509SubjectName", "X509"),
214                    (
215                        "urn:oasis:names:tc:SAML:2.0:nameid-format:WindowsDomainQualifiedName",
216                        "Windows",
217                    ),
218                    ("urn:oasis:names:tc:SAML:2.0:nameid-format:transient", "Transient"),
219                ],
220                default="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent",
221                help_text=(
222                    "NameID Policy sent to the IdP. Can be unset, in which case no Policy is sent."
223                ),
224            ),
225        ),
226    ]
def update_algorithms( apps: django.apps.registry.Apps, schema_editor: django.db.backends.base.schema.BaseDatabaseSchemaEditor):
13def update_algorithms(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
14    db_alias = schema_editor.connection.alias
15
16    SAMLSource = apps.get_model("authentik_sources_saml", "SAMLSource")
17    signature_translation_map = {
18        "rsa-sha1": constants.RSA_SHA1,
19        "rsa-sha256": constants.RSA_SHA256,
20        "ecdsa-sha256": constants.RSA_SHA256,
21        "dsa-sha1": constants.DSA_SHA1,
22    }
23    digest_translation_map = {
24        "sha1": constants.SHA1,
25        "sha256": constants.SHA256,
26    }
27
28    for source in SAMLSource.objects.using(db_alias).all():
29        source.signature_algorithm = signature_translation_map.get(
30            source.signature_algorithm, constants.RSA_SHA256
31        )
32        source.digest_algorithm = digest_translation_map.get(
33            source.digest_algorithm, constants.SHA256
34        )
35        source.save()
class Migration(django.db.migrations.migration.Migration):
 38class Migration(migrations.Migration):
 39    replaces = [
 40        ("authentik_sources_saml", "0001_initial"),
 41        ("authentik_sources_saml", "0002_auto_20200523_2329"),
 42        ("authentik_sources_saml", "0003_auto_20200624_1957"),
 43        ("authentik_sources_saml", "0004_auto_20200708_1207"),
 44        ("authentik_sources_saml", "0005_samlsource_name_id_policy"),
 45        ("authentik_sources_saml", "0006_samlsource_allow_idp_initiated"),
 46        ("authentik_sources_saml", "0007_auto_20201112_1055"),
 47        ("authentik_sources_saml", "0008_auto_20201112_2016"),
 48        ("authentik_sources_saml", "0009_auto_20210301_0949"),
 49    ]
 50
 51    initial = True
 52
 53    dependencies = [
 54        ("authentik_core", "0001_initial"),
 55        ("authentik_crypto", "0002_create_self_signed_kp"),
 56        ("authentik_crypto", "0001_initial"),
 57    ]
 58
 59    operations = [
 60        migrations.CreateModel(
 61            name="SAMLSource",
 62            fields=[
 63                (
 64                    "source_ptr",
 65                    models.OneToOneField(
 66                        auto_created=True,
 67                        on_delete=django.db.models.deletion.CASCADE,
 68                        parent_link=True,
 69                        primary_key=True,
 70                        serialize=False,
 71                        to="authentik_core.source",
 72                    ),
 73                ),
 74                (
 75                    "issuer",
 76                    models.TextField(
 77                        blank=True,
 78                        default=None,
 79                        help_text="Also known as Entity ID. Defaults the Metadata URL.",
 80                        verbose_name="Issuer",
 81                    ),
 82                ),
 83                (
 84                    "sso_url",
 85                    models.URLField(
 86                        help_text="URL that the initial Login request is sent to.",
 87                        verbose_name="SSO URL",
 88                    ),
 89                ),
 90                (
 91                    "slo_url",
 92                    models.URLField(
 93                        blank=True,
 94                        default=None,
 95                        help_text="Optional URL if your IDP supports Single-Logout.",
 96                        null=True,
 97                        verbose_name="SLO URL",
 98                    ),
 99                ),
100                (
101                    "signing_kp",
102                    models.ForeignKey(
103                        blank=True,
104                        default=None,
105                        help_text=(
106                            "Keypair which is used to sign outgoing requests. Leave empty to"
107                            " disable signing."
108                        ),
109                        null=True,
110                        on_delete=django.db.models.deletion.SET_DEFAULT,
111                        to="authentik_crypto.certificatekeypair",
112                        verbose_name="Signing Keypair",
113                    ),
114                ),
115                (
116                    "binding_type",
117                    models.CharField(
118                        choices=[
119                            ("REDIRECT", "Redirect Binding"),
120                            ("POST", "POST Binding"),
121                            ("POST_AUTO", "POST Binding with auto-confirmation"),
122                        ],
123                        default="REDIRECT",
124                        max_length=100,
125                    ),
126                ),
127                (
128                    "temporary_user_delete_after",
129                    models.TextField(
130                        default="days=1",
131                        help_text=(
132                            "Time offset when temporary users should be deleted. This only applies"
133                            " if your IDP uses the NameID Format 'transient', and the user doesn't"
134                            " log out manually. (Format: hours=1;minutes=2;seconds=3)."
135                        ),
136                        validators=[authentik.lib.utils.time.timedelta_string_validator],
137                        verbose_name="Delete temporary users after",
138                    ),
139                ),
140                (
141                    "name_id_policy",
142                    models.TextField(
143                        choices=[
144                            ("urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", "Email"),
145                            ("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", "Persistent"),
146                            ("urn:oasis:names:tc:SAML:2.0:nameid-format:X509SubjectName", "X509"),
147                            (
148                                "urn:oasis:names:tc:SAML:2.0:nameid-format:WindowsDomainQualifiedName",
149                                "Windows",
150                            ),
151                            ("urn:oasis:names:tc:SAML:2.0:nameid-format:transient", "Transient"),
152                        ],
153                        default="urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
154                        help_text=(
155                            "NameID Policy sent to the IdP. Can be unset, in which case no Policy"
156                            " is sent."
157                        ),
158                    ),
159                ),
160                (
161                    "allow_idp_initiated",
162                    models.BooleanField(
163                        default=False,
164                        help_text=(
165                            "Allows authentication flows initiated by the IdP. This can be a"
166                            " security risk, as no validation of the request ID is done."
167                        ),
168                    ),
169                ),
170                (
171                    "digest_algorithm",
172                    models.CharField(
173                        choices=[
174                            ("http://www.w3.org/2000/09/xmldsig#sha1", "SHA1"),
175                            ("http://www.w3.org/2001/04/xmlenc#sha256", "SHA256"),
176                            ("http://www.w3.org/2001/04/xmldsig-more#sha384", "SHA384"),
177                            ("http://www.w3.org/2001/04/xmlenc#sha512", "SHA512"),
178                        ],
179                        default="http://www.w3.org/2001/04/xmlenc#sha256",
180                        max_length=50,
181                    ),
182                ),
183                (
184                    "signature_algorithm",
185                    models.CharField(
186                        choices=[
187                            ("http://www.w3.org/2000/09/xmldsig#rsa-sha1", "RSA-SHA1"),
188                            ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", "RSA-SHA256"),
189                            ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha384", "RSA-SHA384"),
190                            ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha512", "RSA-SHA512"),
191                            ("http://www.w3.org/2000/09/xmldsig#dsa-sha1", "DSA-SHA1"),
192                        ],
193                        default="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256",
194                        max_length=50,
195                    ),
196                ),
197            ],
198            options={
199                "verbose_name": "SAML Source",
200                "verbose_name_plural": "SAML Sources",
201            },
202            bases=("authentik_core.source",),
203        ),
204        migrations.RunPython(
205            code=update_algorithms,
206        ),
207        migrations.AlterField(
208            model_name="samlsource",
209            name="name_id_policy",
210            field=models.TextField(
211                choices=[
212                    ("urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", "Email"),
213                    ("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", "Persistent"),
214                    ("urn:oasis:names:tc:SAML:2.0:nameid-format:X509SubjectName", "X509"),
215                    (
216                        "urn:oasis:names:tc:SAML:2.0:nameid-format:WindowsDomainQualifiedName",
217                        "Windows",
218                    ),
219                    ("urn:oasis:names:tc:SAML:2.0:nameid-format:transient", "Transient"),
220                ],
221                default="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent",
222                help_text=(
223                    "NameID Policy sent to the IdP. Can be unset, in which case no Policy is sent."
224                ),
225            ),
226        ),
227    ]

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.

replaces = [('authentik_sources_saml', '0001_initial'), ('authentik_sources_saml', '0002_auto_20200523_2329'), ('authentik_sources_saml', '0003_auto_20200624_1957'), ('authentik_sources_saml', '0004_auto_20200708_1207'), ('authentik_sources_saml', '0005_samlsource_name_id_policy'), ('authentik_sources_saml', '0006_samlsource_allow_idp_initiated'), ('authentik_sources_saml', '0007_auto_20201112_1055'), ('authentik_sources_saml', '0008_auto_20201112_2016'), ('authentik_sources_saml', '0009_auto_20210301_0949')]
initial = True
dependencies = [('authentik_core', '0001_initial'), ('authentik_crypto', '0002_create_self_signed_kp'), ('authentik_crypto', '0001_initial')]
operations = [<CreateModel name='SAMLSource', fields=[('source_ptr', <django.db.models.fields.related.OneToOneField>), ('issuer', <django.db.models.fields.TextField>), ('sso_url', <django.db.models.fields.URLField>), ('slo_url', <django.db.models.fields.URLField>), ('signing_kp', <django.db.models.fields.related.ForeignKey>), ('binding_type', <django.db.models.fields.CharField>), ('temporary_user_delete_after', <django.db.models.fields.TextField>), ('name_id_policy', <django.db.models.fields.TextField>), ('allow_idp_initiated', <django.db.models.fields.BooleanField>), ('digest_algorithm', <django.db.models.fields.CharField>), ('signature_algorithm', <django.db.models.fields.CharField>)], options={'verbose_name': 'SAML Source', 'verbose_name_plural': 'SAML Sources'}, bases=('authentik_core.source',)>, <RunPython code=<function update_algorithms>>, <AlterField model_name='samlsource', name='name_id_policy', field=<django.db.models.fields.TextField>>]