migrate to per-model UUID Primary key, remove UUIDModel (#26)
* *: migrate to per-model UUID Primary key, remove UUIDModel * *: fix import order, fix unittests
This commit is contained in:
		@ -166,7 +166,7 @@ urlpatterns = [
 | 
			
		||||
        stages_prompts.PromptDeleteView.as_view(),
 | 
			
		||||
        name="stage-prompt-delete",
 | 
			
		||||
    ),
 | 
			
		||||
    # Invitations
 | 
			
		||||
    # Stage Invitations
 | 
			
		||||
    path(
 | 
			
		||||
        "stages/invitations/",
 | 
			
		||||
        stages_invitations.InvitationListView.as_view(),
 | 
			
		||||
 | 
			
		||||
@ -38,7 +38,7 @@ class PolicyBindingCreateView(
 | 
			
		||||
    form_class = PolicyBindingForm
 | 
			
		||||
 | 
			
		||||
    template_name = "generic/create.html"
 | 
			
		||||
    success_url = reverse_lazy("passbook_admin:policies")
 | 
			
		||||
    success_url = reverse_lazy("passbook_admin:policies-bindings")
 | 
			
		||||
    success_message = _("Successfully created PolicyBinding")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -52,7 +52,7 @@ class PolicyBindingUpdateView(
 | 
			
		||||
    form_class = PolicyBindingForm
 | 
			
		||||
 | 
			
		||||
    template_name = "generic/update.html"
 | 
			
		||||
    success_url = reverse_lazy("passbook_admin:policies")
 | 
			
		||||
    success_url = reverse_lazy("passbook_admin:policies-bindings")
 | 
			
		||||
    success_message = _("Successfully updated PolicyBinding")
 | 
			
		||||
 | 
			
		||||
    def get_context_data(self, **kwargs):
 | 
			
		||||
@ -72,7 +72,7 @@ class PolicyBindingDeleteView(
 | 
			
		||||
    permission_required = "passbook_policies.delete_policybinding"
 | 
			
		||||
 | 
			
		||||
    template_name = "generic/delete.html"
 | 
			
		||||
    success_url = reverse_lazy("passbook_admin:policies")
 | 
			
		||||
    success_url = reverse_lazy("passbook_admin:policies-bindings")
 | 
			
		||||
    success_message = _("Successfully deleted PolicyBinding")
 | 
			
		||||
 | 
			
		||||
    def delete(self, request, *args, **kwargs):
 | 
			
		||||
 | 
			
		||||
@ -38,7 +38,7 @@ class StageBindingCreateView(
 | 
			
		||||
    form_class = FlowStageBindingForm
 | 
			
		||||
 | 
			
		||||
    template_name = "generic/create.html"
 | 
			
		||||
    success_url = reverse_lazy("passbook_admin:flows")
 | 
			
		||||
    success_url = reverse_lazy("passbook_admin:stage-bindings")
 | 
			
		||||
    success_message = _("Successfully created StageBinding")
 | 
			
		||||
 | 
			
		||||
    def get_context_data(self, **kwargs):
 | 
			
		||||
@ -59,7 +59,7 @@ class StageBindingUpdateView(
 | 
			
		||||
    form_class = FlowStageBindingForm
 | 
			
		||||
 | 
			
		||||
    template_name = "generic/update.html"
 | 
			
		||||
    success_url = reverse_lazy("passbook_admin:flows")
 | 
			
		||||
    success_url = reverse_lazy("passbook_admin:stage-bindings")
 | 
			
		||||
    success_message = _("Successfully updated StageBinding")
 | 
			
		||||
 | 
			
		||||
    def get_context_data(self, **kwargs):
 | 
			
		||||
@ -79,7 +79,7 @@ class StageBindingDeleteView(
 | 
			
		||||
    permission_required = "passbook_flows.delete_flowstagebinding"
 | 
			
		||||
 | 
			
		||||
    template_name = "generic/delete.html"
 | 
			
		||||
    success_url = reverse_lazy("passbook_admin:flows")
 | 
			
		||||
    success_url = reverse_lazy("passbook_admin:stage-bindings")
 | 
			
		||||
    success_message = _("Successfully deleted FlowStageBinding")
 | 
			
		||||
 | 
			
		||||
    def delete(self, request, *args, **kwargs):
 | 
			
		||||
 | 
			
		||||
@ -40,7 +40,7 @@ class InvitationCreateView(
 | 
			
		||||
    permission_required = "passbook_stages_invitation.add_invitation"
 | 
			
		||||
 | 
			
		||||
    template_name = "generic/create.html"
 | 
			
		||||
    success_url = reverse_lazy("passbook_admin:invitations")
 | 
			
		||||
    success_url = reverse_lazy("passbook_admin:stage-invitations")
 | 
			
		||||
    success_message = _("Successfully created Invitation")
 | 
			
		||||
 | 
			
		||||
    def get_context_data(self, **kwargs):
 | 
			
		||||
@ -64,7 +64,7 @@ class InvitationDeleteView(
 | 
			
		||||
    permission_required = "passbook_stages_invitation.delete_invitation"
 | 
			
		||||
 | 
			
		||||
    template_name = "generic/delete.html"
 | 
			
		||||
    success_url = reverse_lazy("passbook_admin:invitations")
 | 
			
		||||
    success_url = reverse_lazy("passbook_admin:stage-invitations")
 | 
			
		||||
    success_message = _("Successfully deleted Invitation")
 | 
			
		||||
 | 
			
		||||
    def delete(self, request, *args, **kwargs):
 | 
			
		||||
 | 
			
		||||
@ -38,7 +38,7 @@ class PromptCreateView(
 | 
			
		||||
    permission_required = "passbook_stages_prompt.add_prompt"
 | 
			
		||||
 | 
			
		||||
    template_name = "generic/create.html"
 | 
			
		||||
    success_url = reverse_lazy("passbook_admin:prompts")
 | 
			
		||||
    success_url = reverse_lazy("passbook_admin:stage-prompts")
 | 
			
		||||
    success_message = _("Successfully created Prompt")
 | 
			
		||||
 | 
			
		||||
    def get_context_data(self, **kwargs):
 | 
			
		||||
@ -56,7 +56,7 @@ class PromptUpdateView(
 | 
			
		||||
    permission_required = "passbook_stages_prompt.change_prompt"
 | 
			
		||||
 | 
			
		||||
    template_name = "generic/update.html"
 | 
			
		||||
    success_url = reverse_lazy("passbook_admin:prompts")
 | 
			
		||||
    success_url = reverse_lazy("passbook_admin:stage-prompts")
 | 
			
		||||
    success_message = _("Successfully updated Prompt")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -69,7 +69,7 @@ class PromptDeleteView(
 | 
			
		||||
    permission_required = "passbook_stages_prompt.delete_prompt"
 | 
			
		||||
 | 
			
		||||
    template_name = "generic/delete.html"
 | 
			
		||||
    success_url = reverse_lazy("passbook_admin:prompts")
 | 
			
		||||
    success_url = reverse_lazy("passbook_admin:stage-prompts")
 | 
			
		||||
    success_message = _("Successfully deleted Prompt")
 | 
			
		||||
 | 
			
		||||
    def delete(self, request, *args, **kwargs):
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Generated by Django 2.2.6 on 2019-10-07 14:07
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:08
 | 
			
		||||
 | 
			
		||||
import uuid
 | 
			
		||||
 | 
			
		||||
@ -18,10 +18,10 @@ class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name="AuditEntry",
 | 
			
		||||
            name="Event",
 | 
			
		||||
            fields=[
 | 
			
		||||
                (
 | 
			
		||||
                    "uuid",
 | 
			
		||||
                    "event_uuid",
 | 
			
		||||
                    models.UUIDField(
 | 
			
		||||
                        default=uuid.uuid4,
 | 
			
		||||
                        editable=False,
 | 
			
		||||
@ -33,15 +33,16 @@ class Migration(migrations.Migration):
 | 
			
		||||
                    "action",
 | 
			
		||||
                    models.TextField(
 | 
			
		||||
                        choices=[
 | 
			
		||||
                            ("login", "login"),
 | 
			
		||||
                            ("login_failed", "login_failed"),
 | 
			
		||||
                            ("logout", "logout"),
 | 
			
		||||
                            ("authorize_application", "authorize_application"),
 | 
			
		||||
                            ("suspicious_request", "suspicious_request"),
 | 
			
		||||
                            ("sign_up", "sign_up"),
 | 
			
		||||
                            ("password_reset", "password_reset"),
 | 
			
		||||
                            ("invitation_created", "invitation_created"),
 | 
			
		||||
                            ("invitation_used", "invitation_used"),
 | 
			
		||||
                            ("LOGIN", "login"),
 | 
			
		||||
                            ("LOGIN_FAILED", "login_failed"),
 | 
			
		||||
                            ("LOGOUT", "logout"),
 | 
			
		||||
                            ("AUTHORIZE_APPLICATION", "authorize_application"),
 | 
			
		||||
                            ("SUSPICIOUS_REQUEST", "suspicious_request"),
 | 
			
		||||
                            ("SIGN_UP", "sign_up"),
 | 
			
		||||
                            ("PASSWORD_RESET", "password_reset"),
 | 
			
		||||
                            ("INVITE_CREATED", "invitation_created"),
 | 
			
		||||
                            ("INVITE_USED", "invitation_used"),
 | 
			
		||||
                            ("CUSTOM", "custom"),
 | 
			
		||||
                        ]
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
@ -53,7 +54,7 @@ class Migration(migrations.Migration):
 | 
			
		||||
                        blank=True, default=dict
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("request_ip", models.GenericIPAddressField()),
 | 
			
		||||
                ("client_ip", models.GenericIPAddressField(null=True)),
 | 
			
		||||
                ("created", models.DateTimeField(auto_now_add=True)),
 | 
			
		||||
                (
 | 
			
		||||
                    "user",
 | 
			
		||||
@ -65,8 +66,8 @@ class Migration(migrations.Migration):
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
            options={
 | 
			
		||||
                "verbose_name": "Audit Entry",
 | 
			
		||||
                "verbose_name_plural": "Audit Entries",
 | 
			
		||||
                "verbose_name": "Audit Event",
 | 
			
		||||
                "verbose_name_plural": "Audit Events",
 | 
			
		||||
            },
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
@ -1,16 +0,0 @@
 | 
			
		||||
# Generated by Django 2.2.6 on 2019-10-28 08:29
 | 
			
		||||
 | 
			
		||||
from django.conf import settings
 | 
			
		||||
from django.db import migrations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
 | 
			
		||||
        ("passbook_audit", "0001_initial"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.RenameModel(old_name="AuditEntry", new_name="Event",),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,40 +0,0 @@
 | 
			
		||||
# Generated by Django 2.2.8 on 2019-12-05 14:07
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
import passbook.audit.models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_audit", "0002_auto_20191028_0829"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AlterModelOptions(
 | 
			
		||||
            name="event",
 | 
			
		||||
            options={
 | 
			
		||||
                "verbose_name": "Audit Event",
 | 
			
		||||
                "verbose_name_plural": "Audit Events",
 | 
			
		||||
            },
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="event",
 | 
			
		||||
            name="action",
 | 
			
		||||
            field=models.TextField(
 | 
			
		||||
                choices=[
 | 
			
		||||
                    ("LOGIN", "login"),
 | 
			
		||||
                    ("LOGIN_FAILED", "login_failed"),
 | 
			
		||||
                    ("LOGOUT", "logout"),
 | 
			
		||||
                    ("AUTHORIZE_APPLICATION", "authorize_application"),
 | 
			
		||||
                    ("SUSPICIOUS_REQUEST", "suspicious_request"),
 | 
			
		||||
                    ("SIGN_UP", "sign_up"),
 | 
			
		||||
                    ("PASSWORD_RESET", "password_reset"),
 | 
			
		||||
                    ("INVITE_CREATED", "invitation_created"),
 | 
			
		||||
                    ("INVITE_USED", "invitation_used"),
 | 
			
		||||
                    ("CUSTOM", "custom"),
 | 
			
		||||
                ]
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,19 +0,0 @@
 | 
			
		||||
# Generated by Django 2.2.8 on 2019-12-05 15:02
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_audit", "0003_auto_20191205_1407"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.RemoveField(model_name="event", name="request_ip",),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="event",
 | 
			
		||||
            name="client_ip",
 | 
			
		||||
            field=models.GenericIPAddressField(null=True),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -2,7 +2,7 @@
 | 
			
		||||
from enum import Enum
 | 
			
		||||
from inspect import getmodule, stack
 | 
			
		||||
from typing import Any, Dict, Optional
 | 
			
		||||
from uuid import UUID
 | 
			
		||||
from uuid import UUID, uuid4
 | 
			
		||||
 | 
			
		||||
from django.conf import settings
 | 
			
		||||
from django.contrib.auth.models import AnonymousUser
 | 
			
		||||
@ -15,7 +15,6 @@ from django.utils.translation import gettext as _
 | 
			
		||||
from guardian.shortcuts import get_anonymous_user
 | 
			
		||||
from structlog import get_logger
 | 
			
		||||
 | 
			
		||||
from passbook.lib.models import UUIDModel
 | 
			
		||||
from passbook.lib.utils.http import get_client_ip
 | 
			
		||||
 | 
			
		||||
LOGGER = get_logger()
 | 
			
		||||
@ -71,9 +70,10 @@ class EventAction(Enum):
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Event(UUIDModel):
 | 
			
		||||
class Event(models.Model):
 | 
			
		||||
    """An individual audit log event"""
 | 
			
		||||
 | 
			
		||||
    event_uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4)
 | 
			
		||||
    user = models.ForeignKey(
 | 
			
		||||
        settings.AUTH_USER_MODEL, null=True, on_delete=models.SET_NULL
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Generated by Django 2.2.6 on 2019-10-07 14:06
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:07
 | 
			
		||||
 | 
			
		||||
import uuid
 | 
			
		||||
 | 
			
		||||
@ -7,6 +7,7 @@ import django.contrib.auth.validators
 | 
			
		||||
import django.contrib.postgres.fields.jsonb
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
import django.utils.timezone
 | 
			
		||||
import guardian.mixins
 | 
			
		||||
from django.conf import settings
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
@ -18,8 +19,8 @@ class Migration(migrations.Migration):
 | 
			
		||||
    initial = True
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("auth", "0011_update_proxy_permissions"),
 | 
			
		||||
        ("passbook_policies", "0001_initial"),
 | 
			
		||||
        ("auth", "0011_update_proxy_permissions"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
@ -106,69 +107,24 @@ class Migration(migrations.Migration):
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("uuid", models.UUIDField(default=uuid.uuid4, editable=False)),
 | 
			
		||||
                ("name", models.TextField()),
 | 
			
		||||
                ("name", models.TextField(help_text="User's display name.")),
 | 
			
		||||
                ("password_change_date", models.DateTimeField(auto_now_add=True)),
 | 
			
		||||
                (
 | 
			
		||||
                    "attributes",
 | 
			
		||||
                    django.contrib.postgres.fields.jsonb.JSONField(
 | 
			
		||||
                        blank=True, default=dict
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
            options={
 | 
			
		||||
                "verbose_name": "user",
 | 
			
		||||
                "verbose_name_plural": "users",
 | 
			
		||||
                "abstract": False,
 | 
			
		||||
            },
 | 
			
		||||
            options={"permissions": (("reset_user_password", "Reset Password"),),},
 | 
			
		||||
            bases=(guardian.mixins.GuardianUserMixin, models.Model),
 | 
			
		||||
            managers=[("objects", django.contrib.auth.models.UserManager()),],
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name="Policy",
 | 
			
		||||
            fields=[
 | 
			
		||||
                ("created", models.DateTimeField(auto_now_add=True)),
 | 
			
		||||
                ("last_updated", models.DateTimeField(auto_now=True)),
 | 
			
		||||
                (
 | 
			
		||||
                    "uuid",
 | 
			
		||||
                    models.UUIDField(
 | 
			
		||||
                        default=uuid.uuid4,
 | 
			
		||||
                        editable=False,
 | 
			
		||||
                        primary_key=True,
 | 
			
		||||
                        serialize=False,
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("name", models.TextField(blank=True, null=True)),
 | 
			
		||||
                (
 | 
			
		||||
                    "action",
 | 
			
		||||
                    models.CharField(
 | 
			
		||||
                        choices=[("allow", "allow"), ("deny", "deny")], max_length=20
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("negate", models.BooleanField(default=False)),
 | 
			
		||||
                ("order", models.IntegerField(default=0)),
 | 
			
		||||
                ("timeout", models.IntegerField(default=30)),
 | 
			
		||||
            ],
 | 
			
		||||
            options={"abstract": False,},
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name="PolicyModel",
 | 
			
		||||
            fields=[
 | 
			
		||||
                ("created", models.DateTimeField(auto_now_add=True)),
 | 
			
		||||
                ("last_updated", models.DateTimeField(auto_now=True)),
 | 
			
		||||
                (
 | 
			
		||||
                    "uuid",
 | 
			
		||||
                    models.UUIDField(
 | 
			
		||||
                        default=uuid.uuid4,
 | 
			
		||||
                        editable=False,
 | 
			
		||||
                        primary_key=True,
 | 
			
		||||
                        serialize=False,
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "policies",
 | 
			
		||||
                    models.ManyToManyField(blank=True, to="passbook_policies.Policy"),
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
            options={"abstract": False,},
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name="PropertyMapping",
 | 
			
		||||
            fields=[
 | 
			
		||||
                (
 | 
			
		||||
                    "uuid",
 | 
			
		||||
                    "pm_uuid",
 | 
			
		||||
                    models.UUIDField(
 | 
			
		||||
                        default=uuid.uuid4,
 | 
			
		||||
                        editable=False,
 | 
			
		||||
@ -177,39 +133,18 @@ class Migration(migrations.Migration):
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("name", models.TextField()),
 | 
			
		||||
                ("expression", models.TextField()),
 | 
			
		||||
            ],
 | 
			
		||||
            options={
 | 
			
		||||
                "verbose_name": "Property Mapping",
 | 
			
		||||
                "verbose_name_plural": "Property Mappings",
 | 
			
		||||
            },
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name="Factor",
 | 
			
		||||
            fields=[
 | 
			
		||||
                (
 | 
			
		||||
                    "policymodel_ptr",
 | 
			
		||||
                    models.OneToOneField(
 | 
			
		||||
                        auto_created=True,
 | 
			
		||||
                        on_delete=django.db.models.deletion.CASCADE,
 | 
			
		||||
                        parent_link=True,
 | 
			
		||||
                        primary_key=True,
 | 
			
		||||
                        serialize=False,
 | 
			
		||||
                        to="passbook_policies.PolicyBindingModel",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("name", models.TextField()),
 | 
			
		||||
                ("slug", models.SlugField(unique=True)),
 | 
			
		||||
                ("order", models.IntegerField()),
 | 
			
		||||
                ("enabled", models.BooleanField(default=True)),
 | 
			
		||||
            ],
 | 
			
		||||
            options={"abstract": False,},
 | 
			
		||||
            bases=("passbook_policies.policybindingmodel",),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name="Source",
 | 
			
		||||
            fields=[
 | 
			
		||||
                (
 | 
			
		||||
                    "policymodel_ptr",
 | 
			
		||||
                    "policybindingmodel_ptr",
 | 
			
		||||
                    models.OneToOneField(
 | 
			
		||||
                        auto_created=True,
 | 
			
		||||
                        on_delete=django.db.models.deletion.CASCADE,
 | 
			
		||||
@ -219,13 +154,83 @@ class Migration(migrations.Migration):
 | 
			
		||||
                        to="passbook_policies.PolicyBindingModel",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("name", models.TextField()),
 | 
			
		||||
                ("slug", models.SlugField()),
 | 
			
		||||
                ("name", models.TextField(help_text="Source's display Name.")),
 | 
			
		||||
                (
 | 
			
		||||
                    "slug",
 | 
			
		||||
                    models.SlugField(help_text="Internal source name, used in URLs."),
 | 
			
		||||
                ),
 | 
			
		||||
                ("enabled", models.BooleanField(default=True)),
 | 
			
		||||
                (
 | 
			
		||||
                    "property_mappings",
 | 
			
		||||
                    models.ManyToManyField(
 | 
			
		||||
                        blank=True, default=None, to="passbook_core.PropertyMapping"
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
            options={"abstract": False,},
 | 
			
		||||
            bases=("passbook_policies.policybindingmodel",),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name="UserSourceConnection",
 | 
			
		||||
            fields=[
 | 
			
		||||
                (
 | 
			
		||||
                    "id",
 | 
			
		||||
                    models.AutoField(
 | 
			
		||||
                        auto_created=True,
 | 
			
		||||
                        primary_key=True,
 | 
			
		||||
                        serialize=False,
 | 
			
		||||
                        verbose_name="ID",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("created", models.DateTimeField(auto_now_add=True)),
 | 
			
		||||
                ("last_updated", models.DateTimeField(auto_now=True)),
 | 
			
		||||
                (
 | 
			
		||||
                    "source",
 | 
			
		||||
                    models.ForeignKey(
 | 
			
		||||
                        on_delete=django.db.models.deletion.CASCADE,
 | 
			
		||||
                        to="passbook_core.Source",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "user",
 | 
			
		||||
                    models.ForeignKey(
 | 
			
		||||
                        on_delete=django.db.models.deletion.CASCADE,
 | 
			
		||||
                        to=settings.AUTH_USER_MODEL,
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
            options={"unique_together": {("user", "source")},},
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name="Token",
 | 
			
		||||
            fields=[
 | 
			
		||||
                (
 | 
			
		||||
                    "token_uuid",
 | 
			
		||||
                    models.UUIDField(
 | 
			
		||||
                        default=uuid.uuid4,
 | 
			
		||||
                        editable=False,
 | 
			
		||||
                        primary_key=True,
 | 
			
		||||
                        serialize=False,
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "expires",
 | 
			
		||||
                    models.DateTimeField(
 | 
			
		||||
                        default=passbook.core.models.default_token_duration
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("expiring", models.BooleanField(default=True)),
 | 
			
		||||
                ("description", models.TextField(blank=True, default="")),
 | 
			
		||||
                (
 | 
			
		||||
                    "user",
 | 
			
		||||
                    models.ForeignKey(
 | 
			
		||||
                        on_delete=django.db.models.deletion.CASCADE,
 | 
			
		||||
                        related_name="+",
 | 
			
		||||
                        to=settings.AUTH_USER_MODEL,
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
            options={"verbose_name": "Token", "verbose_name_plural": "Tokens",},
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name="Provider",
 | 
			
		||||
            fields=[
 | 
			
		||||
@ -246,69 +251,11 @@ class Migration(migrations.Migration):
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name="Nonce",
 | 
			
		||||
            fields=[
 | 
			
		||||
                (
 | 
			
		||||
                    "uuid",
 | 
			
		||||
                    models.UUIDField(
 | 
			
		||||
                        default=uuid.uuid4,
 | 
			
		||||
                        editable=False,
 | 
			
		||||
                        primary_key=True,
 | 
			
		||||
                        serialize=False,
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "expires",
 | 
			
		||||
                    models.DateTimeField(
 | 
			
		||||
                        default=passbook.core.models.default_token_duration
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("expiring", models.BooleanField(default=True)),
 | 
			
		||||
                (
 | 
			
		||||
                    "user",
 | 
			
		||||
                    models.ForeignKey(
 | 
			
		||||
                        on_delete=django.db.models.deletion.CASCADE,
 | 
			
		||||
                        to=settings.AUTH_USER_MODEL,
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
            options={"verbose_name": "Nonce", "verbose_name_plural": "Nonces",},
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name="Invitation",
 | 
			
		||||
            fields=[
 | 
			
		||||
                (
 | 
			
		||||
                    "uuid",
 | 
			
		||||
                    models.UUIDField(
 | 
			
		||||
                        default=uuid.uuid4,
 | 
			
		||||
                        editable=False,
 | 
			
		||||
                        primary_key=True,
 | 
			
		||||
                        serialize=False,
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("expires", models.DateTimeField(blank=True, default=None, null=True)),
 | 
			
		||||
                ("fixed_username", models.TextField(blank=True, default=None)),
 | 
			
		||||
                ("fixed_email", models.TextField(blank=True, default=None)),
 | 
			
		||||
                ("needs_confirmation", models.BooleanField(default=True)),
 | 
			
		||||
                (
 | 
			
		||||
                    "created_by",
 | 
			
		||||
                    models.ForeignKey(
 | 
			
		||||
                        on_delete=django.db.models.deletion.CASCADE,
 | 
			
		||||
                        to=settings.AUTH_USER_MODEL,
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
            options={
 | 
			
		||||
                "verbose_name": "Invitation",
 | 
			
		||||
                "verbose_name_plural": "Invitations",
 | 
			
		||||
            },
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name="Group",
 | 
			
		||||
            fields=[
 | 
			
		||||
                (
 | 
			
		||||
                    "uuid",
 | 
			
		||||
                    "group_uuid",
 | 
			
		||||
                    models.UUIDField(
 | 
			
		||||
                        default=uuid.uuid4,
 | 
			
		||||
                        editable=False,
 | 
			
		||||
@ -318,7 +265,7 @@ class Migration(migrations.Migration):
 | 
			
		||||
                ),
 | 
			
		||||
                ("name", models.CharField(max_length=80, verbose_name="name")),
 | 
			
		||||
                (
 | 
			
		||||
                    "tags",
 | 
			
		||||
                    "attributes",
 | 
			
		||||
                    django.contrib.postgres.fields.jsonb.JSONField(
 | 
			
		||||
                        blank=True, default=dict
 | 
			
		||||
                    ),
 | 
			
		||||
@ -336,11 +283,57 @@ class Migration(migrations.Migration):
 | 
			
		||||
            ],
 | 
			
		||||
            options={"unique_together": {("name", "parent")},},
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name="Application",
 | 
			
		||||
            fields=[
 | 
			
		||||
                (
 | 
			
		||||
                    "policybindingmodel_ptr",
 | 
			
		||||
                    models.OneToOneField(
 | 
			
		||||
                        auto_created=True,
 | 
			
		||||
                        on_delete=django.db.models.deletion.CASCADE,
 | 
			
		||||
                        parent_link=True,
 | 
			
		||||
                        primary_key=True,
 | 
			
		||||
                        serialize=False,
 | 
			
		||||
                        to="passbook_policies.PolicyBindingModel",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("name", models.TextField(help_text="Application's display Name.")),
 | 
			
		||||
                (
 | 
			
		||||
                    "slug",
 | 
			
		||||
                    models.SlugField(
 | 
			
		||||
                        help_text="Internal application name, used in URLs."
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("skip_authorization", models.BooleanField(default=False)),
 | 
			
		||||
                ("meta_launch_url", models.URLField(blank=True, default="")),
 | 
			
		||||
                ("meta_icon_url", models.TextField(blank=True, default="")),
 | 
			
		||||
                ("meta_description", models.TextField(blank=True, default="")),
 | 
			
		||||
                ("meta_publisher", models.TextField(blank=True, default="")),
 | 
			
		||||
                (
 | 
			
		||||
                    "provider",
 | 
			
		||||
                    models.OneToOneField(
 | 
			
		||||
                        blank=True,
 | 
			
		||||
                        default=None,
 | 
			
		||||
                        null=True,
 | 
			
		||||
                        on_delete=django.db.models.deletion.SET_DEFAULT,
 | 
			
		||||
                        to="passbook_core.Provider",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
            bases=("passbook_policies.policybindingmodel",),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="user",
 | 
			
		||||
            name="groups",
 | 
			
		||||
            field=models.ManyToManyField(to="passbook_core.Group"),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="user",
 | 
			
		||||
            name="sources",
 | 
			
		||||
            field=models.ManyToManyField(
 | 
			
		||||
                through="passbook_core.UserSourceConnection", to="passbook_core.Source"
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="user",
 | 
			
		||||
            name="user_permissions",
 | 
			
		||||
@ -353,75 +346,4 @@ class Migration(migrations.Migration):
 | 
			
		||||
                verbose_name="user permissions",
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name="UserSourceConnection",
 | 
			
		||||
            fields=[
 | 
			
		||||
                (
 | 
			
		||||
                    "id",
 | 
			
		||||
                    models.AutoField(
 | 
			
		||||
                        auto_created=True,
 | 
			
		||||
                        primary_key=True,
 | 
			
		||||
                        serialize=False,
 | 
			
		||||
                        verbose_name="ID",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("created", models.DateTimeField(auto_now_add=True)),
 | 
			
		||||
                ("last_updated", models.DateTimeField(auto_now=True)),
 | 
			
		||||
                (
 | 
			
		||||
                    "user",
 | 
			
		||||
                    models.ForeignKey(
 | 
			
		||||
                        on_delete=django.db.models.deletion.CASCADE,
 | 
			
		||||
                        to=settings.AUTH_USER_MODEL,
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "source",
 | 
			
		||||
                    models.ForeignKey(
 | 
			
		||||
                        on_delete=django.db.models.deletion.CASCADE,
 | 
			
		||||
                        to="passbook_core.Source",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
            options={"unique_together": {("user", "source")},},
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name="Application",
 | 
			
		||||
            fields=[
 | 
			
		||||
                (
 | 
			
		||||
                    "policymodel_ptr",
 | 
			
		||||
                    models.OneToOneField(
 | 
			
		||||
                        auto_created=True,
 | 
			
		||||
                        on_delete=django.db.models.deletion.CASCADE,
 | 
			
		||||
                        parent_link=True,
 | 
			
		||||
                        primary_key=True,
 | 
			
		||||
                        serialize=False,
 | 
			
		||||
                        to="passbook_policies.PolicyBindingModel",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("name", models.TextField()),
 | 
			
		||||
                ("slug", models.SlugField()),
 | 
			
		||||
                ("launch_url", models.URLField(blank=True, null=True)),
 | 
			
		||||
                ("icon_url", models.TextField(blank=True, null=True)),
 | 
			
		||||
                ("skip_authorization", models.BooleanField(default=False)),
 | 
			
		||||
                (
 | 
			
		||||
                    "provider",
 | 
			
		||||
                    models.OneToOneField(
 | 
			
		||||
                        blank=True,
 | 
			
		||||
                        default=None,
 | 
			
		||||
                        null=True,
 | 
			
		||||
                        on_delete=django.db.models.deletion.SET_DEFAULT,
 | 
			
		||||
                        to="passbook_core.Provider",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
            options={"abstract": False,},
 | 
			
		||||
            bases=("passbook_policies.policybindingmodel",),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="user",
 | 
			
		||||
            name="sources",
 | 
			
		||||
            field=models.ManyToManyField(
 | 
			
		||||
                through="passbook_core.UserSourceConnection", to="passbook_core.Source"
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
@ -1,17 +0,0 @@
 | 
			
		||||
# Generated by Django 2.2.6 on 2019-10-10 10:58
 | 
			
		||||
 | 
			
		||||
from django.db import migrations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_core", "0001_initial"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AlterModelOptions(
 | 
			
		||||
            name="user",
 | 
			
		||||
            options={"permissions": (("reset_user_password", "Reset Password"),)},
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,18 +0,0 @@
 | 
			
		||||
# Generated by Django 2.2.6 on 2019-10-10 11:48
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_core", "0001_initial"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="nonce",
 | 
			
		||||
            name="description",
 | 
			
		||||
            field=models.TextField(blank=True, default=""),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,31 +0,0 @@
 | 
			
		||||
# Generated by Django 2.2.6 on 2019-10-11 09:14
 | 
			
		||||
 | 
			
		||||
import django.contrib.postgres.fields.jsonb
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_core", "0002_nonce_description"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.RenameField(
 | 
			
		||||
            model_name="group", old_name="tags", new_name="attributes",
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="source",
 | 
			
		||||
            name="property_mappings",
 | 
			
		||||
            field=models.ManyToManyField(
 | 
			
		||||
                blank=True, default=None, to="passbook_core.PropertyMapping"
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="user",
 | 
			
		||||
            name="attributes",
 | 
			
		||||
            field=django.contrib.postgres.fields.jsonb.JSONField(
 | 
			
		||||
                blank=True, default=dict
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,13 +0,0 @@
 | 
			
		||||
# Generated by Django 2.2.6 on 2019-10-10 15:41
 | 
			
		||||
 | 
			
		||||
from django.db import migrations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_core", "0002_auto_20191010_1058"),
 | 
			
		||||
        ("passbook_core", "0002_nonce_description"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = []
 | 
			
		||||
@ -1,14 +0,0 @@
 | 
			
		||||
# Generated by Django 2.2.6 on 2019-10-14 11:56
 | 
			
		||||
 | 
			
		||||
from django.db import migrations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_core", "0003_auto_20191011_0914"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.RemoveField(model_name="policy", name="action",),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,13 +0,0 @@
 | 
			
		||||
# Generated by Django 2.2.6 on 2019-10-25 20:22
 | 
			
		||||
 | 
			
		||||
from django.db import migrations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_core", "0004_remove_policy_action"),
 | 
			
		||||
        ("passbook_core", "0003_merge_20191010_1541"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = []
 | 
			
		||||
@ -1,19 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-02-17 16:15
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_core", "0005_merge_20191025_2022"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="propertymapping",
 | 
			
		||||
            name="template",
 | 
			
		||||
            field=models.TextField(default=""),
 | 
			
		||||
            preserve_default=False,
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,16 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-02-17 19:34
 | 
			
		||||
 | 
			
		||||
from django.db import migrations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_core", "0006_propertymapping_template"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.RenameField(
 | 
			
		||||
            model_name="propertymapping", old_name="template", new_name="expression",
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,29 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-02-20 12:42
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_core", "0007_auto_20200217_1934"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.RenameField(
 | 
			
		||||
            model_name="application", old_name="icon_url", new_name="meta_icon_url",
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.RenameField(
 | 
			
		||||
            model_name="application", old_name="launch_url", new_name="meta_launch_url",
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="application",
 | 
			
		||||
            name="meta_description",
 | 
			
		||||
            field=models.TextField(blank=True, null=True),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="application",
 | 
			
		||||
            name="meta_publisher",
 | 
			
		||||
            field=models.TextField(blank=True, null=True),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,52 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-02-21 14:10
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_core", "0008_auto_20200220_1242"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="application",
 | 
			
		||||
            name="name",
 | 
			
		||||
            field=models.TextField(help_text="Application's display Name."),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="application",
 | 
			
		||||
            name="slug",
 | 
			
		||||
            field=models.SlugField(
 | 
			
		||||
                help_text="Internal application name, used in URLs."
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="factor",
 | 
			
		||||
            name="name",
 | 
			
		||||
            field=models.TextField(help_text="Factor's display Name."),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="factor",
 | 
			
		||||
            name="slug",
 | 
			
		||||
            field=models.SlugField(
 | 
			
		||||
                help_text="Internal factor name, used in URLs.", unique=True
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="source",
 | 
			
		||||
            name="name",
 | 
			
		||||
            field=models.TextField(help_text="Source's display Name."),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="source",
 | 
			
		||||
            name="slug",
 | 
			
		||||
            field=models.SlugField(help_text="Internal source name, used in URLs."),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="user",
 | 
			
		||||
            name="name",
 | 
			
		||||
            field=models.TextField(help_text="User's display name."),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,33 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-02-21 22:08
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_core", "0009_auto_20200221_1410"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="application",
 | 
			
		||||
            name="meta_description",
 | 
			
		||||
            field=models.TextField(blank=True, default=""),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="application",
 | 
			
		||||
            name="meta_icon_url",
 | 
			
		||||
            field=models.TextField(blank=True, default=""),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="application",
 | 
			
		||||
            name="meta_launch_url",
 | 
			
		||||
            field=models.URLField(blank=True, default=""),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="application",
 | 
			
		||||
            name="meta_publisher",
 | 
			
		||||
            field=models.TextField(blank=True, default=""),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,27 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-02-22 18:22
 | 
			
		||||
 | 
			
		||||
from django.db import migrations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def fix_application_null(apps, schema_editor):
 | 
			
		||||
    """Fix Application meta_fields being null"""
 | 
			
		||||
    Application = apps.get_model("passbook_core", "Application")
 | 
			
		||||
    for app in Application.objects.all():
 | 
			
		||||
        if app.meta_launch_url is None:
 | 
			
		||||
            app.meta_launch_url = ""
 | 
			
		||||
        if app.meta_icon_url is None:
 | 
			
		||||
            app.meta_icon_url = ""
 | 
			
		||||
        if app.meta_description is None:
 | 
			
		||||
            app.meta_description = ""
 | 
			
		||||
        if app.meta_publisher is None:
 | 
			
		||||
            app.meta_publisher = ""
 | 
			
		||||
        app.save()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_core", "0010_auto_20200221_2208"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [migrations.RunPython(fix_application_null)]
 | 
			
		||||
@ -1,14 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-05-08 17:58
 | 
			
		||||
 | 
			
		||||
from django.db import migrations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_core", "0011_auto_20200222_1822"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.DeleteModel(name="Factor",),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,12 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.5 on 2020-05-10 10:01
 | 
			
		||||
 | 
			
		||||
from django.db import migrations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_core", "0012_delete_factor"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = []
 | 
			
		||||
@ -1,14 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.5 on 2020-05-11 19:57
 | 
			
		||||
 | 
			
		||||
from django.db import migrations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_core", "0013_delete_debugpolicy"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.DeleteModel(name="Invitation",),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,52 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.5 on 2020-05-16 14:07
 | 
			
		||||
 | 
			
		||||
import uuid
 | 
			
		||||
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
from django.conf import settings
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
import passbook.core.models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_core", "0014_delete_invitation"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name="Token",
 | 
			
		||||
            fields=[
 | 
			
		||||
                (
 | 
			
		||||
                    "uuid",
 | 
			
		||||
                    models.UUIDField(
 | 
			
		||||
                        default=uuid.uuid4,
 | 
			
		||||
                        editable=False,
 | 
			
		||||
                        primary_key=True,
 | 
			
		||||
                        serialize=False,
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "expires",
 | 
			
		||||
                    models.DateTimeField(
 | 
			
		||||
                        default=passbook.core.models.default_token_duration
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("expiring", models.BooleanField(default=True)),
 | 
			
		||||
                ("description", models.TextField(blank=True, default="")),
 | 
			
		||||
                (
 | 
			
		||||
                    "user",
 | 
			
		||||
                    models.ForeignKey(
 | 
			
		||||
                        on_delete=django.db.models.deletion.CASCADE,
 | 
			
		||||
                        related_name="+",
 | 
			
		||||
                        to=settings.AUTH_USER_MODEL,
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
            options={"verbose_name": "Token", "verbose_name_plural": "Tokens",},
 | 
			
		||||
            bases=(models.Model,),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.DeleteModel(name="Nonce",),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,48 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.5 on 2020-05-16 14:46
 | 
			
		||||
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_policies", "__first__"),
 | 
			
		||||
        ("passbook_core", "0015_auto_20200516_1407"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.RemoveField(model_name="policymodel", name="policies",),
 | 
			
		||||
        migrations.RemoveField(model_name="application", name="policymodel_ptr",),
 | 
			
		||||
        migrations.RemoveField(model_name="source", name="policymodel_ptr",),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="application",
 | 
			
		||||
            name="policybindingmodel_ptr",
 | 
			
		||||
            field=models.OneToOneField(
 | 
			
		||||
                auto_created=True,
 | 
			
		||||
                default=None,
 | 
			
		||||
                on_delete=django.db.models.deletion.CASCADE,
 | 
			
		||||
                parent_link=True,
 | 
			
		||||
                primary_key=True,
 | 
			
		||||
                serialize=False,
 | 
			
		||||
                to="passbook_policies.PolicyBindingModel",
 | 
			
		||||
            ),
 | 
			
		||||
            preserve_default=False,
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="source",
 | 
			
		||||
            name="policybindingmodel_ptr",
 | 
			
		||||
            field=models.OneToOneField(
 | 
			
		||||
                auto_created=True,
 | 
			
		||||
                default=None,
 | 
			
		||||
                on_delete=django.db.models.deletion.CASCADE,
 | 
			
		||||
                parent_link=True,
 | 
			
		||||
                primary_key=True,
 | 
			
		||||
                serialize=False,
 | 
			
		||||
                to="passbook_policies.PolicyBindingModel",
 | 
			
		||||
            ),
 | 
			
		||||
            preserve_default=False,
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.DeleteModel(name="Policy",),
 | 
			
		||||
        migrations.DeleteModel(name="PolicyModel",),
 | 
			
		||||
    ]
 | 
			
		||||
@ -10,7 +10,6 @@ from django.db import models
 | 
			
		||||
from django.http import HttpRequest
 | 
			
		||||
from django.utils.timezone import now
 | 
			
		||||
from django.utils.translation import gettext_lazy as _
 | 
			
		||||
from django_prometheus.models import ExportModelOperationsMixin
 | 
			
		||||
from guardian.mixins import GuardianUserMixin
 | 
			
		||||
from jinja2 import Undefined
 | 
			
		||||
from jinja2.exceptions import TemplateSyntaxError, UndefinedError
 | 
			
		||||
@ -21,7 +20,7 @@ from structlog import get_logger
 | 
			
		||||
from passbook.core.exceptions import PropertyMappingExpressionException
 | 
			
		||||
from passbook.core.signals import password_changed
 | 
			
		||||
from passbook.core.types import UILoginButton, UIUserSettings
 | 
			
		||||
from passbook.lib.models import CreatedUpdatedModel, UUIDModel
 | 
			
		||||
from passbook.lib.models import CreatedUpdatedModel
 | 
			
		||||
from passbook.policies.models import PolicyBindingModel
 | 
			
		||||
 | 
			
		||||
LOGGER = get_logger()
 | 
			
		||||
@ -33,9 +32,10 @@ def default_token_duration():
 | 
			
		||||
    return now() + timedelta(minutes=30)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Group(ExportModelOperationsMixin("group"), UUIDModel):
 | 
			
		||||
class Group(models.Model):
 | 
			
		||||
    """Custom Group model which supports a basic hierarchy"""
 | 
			
		||||
 | 
			
		||||
    group_uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4)
 | 
			
		||||
    name = models.CharField(_("name"), max_length=80)
 | 
			
		||||
    parent = models.ForeignKey(
 | 
			
		||||
        "Group",
 | 
			
		||||
@ -54,7 +54,7 @@ class Group(ExportModelOperationsMixin("group"), UUIDModel):
 | 
			
		||||
        unique_together = (("name", "parent",),)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class User(ExportModelOperationsMixin("user"), GuardianUserMixin, AbstractUser):
 | 
			
		||||
class User(GuardianUserMixin, AbstractUser):
 | 
			
		||||
    """Custom User model to allow easier adding o f user-based settings"""
 | 
			
		||||
 | 
			
		||||
    uuid = models.UUIDField(default=uuid4, editable=False)
 | 
			
		||||
@ -77,7 +77,7 @@ class User(ExportModelOperationsMixin("user"), GuardianUserMixin, AbstractUser):
 | 
			
		||||
        permissions = (("reset_user_password", "Reset Password"),)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Provider(ExportModelOperationsMixin("provider"), models.Model):
 | 
			
		||||
class Provider(models.Model):
 | 
			
		||||
    """Application-independent Provider instance. For example SAML2 Remote, OAuth2 Application"""
 | 
			
		||||
 | 
			
		||||
    property_mappings = models.ManyToManyField(
 | 
			
		||||
@ -93,7 +93,7 @@ class Provider(ExportModelOperationsMixin("provider"), models.Model):
 | 
			
		||||
        return super().__str__()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Application(ExportModelOperationsMixin("application"), PolicyBindingModel):
 | 
			
		||||
class Application(PolicyBindingModel):
 | 
			
		||||
    """Every Application which uses passbook for authentication/identification/authorization
 | 
			
		||||
    needs an Application record. Other authentication types can subclass this Model to
 | 
			
		||||
    add custom fields and other properties"""
 | 
			
		||||
@ -122,7 +122,7 @@ class Application(ExportModelOperationsMixin("application"), PolicyBindingModel)
 | 
			
		||||
        return self.name
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Source(ExportModelOperationsMixin("source"), PolicyBindingModel):
 | 
			
		||||
class Source(PolicyBindingModel):
 | 
			
		||||
    """Base Authentication source, i.e. an OAuth Provider, SAML Remote or LDAP Server"""
 | 
			
		||||
 | 
			
		||||
    name = models.TextField(help_text=_("Source's display Name."))
 | 
			
		||||
@ -169,9 +169,10 @@ class UserSourceConnection(CreatedUpdatedModel):
 | 
			
		||||
        unique_together = (("user", "source"),)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Token(ExportModelOperationsMixin("token"), UUIDModel):
 | 
			
		||||
class Token(models.Model):
 | 
			
		||||
    """One-time link for password resets/sign-up-confirmations"""
 | 
			
		||||
 | 
			
		||||
    token_uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4)
 | 
			
		||||
    expires = models.DateTimeField(default=default_token_duration)
 | 
			
		||||
    user = models.ForeignKey("User", on_delete=models.CASCADE, related_name="+")
 | 
			
		||||
    expiring = models.BooleanField(default=True)
 | 
			
		||||
@ -183,7 +184,9 @@ class Token(ExportModelOperationsMixin("token"), UUIDModel):
 | 
			
		||||
        return now() > self.expires
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return f"Token f{self.uuid.hex} {self.description} (expires={self.expires})"
 | 
			
		||||
        return (
 | 
			
		||||
            f"Token f{self.token_uuid.hex} {self.description} (expires={self.expires})"
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
 | 
			
		||||
@ -191,9 +194,10 @@ class Token(ExportModelOperationsMixin("token"), UUIDModel):
 | 
			
		||||
        verbose_name_plural = _("Tokens")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PropertyMapping(UUIDModel):
 | 
			
		||||
class PropertyMapping(models.Model):
 | 
			
		||||
    """User-defined key -> x mapping which can be used by providers to expose extra data."""
 | 
			
		||||
 | 
			
		||||
    pm_uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4)
 | 
			
		||||
    name = models.TextField()
 | 
			
		||||
    expression = models.TextField()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,24 +1,10 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-03-03 21:45
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:08
 | 
			
		||||
 | 
			
		||||
import uuid
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def create_self_signed(apps, schema_editor):
 | 
			
		||||
    CertificateKeyPair = apps.get_model("passbook_crypto", "CertificateKeyPair")
 | 
			
		||||
    db_alias = schema_editor.connection.alias
 | 
			
		||||
    from passbook.crypto.builder import CertificateBuilder
 | 
			
		||||
 | 
			
		||||
    builder = CertificateBuilder()
 | 
			
		||||
    builder.build()
 | 
			
		||||
    CertificateKeyPair.objects.using(db_alias).create(
 | 
			
		||||
        name="passbook Self-signed Certificate",
 | 
			
		||||
        certificate_data=builder.certificate,
 | 
			
		||||
        key_data=builder.private_key,
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    initial = True
 | 
			
		||||
@ -32,7 +18,7 @@ class Migration(migrations.Migration):
 | 
			
		||||
                ("created", models.DateTimeField(auto_now_add=True)),
 | 
			
		||||
                ("last_updated", models.DateTimeField(auto_now=True)),
 | 
			
		||||
                (
 | 
			
		||||
                    "uuid",
 | 
			
		||||
                    "kp_uuid",
 | 
			
		||||
                    models.UUIDField(
 | 
			
		||||
                        default=uuid.uuid4,
 | 
			
		||||
                        editable=False,
 | 
			
		||||
@ -41,27 +27,22 @@ class Migration(migrations.Migration):
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("name", models.TextField()),
 | 
			
		||||
                ("certificate_data", models.TextField()),
 | 
			
		||||
                ("key_data", models.TextField(blank=True, default="")),
 | 
			
		||||
                (
 | 
			
		||||
                    "certificate_data",
 | 
			
		||||
                    models.TextField(help_text="PEM-encoded Certificate data"),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "key_data",
 | 
			
		||||
                    models.TextField(
 | 
			
		||||
                        blank=True,
 | 
			
		||||
                        default="",
 | 
			
		||||
                        help_text="Optional Private Key. If this is set, you can use this keypair for encryption.",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
            options={
 | 
			
		||||
                "verbose_name": "Certificate-Key Pair",
 | 
			
		||||
                "verbose_name_plural": "Certificate-Key Pairs",
 | 
			
		||||
            },
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.RunPython(create_self_signed),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="certificatekeypair",
 | 
			
		||||
            name="certificate_data",
 | 
			
		||||
            field=models.TextField(help_text="PEM-encoded Certificate data"),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="certificatekeypair",
 | 
			
		||||
            name="key_data",
 | 
			
		||||
            field=models.TextField(
 | 
			
		||||
                blank=True,
 | 
			
		||||
                default="",
 | 
			
		||||
                help_text="Optional Private Key. If this is set, you can use this keypair for encryption.",
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
"""passbook crypto models"""
 | 
			
		||||
from binascii import hexlify
 | 
			
		||||
from typing import Optional
 | 
			
		||||
from uuid import uuid4
 | 
			
		||||
 | 
			
		||||
from cryptography.hazmat.backends import default_backend
 | 
			
		||||
from cryptography.hazmat.primitives import hashes
 | 
			
		||||
@ -10,13 +11,15 @@ from cryptography.x509 import Certificate, load_pem_x509_certificate
 | 
			
		||||
from django.db import models
 | 
			
		||||
from django.utils.translation import gettext_lazy as _
 | 
			
		||||
 | 
			
		||||
from passbook.lib.models import CreatedUpdatedModel, UUIDModel
 | 
			
		||||
from passbook.lib.models import CreatedUpdatedModel
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class CertificateKeyPair(UUIDModel, CreatedUpdatedModel):
 | 
			
		||||
class CertificateKeyPair(CreatedUpdatedModel):
 | 
			
		||||
    """CertificateKeyPair that can be used for signing or encrypting if `key_data`
 | 
			
		||||
    is set, otherwise it can be used to verify remote data."""
 | 
			
		||||
 | 
			
		||||
    kp_uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4)
 | 
			
		||||
 | 
			
		||||
    name = models.TextField()
 | 
			
		||||
    certificate_data = models.TextField(help_text=_("PEM-encoded Certificate data"))
 | 
			
		||||
    key_data = models.TextField(
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-05-08 18:27
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:07
 | 
			
		||||
 | 
			
		||||
import uuid
 | 
			
		||||
 | 
			
		||||
@ -19,7 +19,7 @@ class Migration(migrations.Migration):
 | 
			
		||||
            name="Flow",
 | 
			
		||||
            fields=[
 | 
			
		||||
                (
 | 
			
		||||
                    "uuid",
 | 
			
		||||
                    "flow_uuid",
 | 
			
		||||
                    models.UUIDField(
 | 
			
		||||
                        default=uuid.uuid4,
 | 
			
		||||
                        editable=False,
 | 
			
		||||
@ -33,10 +33,12 @@ class Migration(migrations.Migration):
 | 
			
		||||
                    "designation",
 | 
			
		||||
                    models.CharField(
 | 
			
		||||
                        choices=[
 | 
			
		||||
                            ("AUTHENTICATION", "authentication"),
 | 
			
		||||
                            ("ENROLLMENT", "enrollment"),
 | 
			
		||||
                            ("RECOVERY", "recovery"),
 | 
			
		||||
                            ("PASSWORD_CHANGE", "password_change"),
 | 
			
		||||
                            ("authentication", "Authentication"),
 | 
			
		||||
                            ("invalidation", "Invalidation"),
 | 
			
		||||
                            ("enrollment", "Enrollment"),
 | 
			
		||||
                            ("unenrollment", "Unrenollment"),
 | 
			
		||||
                            ("recovery", "Recovery"),
 | 
			
		||||
                            ("password_change", "Password Change"),
 | 
			
		||||
                        ],
 | 
			
		||||
                        max_length=100,
 | 
			
		||||
                    ),
 | 
			
		||||
@ -52,13 +54,13 @@ class Migration(migrations.Migration):
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
            options={"verbose_name": "Flow", "verbose_name_plural": "Flows",},
 | 
			
		||||
            bases=("passbook_policies.policybindingmodel", models.Model),
 | 
			
		||||
            bases=("passbook_policies.policybindingmodel",),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name="Stage",
 | 
			
		||||
            fields=[
 | 
			
		||||
                (
 | 
			
		||||
                    "uuid",
 | 
			
		||||
                    "stage_uuid",
 | 
			
		||||
                    models.UUIDField(
 | 
			
		||||
                        default=uuid.uuid4,
 | 
			
		||||
                        editable=False,
 | 
			
		||||
@ -68,7 +70,6 @@ class Migration(migrations.Migration):
 | 
			
		||||
                ),
 | 
			
		||||
                ("name", models.TextField()),
 | 
			
		||||
            ],
 | 
			
		||||
            options={"abstract": False,},
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name="FlowStageBinding",
 | 
			
		||||
@ -83,7 +84,7 @@ class Migration(migrations.Migration):
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "uuid",
 | 
			
		||||
                    "fsb_uuid",
 | 
			
		||||
                    models.UUIDField(
 | 
			
		||||
                        default=uuid.uuid4,
 | 
			
		||||
                        editable=False,
 | 
			
		||||
@ -120,7 +121,7 @@ class Migration(migrations.Migration):
 | 
			
		||||
                "ordering": ["order", "flow"],
 | 
			
		||||
                "unique_together": {("flow", "stage", "order")},
 | 
			
		||||
            },
 | 
			
		||||
            bases=("passbook_policies.policybindingmodel", models.Model),
 | 
			
		||||
            bases=("passbook_policies.policybindingmodel",),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="flow",
 | 
			
		||||
 | 
			
		||||
@ -1,26 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-05-09 12:58
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_flows", "0002_default_flows"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="flow",
 | 
			
		||||
            name="designation",
 | 
			
		||||
            field=models.CharField(
 | 
			
		||||
                choices=[
 | 
			
		||||
                    ("authentication", "Authentication"),
 | 
			
		||||
                    ("enrollment", "Enrollment"),
 | 
			
		||||
                    ("recovery", "Recovery"),
 | 
			
		||||
                    ("password_change", "Password Change"),
 | 
			
		||||
                ],
 | 
			
		||||
                max_length=100,
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,27 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.5 on 2020-05-10 23:10
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_flows", "0003_auto_20200509_1258"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="flow",
 | 
			
		||||
            name="designation",
 | 
			
		||||
            field=models.CharField(
 | 
			
		||||
                choices=[
 | 
			
		||||
                    ("authentication", "Authentication"),
 | 
			
		||||
                    ("enrollment", "Enrollment"),
 | 
			
		||||
                    ("recovery", "Recovery"),
 | 
			
		||||
                    ("password_change", "Password Change"),
 | 
			
		||||
                    ("invalidation", "Invalidation"),
 | 
			
		||||
                ],
 | 
			
		||||
                max_length=100,
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,28 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.5 on 2020-05-12 11:58
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_flows", "0004_auto_20200510_2310"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="flow",
 | 
			
		||||
            name="designation",
 | 
			
		||||
            field=models.CharField(
 | 
			
		||||
                choices=[
 | 
			
		||||
                    ("authentication", "Authentication"),
 | 
			
		||||
                    ("invalidation", "Invalidation"),
 | 
			
		||||
                    ("enrollment", "Enrollment"),
 | 
			
		||||
                    ("unenrollment", "Unrenollment"),
 | 
			
		||||
                    ("recovery", "Recovery"),
 | 
			
		||||
                    ("password_change", "Password Change"),
 | 
			
		||||
                ],
 | 
			
		||||
                max_length=100,
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,12 +1,12 @@
 | 
			
		||||
"""Flow models"""
 | 
			
		||||
from typing import Optional
 | 
			
		||||
from uuid import uuid4
 | 
			
		||||
 | 
			
		||||
from django.db import models
 | 
			
		||||
from django.utils.translation import gettext_lazy as _
 | 
			
		||||
from model_utils.managers import InheritanceManager
 | 
			
		||||
 | 
			
		||||
from passbook.core.types import UIUserSettings
 | 
			
		||||
from passbook.lib.models import UUIDModel
 | 
			
		||||
from passbook.policies.models import PolicyBindingModel
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -22,10 +22,12 @@ class FlowDesignation(models.TextChoices):
 | 
			
		||||
    PASSWORD_CHANGE = "password_change"  # nosec # noqa
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Stage(UUIDModel):
 | 
			
		||||
class Stage(models.Model):
 | 
			
		||||
    """Stage is an instance of a component used in a flow. This can verify the user,
 | 
			
		||||
    enroll the user or offer a way of recovery"""
 | 
			
		||||
 | 
			
		||||
    stage_uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4)
 | 
			
		||||
 | 
			
		||||
    name = models.TextField()
 | 
			
		||||
 | 
			
		||||
    objects = InheritanceManager()
 | 
			
		||||
@ -42,11 +44,13 @@ class Stage(UUIDModel):
 | 
			
		||||
        return f"Stage {self.name}"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Flow(PolicyBindingModel, UUIDModel):
 | 
			
		||||
class Flow(PolicyBindingModel):
 | 
			
		||||
    """Flow describes how a series of Stages should be executed to authenticate/enroll/recover
 | 
			
		||||
    a user. Additionally, policies can be applied, to specify which users
 | 
			
		||||
    have access to this flow."""
 | 
			
		||||
 | 
			
		||||
    flow_uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4)
 | 
			
		||||
 | 
			
		||||
    name = models.TextField()
 | 
			
		||||
    slug = models.SlugField(unique=True)
 | 
			
		||||
 | 
			
		||||
@ -72,11 +76,13 @@ class Flow(PolicyBindingModel, UUIDModel):
 | 
			
		||||
        verbose_name_plural = _("Flows")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class FlowStageBinding(PolicyBindingModel, UUIDModel):
 | 
			
		||||
class FlowStageBinding(PolicyBindingModel):
 | 
			
		||||
    """Relationship between Flow and Stage. Order is required and unique for
 | 
			
		||||
    each flow-stage Binding. Additionally, policies can be specified, which determine if
 | 
			
		||||
    this Binding applies to the current user"""
 | 
			
		||||
 | 
			
		||||
    fsb_uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4)
 | 
			
		||||
 | 
			
		||||
    flow = models.ForeignKey("Flow", on_delete=models.CASCADE)
 | 
			
		||||
    stage = models.ForeignKey(Stage, on_delete=models.CASCADE)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,4 @@
 | 
			
		||||
"""Generic models"""
 | 
			
		||||
from uuid import uuid4
 | 
			
		||||
 | 
			
		||||
from django.db import models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -12,12 +10,3 @@ class CreatedUpdatedModel(models.Model):
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        abstract = True
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class UUIDModel(models.Model):
 | 
			
		||||
    """Abstract base model which uses a UUID as primary key"""
 | 
			
		||||
 | 
			
		||||
    uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4)
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        abstract = True
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Generated by Django 3.0.5 on 2020-05-10 10:01
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:08
 | 
			
		||||
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Generated by Django 2.2.6 on 2019-10-07 14:07
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:08
 | 
			
		||||
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-02-18 14:00
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:08
 | 
			
		||||
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
@ -11,7 +11,8 @@ class PolicyBindingForm(forms.ModelForm):
 | 
			
		||||
    """Form to edit Policy to PolicyBindingModel Binding"""
 | 
			
		||||
 | 
			
		||||
    target = forms.ModelChoiceField(
 | 
			
		||||
        queryset=PolicyBindingModel.objects.all().select_subclasses()
 | 
			
		||||
        queryset=PolicyBindingModel.objects.all().select_subclasses(),
 | 
			
		||||
        to_field_name="pbm_uuid",
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Generated by Django 2.2.6 on 2019-10-07 14:07
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:08
 | 
			
		||||
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-05-07 18:35
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:07
 | 
			
		||||
 | 
			
		||||
import uuid
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,8 @@ class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    initial = True
 | 
			
		||||
 | 
			
		||||
    dependencies = []
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name="Policy",
 | 
			
		||||
@ -17,7 +19,7 @@ class Migration(migrations.Migration):
 | 
			
		||||
                ("created", models.DateTimeField(auto_now_add=True)),
 | 
			
		||||
                ("last_updated", models.DateTimeField(auto_now=True)),
 | 
			
		||||
                (
 | 
			
		||||
                    "uuid",
 | 
			
		||||
                    "policy_uuid",
 | 
			
		||||
                    models.UUIDField(
 | 
			
		||||
                        default=uuid.uuid4,
 | 
			
		||||
                        editable=False,
 | 
			
		||||
@ -36,7 +38,7 @@ class Migration(migrations.Migration):
 | 
			
		||||
            name="PolicyBinding",
 | 
			
		||||
            fields=[
 | 
			
		||||
                (
 | 
			
		||||
                    "uuid",
 | 
			
		||||
                    "policy_binding_uuid",
 | 
			
		||||
                    models.UUIDField(
 | 
			
		||||
                        default=uuid.uuid4,
 | 
			
		||||
                        editable=False,
 | 
			
		||||
@ -64,23 +66,28 @@ class Migration(migrations.Migration):
 | 
			
		||||
            name="PolicyBindingModel",
 | 
			
		||||
            fields=[
 | 
			
		||||
                (
 | 
			
		||||
                    "id",
 | 
			
		||||
                    models.AutoField(
 | 
			
		||||
                        auto_created=True,
 | 
			
		||||
                    "pbm_uuid",
 | 
			
		||||
                    models.UUIDField(
 | 
			
		||||
                        default=uuid.uuid4,
 | 
			
		||||
                        editable=False,
 | 
			
		||||
                        primary_key=True,
 | 
			
		||||
                        serialize=False,
 | 
			
		||||
                        verbose_name="ID",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "policies",
 | 
			
		||||
                    models.ManyToManyField(
 | 
			
		||||
                        related_name="_policybindingmodel_policies_+",
 | 
			
		||||
                        blank=True,
 | 
			
		||||
                        related_name="bindings",
 | 
			
		||||
                        through="passbook_policies.PolicyBinding",
 | 
			
		||||
                        to="passbook_policies.Policy",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
            options={
 | 
			
		||||
                "verbose_name": "Policy Binding Model",
 | 
			
		||||
                "verbose_name_plural": "Policy Binding Models",
 | 
			
		||||
            },
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="policybinding",
 | 
			
		||||
 | 
			
		||||
@ -1,20 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-05-08 12:30
 | 
			
		||||
 | 
			
		||||
from django.db import migrations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_policies", "0001_initial"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AlterModelOptions(
 | 
			
		||||
            name="policybindingmodel",
 | 
			
		||||
            options={
 | 
			
		||||
                "verbose_name": "Policy Binding Model",
 | 
			
		||||
                "verbose_name_plural": "Policy Binding Models",
 | 
			
		||||
            },
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,23 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.5 on 2020-05-16 15:16
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_policies", "0002_auto_20200508_1230"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="policybindingmodel",
 | 
			
		||||
            name="policies",
 | 
			
		||||
            field=models.ManyToManyField(
 | 
			
		||||
                blank=True,
 | 
			
		||||
                related_name="_policybindingmodel_policies_+",
 | 
			
		||||
                through="passbook_policies.PolicyBinding",
 | 
			
		||||
                to="passbook_policies.Policy",
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,9 +1,11 @@
 | 
			
		||||
"""Policy base models"""
 | 
			
		||||
from uuid import uuid4
 | 
			
		||||
 | 
			
		||||
from django.db import models
 | 
			
		||||
from django.utils.translation import gettext_lazy as _
 | 
			
		||||
from model_utils.managers import InheritanceManager
 | 
			
		||||
 | 
			
		||||
from passbook.lib.models import CreatedUpdatedModel, UUIDModel
 | 
			
		||||
from passbook.lib.models import CreatedUpdatedModel
 | 
			
		||||
from passbook.policies.exceptions import PolicyException
 | 
			
		||||
from passbook.policies.types import PolicyRequest, PolicyResult
 | 
			
		||||
 | 
			
		||||
@ -11,6 +13,8 @@ from passbook.policies.types import PolicyRequest, PolicyResult
 | 
			
		||||
class PolicyBindingModel(models.Model):
 | 
			
		||||
    """Base Model for objects that have policies applied to them."""
 | 
			
		||||
 | 
			
		||||
    pbm_uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4)
 | 
			
		||||
 | 
			
		||||
    policies = models.ManyToManyField(
 | 
			
		||||
        "Policy", through="PolicyBinding", related_name="bindings", blank=True
 | 
			
		||||
    )
 | 
			
		||||
@ -23,9 +27,13 @@ class PolicyBindingModel(models.Model):
 | 
			
		||||
        verbose_name_plural = _("Policy Binding Models")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class PolicyBinding(UUIDModel):
 | 
			
		||||
class PolicyBinding(models.Model):
 | 
			
		||||
    """Relationship between a Policy and a PolicyBindingModel."""
 | 
			
		||||
 | 
			
		||||
    policy_binding_uuid = models.UUIDField(
 | 
			
		||||
        primary_key=True, editable=False, default=uuid4
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    enabled = models.BooleanField(default=True)
 | 
			
		||||
 | 
			
		||||
    policy = models.ForeignKey("Policy", on_delete=models.CASCADE, related_name="+")
 | 
			
		||||
@ -45,10 +53,12 @@ class PolicyBinding(UUIDModel):
 | 
			
		||||
        verbose_name_plural = _("Policy Bindings")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Policy(UUIDModel, CreatedUpdatedModel):
 | 
			
		||||
class Policy(CreatedUpdatedModel):
 | 
			
		||||
    """Policies which specify if a user is authorized to use an Application. Can be overridden by
 | 
			
		||||
    other types to add other fields, more logic, etc."""
 | 
			
		||||
 | 
			
		||||
    policy_uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4)
 | 
			
		||||
 | 
			
		||||
    name = models.TextField(blank=True, null=True)
 | 
			
		||||
    negate = models.BooleanField(default=False)
 | 
			
		||||
    order = models.IntegerField(default=0)
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Generated by Django 2.2.6 on 2019-10-07 14:07
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:08
 | 
			
		||||
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Generated by Django 2.2.6 on 2019-10-07 14:07
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:08
 | 
			
		||||
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
from django.conf import settings
 | 
			
		||||
@ -10,8 +10,8 @@ class Migration(migrations.Migration):
 | 
			
		||||
    initial = True
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_policies", "0001_initial"),
 | 
			
		||||
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
 | 
			
		||||
        ("passbook_policies", "0001_initial"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
# Generated by Django 2.2.6 on 2019-10-07 14:07
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:08
 | 
			
		||||
 | 
			
		||||
import django.contrib.postgres.fields
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
@ -10,8 +9,8 @@ class Migration(migrations.Migration):
 | 
			
		||||
    initial = True
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("oidc_provider", "0026_client_multiple_response_types"),
 | 
			
		||||
        ("passbook_core", "0001_initial"),
 | 
			
		||||
        ("passbook_policies", "0001_initial"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
@ -29,28 +28,16 @@ class Migration(migrations.Migration):
 | 
			
		||||
                        to="passbook_core.Provider",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("name", models.TextField()),
 | 
			
		||||
                ("internal_host", models.TextField()),
 | 
			
		||||
                ("external_host", models.TextField()),
 | 
			
		||||
                (
 | 
			
		||||
                    "server_name",
 | 
			
		||||
                    django.contrib.postgres.fields.ArrayField(
 | 
			
		||||
                        base_field=models.TextField(), size=None
 | 
			
		||||
                    "client",
 | 
			
		||||
                    models.ForeignKey(
 | 
			
		||||
                        on_delete=django.db.models.deletion.CASCADE,
 | 
			
		||||
                        to="oidc_provider.Client",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "upstream",
 | 
			
		||||
                    django.contrib.postgres.fields.ArrayField(
 | 
			
		||||
                        base_field=models.TextField(), size=None
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("enabled", models.BooleanField(default=True)),
 | 
			
		||||
                (
 | 
			
		||||
                    "authentication_header",
 | 
			
		||||
                    models.TextField(blank=True, default="X-Remote-User"),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "default_content_type",
 | 
			
		||||
                    models.TextField(default="application/octet-stream"),
 | 
			
		||||
                ),
 | 
			
		||||
                ("upstream_ssl_verification", models.BooleanField(default=True)),
 | 
			
		||||
            ],
 | 
			
		||||
            options={
 | 
			
		||||
                "verbose_name": "Application Gateway Provider",
 | 
			
		||||
@ -58,43 +45,4 @@ class Migration(migrations.Migration):
 | 
			
		||||
            },
 | 
			
		||||
            bases=("passbook_core.provider",),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name="RewriteRule",
 | 
			
		||||
            fields=[
 | 
			
		||||
                (
 | 
			
		||||
                    "propertymapping_ptr",
 | 
			
		||||
                    models.OneToOneField(
 | 
			
		||||
                        auto_created=True,
 | 
			
		||||
                        on_delete=django.db.models.deletion.CASCADE,
 | 
			
		||||
                        parent_link=True,
 | 
			
		||||
                        primary_key=True,
 | 
			
		||||
                        serialize=False,
 | 
			
		||||
                        to="passbook_core.PropertyMapping",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("match", models.TextField()),
 | 
			
		||||
                ("halt", models.BooleanField(default=False)),
 | 
			
		||||
                ("replacement", models.TextField()),
 | 
			
		||||
                (
 | 
			
		||||
                    "redirect",
 | 
			
		||||
                    models.CharField(
 | 
			
		||||
                        choices=[
 | 
			
		||||
                            ("internal", "Internal"),
 | 
			
		||||
                            (301, "Moved Permanently"),
 | 
			
		||||
                            (302, "Found"),
 | 
			
		||||
                        ],
 | 
			
		||||
                        max_length=50,
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "conditions",
 | 
			
		||||
                    models.ManyToManyField(blank=True, to="passbook_policies.Policy"),
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
            options={
 | 
			
		||||
                "verbose_name": "Rewrite Rule",
 | 
			
		||||
                "verbose_name_plural": "Rewrite Rules",
 | 
			
		||||
            },
 | 
			
		||||
            bases=("passbook_core.propertymapping",),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
@ -1,18 +0,0 @@
 | 
			
		||||
# Generated by Django 2.2.7 on 2019-11-11 17:03
 | 
			
		||||
 | 
			
		||||
from django.db import migrations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_core", "0005_merge_20191025_2022"),
 | 
			
		||||
        ("passbook_providers_app_gw", "0001_initial"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.RemoveField(model_name="rewriterule", name="conditions",),
 | 
			
		||||
        migrations.RemoveField(model_name="rewriterule", name="propertymapping_ptr",),
 | 
			
		||||
        migrations.DeleteModel(name="ApplicationGatewayProvider",),
 | 
			
		||||
        migrations.DeleteModel(name="RewriteRule",),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,48 +0,0 @@
 | 
			
		||||
# Generated by Django 2.2.7 on 2019-11-11 17:08
 | 
			
		||||
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    initial = True
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_core", "0005_merge_20191025_2022"),
 | 
			
		||||
        ("oidc_provider", "0026_client_multiple_response_types"),
 | 
			
		||||
        ("passbook_providers_app_gw", "0002_auto_20191111_1703"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
            name="ApplicationGatewayProvider",
 | 
			
		||||
            fields=[
 | 
			
		||||
                (
 | 
			
		||||
                    "provider_ptr",
 | 
			
		||||
                    models.OneToOneField(
 | 
			
		||||
                        auto_created=True,
 | 
			
		||||
                        on_delete=django.db.models.deletion.CASCADE,
 | 
			
		||||
                        parent_link=True,
 | 
			
		||||
                        primary_key=True,
 | 
			
		||||
                        serialize=False,
 | 
			
		||||
                        to="passbook_core.Provider",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("name", models.TextField()),
 | 
			
		||||
                ("host", models.TextField()),
 | 
			
		||||
                (
 | 
			
		||||
                    "client",
 | 
			
		||||
                    models.ForeignKey(
 | 
			
		||||
                        on_delete=django.db.models.deletion.CASCADE,
 | 
			
		||||
                        to="oidc_provider.Client",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
            options={
 | 
			
		||||
                "verbose_name": "Application Gateway Provider",
 | 
			
		||||
                "verbose_name_plural": "Application Gateway Providers",
 | 
			
		||||
            },
 | 
			
		||||
            bases=("passbook_core.provider",),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,24 +0,0 @@
 | 
			
		||||
# Generated by Django 2.2.9 on 2020-01-02 15:05
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_providers_app_gw", "0003_applicationgatewayprovider"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.RenameField(
 | 
			
		||||
            model_name="applicationgatewayprovider",
 | 
			
		||||
            old_name="host",
 | 
			
		||||
            new_name="external_host",
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="applicationgatewayprovider",
 | 
			
		||||
            name="internal_host",
 | 
			
		||||
            field=models.TextField(default=""),
 | 
			
		||||
            preserve_default=False,
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Generated by Django 2.2.6 on 2019-10-07 14:07
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:08
 | 
			
		||||
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
import oauth2_provider.generators
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Generated by Django 2.2.6 on 2019-10-07 14:07
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:08
 | 
			
		||||
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
@ -9,8 +9,8 @@ class Migration(migrations.Migration):
 | 
			
		||||
    initial = True
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_core", "0001_initial"),
 | 
			
		||||
        ("oidc_provider", "0026_client_multiple_response_types"),
 | 
			
		||||
        ("passbook_core", "0001_initial"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
 | 
			
		||||
@ -1,15 +1,17 @@
 | 
			
		||||
# Generated by Django 2.2.6 on 2019-10-07 14:07
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:08
 | 
			
		||||
 | 
			
		||||
import django.contrib.postgres.fields
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
import passbook.providers.saml.utils.time
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    initial = True
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_crypto", "0001_initial"),
 | 
			
		||||
        ("passbook_core", "0001_initial"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
@ -28,17 +30,11 @@ class Migration(migrations.Migration):
 | 
			
		||||
                        to="passbook_core.PropertyMapping",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("saml_name", models.TextField()),
 | 
			
		||||
                ("saml_name", models.TextField(verbose_name="SAML Name")),
 | 
			
		||||
                (
 | 
			
		||||
                    "friendly_name",
 | 
			
		||||
                    models.TextField(blank=True, default=None, null=True),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "values",
 | 
			
		||||
                    django.contrib.postgres.fields.ArrayField(
 | 
			
		||||
                        base_field=models.TextField(), size=None
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
            options={
 | 
			
		||||
                "verbose_name": "SAML Property Mapping",
 | 
			
		||||
@ -61,14 +57,79 @@ class Migration(migrations.Migration):
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("name", models.TextField()),
 | 
			
		||||
                ("acs_url", models.URLField()),
 | 
			
		||||
                ("processor_path", models.CharField(choices=[], max_length=255)),
 | 
			
		||||
                ("acs_url", models.URLField(verbose_name="ACS URL")),
 | 
			
		||||
                ("audience", models.TextField(default="")),
 | 
			
		||||
                ("processor_path", models.CharField(max_length=255)),
 | 
			
		||||
                ("issuer", models.TextField()),
 | 
			
		||||
                ("assertion_valid_for", models.IntegerField(default=86400)),
 | 
			
		||||
                ("signing", models.BooleanField(default=True)),
 | 
			
		||||
                ("signing_cert", models.TextField()),
 | 
			
		||||
                ("signing_key", models.TextField()),
 | 
			
		||||
                ("issuer", models.TextField(help_text="Also known as EntityID")),
 | 
			
		||||
                (
 | 
			
		||||
                    "assertion_valid_not_before",
 | 
			
		||||
                    models.TextField(
 | 
			
		||||
                        default="minutes=-5",
 | 
			
		||||
                        help_text="Assertion valid not before current time + this value (Format: hours=-1;minutes=-2;seconds=-3).",
 | 
			
		||||
                        validators=[
 | 
			
		||||
                            passbook.providers.saml.utils.time.timedelta_string_validator
 | 
			
		||||
                        ],
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "assertion_valid_not_on_or_after",
 | 
			
		||||
                    models.TextField(
 | 
			
		||||
                        default="minutes=5",
 | 
			
		||||
                        help_text="Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3).",
 | 
			
		||||
                        validators=[
 | 
			
		||||
                            passbook.providers.saml.utils.time.timedelta_string_validator
 | 
			
		||||
                        ],
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "session_valid_not_on_or_after",
 | 
			
		||||
                    models.TextField(
 | 
			
		||||
                        default="minutes=86400",
 | 
			
		||||
                        help_text="Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3).",
 | 
			
		||||
                        validators=[
 | 
			
		||||
                            passbook.providers.saml.utils.time.timedelta_string_validator
 | 
			
		||||
                        ],
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "digest_algorithm",
 | 
			
		||||
                    models.CharField(
 | 
			
		||||
                        choices=[("sha1", "SHA1"), ("sha256", "SHA256")],
 | 
			
		||||
                        default="sha256",
 | 
			
		||||
                        max_length=50,
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "signature_algorithm",
 | 
			
		||||
                    models.CharField(
 | 
			
		||||
                        choices=[
 | 
			
		||||
                            ("rsa-sha1", "RSA-SHA1"),
 | 
			
		||||
                            ("rsa-sha256", "RSA-SHA256"),
 | 
			
		||||
                            ("ecdsa-sha256", "ECDSA-SHA256"),
 | 
			
		||||
                            ("dsa-sha1", "DSA-SHA1"),
 | 
			
		||||
                        ],
 | 
			
		||||
                        default="rsa-sha256",
 | 
			
		||||
                        max_length=50,
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "require_signing",
 | 
			
		||||
                    models.BooleanField(
 | 
			
		||||
                        default=False,
 | 
			
		||||
                        help_text="Require Requests to be signed by an X509 Certificate. Must match the Certificate selected in `Singing Keypair`.",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "signing_kp",
 | 
			
		||||
                    models.ForeignKey(
 | 
			
		||||
                        default=None,
 | 
			
		||||
                        help_text="Singing is enabled upon selection of a Key Pair.",
 | 
			
		||||
                        null=True,
 | 
			
		||||
                        on_delete=django.db.models.deletion.SET_NULL,
 | 
			
		||||
                        to="passbook_crypto.CertificateKeyPair",
 | 
			
		||||
                        verbose_name="Signing Keypair",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
            options={
 | 
			
		||||
                "verbose_name": "SAML Provider",
 | 
			
		||||
 | 
			
		||||
@ -1,61 +0,0 @@
 | 
			
		||||
# Generated by Django 2.2.9 on 2020-02-14 13:54
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
import passbook.providers.saml.utils.time
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def migrate_valid_for(apps, schema_editor):
 | 
			
		||||
    """Migrate from single number standing for minutes to 'minutes=3'"""
 | 
			
		||||
    SAMLProvider = apps.get_model("passbook_providers_saml", "SAMLProvider")
 | 
			
		||||
    db_alias = schema_editor.connection.alias
 | 
			
		||||
    for provider in SAMLProvider.objects.using(db_alias).all():
 | 
			
		||||
        provider.assertion_valid_not_on_or_after = (
 | 
			
		||||
            f"minutes={provider.assertion_valid_for}"
 | 
			
		||||
        )
 | 
			
		||||
        provider.save()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_providers_saml", "0001_initial"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="samlprovider",
 | 
			
		||||
            name="assertion_valid_not_before",
 | 
			
		||||
            field=models.TextField(
 | 
			
		||||
                default="minutes=5",
 | 
			
		||||
                help_text="Assertion valid not before current time - this value (Format: hours=1;minutes=2;seconds=3).",
 | 
			
		||||
                validators=[
 | 
			
		||||
                    passbook.providers.saml.utils.time.timedelta_string_validator
 | 
			
		||||
                ],
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="samlprovider",
 | 
			
		||||
            name="assertion_valid_not_on_or_after",
 | 
			
		||||
            field=models.TextField(
 | 
			
		||||
                default="minutes=5",
 | 
			
		||||
                help_text="Assertion not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3).",
 | 
			
		||||
                validators=[
 | 
			
		||||
                    passbook.providers.saml.utils.time.timedelta_string_validator
 | 
			
		||||
                ],
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.RunPython(migrate_valid_for),
 | 
			
		||||
        migrations.RemoveField(model_name="samlprovider", name="assertion_valid_for",),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="samlprovider",
 | 
			
		||||
            name="session_valid_not_on_or_after",
 | 
			
		||||
            field=models.TextField(
 | 
			
		||||
                default="minutes=86400",
 | 
			
		||||
                help_text="Session not valid on or after current time + this value (Format: hours=1;minutes=2;seconds=3).",
 | 
			
		||||
                validators=[
 | 
			
		||||
                    passbook.providers.saml.utils.time.timedelta_string_validator
 | 
			
		||||
                ],
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,38 +0,0 @@
 | 
			
		||||
# Generated by Django 2.2.9 on 2020-02-16 11:09
 | 
			
		||||
 | 
			
		||||
import django.contrib.postgres.fields
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_providers_saml", "0002_auto_20200214_1354"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="samlpropertymapping",
 | 
			
		||||
            name="saml_name",
 | 
			
		||||
            field=models.TextField(verbose_name="SAML Name"),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="samlpropertymapping",
 | 
			
		||||
            name="values",
 | 
			
		||||
            field=django.contrib.postgres.fields.ArrayField(
 | 
			
		||||
                base_field=models.TextField(),
 | 
			
		||||
                help_text="This string can contain string substitutions delimited by {}. The following Variables are available: user, request",
 | 
			
		||||
                size=None,
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="samlprovider",
 | 
			
		||||
            name="acs_url",
 | 
			
		||||
            field=models.URLField(verbose_name="ACS URL"),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="samlprovider",
 | 
			
		||||
            name="signing_cert",
 | 
			
		||||
            field=models.TextField(verbose_name="Singing Certificate"),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,41 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-02-17 15:26
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_providers_saml", "0003_auto_20200216_1109"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="samlprovider",
 | 
			
		||||
            name="digest_algorithm",
 | 
			
		||||
            field=models.CharField(
 | 
			
		||||
                choices=[("sha1", "SHA1"), ("sha256", "SHA256")],
 | 
			
		||||
                default="sha256",
 | 
			
		||||
                max_length=50,
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="samlprovider",
 | 
			
		||||
            name="signature_algorithm",
 | 
			
		||||
            field=models.CharField(
 | 
			
		||||
                choices=[
 | 
			
		||||
                    ("rsa-sha1", "RSA-SHA1"),
 | 
			
		||||
                    ("rsa-sha256", "RSA-SHA256"),
 | 
			
		||||
                    ("ecdsa-sha256", "ECDSA-SHA256"),
 | 
			
		||||
                    ("dsa-sha1", "DSA-SHA1"),
 | 
			
		||||
                ],
 | 
			
		||||
                default="rsa-sha256",
 | 
			
		||||
                max_length=50,
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="samlprovider",
 | 
			
		||||
            name="processor_path",
 | 
			
		||||
            field=models.CharField(choices=[], max_length=255),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,76 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-02-17 16:15
 | 
			
		||||
 | 
			
		||||
from django.db import migrations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def cleanup_old_autogenerated(apps, schema_editor):
 | 
			
		||||
    SAMLPropertyMapping = apps.get_model(
 | 
			
		||||
        "passbook_providers_saml", "SAMLPropertyMapping"
 | 
			
		||||
    )
 | 
			
		||||
    db_alias = schema_editor.connection.alias
 | 
			
		||||
    SAMLPropertyMapping.objects.using(db_alias).filter(
 | 
			
		||||
        name__startswith="Autogenerated"
 | 
			
		||||
    ).delete()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def create_default_property_mappings(apps, schema_editor):
 | 
			
		||||
    """Create default SAML Property Mappings"""
 | 
			
		||||
    SAMLPropertyMapping = apps.get_model(
 | 
			
		||||
        "passbook_providers_saml", "SAMLPropertyMapping"
 | 
			
		||||
    )
 | 
			
		||||
    db_alias = schema_editor.connection.alias
 | 
			
		||||
    defaults = [
 | 
			
		||||
        {
 | 
			
		||||
            "FriendlyName": "eduPersonPrincipalName",
 | 
			
		||||
            "Name": "urn:oid:1.3.6.1.4.1.5923.1.1.1.6",
 | 
			
		||||
            "Expression": "{{ user.email }}",
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "FriendlyName": "cn",
 | 
			
		||||
            "Name": "urn:oid:2.5.4.3",
 | 
			
		||||
            "Expression": "{{ user.name }}",
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "FriendlyName": "mail",
 | 
			
		||||
            "Name": "urn:oid:0.9.2342.19200300.100.1.3",
 | 
			
		||||
            "Expression": "{{ user.email }}",
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "FriendlyName": "displayName",
 | 
			
		||||
            "Name": "urn:oid:2.16.840.1.113730.3.1.241",
 | 
			
		||||
            "Expression": "{{ user.username }}",
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "FriendlyName": "uid",
 | 
			
		||||
            "Name": "urn:oid:0.9.2342.19200300.100.1.1",
 | 
			
		||||
            "Expression": "{{ user.pk }}",
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "FriendlyName": "member-of",
 | 
			
		||||
            "Name": "member-of",
 | 
			
		||||
            "Expression": "[{% for group in user.groups.all() %}'{{ group.name }}',{% endfor %}]",
 | 
			
		||||
        },
 | 
			
		||||
    ]
 | 
			
		||||
    for default in defaults:
 | 
			
		||||
        SAMLPropertyMapping.objects.using(db_alias).get_or_create(
 | 
			
		||||
            saml_name=default["Name"],
 | 
			
		||||
            friendly_name=default["FriendlyName"],
 | 
			
		||||
            expression=default["Expression"],
 | 
			
		||||
            defaults={
 | 
			
		||||
                "name": f"Autogenerated SAML Mapping: {default['FriendlyName']} -> {default['Expression']}"
 | 
			
		||||
            },
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_providers_saml", "0004_auto_20200217_1526"),
 | 
			
		||||
        ("passbook_core", "0007_auto_20200217_1934"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.RunPython(cleanup_old_autogenerated),
 | 
			
		||||
        migrations.RemoveField(model_name="samlpropertymapping", name="values",),
 | 
			
		||||
        migrations.RunPython(create_default_property_mappings),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,26 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-02-17 20:31
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
import passbook.providers.saml.utils.time
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_providers_saml", "0005_remove_samlpropertymapping_values"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="samlprovider",
 | 
			
		||||
            name="assertion_valid_not_before",
 | 
			
		||||
            field=models.TextField(
 | 
			
		||||
                default="minutes=-5",
 | 
			
		||||
                help_text="Assertion valid not before current time + this value (Format: hours=-1;minutes=-2;seconds=-3).",
 | 
			
		||||
                validators=[
 | 
			
		||||
                    passbook.providers.saml.utils.time.timedelta_string_validator
 | 
			
		||||
                ],
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,29 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-03-03 21:57
 | 
			
		||||
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_crypto", "0001_initial"),
 | 
			
		||||
        ("passbook_providers_saml", "0006_auto_20200217_2031"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.RemoveField(model_name="samlprovider", name="signing",),
 | 
			
		||||
        migrations.RemoveField(model_name="samlprovider", name="signing_cert",),
 | 
			
		||||
        migrations.RemoveField(model_name="samlprovider", name="signing_key",),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="samlprovider",
 | 
			
		||||
            name="singing_kp",
 | 
			
		||||
            field=models.ForeignKey(
 | 
			
		||||
                default=None,
 | 
			
		||||
                help_text="Singing is enabled upon selection of a Key Pair.",
 | 
			
		||||
                null=True,
 | 
			
		||||
                on_delete=django.db.models.deletion.SET_NULL,
 | 
			
		||||
                to="passbook_crypto.CertificateKeyPair",
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,16 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-03-05 16:06
 | 
			
		||||
 | 
			
		||||
from django.db import migrations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_providers_saml", "0007_auto_20200303_2157"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.RenameField(
 | 
			
		||||
            model_name="samlprovider", old_name="singing_kp", new_name="signing_kp",
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,40 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-05-06 15:51
 | 
			
		||||
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_crypto", "0001_initial"),
 | 
			
		||||
        ("passbook_providers_saml", "0008_auto_20200305_1606"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="samlprovider",
 | 
			
		||||
            name="require_signing",
 | 
			
		||||
            field=models.BooleanField(
 | 
			
		||||
                default=False,
 | 
			
		||||
                help_text="Require Requests to be signed by an X509 Certificate. Must match the Certificate selected in `Singing Keypair`.",
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="samlprovider",
 | 
			
		||||
            name="issuer",
 | 
			
		||||
            field=models.TextField(help_text="Also known as EntityID"),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="samlprovider",
 | 
			
		||||
            name="signing_kp",
 | 
			
		||||
            field=models.ForeignKey(
 | 
			
		||||
                default=None,
 | 
			
		||||
                help_text="Singing is enabled upon selection of a Key Pair.",
 | 
			
		||||
                null=True,
 | 
			
		||||
                on_delete=django.db.models.deletion.SET_NULL,
 | 
			
		||||
                to="passbook_crypto.CertificateKeyPair",
 | 
			
		||||
                verbose_name="Signing Keypair",
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -32,7 +32,9 @@ class Command(BaseCommand):
 | 
			
		||||
 | 
			
		||||
    def get_url(self, token: Token) -> str:
 | 
			
		||||
        """Get full recovery link"""
 | 
			
		||||
        path = reverse("passbook_recovery:use-token", kwargs={"uuid": str(token.uuid)})
 | 
			
		||||
        path = reverse(
 | 
			
		||||
            "passbook_recovery:use-token", kwargs={"uuid": str(token.token_uuid)}
 | 
			
		||||
        )
 | 
			
		||||
        return f"https://{CONFIG.y('domain')}{path}"
 | 
			
		||||
 | 
			
		||||
    def handle(self, *args, **options):
 | 
			
		||||
 | 
			
		||||
@ -30,6 +30,8 @@ class TestRecovery(TestCase):
 | 
			
		||||
        call_command("create_recovery_key", "1", self.user.username, stdout=out)
 | 
			
		||||
        token = Token.objects.first()
 | 
			
		||||
        self.client.get(
 | 
			
		||||
            reverse("passbook_recovery:use-token", kwargs={"uuid": str(token.uuid)})
 | 
			
		||||
            reverse(
 | 
			
		||||
                "passbook_recovery:use-token", kwargs={"uuid": str(token.token_uuid)}
 | 
			
		||||
            )
 | 
			
		||||
        )
 | 
			
		||||
        self.assertEqual(int(self.client.session["_auth_user_id"]), token.user.pk)
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Generated by Django 2.2.6 on 2019-10-08 20:43
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:08
 | 
			
		||||
 | 
			
		||||
import django.core.validators
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
@ -28,10 +28,12 @@ class Migration(migrations.Migration):
 | 
			
		||||
                        to="passbook_core.PropertyMapping",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("ldap_property", models.TextField()),
 | 
			
		||||
                ("object_field", models.TextField()),
 | 
			
		||||
            ],
 | 
			
		||||
            options={"abstract": False,},
 | 
			
		||||
            options={
 | 
			
		||||
                "verbose_name": "LDAP Property Mapping",
 | 
			
		||||
                "verbose_name_plural": "LDAP Property Mappings",
 | 
			
		||||
            },
 | 
			
		||||
            bases=("passbook_core.propertymapping",),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.CreateModel(
 | 
			
		||||
@ -50,38 +52,71 @@ class Migration(migrations.Migration):
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "server_uri",
 | 
			
		||||
                    models.URLField(
 | 
			
		||||
                    models.TextField(
 | 
			
		||||
                        validators=[
 | 
			
		||||
                            django.core.validators.URLValidator(
 | 
			
		||||
                                schemes=["ldap", "ldaps"]
 | 
			
		||||
                            )
 | 
			
		||||
                        ]
 | 
			
		||||
                        ],
 | 
			
		||||
                        verbose_name="Server URI",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("bind_cn", models.TextField()),
 | 
			
		||||
                ("bind_cn", models.TextField(verbose_name="Bind CN")),
 | 
			
		||||
                ("bind_password", models.TextField()),
 | 
			
		||||
                ("start_tls", models.BooleanField(default=False)),
 | 
			
		||||
                ("base_dn", models.TextField()),
 | 
			
		||||
                (
 | 
			
		||||
                    "start_tls",
 | 
			
		||||
                    models.BooleanField(default=False, verbose_name="Enable Start TLS"),
 | 
			
		||||
                ),
 | 
			
		||||
                ("base_dn", models.TextField(verbose_name="Base DN")),
 | 
			
		||||
                (
 | 
			
		||||
                    "additional_user_dn",
 | 
			
		||||
                    models.TextField(
 | 
			
		||||
                        help_text="Prepended to Base DN for User-queries."
 | 
			
		||||
                        help_text="Prepended to Base DN for User-queries.",
 | 
			
		||||
                        verbose_name="Addition User DN",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "additional_group_dn",
 | 
			
		||||
                    models.TextField(
 | 
			
		||||
                        help_text="Prepended to Base DN for Group-queries."
 | 
			
		||||
                        help_text="Prepended to Base DN for Group-queries.",
 | 
			
		||||
                        verbose_name="Addition Group DN",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "user_object_filter",
 | 
			
		||||
                    models.TextField(
 | 
			
		||||
                        default="(objectCategory=Person)",
 | 
			
		||||
                        help_text="Consider Objects matching this filter to be Users.",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "user_group_membership_field",
 | 
			
		||||
                    models.TextField(
 | 
			
		||||
                        default="memberOf",
 | 
			
		||||
                        help_text="Field which contains Groups of user.",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "group_object_filter",
 | 
			
		||||
                    models.TextField(
 | 
			
		||||
                        default="(objectCategory=Group)",
 | 
			
		||||
                        help_text="Consider Objects matching this filter to be Groups.",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "object_uniqueness_field",
 | 
			
		||||
                    models.TextField(
 | 
			
		||||
                        default="objectSid",
 | 
			
		||||
                        help_text="Field which contains a unique Identifier.",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("user_object_filter", models.TextField()),
 | 
			
		||||
                ("group_object_filter", models.TextField()),
 | 
			
		||||
                ("sync_groups", models.BooleanField(default=True)),
 | 
			
		||||
                (
 | 
			
		||||
                    "sync_parent_group",
 | 
			
		||||
                    models.ForeignKey(
 | 
			
		||||
                        blank=True,
 | 
			
		||||
                        default=None,
 | 
			
		||||
                        null=True,
 | 
			
		||||
                        on_delete=django.db.models.deletion.SET_DEFAULT,
 | 
			
		||||
                        to="passbook_core.Group",
 | 
			
		||||
                    ),
 | 
			
		||||
 | 
			
		||||
@ -1,20 +0,0 @@
 | 
			
		||||
# Generated by Django 2.2.6 on 2019-10-11 08:25
 | 
			
		||||
 | 
			
		||||
from django.db import migrations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_sources_ldap", "0001_initial"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AlterModelOptions(
 | 
			
		||||
            name="ldappropertymapping",
 | 
			
		||||
            options={
 | 
			
		||||
                "verbose_name": "LDAP Property Mapping",
 | 
			
		||||
                "verbose_name_plural": "LDAP Property Mappings",
 | 
			
		||||
            },
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,33 +0,0 @@
 | 
			
		||||
# Generated by Django 2.2.6 on 2019-10-11 08:25
 | 
			
		||||
 | 
			
		||||
from django.apps.registry import Apps
 | 
			
		||||
from django.db import migrations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def create_default_ad_property_mappings(apps: Apps, schema_editor):
 | 
			
		||||
    LDAPPropertyMapping = apps.get_model("passbook_sources_ldap", "LDAPPropertyMapping")
 | 
			
		||||
    mapping = {
 | 
			
		||||
        "name": "name",
 | 
			
		||||
        "givenName": "first_name",
 | 
			
		||||
        "sn": "last_name",
 | 
			
		||||
        "sAMAccountName": "username",
 | 
			
		||||
        "mail": "email",
 | 
			
		||||
    }
 | 
			
		||||
    db_alias = schema_editor.connection.alias
 | 
			
		||||
    for ldap_property, object_field in mapping.items():
 | 
			
		||||
        LDAPPropertyMapping.objects.using(db_alias).get_or_create(
 | 
			
		||||
            ldap_property=ldap_property,
 | 
			
		||||
            object_field=object_field,
 | 
			
		||||
            defaults={
 | 
			
		||||
                "name": f"Autogenerated LDAP Mapping: {ldap_property} -> {object_field}"
 | 
			
		||||
            },
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_sources_ldap", "0002_auto_20191011_0825"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [migrations.RunPython(create_default_ad_property_mappings)]
 | 
			
		||||
@ -1,35 +0,0 @@
 | 
			
		||||
# Generated by Django 2.2.6 on 2019-10-11 08:39
 | 
			
		||||
 | 
			
		||||
import django.core.validators
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_sources_ldap", "0003_auto_20191011_0825"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="ldapsource",
 | 
			
		||||
            name="server_uri",
 | 
			
		||||
            field=models.TextField(
 | 
			
		||||
                validators=[
 | 
			
		||||
                    django.core.validators.URLValidator(schemes=["ldap", "ldaps"])
 | 
			
		||||
                ]
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="ldapsource",
 | 
			
		||||
            name="sync_parent_group",
 | 
			
		||||
            field=models.ForeignKey(
 | 
			
		||||
                blank=True,
 | 
			
		||||
                default=None,
 | 
			
		||||
                null=True,
 | 
			
		||||
                on_delete=django.db.models.deletion.SET_DEFAULT,
 | 
			
		||||
                to="passbook_core.Group",
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,44 +0,0 @@
 | 
			
		||||
# Generated by Django 2.2.6 on 2019-10-11 10:59
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_sources_ldap", "0004_auto_20191011_0839"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="ldapsource",
 | 
			
		||||
            name="object_uniqueness_field",
 | 
			
		||||
            field=models.TextField(
 | 
			
		||||
                default="objectSid",
 | 
			
		||||
                help_text="Field which contains a unique Identifier.",
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="ldapsource",
 | 
			
		||||
            name="user_group_membership_field",
 | 
			
		||||
            field=models.TextField(
 | 
			
		||||
                default="memberOf", help_text="Field which contains Groups of user."
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="ldapsource",
 | 
			
		||||
            name="group_object_filter",
 | 
			
		||||
            field=models.TextField(
 | 
			
		||||
                default="(objectCategory=Group)",
 | 
			
		||||
                help_text="Consider Objects matching this filter to be Groups.",
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="ldapsource",
 | 
			
		||||
            name="user_object_filter",
 | 
			
		||||
            field=models.TextField(
 | 
			
		||||
                default="(objectCategory=Person)",
 | 
			
		||||
                help_text="Consider Objects matching this filter to be Users.",
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,60 +0,0 @@
 | 
			
		||||
# Generated by Django 2.2.9 on 2020-02-16 11:16
 | 
			
		||||
 | 
			
		||||
import django.core.validators
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_sources_ldap", "0005_auto_20191011_1059"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="ldappropertymapping",
 | 
			
		||||
            name="ldap_property",
 | 
			
		||||
            field=models.TextField(verbose_name="LDAP Property"),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="ldapsource",
 | 
			
		||||
            name="additional_group_dn",
 | 
			
		||||
            field=models.TextField(
 | 
			
		||||
                help_text="Prepended to Base DN for Group-queries.",
 | 
			
		||||
                verbose_name="Addition Group DN",
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="ldapsource",
 | 
			
		||||
            name="additional_user_dn",
 | 
			
		||||
            field=models.TextField(
 | 
			
		||||
                help_text="Prepended to Base DN for User-queries.",
 | 
			
		||||
                verbose_name="Addition User DN",
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="ldapsource",
 | 
			
		||||
            name="base_dn",
 | 
			
		||||
            field=models.TextField(verbose_name="Base DN"),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="ldapsource",
 | 
			
		||||
            name="bind_cn",
 | 
			
		||||
            field=models.TextField(verbose_name="Bind CN"),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="ldapsource",
 | 
			
		||||
            name="server_uri",
 | 
			
		||||
            field=models.TextField(
 | 
			
		||||
                validators=[
 | 
			
		||||
                    django.core.validators.URLValidator(schemes=["ldap", "ldaps"])
 | 
			
		||||
                ],
 | 
			
		||||
                verbose_name="Server URI",
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="ldapsource",
 | 
			
		||||
            name="start_tls",
 | 
			
		||||
            field=models.BooleanField(default=False, verbose_name="Enable Start TLS"),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,46 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-02-17 16:19
 | 
			
		||||
 | 
			
		||||
from django.apps.registry import Apps
 | 
			
		||||
from django.db import migrations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def cleanup_old_autogenerated(apps, schema_editor):
 | 
			
		||||
    LDAPPropertyMapping = apps.get_model("passbook_sources_ldap", "LDAPPropertyMapping")
 | 
			
		||||
    db_alias = schema_editor.connection.alias
 | 
			
		||||
    LDAPPropertyMapping.objects.using(db_alias).filter(
 | 
			
		||||
        name__startswith="Autogenerated"
 | 
			
		||||
    ).delete()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def create_default_ad_property_mappings(apps: Apps, schema_editor):
 | 
			
		||||
    LDAPPropertyMapping = apps.get_model("passbook_sources_ldap", "LDAPPropertyMapping")
 | 
			
		||||
    mapping = {
 | 
			
		||||
        "name": "{{ ldap.name }}",
 | 
			
		||||
        "first_name": "{{ ldap.givenName }}",
 | 
			
		||||
        "last_name": "{{ ldap.sn }}",
 | 
			
		||||
        "username": "{{ ldap.sAMAccountName }}",
 | 
			
		||||
        "email": "{{ ldap.mail }}",
 | 
			
		||||
    }
 | 
			
		||||
    db_alias = schema_editor.connection.alias
 | 
			
		||||
    for object_field, expression in mapping.items():
 | 
			
		||||
        LDAPPropertyMapping.objects.using(db_alias).get_or_create(
 | 
			
		||||
            expression=expression,
 | 
			
		||||
            object_field=object_field,
 | 
			
		||||
            defaults={
 | 
			
		||||
                "name": f"Autogenerated LDAP Mapping: {expression} -> {object_field}"
 | 
			
		||||
            },
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_sources_ldap", "0006_auto_20200216_1116"),
 | 
			
		||||
        ("passbook_core", "0007_auto_20200217_1934"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.RunPython(cleanup_old_autogenerated),
 | 
			
		||||
        migrations.RemoveField(model_name="ldappropertymapping", name="ldap_property",),
 | 
			
		||||
        migrations.RunPython(create_default_ad_property_mappings),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Generated by Django 2.2.6 on 2019-10-07 14:07
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:08
 | 
			
		||||
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
@ -28,10 +28,24 @@ class Migration(migrations.Migration):
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("provider_type", models.CharField(max_length=255)),
 | 
			
		||||
                ("request_token_url", models.CharField(blank=True, max_length=255)),
 | 
			
		||||
                ("authorization_url", models.CharField(max_length=255)),
 | 
			
		||||
                ("access_token_url", models.CharField(max_length=255)),
 | 
			
		||||
                ("profile_url", models.CharField(max_length=255)),
 | 
			
		||||
                (
 | 
			
		||||
                    "request_token_url",
 | 
			
		||||
                    models.CharField(
 | 
			
		||||
                        blank=True, max_length=255, verbose_name="Request Token URL"
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "authorization_url",
 | 
			
		||||
                    models.CharField(max_length=255, verbose_name="Authorization URL"),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "access_token_url",
 | 
			
		||||
                    models.CharField(max_length=255, verbose_name="Access Token URL"),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "profile_url",
 | 
			
		||||
                    models.CharField(max_length=255, verbose_name="Profile URL"),
 | 
			
		||||
                ),
 | 
			
		||||
                ("consumer_key", models.TextField()),
 | 
			
		||||
                ("consumer_secret", models.TextField()),
 | 
			
		||||
            ],
 | 
			
		||||
 | 
			
		||||
@ -1,35 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-02-17 15:26
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_sources_oauth", "0001_initial"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="oauthsource",
 | 
			
		||||
            name="access_token_url",
 | 
			
		||||
            field=models.CharField(max_length=255, verbose_name="Access Token URL"),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="oauthsource",
 | 
			
		||||
            name="authorization_url",
 | 
			
		||||
            field=models.CharField(max_length=255, verbose_name="Authorization URL"),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="oauthsource",
 | 
			
		||||
            name="profile_url",
 | 
			
		||||
            field=models.CharField(max_length=255, verbose_name="Profile URL"),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="oauthsource",
 | 
			
		||||
            name="request_token_url",
 | 
			
		||||
            field=models.CharField(
 | 
			
		||||
                blank=True, max_length=255, verbose_name="Request Token URL"
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -60,6 +60,9 @@ class OAuthSource(Source):
 | 
			
		||||
            view_name=reverse((view_name), kwargs={"source_slug": self.slug}),
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    def __str__(self) -> str:
 | 
			
		||||
        return f"OAuth Source {self.name}"
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
 | 
			
		||||
        verbose_name = _("Generic OAuth Source")
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@ class OpenIDConnectOAuthRedirect(OAuthRedirect):
 | 
			
		||||
 | 
			
		||||
    def get_additional_parameters(self, source: OAuthSource):
 | 
			
		||||
        return {
 | 
			
		||||
            "scope": "openid email",
 | 
			
		||||
            "scope": "openid email profile",
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -26,9 +26,9 @@ class OpenIDConnectOAuth2Callback(OAuthCallback):
 | 
			
		||||
 | 
			
		||||
    def get_or_create_user(self, source: OAuthSource, access, info: Dict[str, str]):
 | 
			
		||||
        user_data = {
 | 
			
		||||
            "username": info.get("username"),
 | 
			
		||||
            "username": info.get("nickname"),
 | 
			
		||||
            "email": info.get("email"),
 | 
			
		||||
            "name": info.get("username"),
 | 
			
		||||
            "name": info.get("name"),
 | 
			
		||||
            "password": None,
 | 
			
		||||
        }
 | 
			
		||||
        return user_get_or_create(**user_data)
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Generated by Django 2.2.6 on 2019-11-07 13:54
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:08
 | 
			
		||||
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
@ -9,7 +9,8 @@ class Migration(migrations.Migration):
 | 
			
		||||
    initial = True
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_core", "0005_merge_20191025_2022"),
 | 
			
		||||
        ("passbook_crypto", "0001_initial"),
 | 
			
		||||
        ("passbook_core", "0001_initial"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
@ -27,15 +28,41 @@ class Migration(migrations.Migration):
 | 
			
		||||
                        to="passbook_core.Source",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("acs_url", models.URLField()),
 | 
			
		||||
                ("slo_url", models.URLField()),
 | 
			
		||||
                ("entity_id", models.TextField(blank=True, default=None)),
 | 
			
		||||
                ("idp_url", models.URLField()),
 | 
			
		||||
                (
 | 
			
		||||
                    "issuer",
 | 
			
		||||
                    models.TextField(
 | 
			
		||||
                        blank=True,
 | 
			
		||||
                        default=None,
 | 
			
		||||
                        help_text="Also known as Entity ID. Defaults the Metadata URL.",
 | 
			
		||||
                        verbose_name="Issuer",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("idp_url", models.URLField(verbose_name="IDP URL")),
 | 
			
		||||
                (
 | 
			
		||||
                    "idp_logout_url",
 | 
			
		||||
                    models.URLField(
 | 
			
		||||
                        blank=True,
 | 
			
		||||
                        default=None,
 | 
			
		||||
                        null=True,
 | 
			
		||||
                        verbose_name="IDP Logout URL",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("auto_logout", models.BooleanField(default=False)),
 | 
			
		||||
                ("signing_cert", models.TextField()),
 | 
			
		||||
                ("signing_key", models.TextField()),
 | 
			
		||||
                (
 | 
			
		||||
                    "signing_kp",
 | 
			
		||||
                    models.ForeignKey(
 | 
			
		||||
                        default=None,
 | 
			
		||||
                        help_text="Certificate Key Pair of the IdP which Assertions are validated against.",
 | 
			
		||||
                        null=True,
 | 
			
		||||
                        on_delete=django.db.models.deletion.SET_NULL,
 | 
			
		||||
                        to="passbook_crypto.CertificateKeyPair",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
            options={"abstract": False,},
 | 
			
		||||
            options={
 | 
			
		||||
                "verbose_name": "SAML Source",
 | 
			
		||||
                "verbose_name_plural": "SAML Sources",
 | 
			
		||||
            },
 | 
			
		||||
            bases=("passbook_core.source",),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
@ -1,22 +0,0 @@
 | 
			
		||||
# Generated by Django 2.2.6 on 2019-11-07 15:05
 | 
			
		||||
 | 
			
		||||
from django.db import migrations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_sources_saml", "0001_initial"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AlterModelOptions(
 | 
			
		||||
            name="samlsource",
 | 
			
		||||
            options={
 | 
			
		||||
                "verbose_name": "SAML Source",
 | 
			
		||||
                "verbose_name_plural": "SAML Sources",
 | 
			
		||||
            },
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.RemoveField(model_name="samlsource", name="acs_url",),
 | 
			
		||||
        migrations.RemoveField(model_name="samlsource", name="slo_url",),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,19 +0,0 @@
 | 
			
		||||
# Generated by Django 2.2.6 on 2019-11-07 15:50
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_sources_saml", "0002_auto_20191107_1505"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.RemoveField(model_name="samlsource", name="signing_key",),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="samlsource",
 | 
			
		||||
            name="idp_logout_url",
 | 
			
		||||
            field=models.URLField(blank=True, default=None, null=True),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,30 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-02-17 15:26
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_sources_saml", "0003_auto_20191107_1550"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="samlsource",
 | 
			
		||||
            name="entity_id",
 | 
			
		||||
            field=models.TextField(blank=True, default=None, verbose_name="Entity ID"),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="samlsource",
 | 
			
		||||
            name="idp_logout_url",
 | 
			
		||||
            field=models.URLField(
 | 
			
		||||
                blank=True, default=None, null=True, verbose_name="IDP Logout URL"
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="samlsource",
 | 
			
		||||
            name="idp_url",
 | 
			
		||||
            field=models.URLField(verbose_name="IDP URL"),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,26 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-02-20 16:21
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_sources_saml", "0004_auto_20200217_1526"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.RenameField(
 | 
			
		||||
            model_name="samlsource", old_name="entity_id", new_name="issuer",
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="samlsource",
 | 
			
		||||
            name="issuer",
 | 
			
		||||
            field=models.TextField(
 | 
			
		||||
                blank=True,
 | 
			
		||||
                default=None,
 | 
			
		||||
                help_text="Also known as Entity ID. Defaults the Metadata URL.",
 | 
			
		||||
                verbose_name="Issuer",
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,27 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-03-03 22:01
 | 
			
		||||
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_crypto", "0001_initial"),
 | 
			
		||||
        ("passbook_sources_saml", "0005_auto_20200220_1621"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.RemoveField(model_name="samlsource", name="signing_cert",),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="samlsource",
 | 
			
		||||
            name="signing_kp",
 | 
			
		||||
            field=models.ForeignKey(
 | 
			
		||||
                default=None,
 | 
			
		||||
                help_text="Certificate Key Pair of the IdP which Assertions are validated against.",
 | 
			
		||||
                null=True,
 | 
			
		||||
                on_delete=django.db.models.deletion.SET_NULL,
 | 
			
		||||
                to="passbook_crypto.CertificateKeyPair",
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-05-08 17:58
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:08
 | 
			
		||||
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-05-08 17:58
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:08
 | 
			
		||||
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-05-08 17:59
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:08
 | 
			
		||||
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
@ -34,12 +34,33 @@ class Migration(migrations.Migration):
 | 
			
		||||
                ("use_tls", models.BooleanField(default=False)),
 | 
			
		||||
                ("use_ssl", models.BooleanField(default=False)),
 | 
			
		||||
                ("timeout", models.IntegerField(default=10)),
 | 
			
		||||
                ("ssl_keyfile", models.TextField(blank=True, default=None, null=True)),
 | 
			
		||||
                ("ssl_certfile", models.TextField(blank=True, default=None, null=True)),
 | 
			
		||||
                (
 | 
			
		||||
                    "from_address",
 | 
			
		||||
                    models.EmailField(default="system@passbook.local", max_length=254),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "token_expiry",
 | 
			
		||||
                    models.IntegerField(
 | 
			
		||||
                        default=30, help_text="Time in minutes the token sent is valid."
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("subject", models.TextField(default="passbook")),
 | 
			
		||||
                (
 | 
			
		||||
                    "template",
 | 
			
		||||
                    models.TextField(
 | 
			
		||||
                        choices=[
 | 
			
		||||
                            (
 | 
			
		||||
                                "stages/email/for_email/password_reset.html",
 | 
			
		||||
                                "Password Reset",
 | 
			
		||||
                            ),
 | 
			
		||||
                            (
 | 
			
		||||
                                "stages/email/for_email/account_confirmation.html",
 | 
			
		||||
                                "Account Confirmation",
 | 
			
		||||
                            ),
 | 
			
		||||
                        ],
 | 
			
		||||
                        default="stages/email/for_email/password_reset.html",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
            options={
 | 
			
		||||
                "verbose_name": "Email Stage",
 | 
			
		||||
 | 
			
		||||
@ -1,22 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.5 on 2020-05-10 18:44
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_stages_email", "0001_initial"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.RemoveField(model_name="emailstage", name="ssl_certfile",),
 | 
			
		||||
        migrations.RemoveField(model_name="emailstage", name="ssl_keyfile",),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="emailstage",
 | 
			
		||||
            name="token_expiry",
 | 
			
		||||
            field=models.IntegerField(
 | 
			
		||||
                default=30, help_text="Time in minutes the token sent is valid."
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,32 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.5 on 2020-05-15 12:42
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_stages_email", "0002_auto_20200510_1844"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="emailstage",
 | 
			
		||||
            name="subject",
 | 
			
		||||
            field=models.TextField(default="passbook"),
 | 
			
		||||
        ),
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="emailstage",
 | 
			
		||||
            name="template",
 | 
			
		||||
            field=models.TextField(
 | 
			
		||||
                choices=[
 | 
			
		||||
                    ("stages/email/for_email/password_reset.html", "Password Reset"),
 | 
			
		||||
                    (
 | 
			
		||||
                        "stages/email/for_email/account_confirmation.html",
 | 
			
		||||
                        "Account Confirmation",
 | 
			
		||||
                    ),
 | 
			
		||||
                ],
 | 
			
		||||
                default="stages/email/for_email/password_reset.html",
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-05-09 18:34
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:08
 | 
			
		||||
 | 
			
		||||
import django.contrib.postgres.fields
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
@ -32,14 +32,22 @@ class Migration(migrations.Migration):
 | 
			
		||||
                    "user_fields",
 | 
			
		||||
                    django.contrib.postgres.fields.ArrayField(
 | 
			
		||||
                        base_field=models.CharField(
 | 
			
		||||
                            choices=[("e-mail", "E Mail"), ("username", "Username")],
 | 
			
		||||
                            choices=[("email", "E Mail"), ("username", "Username")],
 | 
			
		||||
                            max_length=100,
 | 
			
		||||
                        ),
 | 
			
		||||
                        help_text="Fields of the user object to match against.",
 | 
			
		||||
                        size=None,
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                ("template", models.TextField()),
 | 
			
		||||
                (
 | 
			
		||||
                    "template",
 | 
			
		||||
                    models.TextField(
 | 
			
		||||
                        choices=[
 | 
			
		||||
                            ("stages/identification/login.html", "Default Login"),
 | 
			
		||||
                            ("stages/identification/recovery.html", "Default Recovery"),
 | 
			
		||||
                        ]
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
            options={
 | 
			
		||||
                "verbose_name": "Identification Stage",
 | 
			
		||||
 | 
			
		||||
@ -1,18 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-05-09 19:16
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_stages_identification", "0001_initial"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="identificationstage",
 | 
			
		||||
            name="template",
 | 
			
		||||
            field=models.TextField(choices=[("login/form.html", "Default Login")]),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,26 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-05-09 20:25
 | 
			
		||||
 | 
			
		||||
import django.contrib.postgres.fields
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_stages_identification", "0002_auto_20200509_1916"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="identificationstage",
 | 
			
		||||
            name="user_fields",
 | 
			
		||||
            field=django.contrib.postgres.fields.ArrayField(
 | 
			
		||||
                base_field=models.CharField(
 | 
			
		||||
                    choices=[("email", "E Mail"), ("username", "Username")],
 | 
			
		||||
                    max_length=100,
 | 
			
		||||
                ),
 | 
			
		||||
                help_text="Fields of the user object to match against.",
 | 
			
		||||
                size=None,
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,23 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.5 on 2020-05-10 16:48
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_stages_identification", "0003_auto_20200509_2025"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AlterField(
 | 
			
		||||
            model_name="identificationstage",
 | 
			
		||||
            name="template",
 | 
			
		||||
            field=models.TextField(
 | 
			
		||||
                choices=[
 | 
			
		||||
                    ("stages/identification/login.html", "Default Login"),
 | 
			
		||||
                    ("stages/identification/recovery.html", "Default Recovery"),
 | 
			
		||||
                ]
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Generated by Django 3.0.5 on 2020-05-11 19:09
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:08
 | 
			
		||||
 | 
			
		||||
import uuid
 | 
			
		||||
 | 
			
		||||
@ -13,8 +13,8 @@ class Migration(migrations.Migration):
 | 
			
		||||
    initial = True
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_flows", "0004_auto_20200510_2310"),
 | 
			
		||||
        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
 | 
			
		||||
        ("passbook_flows", "0001_initial"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
@ -32,6 +32,13 @@ class Migration(migrations.Migration):
 | 
			
		||||
                        to="passbook_flows.Stage",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "continue_flow_without_invitation",
 | 
			
		||||
                    models.BooleanField(
 | 
			
		||||
                        default=False,
 | 
			
		||||
                        help_text="If this flag is set, this Stage will jump to the next Stage when no Invitation is given. By default this Stage will cancel the Flow when no invitation is given.",
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
            options={
 | 
			
		||||
                "verbose_name": "Invitation Stage",
 | 
			
		||||
@ -43,7 +50,7 @@ class Migration(migrations.Migration):
 | 
			
		||||
            name="Invitation",
 | 
			
		||||
            fields=[
 | 
			
		||||
                (
 | 
			
		||||
                    "uuid",
 | 
			
		||||
                    "invite_uuid",
 | 
			
		||||
                    models.UUIDField(
 | 
			
		||||
                        default=uuid.uuid4,
 | 
			
		||||
                        editable=False,
 | 
			
		||||
 | 
			
		||||
@ -1,21 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.5 on 2020-05-11 19:46
 | 
			
		||||
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_stages_invitation", "0001_initial"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.AddField(
 | 
			
		||||
            model_name="invitationstage",
 | 
			
		||||
            name="continue_flow_without_invitation",
 | 
			
		||||
            field=models.BooleanField(
 | 
			
		||||
                default=False,
 | 
			
		||||
                help_text="If this flag is set, this Stage will jump to the next Stage when no Invitation is given. By default this Stage will cancel the Flow when no invitation is given.",
 | 
			
		||||
            ),
 | 
			
		||||
        ),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,11 +1,12 @@
 | 
			
		||||
"""invitation stage models"""
 | 
			
		||||
from uuid import uuid4
 | 
			
		||||
 | 
			
		||||
from django.contrib.postgres.fields import JSONField
 | 
			
		||||
from django.db import models
 | 
			
		||||
from django.utils.translation import gettext_lazy as _
 | 
			
		||||
 | 
			
		||||
from passbook.core.models import User
 | 
			
		||||
from passbook.flows.models import Stage
 | 
			
		||||
from passbook.lib.models import UUIDModel
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class InvitationStage(Stage):
 | 
			
		||||
@ -34,15 +35,17 @@ class InvitationStage(Stage):
 | 
			
		||||
        verbose_name_plural = _("Invitation Stages")
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Invitation(UUIDModel):
 | 
			
		||||
class Invitation(models.Model):
 | 
			
		||||
    """Single-use invitation link"""
 | 
			
		||||
 | 
			
		||||
    invite_uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4)
 | 
			
		||||
 | 
			
		||||
    created_by = models.ForeignKey(User, on_delete=models.CASCADE)
 | 
			
		||||
    expires = models.DateTimeField(default=None, blank=True, null=True)
 | 
			
		||||
    fixed_data = JSONField(default=dict)
 | 
			
		||||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        return f"Invitation {self.uuid.hex} created by {self.created_by}"
 | 
			
		||||
        return f"Invitation {self.invite_uuid.hex} created by {self.created_by}"
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-05-08 17:59
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:08
 | 
			
		||||
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Generated by Django 3.0.3 on 2020-05-08 17:58
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:08
 | 
			
		||||
 | 
			
		||||
import django.contrib.postgres.fields
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
@ -11,7 +11,6 @@ class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_flows", "0001_initial"),
 | 
			
		||||
        ("passbook_policies", "0001_initial"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
@ -37,10 +36,6 @@ class Migration(migrations.Migration):
 | 
			
		||||
                        size=None,
 | 
			
		||||
                    ),
 | 
			
		||||
                ),
 | 
			
		||||
                (
 | 
			
		||||
                    "password_policies",
 | 
			
		||||
                    models.ManyToManyField(blank=True, to="passbook_policies.Policy"),
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
            options={
 | 
			
		||||
                "verbose_name": "Password Stage",
 | 
			
		||||
 | 
			
		||||
@ -1,14 +0,0 @@
 | 
			
		||||
# Generated by Django 3.0.5 on 2020-05-10 16:48
 | 
			
		||||
 | 
			
		||||
from django.db import migrations
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Migration(migrations.Migration):
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_stages_password", "0001_initial"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
        migrations.RemoveField(model_name="passwordstage", name="password_policies",),
 | 
			
		||||
    ]
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Generated by Django 3.0.5 on 2020-05-14 11:46
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:08
 | 
			
		||||
 | 
			
		||||
import uuid
 | 
			
		||||
 | 
			
		||||
@ -11,8 +11,8 @@ class Migration(migrations.Migration):
 | 
			
		||||
    initial = True
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_flows", "0005_auto_20200512_1158"),
 | 
			
		||||
        ("passbook_policies", "0001_initial"),
 | 
			
		||||
        ("passbook_flows", "0001_initial"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
@ -20,7 +20,7 @@ class Migration(migrations.Migration):
 | 
			
		||||
            name="Prompt",
 | 
			
		||||
            fields=[
 | 
			
		||||
                (
 | 
			
		||||
                    "uuid",
 | 
			
		||||
                    "prompt_uuid",
 | 
			
		||||
                    models.UUIDField(
 | 
			
		||||
                        default=uuid.uuid4,
 | 
			
		||||
                        editable=False,
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,11 @@
 | 
			
		||||
"""prompt models"""
 | 
			
		||||
from uuid import uuid4
 | 
			
		||||
 | 
			
		||||
from django import forms
 | 
			
		||||
from django.db import models
 | 
			
		||||
from django.utils.translation import gettext_lazy as _
 | 
			
		||||
 | 
			
		||||
from passbook.flows.models import Stage
 | 
			
		||||
from passbook.lib.models import UUIDModel
 | 
			
		||||
from passbook.policies.models import PolicyBindingModel
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -18,9 +19,11 @@ class FieldTypes(models.TextChoices):
 | 
			
		||||
    HIDDEN = "hidden"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Prompt(UUIDModel):
 | 
			
		||||
class Prompt(models.Model):
 | 
			
		||||
    """Single Prompt, part of a prompt stage."""
 | 
			
		||||
 | 
			
		||||
    prompt_uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4)
 | 
			
		||||
 | 
			
		||||
    field_key = models.SlugField(
 | 
			
		||||
        help_text=_("Name of the form field, also used to store the value")
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
# Generated by Django 3.0.5 on 2020-05-12 11:59
 | 
			
		||||
# Generated by Django 3.0.6 on 2020-05-19 22:08
 | 
			
		||||
 | 
			
		||||
import django.db.models.deletion
 | 
			
		||||
from django.db import migrations, models
 | 
			
		||||
@ -9,7 +9,7 @@ class Migration(migrations.Migration):
 | 
			
		||||
    initial = True
 | 
			
		||||
 | 
			
		||||
    dependencies = [
 | 
			
		||||
        ("passbook_flows", "0005_auto_20200512_1158"),
 | 
			
		||||
        ("passbook_flows", "0001_initial"),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    operations = [
 | 
			
		||||
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user