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:
Jens L 2020-05-20 09:17:06 +02:00 committed by GitHub
parent 13a20478fd
commit 24a3e787dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
104 changed files with 671 additions and 2189 deletions

View File

@ -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(),

View File

@ -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):

View File

@ -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):

View File

@ -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):

View File

@ -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):

View File

@ -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",
},
),
]

View File

@ -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",),
]

View File

@ -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"),
]
),
),
]

View File

@ -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),
),
]

View File

@ -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
)

View File

@ -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"
),
),
]

View File

@ -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"),)},
),
]

View File

@ -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=""),
),
]

View File

@ -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
),
),
]

View File

@ -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 = []

View File

@ -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",),
]

View File

@ -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 = []

View File

@ -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,
),
]

View File

@ -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",
),
]

View File

@ -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),
),
]

View File

@ -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."),
),
]

View File

@ -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=""),
),
]

View File

@ -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)]

View File

@ -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",),
]

View File

@ -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 = []

View File

@ -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",),
]

View File

@ -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",),
]

View File

@ -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",),
]

View File

@ -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()

View File

@ -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.",
),
),
]

View File

@ -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(

View File

@ -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",

View File

@ -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,
),
),
]

View File

@ -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,
),
),
]

View File

@ -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,
),
),
]

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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:

View File

@ -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

View File

@ -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",

View File

@ -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",
},
),
]

View File

@ -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",
),
),
]

View File

@ -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)

View File

@ -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

View File

@ -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 = [

View File

@ -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",),
),
]

View File

@ -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",),
]

View File

@ -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",),
),
]

View File

@ -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,
),
]

View File

@ -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

View File

@ -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 = [

View File

@ -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",

View File

@ -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
],
),
),
]

View File

@ -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"),
),
]

View File

@ -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),
),
]

View File

@ -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),
]

View File

@ -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
],
),
),
]

View File

@ -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",
),
),
]

View File

@ -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",
),
]

View File

@ -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",
),
),
]

View File

@ -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):

View File

@ -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)

View File

@ -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",
),

View File

@ -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",
},
),
]

View File

@ -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)]

View File

@ -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",
),
),
]

View File

@ -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.",
),
),
]

View File

@ -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"),
),
]

View File

@ -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),
]

View File

@ -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()),
],

View File

@ -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"
),
),
]

View File

@ -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")

View File

@ -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)

View File

@ -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",),
),
]

View File

@ -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",),
]

View File

@ -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),
),
]

View File

@ -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"),
),
]

View File

@ -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",
),
),
]

View File

@ -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",
),
),
]

View File

@ -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

View File

@ -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

View File

@ -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",

View File

@ -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."
),
),
]

View File

@ -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",
),
),
]

View File

@ -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",

View File

@ -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")]),
),
]

View File

@ -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,
),
),
]

View File

@ -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"),
]
),
),
]

View File

@ -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,

View File

@ -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.",
),
),
]

View File

@ -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:

View File

@ -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

View File

@ -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",

View File

@ -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",),
]

View File

@ -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,

View File

@ -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")
)

View File

@ -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