# Generated by Django 3.2.8 on 2021-10-11 15:55

import django.db.models.deletion
from django.apps.registry import Apps
from django.db import migrations, models
from django.db.backends.base.schema import BaseDatabaseSchemaEditor

import authentik.lib.utils.time
from authentik.sources.saml.processors import constants


def update_algorithms(apps: Apps, schema_editor: BaseDatabaseSchemaEditor):
    db_alias = schema_editor.connection.alias

    SAMLSource = apps.get_model("authentik_sources_saml", "SAMLSource")
    signature_translation_map = {
        "rsa-sha1": constants.RSA_SHA1,
        "rsa-sha256": constants.RSA_SHA256,
        "ecdsa-sha256": constants.RSA_SHA256,
        "dsa-sha1": constants.DSA_SHA1,
    }
    digest_translation_map = {
        "sha1": constants.SHA1,
        "sha256": constants.SHA256,
    }

    for source in SAMLSource.objects.using(db_alias).all():
        source.signature_algorithm = signature_translation_map.get(
            source.signature_algorithm, constants.RSA_SHA256
        )
        source.digest_algorithm = digest_translation_map.get(
            source.digest_algorithm, constants.SHA256
        )
        source.save()


class Migration(migrations.Migration):
    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 = [
        migrations.CreateModel(
            name="SAMLSource",
            fields=[
                (
                    "source_ptr",
                    models.OneToOneField(
                        auto_created=True,
                        on_delete=django.db.models.deletion.CASCADE,
                        parent_link=True,
                        primary_key=True,
                        serialize=False,
                        to="authentik_core.source",
                    ),
                ),
                (
                    "issuer",
                    models.TextField(
                        blank=True,
                        default=None,
                        help_text="Also known as Entity ID. Defaults the Metadata URL.",
                        verbose_name="Issuer",
                    ),
                ),
                (
                    "sso_url",
                    models.URLField(
                        help_text="URL that the initial Login request is sent to.",
                        verbose_name="SSO URL",
                    ),
                ),
                (
                    "slo_url",
                    models.URLField(
                        blank=True,
                        default=None,
                        help_text="Optional URL if your IDP supports Single-Logout.",
                        null=True,
                        verbose_name="SLO URL",
                    ),
                ),
                (
                    "signing_kp",
                    models.ForeignKey(
                        blank=True,
                        default=None,
                        help_text=(
                            "Keypair which is used to sign outgoing requests. Leave empty to"
                            " disable signing."
                        ),
                        null=True,
                        on_delete=django.db.models.deletion.SET_DEFAULT,
                        to="authentik_crypto.certificatekeypair",
                        verbose_name="Signing Keypair",
                    ),
                ),
                (
                    "binding_type",
                    models.CharField(
                        choices=[
                            ("REDIRECT", "Redirect Binding"),
                            ("POST", "POST Binding"),
                            ("POST_AUTO", "POST Binding with auto-confirmation"),
                        ],
                        default="REDIRECT",
                        max_length=100,
                    ),
                ),
                (
                    "temporary_user_delete_after",
                    models.TextField(
                        default="days=1",
                        help_text=(
                            "Time offset when temporary users should be deleted. This only applies"
                            " if your IDP uses the NameID Format 'transient', and the user doesn't"
                            " log out manually. (Format: hours=1;minutes=2;seconds=3)."
                        ),
                        validators=[authentik.lib.utils.time.timedelta_string_validator],
                        verbose_name="Delete temporary users after",
                    ),
                ),
                (
                    "name_id_policy",
                    models.TextField(
                        choices=[
                            ("urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", "Email"),
                            ("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", "Persistent"),
                            ("urn:oasis:names:tc:SAML:2.0:nameid-format:X509SubjectName", "X509"),
                            (
                                "urn:oasis:names:tc:SAML:2.0:nameid-format:WindowsDomainQualifiedName",
                                "Windows",
                            ),
                            ("urn:oasis:names:tc:SAML:2.0:nameid-format:transient", "Transient"),
                        ],
                        default="urn:oasis:names:tc:SAML:2.0:nameid-format:transient",
                        help_text=(
                            "NameID Policy sent to the IdP. Can be unset, in which case no Policy"
                            " is sent."
                        ),
                    ),
                ),
                (
                    "allow_idp_initiated",
                    models.BooleanField(
                        default=False,
                        help_text=(
                            "Allows authentication flows initiated by the IdP. This can be a"
                            " security risk, as no validation of the request ID is done."
                        ),
                    ),
                ),
                (
                    "digest_algorithm",
                    models.CharField(
                        choices=[
                            ("http://www.w3.org/2000/09/xmldsig#sha1", "SHA1"),
                            ("http://www.w3.org/2001/04/xmlenc#sha256", "SHA256"),
                            ("http://www.w3.org/2001/04/xmldsig-more#sha384", "SHA384"),
                            ("http://www.w3.org/2001/04/xmlenc#sha512", "SHA512"),
                        ],
                        default="http://www.w3.org/2001/04/xmlenc#sha256",
                        max_length=50,
                    ),
                ),
                (
                    "signature_algorithm",
                    models.CharField(
                        choices=[
                            ("http://www.w3.org/2000/09/xmldsig#rsa-sha1", "RSA-SHA1"),
                            ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha256", "RSA-SHA256"),
                            ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha384", "RSA-SHA384"),
                            ("http://www.w3.org/2001/04/xmldsig-more#rsa-sha512", "RSA-SHA512"),
                            ("http://www.w3.org/2000/09/xmldsig#dsa-sha1", "DSA-SHA1"),
                        ],
                        default="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256",
                        max_length=50,
                    ),
                ),
            ],
            options={
                "verbose_name": "SAML Source",
                "verbose_name_plural": "SAML Sources",
            },
            bases=("authentik_core.source",),
        ),
        migrations.RunPython(
            code=update_algorithms,
        ),
        migrations.AlterField(
            model_name="samlsource",
            name="name_id_policy",
            field=models.TextField(
                choices=[
                    ("urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress", "Email"),
                    ("urn:oasis:names:tc:SAML:2.0:nameid-format:persistent", "Persistent"),
                    ("urn:oasis:names:tc:SAML:2.0:nameid-format:X509SubjectName", "X509"),
                    (
                        "urn:oasis:names:tc:SAML:2.0:nameid-format:WindowsDomainQualifiedName",
                        "Windows",
                    ),
                    ("urn:oasis:names:tc:SAML:2.0:nameid-format:transient", "Transient"),
                ],
                default="urn:oasis:names:tc:SAML:2.0:nameid-format:persistent",
                help_text=(
                    "NameID Policy sent to the IdP. Can be unset, in which case no Policy is sent."
                ),
            ),
        ),
    ]
