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(), |         stages_prompts.PromptDeleteView.as_view(), | ||||||
|         name="stage-prompt-delete", |         name="stage-prompt-delete", | ||||||
|     ), |     ), | ||||||
|     # Invitations |     # Stage Invitations | ||||||
|     path( |     path( | ||||||
|         "stages/invitations/", |         "stages/invitations/", | ||||||
|         stages_invitations.InvitationListView.as_view(), |         stages_invitations.InvitationListView.as_view(), | ||||||
|  | |||||||
| @ -38,7 +38,7 @@ class PolicyBindingCreateView( | |||||||
|     form_class = PolicyBindingForm |     form_class = PolicyBindingForm | ||||||
|  |  | ||||||
|     template_name = "generic/create.html" |     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") |     success_message = _("Successfully created PolicyBinding") | ||||||
|  |  | ||||||
|  |  | ||||||
| @ -52,7 +52,7 @@ class PolicyBindingUpdateView( | |||||||
|     form_class = PolicyBindingForm |     form_class = PolicyBindingForm | ||||||
|  |  | ||||||
|     template_name = "generic/update.html" |     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") |     success_message = _("Successfully updated PolicyBinding") | ||||||
|  |  | ||||||
|     def get_context_data(self, **kwargs): |     def get_context_data(self, **kwargs): | ||||||
| @ -72,7 +72,7 @@ class PolicyBindingDeleteView( | |||||||
|     permission_required = "passbook_policies.delete_policybinding" |     permission_required = "passbook_policies.delete_policybinding" | ||||||
|  |  | ||||||
|     template_name = "generic/delete.html" |     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") |     success_message = _("Successfully deleted PolicyBinding") | ||||||
|  |  | ||||||
|     def delete(self, request, *args, **kwargs): |     def delete(self, request, *args, **kwargs): | ||||||
|  | |||||||
| @ -38,7 +38,7 @@ class StageBindingCreateView( | |||||||
|     form_class = FlowStageBindingForm |     form_class = FlowStageBindingForm | ||||||
|  |  | ||||||
|     template_name = "generic/create.html" |     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") |     success_message = _("Successfully created StageBinding") | ||||||
|  |  | ||||||
|     def get_context_data(self, **kwargs): |     def get_context_data(self, **kwargs): | ||||||
| @ -59,7 +59,7 @@ class StageBindingUpdateView( | |||||||
|     form_class = FlowStageBindingForm |     form_class = FlowStageBindingForm | ||||||
|  |  | ||||||
|     template_name = "generic/update.html" |     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") |     success_message = _("Successfully updated StageBinding") | ||||||
|  |  | ||||||
|     def get_context_data(self, **kwargs): |     def get_context_data(self, **kwargs): | ||||||
| @ -79,7 +79,7 @@ class StageBindingDeleteView( | |||||||
|     permission_required = "passbook_flows.delete_flowstagebinding" |     permission_required = "passbook_flows.delete_flowstagebinding" | ||||||
|  |  | ||||||
|     template_name = "generic/delete.html" |     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") |     success_message = _("Successfully deleted FlowStageBinding") | ||||||
|  |  | ||||||
|     def delete(self, request, *args, **kwargs): |     def delete(self, request, *args, **kwargs): | ||||||
|  | |||||||
| @ -40,7 +40,7 @@ class InvitationCreateView( | |||||||
|     permission_required = "passbook_stages_invitation.add_invitation" |     permission_required = "passbook_stages_invitation.add_invitation" | ||||||
|  |  | ||||||
|     template_name = "generic/create.html" |     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") |     success_message = _("Successfully created Invitation") | ||||||
|  |  | ||||||
|     def get_context_data(self, **kwargs): |     def get_context_data(self, **kwargs): | ||||||
| @ -64,7 +64,7 @@ class InvitationDeleteView( | |||||||
|     permission_required = "passbook_stages_invitation.delete_invitation" |     permission_required = "passbook_stages_invitation.delete_invitation" | ||||||
|  |  | ||||||
|     template_name = "generic/delete.html" |     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") |     success_message = _("Successfully deleted Invitation") | ||||||
|  |  | ||||||
|     def delete(self, request, *args, **kwargs): |     def delete(self, request, *args, **kwargs): | ||||||
|  | |||||||
| @ -38,7 +38,7 @@ class PromptCreateView( | |||||||
|     permission_required = "passbook_stages_prompt.add_prompt" |     permission_required = "passbook_stages_prompt.add_prompt" | ||||||
|  |  | ||||||
|     template_name = "generic/create.html" |     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") |     success_message = _("Successfully created Prompt") | ||||||
|  |  | ||||||
|     def get_context_data(self, **kwargs): |     def get_context_data(self, **kwargs): | ||||||
| @ -56,7 +56,7 @@ class PromptUpdateView( | |||||||
|     permission_required = "passbook_stages_prompt.change_prompt" |     permission_required = "passbook_stages_prompt.change_prompt" | ||||||
|  |  | ||||||
|     template_name = "generic/update.html" |     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") |     success_message = _("Successfully updated Prompt") | ||||||
|  |  | ||||||
|  |  | ||||||
| @ -69,7 +69,7 @@ class PromptDeleteView( | |||||||
|     permission_required = "passbook_stages_prompt.delete_prompt" |     permission_required = "passbook_stages_prompt.delete_prompt" | ||||||
|  |  | ||||||
|     template_name = "generic/delete.html" |     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") |     success_message = _("Successfully deleted Prompt") | ||||||
|  |  | ||||||
|     def delete(self, request, *args, **kwargs): |     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 | import uuid | ||||||
|  |  | ||||||
| @ -18,10 +18,10 @@ class Migration(migrations.Migration): | |||||||
|  |  | ||||||
|     operations = [ |     operations = [ | ||||||
|         migrations.CreateModel( |         migrations.CreateModel( | ||||||
|             name="AuditEntry", |             name="Event", | ||||||
|             fields=[ |             fields=[ | ||||||
|                 ( |                 ( | ||||||
|                     "uuid", |                     "event_uuid", | ||||||
|                     models.UUIDField( |                     models.UUIDField( | ||||||
|                         default=uuid.uuid4, |                         default=uuid.uuid4, | ||||||
|                         editable=False, |                         editable=False, | ||||||
| @ -33,15 +33,16 @@ class Migration(migrations.Migration): | |||||||
|                     "action", |                     "action", | ||||||
|                     models.TextField( |                     models.TextField( | ||||||
|                         choices=[ |                         choices=[ | ||||||
|                             ("login", "login"), |                             ("LOGIN", "login"), | ||||||
|                             ("login_failed", "login_failed"), |                             ("LOGIN_FAILED", "login_failed"), | ||||||
|                             ("logout", "logout"), |                             ("LOGOUT", "logout"), | ||||||
|                             ("authorize_application", "authorize_application"), |                             ("AUTHORIZE_APPLICATION", "authorize_application"), | ||||||
|                             ("suspicious_request", "suspicious_request"), |                             ("SUSPICIOUS_REQUEST", "suspicious_request"), | ||||||
|                             ("sign_up", "sign_up"), |                             ("SIGN_UP", "sign_up"), | ||||||
|                             ("password_reset", "password_reset"), |                             ("PASSWORD_RESET", "password_reset"), | ||||||
|                             ("invitation_created", "invitation_created"), |                             ("INVITE_CREATED", "invitation_created"), | ||||||
|                             ("invitation_used", "invitation_used"), |                             ("INVITE_USED", "invitation_used"), | ||||||
|  |                             ("CUSTOM", "custom"), | ||||||
|                         ] |                         ] | ||||||
|                     ), |                     ), | ||||||
|                 ), |                 ), | ||||||
| @ -53,7 +54,7 @@ class Migration(migrations.Migration): | |||||||
|                         blank=True, default=dict |                         blank=True, default=dict | ||||||
|                     ), |                     ), | ||||||
|                 ), |                 ), | ||||||
|                 ("request_ip", models.GenericIPAddressField()), |                 ("client_ip", models.GenericIPAddressField(null=True)), | ||||||
|                 ("created", models.DateTimeField(auto_now_add=True)), |                 ("created", models.DateTimeField(auto_now_add=True)), | ||||||
|                 ( |                 ( | ||||||
|                     "user", |                     "user", | ||||||
| @ -65,8 +66,8 @@ class Migration(migrations.Migration): | |||||||
|                 ), |                 ), | ||||||
|             ], |             ], | ||||||
|             options={ |             options={ | ||||||
|                 "verbose_name": "Audit Entry", |                 "verbose_name": "Audit Event", | ||||||
|                 "verbose_name_plural": "Audit Entries", |                 "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 enum import Enum | ||||||
| from inspect import getmodule, stack | from inspect import getmodule, stack | ||||||
| from typing import Any, Dict, Optional | from typing import Any, Dict, Optional | ||||||
| from uuid import UUID | from uuid import UUID, uuid4 | ||||||
|  |  | ||||||
| from django.conf import settings | from django.conf import settings | ||||||
| from django.contrib.auth.models import AnonymousUser | 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 guardian.shortcuts import get_anonymous_user | ||||||
| from structlog import get_logger | from structlog import get_logger | ||||||
|  |  | ||||||
| from passbook.lib.models import UUIDModel |  | ||||||
| from passbook.lib.utils.http import get_client_ip | from passbook.lib.utils.http import get_client_ip | ||||||
|  |  | ||||||
| LOGGER = get_logger() | LOGGER = get_logger() | ||||||
| @ -71,9 +70,10 @@ class EventAction(Enum): | |||||||
|         ) |         ) | ||||||
|  |  | ||||||
|  |  | ||||||
| class Event(UUIDModel): | class Event(models.Model): | ||||||
|     """An individual audit log event""" |     """An individual audit log event""" | ||||||
|  |  | ||||||
|  |     event_uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4) | ||||||
|     user = models.ForeignKey( |     user = models.ForeignKey( | ||||||
|         settings.AUTH_USER_MODEL, null=True, on_delete=models.SET_NULL |         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 | import uuid | ||||||
|  |  | ||||||
| @ -7,6 +7,7 @@ import django.contrib.auth.validators | |||||||
| import django.contrib.postgres.fields.jsonb | import django.contrib.postgres.fields.jsonb | ||||||
| import django.db.models.deletion | import django.db.models.deletion | ||||||
| import django.utils.timezone | import django.utils.timezone | ||||||
|  | import guardian.mixins | ||||||
| from django.conf import settings | from django.conf import settings | ||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
|  |  | ||||||
| @ -18,8 +19,8 @@ class Migration(migrations.Migration): | |||||||
|     initial = True |     initial = True | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ("auth", "0011_update_proxy_permissions"), |  | ||||||
|         ("passbook_policies", "0001_initial"), |         ("passbook_policies", "0001_initial"), | ||||||
|  |         ("auth", "0011_update_proxy_permissions"), | ||||||
|     ] |     ] | ||||||
|  |  | ||||||
|     operations = [ |     operations = [ | ||||||
| @ -106,69 +107,24 @@ class Migration(migrations.Migration): | |||||||
|                     ), |                     ), | ||||||
|                 ), |                 ), | ||||||
|                 ("uuid", models.UUIDField(default=uuid.uuid4, editable=False)), |                 ("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)), |                 ("password_change_date", models.DateTimeField(auto_now_add=True)), | ||||||
|  |                 ( | ||||||
|  |                     "attributes", | ||||||
|  |                     django.contrib.postgres.fields.jsonb.JSONField( | ||||||
|  |                         blank=True, default=dict | ||||||
|  |                     ), | ||||||
|  |                 ), | ||||||
|             ], |             ], | ||||||
|             options={ |             options={"permissions": (("reset_user_password", "Reset Password"),),}, | ||||||
|                 "verbose_name": "user", |             bases=(guardian.mixins.GuardianUserMixin, models.Model), | ||||||
|                 "verbose_name_plural": "users", |  | ||||||
|                 "abstract": False, |  | ||||||
|             }, |  | ||||||
|             managers=[("objects", django.contrib.auth.models.UserManager()),], |             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( |         migrations.CreateModel( | ||||||
|             name="PropertyMapping", |             name="PropertyMapping", | ||||||
|             fields=[ |             fields=[ | ||||||
|                 ( |                 ( | ||||||
|                     "uuid", |                     "pm_uuid", | ||||||
|                     models.UUIDField( |                     models.UUIDField( | ||||||
|                         default=uuid.uuid4, |                         default=uuid.uuid4, | ||||||
|                         editable=False, |                         editable=False, | ||||||
| @ -177,39 +133,18 @@ class Migration(migrations.Migration): | |||||||
|                     ), |                     ), | ||||||
|                 ), |                 ), | ||||||
|                 ("name", models.TextField()), |                 ("name", models.TextField()), | ||||||
|  |                 ("expression", models.TextField()), | ||||||
|             ], |             ], | ||||||
|             options={ |             options={ | ||||||
|                 "verbose_name": "Property Mapping", |                 "verbose_name": "Property Mapping", | ||||||
|                 "verbose_name_plural": "Property Mappings", |                 "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( |         migrations.CreateModel( | ||||||
|             name="Source", |             name="Source", | ||||||
|             fields=[ |             fields=[ | ||||||
|                 ( |                 ( | ||||||
|                     "policymodel_ptr", |                     "policybindingmodel_ptr", | ||||||
|                     models.OneToOneField( |                     models.OneToOneField( | ||||||
|                         auto_created=True, |                         auto_created=True, | ||||||
|                         on_delete=django.db.models.deletion.CASCADE, |                         on_delete=django.db.models.deletion.CASCADE, | ||||||
| @ -219,13 +154,83 @@ class Migration(migrations.Migration): | |||||||
|                         to="passbook_policies.PolicyBindingModel", |                         to="passbook_policies.PolicyBindingModel", | ||||||
|                     ), |                     ), | ||||||
|                 ), |                 ), | ||||||
|                 ("name", models.TextField()), |                 ("name", models.TextField(help_text="Source's display Name.")), | ||||||
|                 ("slug", models.SlugField()), |                 ( | ||||||
|  |                     "slug", | ||||||
|  |                     models.SlugField(help_text="Internal source name, used in URLs."), | ||||||
|  |                 ), | ||||||
|                 ("enabled", models.BooleanField(default=True)), |                 ("enabled", models.BooleanField(default=True)), | ||||||
|  |                 ( | ||||||
|  |                     "property_mappings", | ||||||
|  |                     models.ManyToManyField( | ||||||
|  |                         blank=True, default=None, to="passbook_core.PropertyMapping" | ||||||
|  |                     ), | ||||||
|  |                 ), | ||||||
|             ], |             ], | ||||||
|             options={"abstract": False,}, |  | ||||||
|             bases=("passbook_policies.policybindingmodel",), |             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( |         migrations.CreateModel( | ||||||
|             name="Provider", |             name="Provider", | ||||||
|             fields=[ |             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( |         migrations.CreateModel( | ||||||
|             name="Group", |             name="Group", | ||||||
|             fields=[ |             fields=[ | ||||||
|                 ( |                 ( | ||||||
|                     "uuid", |                     "group_uuid", | ||||||
|                     models.UUIDField( |                     models.UUIDField( | ||||||
|                         default=uuid.uuid4, |                         default=uuid.uuid4, | ||||||
|                         editable=False, |                         editable=False, | ||||||
| @ -318,7 +265,7 @@ class Migration(migrations.Migration): | |||||||
|                 ), |                 ), | ||||||
|                 ("name", models.CharField(max_length=80, verbose_name="name")), |                 ("name", models.CharField(max_length=80, verbose_name="name")), | ||||||
|                 ( |                 ( | ||||||
|                     "tags", |                     "attributes", | ||||||
|                     django.contrib.postgres.fields.jsonb.JSONField( |                     django.contrib.postgres.fields.jsonb.JSONField( | ||||||
|                         blank=True, default=dict |                         blank=True, default=dict | ||||||
|                     ), |                     ), | ||||||
| @ -336,11 +283,57 @@ class Migration(migrations.Migration): | |||||||
|             ], |             ], | ||||||
|             options={"unique_together": {("name", "parent")},}, |             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( |         migrations.AddField( | ||||||
|             model_name="user", |             model_name="user", | ||||||
|             name="groups", |             name="groups", | ||||||
|             field=models.ManyToManyField(to="passbook_core.Group"), |             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( |         migrations.AddField( | ||||||
|             model_name="user", |             model_name="user", | ||||||
|             name="user_permissions", |             name="user_permissions", | ||||||
| @ -353,75 +346,4 @@ class Migration(migrations.Migration): | |||||||
|                 verbose_name="user permissions", |                 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.http import HttpRequest | ||||||
| from django.utils.timezone import now | from django.utils.timezone import now | ||||||
| from django.utils.translation import gettext_lazy as _ | from django.utils.translation import gettext_lazy as _ | ||||||
| from django_prometheus.models import ExportModelOperationsMixin |  | ||||||
| from guardian.mixins import GuardianUserMixin | from guardian.mixins import GuardianUserMixin | ||||||
| from jinja2 import Undefined | from jinja2 import Undefined | ||||||
| from jinja2.exceptions import TemplateSyntaxError, UndefinedError | from jinja2.exceptions import TemplateSyntaxError, UndefinedError | ||||||
| @ -21,7 +20,7 @@ from structlog import get_logger | |||||||
| from passbook.core.exceptions import PropertyMappingExpressionException | from passbook.core.exceptions import PropertyMappingExpressionException | ||||||
| from passbook.core.signals import password_changed | from passbook.core.signals import password_changed | ||||||
| from passbook.core.types import UILoginButton, UIUserSettings | 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 | from passbook.policies.models import PolicyBindingModel | ||||||
|  |  | ||||||
| LOGGER = get_logger() | LOGGER = get_logger() | ||||||
| @ -33,9 +32,10 @@ def default_token_duration(): | |||||||
|     return now() + timedelta(minutes=30) |     return now() + timedelta(minutes=30) | ||||||
|  |  | ||||||
|  |  | ||||||
| class Group(ExportModelOperationsMixin("group"), UUIDModel): | class Group(models.Model): | ||||||
|     """Custom Group model which supports a basic hierarchy""" |     """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) |     name = models.CharField(_("name"), max_length=80) | ||||||
|     parent = models.ForeignKey( |     parent = models.ForeignKey( | ||||||
|         "Group", |         "Group", | ||||||
| @ -54,7 +54,7 @@ class Group(ExportModelOperationsMixin("group"), UUIDModel): | |||||||
|         unique_together = (("name", "parent",),) |         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""" |     """Custom User model to allow easier adding o f user-based settings""" | ||||||
|  |  | ||||||
|     uuid = models.UUIDField(default=uuid4, editable=False) |     uuid = models.UUIDField(default=uuid4, editable=False) | ||||||
| @ -77,7 +77,7 @@ class User(ExportModelOperationsMixin("user"), GuardianUserMixin, AbstractUser): | |||||||
|         permissions = (("reset_user_password", "Reset Password"),) |         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""" |     """Application-independent Provider instance. For example SAML2 Remote, OAuth2 Application""" | ||||||
|  |  | ||||||
|     property_mappings = models.ManyToManyField( |     property_mappings = models.ManyToManyField( | ||||||
| @ -93,7 +93,7 @@ class Provider(ExportModelOperationsMixin("provider"), models.Model): | |||||||
|         return super().__str__() |         return super().__str__() | ||||||
|  |  | ||||||
|  |  | ||||||
| class Application(ExportModelOperationsMixin("application"), PolicyBindingModel): | class Application(PolicyBindingModel): | ||||||
|     """Every Application which uses passbook for authentication/identification/authorization |     """Every Application which uses passbook for authentication/identification/authorization | ||||||
|     needs an Application record. Other authentication types can subclass this Model to |     needs an Application record. Other authentication types can subclass this Model to | ||||||
|     add custom fields and other properties""" |     add custom fields and other properties""" | ||||||
| @ -122,7 +122,7 @@ class Application(ExportModelOperationsMixin("application"), PolicyBindingModel) | |||||||
|         return self.name |         return self.name | ||||||
|  |  | ||||||
|  |  | ||||||
| class Source(ExportModelOperationsMixin("source"), PolicyBindingModel): | class Source(PolicyBindingModel): | ||||||
|     """Base Authentication source, i.e. an OAuth Provider, SAML Remote or LDAP Server""" |     """Base Authentication source, i.e. an OAuth Provider, SAML Remote or LDAP Server""" | ||||||
|  |  | ||||||
|     name = models.TextField(help_text=_("Source's display Name.")) |     name = models.TextField(help_text=_("Source's display Name.")) | ||||||
| @ -169,9 +169,10 @@ class UserSourceConnection(CreatedUpdatedModel): | |||||||
|         unique_together = (("user", "source"),) |         unique_together = (("user", "source"),) | ||||||
|  |  | ||||||
|  |  | ||||||
| class Token(ExportModelOperationsMixin("token"), UUIDModel): | class Token(models.Model): | ||||||
|     """One-time link for password resets/sign-up-confirmations""" |     """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) |     expires = models.DateTimeField(default=default_token_duration) | ||||||
|     user = models.ForeignKey("User", on_delete=models.CASCADE, related_name="+") |     user = models.ForeignKey("User", on_delete=models.CASCADE, related_name="+") | ||||||
|     expiring = models.BooleanField(default=True) |     expiring = models.BooleanField(default=True) | ||||||
| @ -183,7 +184,9 @@ class Token(ExportModelOperationsMixin("token"), UUIDModel): | |||||||
|         return now() > self.expires |         return now() > self.expires | ||||||
|  |  | ||||||
|     def __str__(self): |     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: |     class Meta: | ||||||
|  |  | ||||||
| @ -191,9 +194,10 @@ class Token(ExportModelOperationsMixin("token"), UUIDModel): | |||||||
|         verbose_name_plural = _("Tokens") |         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.""" |     """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() |     name = models.TextField() | ||||||
|     expression = 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 | import uuid | ||||||
|  |  | ||||||
| from django.db import migrations, models | 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): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     initial = True |     initial = True | ||||||
| @ -32,7 +18,7 @@ class Migration(migrations.Migration): | |||||||
|                 ("created", models.DateTimeField(auto_now_add=True)), |                 ("created", models.DateTimeField(auto_now_add=True)), | ||||||
|                 ("last_updated", models.DateTimeField(auto_now=True)), |                 ("last_updated", models.DateTimeField(auto_now=True)), | ||||||
|                 ( |                 ( | ||||||
|                     "uuid", |                     "kp_uuid", | ||||||
|                     models.UUIDField( |                     models.UUIDField( | ||||||
|                         default=uuid.uuid4, |                         default=uuid.uuid4, | ||||||
|                         editable=False, |                         editable=False, | ||||||
| @ -41,27 +27,22 @@ class Migration(migrations.Migration): | |||||||
|                     ), |                     ), | ||||||
|                 ), |                 ), | ||||||
|                 ("name", models.TextField()), |                 ("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={ |             options={ | ||||||
|                 "verbose_name": "Certificate-Key Pair", |                 "verbose_name": "Certificate-Key Pair", | ||||||
|                 "verbose_name_plural": "Certificate-Key Pairs", |                 "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""" | """passbook crypto models""" | ||||||
| from binascii import hexlify | from binascii import hexlify | ||||||
| from typing import Optional | from typing import Optional | ||||||
|  | from uuid import uuid4 | ||||||
|  |  | ||||||
| from cryptography.hazmat.backends import default_backend | from cryptography.hazmat.backends import default_backend | ||||||
| from cryptography.hazmat.primitives import hashes | 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.db import models | ||||||
| from django.utils.translation import gettext_lazy as _ | 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` |     """CertificateKeyPair that can be used for signing or encrypting if `key_data` | ||||||
|     is set, otherwise it can be used to verify remote 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() |     name = models.TextField() | ||||||
|     certificate_data = models.TextField(help_text=_("PEM-encoded Certificate data")) |     certificate_data = models.TextField(help_text=_("PEM-encoded Certificate data")) | ||||||
|     key_data = models.TextField( |     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 | import uuid | ||||||
|  |  | ||||||
| @ -19,7 +19,7 @@ class Migration(migrations.Migration): | |||||||
|             name="Flow", |             name="Flow", | ||||||
|             fields=[ |             fields=[ | ||||||
|                 ( |                 ( | ||||||
|                     "uuid", |                     "flow_uuid", | ||||||
|                     models.UUIDField( |                     models.UUIDField( | ||||||
|                         default=uuid.uuid4, |                         default=uuid.uuid4, | ||||||
|                         editable=False, |                         editable=False, | ||||||
| @ -33,10 +33,12 @@ class Migration(migrations.Migration): | |||||||
|                     "designation", |                     "designation", | ||||||
|                     models.CharField( |                     models.CharField( | ||||||
|                         choices=[ |                         choices=[ | ||||||
|                             ("AUTHENTICATION", "authentication"), |                             ("authentication", "Authentication"), | ||||||
|                             ("ENROLLMENT", "enrollment"), |                             ("invalidation", "Invalidation"), | ||||||
|                             ("RECOVERY", "recovery"), |                             ("enrollment", "Enrollment"), | ||||||
|                             ("PASSWORD_CHANGE", "password_change"), |                             ("unenrollment", "Unrenollment"), | ||||||
|  |                             ("recovery", "Recovery"), | ||||||
|  |                             ("password_change", "Password Change"), | ||||||
|                         ], |                         ], | ||||||
|                         max_length=100, |                         max_length=100, | ||||||
|                     ), |                     ), | ||||||
| @ -52,13 +54,13 @@ class Migration(migrations.Migration): | |||||||
|                 ), |                 ), | ||||||
|             ], |             ], | ||||||
|             options={"verbose_name": "Flow", "verbose_name_plural": "Flows",}, |             options={"verbose_name": "Flow", "verbose_name_plural": "Flows",}, | ||||||
|             bases=("passbook_policies.policybindingmodel", models.Model), |             bases=("passbook_policies.policybindingmodel",), | ||||||
|         ), |         ), | ||||||
|         migrations.CreateModel( |         migrations.CreateModel( | ||||||
|             name="Stage", |             name="Stage", | ||||||
|             fields=[ |             fields=[ | ||||||
|                 ( |                 ( | ||||||
|                     "uuid", |                     "stage_uuid", | ||||||
|                     models.UUIDField( |                     models.UUIDField( | ||||||
|                         default=uuid.uuid4, |                         default=uuid.uuid4, | ||||||
|                         editable=False, |                         editable=False, | ||||||
| @ -68,7 +70,6 @@ class Migration(migrations.Migration): | |||||||
|                 ), |                 ), | ||||||
|                 ("name", models.TextField()), |                 ("name", models.TextField()), | ||||||
|             ], |             ], | ||||||
|             options={"abstract": False,}, |  | ||||||
|         ), |         ), | ||||||
|         migrations.CreateModel( |         migrations.CreateModel( | ||||||
|             name="FlowStageBinding", |             name="FlowStageBinding", | ||||||
| @ -83,7 +84,7 @@ class Migration(migrations.Migration): | |||||||
|                     ), |                     ), | ||||||
|                 ), |                 ), | ||||||
|                 ( |                 ( | ||||||
|                     "uuid", |                     "fsb_uuid", | ||||||
|                     models.UUIDField( |                     models.UUIDField( | ||||||
|                         default=uuid.uuid4, |                         default=uuid.uuid4, | ||||||
|                         editable=False, |                         editable=False, | ||||||
| @ -120,7 +121,7 @@ class Migration(migrations.Migration): | |||||||
|                 "ordering": ["order", "flow"], |                 "ordering": ["order", "flow"], | ||||||
|                 "unique_together": {("flow", "stage", "order")}, |                 "unique_together": {("flow", "stage", "order")}, | ||||||
|             }, |             }, | ||||||
|             bases=("passbook_policies.policybindingmodel", models.Model), |             bases=("passbook_policies.policybindingmodel",), | ||||||
|         ), |         ), | ||||||
|         migrations.AddField( |         migrations.AddField( | ||||||
|             model_name="flow", |             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""" | """Flow models""" | ||||||
| from typing import Optional | from typing import Optional | ||||||
|  | from uuid import uuid4 | ||||||
|  |  | ||||||
| from django.db import models | from django.db import models | ||||||
| from django.utils.translation import gettext_lazy as _ | from django.utils.translation import gettext_lazy as _ | ||||||
| from model_utils.managers import InheritanceManager | from model_utils.managers import InheritanceManager | ||||||
|  |  | ||||||
| from passbook.core.types import UIUserSettings | from passbook.core.types import UIUserSettings | ||||||
| from passbook.lib.models import UUIDModel |  | ||||||
| from passbook.policies.models import PolicyBindingModel | from passbook.policies.models import PolicyBindingModel | ||||||
|  |  | ||||||
|  |  | ||||||
| @ -22,10 +22,12 @@ class FlowDesignation(models.TextChoices): | |||||||
|     PASSWORD_CHANGE = "password_change"  # nosec # noqa |     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, |     """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""" |     enroll the user or offer a way of recovery""" | ||||||
|  |  | ||||||
|  |     stage_uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4) | ||||||
|  |  | ||||||
|     name = models.TextField() |     name = models.TextField() | ||||||
|  |  | ||||||
|     objects = InheritanceManager() |     objects = InheritanceManager() | ||||||
| @ -42,11 +44,13 @@ class Stage(UUIDModel): | |||||||
|         return f"Stage {self.name}" |         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 |     """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 |     a user. Additionally, policies can be applied, to specify which users | ||||||
|     have access to this flow.""" |     have access to this flow.""" | ||||||
|  |  | ||||||
|  |     flow_uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4) | ||||||
|  |  | ||||||
|     name = models.TextField() |     name = models.TextField() | ||||||
|     slug = models.SlugField(unique=True) |     slug = models.SlugField(unique=True) | ||||||
|  |  | ||||||
| @ -72,11 +76,13 @@ class Flow(PolicyBindingModel, UUIDModel): | |||||||
|         verbose_name_plural = _("Flows") |         verbose_name_plural = _("Flows") | ||||||
|  |  | ||||||
|  |  | ||||||
| class FlowStageBinding(PolicyBindingModel, UUIDModel): | class FlowStageBinding(PolicyBindingModel): | ||||||
|     """Relationship between Flow and Stage. Order is required and unique for |     """Relationship between Flow and Stage. Order is required and unique for | ||||||
|     each flow-stage Binding. Additionally, policies can be specified, which determine if |     each flow-stage Binding. Additionally, policies can be specified, which determine if | ||||||
|     this Binding applies to the current user""" |     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) |     flow = models.ForeignKey("Flow", on_delete=models.CASCADE) | ||||||
|     stage = models.ForeignKey(Stage, on_delete=models.CASCADE) |     stage = models.ForeignKey(Stage, on_delete=models.CASCADE) | ||||||
|  |  | ||||||
|  | |||||||
| @ -1,6 +1,4 @@ | |||||||
| """Generic models""" | """Generic models""" | ||||||
| from uuid import uuid4 |  | ||||||
|  |  | ||||||
| from django.db import models | from django.db import models | ||||||
|  |  | ||||||
|  |  | ||||||
| @ -12,12 +10,3 @@ class CreatedUpdatedModel(models.Model): | |||||||
|  |  | ||||||
|     class Meta: |     class Meta: | ||||||
|         abstract = True |         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 | import django.db.models.deletion | ||||||
| from django.db import migrations, models | 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 | import django.db.models.deletion | ||||||
| from django.db import migrations, models | 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 | import django.db.models.deletion | ||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
|  | |||||||
| @ -11,7 +11,8 @@ class PolicyBindingForm(forms.ModelForm): | |||||||
|     """Form to edit Policy to PolicyBindingModel Binding""" |     """Form to edit Policy to PolicyBindingModel Binding""" | ||||||
|  |  | ||||||
|     target = forms.ModelChoiceField( |     target = forms.ModelChoiceField( | ||||||
|         queryset=PolicyBindingModel.objects.all().select_subclasses() |         queryset=PolicyBindingModel.objects.all().select_subclasses(), | ||||||
|  |         to_field_name="pbm_uuid", | ||||||
|     ) |     ) | ||||||
|  |  | ||||||
|     class Meta: |     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 | import django.db.models.deletion | ||||||
| from django.db import migrations, models | 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 | import uuid | ||||||
|  |  | ||||||
| @ -10,6 +10,8 @@ class Migration(migrations.Migration): | |||||||
|  |  | ||||||
|     initial = True |     initial = True | ||||||
|  |  | ||||||
|  |     dependencies = [] | ||||||
|  |  | ||||||
|     operations = [ |     operations = [ | ||||||
|         migrations.CreateModel( |         migrations.CreateModel( | ||||||
|             name="Policy", |             name="Policy", | ||||||
| @ -17,7 +19,7 @@ class Migration(migrations.Migration): | |||||||
|                 ("created", models.DateTimeField(auto_now_add=True)), |                 ("created", models.DateTimeField(auto_now_add=True)), | ||||||
|                 ("last_updated", models.DateTimeField(auto_now=True)), |                 ("last_updated", models.DateTimeField(auto_now=True)), | ||||||
|                 ( |                 ( | ||||||
|                     "uuid", |                     "policy_uuid", | ||||||
|                     models.UUIDField( |                     models.UUIDField( | ||||||
|                         default=uuid.uuid4, |                         default=uuid.uuid4, | ||||||
|                         editable=False, |                         editable=False, | ||||||
| @ -36,7 +38,7 @@ class Migration(migrations.Migration): | |||||||
|             name="PolicyBinding", |             name="PolicyBinding", | ||||||
|             fields=[ |             fields=[ | ||||||
|                 ( |                 ( | ||||||
|                     "uuid", |                     "policy_binding_uuid", | ||||||
|                     models.UUIDField( |                     models.UUIDField( | ||||||
|                         default=uuid.uuid4, |                         default=uuid.uuid4, | ||||||
|                         editable=False, |                         editable=False, | ||||||
| @ -64,23 +66,28 @@ class Migration(migrations.Migration): | |||||||
|             name="PolicyBindingModel", |             name="PolicyBindingModel", | ||||||
|             fields=[ |             fields=[ | ||||||
|                 ( |                 ( | ||||||
|                     "id", |                     "pbm_uuid", | ||||||
|                     models.AutoField( |                     models.UUIDField( | ||||||
|                         auto_created=True, |                         default=uuid.uuid4, | ||||||
|  |                         editable=False, | ||||||
|                         primary_key=True, |                         primary_key=True, | ||||||
|                         serialize=False, |                         serialize=False, | ||||||
|                         verbose_name="ID", |  | ||||||
|                     ), |                     ), | ||||||
|                 ), |                 ), | ||||||
|                 ( |                 ( | ||||||
|                     "policies", |                     "policies", | ||||||
|                     models.ManyToManyField( |                     models.ManyToManyField( | ||||||
|                         related_name="_policybindingmodel_policies_+", |                         blank=True, | ||||||
|  |                         related_name="bindings", | ||||||
|                         through="passbook_policies.PolicyBinding", |                         through="passbook_policies.PolicyBinding", | ||||||
|                         to="passbook_policies.Policy", |                         to="passbook_policies.Policy", | ||||||
|                     ), |                     ), | ||||||
|                 ), |                 ), | ||||||
|             ], |             ], | ||||||
|  |             options={ | ||||||
|  |                 "verbose_name": "Policy Binding Model", | ||||||
|  |                 "verbose_name_plural": "Policy Binding Models", | ||||||
|  |             }, | ||||||
|         ), |         ), | ||||||
|         migrations.AddField( |         migrations.AddField( | ||||||
|             model_name="policybinding", |             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""" | """Policy base models""" | ||||||
|  | from uuid import uuid4 | ||||||
|  |  | ||||||
| from django.db import models | from django.db import models | ||||||
| from django.utils.translation import gettext_lazy as _ | from django.utils.translation import gettext_lazy as _ | ||||||
| from model_utils.managers import InheritanceManager | 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.exceptions import PolicyException | ||||||
| from passbook.policies.types import PolicyRequest, PolicyResult | from passbook.policies.types import PolicyRequest, PolicyResult | ||||||
|  |  | ||||||
| @ -11,6 +13,8 @@ from passbook.policies.types import PolicyRequest, PolicyResult | |||||||
| class PolicyBindingModel(models.Model): | class PolicyBindingModel(models.Model): | ||||||
|     """Base Model for objects that have policies applied to them.""" |     """Base Model for objects that have policies applied to them.""" | ||||||
|  |  | ||||||
|  |     pbm_uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4) | ||||||
|  |  | ||||||
|     policies = models.ManyToManyField( |     policies = models.ManyToManyField( | ||||||
|         "Policy", through="PolicyBinding", related_name="bindings", blank=True |         "Policy", through="PolicyBinding", related_name="bindings", blank=True | ||||||
|     ) |     ) | ||||||
| @ -23,9 +27,13 @@ class PolicyBindingModel(models.Model): | |||||||
|         verbose_name_plural = _("Policy Binding Models") |         verbose_name_plural = _("Policy Binding Models") | ||||||
|  |  | ||||||
|  |  | ||||||
| class PolicyBinding(UUIDModel): | class PolicyBinding(models.Model): | ||||||
|     """Relationship between a Policy and a PolicyBindingModel.""" |     """Relationship between a Policy and a PolicyBindingModel.""" | ||||||
|  |  | ||||||
|  |     policy_binding_uuid = models.UUIDField( | ||||||
|  |         primary_key=True, editable=False, default=uuid4 | ||||||
|  |     ) | ||||||
|  |  | ||||||
|     enabled = models.BooleanField(default=True) |     enabled = models.BooleanField(default=True) | ||||||
|  |  | ||||||
|     policy = models.ForeignKey("Policy", on_delete=models.CASCADE, related_name="+") |     policy = models.ForeignKey("Policy", on_delete=models.CASCADE, related_name="+") | ||||||
| @ -45,10 +53,12 @@ class PolicyBinding(UUIDModel): | |||||||
|         verbose_name_plural = _("Policy Bindings") |         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 |     """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.""" |     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) |     name = models.TextField(blank=True, null=True) | ||||||
|     negate = models.BooleanField(default=False) |     negate = models.BooleanField(default=False) | ||||||
|     order = models.IntegerField(default=0) |     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 | import django.db.models.deletion | ||||||
| from django.db import migrations, models | 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 | import django.db.models.deletion | ||||||
| from django.conf import settings | from django.conf import settings | ||||||
| @ -10,8 +10,8 @@ class Migration(migrations.Migration): | |||||||
|     initial = True |     initial = True | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ("passbook_policies", "0001_initial"), |  | ||||||
|         migrations.swappable_dependency(settings.AUTH_USER_MODEL), |         migrations.swappable_dependency(settings.AUTH_USER_MODEL), | ||||||
|  |         ("passbook_policies", "0001_initial"), | ||||||
|     ] |     ] | ||||||
|  |  | ||||||
|     operations = [ |     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 | import django.db.models.deletion | ||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
|  |  | ||||||
| @ -10,8 +9,8 @@ class Migration(migrations.Migration): | |||||||
|     initial = True |     initial = True | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|  |         ("oidc_provider", "0026_client_multiple_response_types"), | ||||||
|         ("passbook_core", "0001_initial"), |         ("passbook_core", "0001_initial"), | ||||||
|         ("passbook_policies", "0001_initial"), |  | ||||||
|     ] |     ] | ||||||
|  |  | ||||||
|     operations = [ |     operations = [ | ||||||
| @ -29,28 +28,16 @@ class Migration(migrations.Migration): | |||||||
|                         to="passbook_core.Provider", |                         to="passbook_core.Provider", | ||||||
|                     ), |                     ), | ||||||
|                 ), |                 ), | ||||||
|  |                 ("name", models.TextField()), | ||||||
|  |                 ("internal_host", models.TextField()), | ||||||
|  |                 ("external_host", models.TextField()), | ||||||
|                 ( |                 ( | ||||||
|                     "server_name", |                     "client", | ||||||
|                     django.contrib.postgres.fields.ArrayField( |                     models.ForeignKey( | ||||||
|                         base_field=models.TextField(), size=None |                         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={ |             options={ | ||||||
|                 "verbose_name": "Application Gateway Provider", |                 "verbose_name": "Application Gateway Provider", | ||||||
| @ -58,43 +45,4 @@ class Migration(migrations.Migration): | |||||||
|             }, |             }, | ||||||
|             bases=("passbook_core.provider",), |             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 django.db.models.deletion | ||||||
| import oauth2_provider.generators | 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 | import django.db.models.deletion | ||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
| @ -9,8 +9,8 @@ class Migration(migrations.Migration): | |||||||
|     initial = True |     initial = True | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ("passbook_core", "0001_initial"), |  | ||||||
|         ("oidc_provider", "0026_client_multiple_response_types"), |         ("oidc_provider", "0026_client_multiple_response_types"), | ||||||
|  |         ("passbook_core", "0001_initial"), | ||||||
|     ] |     ] | ||||||
|  |  | ||||||
|     operations = [ |     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 | import django.db.models.deletion | ||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
|  |  | ||||||
|  | import passbook.providers.saml.utils.time | ||||||
|  |  | ||||||
|  |  | ||||||
| class Migration(migrations.Migration): | class Migration(migrations.Migration): | ||||||
|  |  | ||||||
|     initial = True |     initial = True | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|  |         ("passbook_crypto", "0001_initial"), | ||||||
|         ("passbook_core", "0001_initial"), |         ("passbook_core", "0001_initial"), | ||||||
|     ] |     ] | ||||||
|  |  | ||||||
| @ -28,17 +30,11 @@ class Migration(migrations.Migration): | |||||||
|                         to="passbook_core.PropertyMapping", |                         to="passbook_core.PropertyMapping", | ||||||
|                     ), |                     ), | ||||||
|                 ), |                 ), | ||||||
|                 ("saml_name", models.TextField()), |                 ("saml_name", models.TextField(verbose_name="SAML Name")), | ||||||
|                 ( |                 ( | ||||||
|                     "friendly_name", |                     "friendly_name", | ||||||
|                     models.TextField(blank=True, default=None, null=True), |                     models.TextField(blank=True, default=None, null=True), | ||||||
|                 ), |                 ), | ||||||
|                 ( |  | ||||||
|                     "values", |  | ||||||
|                     django.contrib.postgres.fields.ArrayField( |  | ||||||
|                         base_field=models.TextField(), size=None |  | ||||||
|                     ), |  | ||||||
|                 ), |  | ||||||
|             ], |             ], | ||||||
|             options={ |             options={ | ||||||
|                 "verbose_name": "SAML Property Mapping", |                 "verbose_name": "SAML Property Mapping", | ||||||
| @ -61,14 +57,79 @@ class Migration(migrations.Migration): | |||||||
|                     ), |                     ), | ||||||
|                 ), |                 ), | ||||||
|                 ("name", models.TextField()), |                 ("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="")), |                 ("audience", models.TextField(default="")), | ||||||
|                 ("processor_path", models.CharField(max_length=255)), |                 ("issuer", models.TextField(help_text="Also known as EntityID")), | ||||||
|                 ("issuer", models.TextField()), |                 ( | ||||||
|                 ("assertion_valid_for", models.IntegerField(default=86400)), |                     "assertion_valid_not_before", | ||||||
|                 ("signing", models.BooleanField(default=True)), |                     models.TextField( | ||||||
|                 ("signing_cert", models.TextField()), |                         default="minutes=-5", | ||||||
|                 ("signing_key", models.TextField()), |                         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={ |             options={ | ||||||
|                 "verbose_name": "SAML Provider", |                 "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: |     def get_url(self, token: Token) -> str: | ||||||
|         """Get full recovery link""" |         """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}" |         return f"https://{CONFIG.y('domain')}{path}" | ||||||
|  |  | ||||||
|     def handle(self, *args, **options): |     def handle(self, *args, **options): | ||||||
|  | |||||||
| @ -30,6 +30,8 @@ class TestRecovery(TestCase): | |||||||
|         call_command("create_recovery_key", "1", self.user.username, stdout=out) |         call_command("create_recovery_key", "1", self.user.username, stdout=out) | ||||||
|         token = Token.objects.first() |         token = Token.objects.first() | ||||||
|         self.client.get( |         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) |         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.core.validators | ||||||
| import django.db.models.deletion | import django.db.models.deletion | ||||||
| @ -28,10 +28,12 @@ class Migration(migrations.Migration): | |||||||
|                         to="passbook_core.PropertyMapping", |                         to="passbook_core.PropertyMapping", | ||||||
|                     ), |                     ), | ||||||
|                 ), |                 ), | ||||||
|                 ("ldap_property", models.TextField()), |  | ||||||
|                 ("object_field", 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",), |             bases=("passbook_core.propertymapping",), | ||||||
|         ), |         ), | ||||||
|         migrations.CreateModel( |         migrations.CreateModel( | ||||||
| @ -50,38 +52,71 @@ class Migration(migrations.Migration): | |||||||
|                 ), |                 ), | ||||||
|                 ( |                 ( | ||||||
|                     "server_uri", |                     "server_uri", | ||||||
|                     models.URLField( |                     models.TextField( | ||||||
|                         validators=[ |                         validators=[ | ||||||
|                             django.core.validators.URLValidator( |                             django.core.validators.URLValidator( | ||||||
|                                 schemes=["ldap", "ldaps"] |                                 schemes=["ldap", "ldaps"] | ||||||
|                             ) |                             ) | ||||||
|                         ] |                         ], | ||||||
|  |                         verbose_name="Server URI", | ||||||
|                     ), |                     ), | ||||||
|                 ), |                 ), | ||||||
|                 ("bind_cn", models.TextField()), |                 ("bind_cn", models.TextField(verbose_name="Bind CN")), | ||||||
|                 ("bind_password", models.TextField()), |                 ("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", |                     "additional_user_dn", | ||||||
|                     models.TextField( |                     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", |                     "additional_group_dn", | ||||||
|                     models.TextField( |                     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_groups", models.BooleanField(default=True)), | ||||||
|                 ( |                 ( | ||||||
|                     "sync_parent_group", |                     "sync_parent_group", | ||||||
|                     models.ForeignKey( |                     models.ForeignKey( | ||||||
|                         blank=True, |                         blank=True, | ||||||
|                         default=None, |                         default=None, | ||||||
|  |                         null=True, | ||||||
|                         on_delete=django.db.models.deletion.SET_DEFAULT, |                         on_delete=django.db.models.deletion.SET_DEFAULT, | ||||||
|                         to="passbook_core.Group", |                         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 | import django.db.models.deletion | ||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
| @ -28,10 +28,24 @@ class Migration(migrations.Migration): | |||||||
|                     ), |                     ), | ||||||
|                 ), |                 ), | ||||||
|                 ("provider_type", models.CharField(max_length=255)), |                 ("provider_type", models.CharField(max_length=255)), | ||||||
|                 ("request_token_url", models.CharField(blank=True, max_length=255)), |                 ( | ||||||
|                 ("authorization_url", models.CharField(max_length=255)), |                     "request_token_url", | ||||||
|                 ("access_token_url", models.CharField(max_length=255)), |                     models.CharField( | ||||||
|                 ("profile_url", models.CharField(max_length=255)), |                         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_key", models.TextField()), | ||||||
|                 ("consumer_secret", 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}), |             view_name=reverse((view_name), kwargs={"source_slug": self.slug}), | ||||||
|         ) |         ) | ||||||
|  |  | ||||||
|  |     def __str__(self) -> str: | ||||||
|  |         return f"OAuth Source {self.name}" | ||||||
|  |  | ||||||
|     class Meta: |     class Meta: | ||||||
|  |  | ||||||
|         verbose_name = _("Generic OAuth Source") |         verbose_name = _("Generic OAuth Source") | ||||||
|  | |||||||
| @ -13,7 +13,7 @@ class OpenIDConnectOAuthRedirect(OAuthRedirect): | |||||||
|  |  | ||||||
|     def get_additional_parameters(self, source: OAuthSource): |     def get_additional_parameters(self, source: OAuthSource): | ||||||
|         return { |         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]): |     def get_or_create_user(self, source: OAuthSource, access, info: Dict[str, str]): | ||||||
|         user_data = { |         user_data = { | ||||||
|             "username": info.get("username"), |             "username": info.get("nickname"), | ||||||
|             "email": info.get("email"), |             "email": info.get("email"), | ||||||
|             "name": info.get("username"), |             "name": info.get("name"), | ||||||
|             "password": None, |             "password": None, | ||||||
|         } |         } | ||||||
|         return user_get_or_create(**user_data) |         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 | import django.db.models.deletion | ||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
| @ -9,7 +9,8 @@ class Migration(migrations.Migration): | |||||||
|     initial = True |     initial = True | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ("passbook_core", "0005_merge_20191025_2022"), |         ("passbook_crypto", "0001_initial"), | ||||||
|  |         ("passbook_core", "0001_initial"), | ||||||
|     ] |     ] | ||||||
|  |  | ||||||
|     operations = [ |     operations = [ | ||||||
| @ -27,15 +28,41 @@ class Migration(migrations.Migration): | |||||||
|                         to="passbook_core.Source", |                         to="passbook_core.Source", | ||||||
|                     ), |                     ), | ||||||
|                 ), |                 ), | ||||||
|                 ("acs_url", models.URLField()), |                 ( | ||||||
|                 ("slo_url", models.URLField()), |                     "issuer", | ||||||
|                 ("entity_id", models.TextField(blank=True, default=None)), |                     models.TextField( | ||||||
|                 ("idp_url", models.URLField()), |                         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)), |                 ("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",), |             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 | import django.db.models.deletion | ||||||
| from django.db import migrations, models | 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 | import django.db.models.deletion | ||||||
| from django.db import migrations, models | 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 | import django.db.models.deletion | ||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
| @ -34,12 +34,33 @@ class Migration(migrations.Migration): | |||||||
|                 ("use_tls", models.BooleanField(default=False)), |                 ("use_tls", models.BooleanField(default=False)), | ||||||
|                 ("use_ssl", models.BooleanField(default=False)), |                 ("use_ssl", models.BooleanField(default=False)), | ||||||
|                 ("timeout", models.IntegerField(default=10)), |                 ("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", |                     "from_address", | ||||||
|                     models.EmailField(default="system@passbook.local", max_length=254), |                     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={ |             options={ | ||||||
|                 "verbose_name": "Email Stage", |                 "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.contrib.postgres.fields | ||||||
| import django.db.models.deletion | import django.db.models.deletion | ||||||
| @ -32,14 +32,22 @@ class Migration(migrations.Migration): | |||||||
|                     "user_fields", |                     "user_fields", | ||||||
|                     django.contrib.postgres.fields.ArrayField( |                     django.contrib.postgres.fields.ArrayField( | ||||||
|                         base_field=models.CharField( |                         base_field=models.CharField( | ||||||
|                             choices=[("e-mail", "E Mail"), ("username", "Username")], |                             choices=[("email", "E Mail"), ("username", "Username")], | ||||||
|                             max_length=100, |                             max_length=100, | ||||||
|                         ), |                         ), | ||||||
|                         help_text="Fields of the user object to match against.", |                         help_text="Fields of the user object to match against.", | ||||||
|                         size=None, |                         size=None, | ||||||
|                     ), |                     ), | ||||||
|                 ), |                 ), | ||||||
|                 ("template", models.TextField()), |                 ( | ||||||
|  |                     "template", | ||||||
|  |                     models.TextField( | ||||||
|  |                         choices=[ | ||||||
|  |                             ("stages/identification/login.html", "Default Login"), | ||||||
|  |                             ("stages/identification/recovery.html", "Default Recovery"), | ||||||
|  |                         ] | ||||||
|  |                     ), | ||||||
|  |                 ), | ||||||
|             ], |             ], | ||||||
|             options={ |             options={ | ||||||
|                 "verbose_name": "Identification Stage", |                 "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 | import uuid | ||||||
|  |  | ||||||
| @ -13,8 +13,8 @@ class Migration(migrations.Migration): | |||||||
|     initial = True |     initial = True | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ("passbook_flows", "0004_auto_20200510_2310"), |  | ||||||
|         migrations.swappable_dependency(settings.AUTH_USER_MODEL), |         migrations.swappable_dependency(settings.AUTH_USER_MODEL), | ||||||
|  |         ("passbook_flows", "0001_initial"), | ||||||
|     ] |     ] | ||||||
|  |  | ||||||
|     operations = [ |     operations = [ | ||||||
| @ -32,6 +32,13 @@ class Migration(migrations.Migration): | |||||||
|                         to="passbook_flows.Stage", |                         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={ |             options={ | ||||||
|                 "verbose_name": "Invitation Stage", |                 "verbose_name": "Invitation Stage", | ||||||
| @ -43,7 +50,7 @@ class Migration(migrations.Migration): | |||||||
|             name="Invitation", |             name="Invitation", | ||||||
|             fields=[ |             fields=[ | ||||||
|                 ( |                 ( | ||||||
|                     "uuid", |                     "invite_uuid", | ||||||
|                     models.UUIDField( |                     models.UUIDField( | ||||||
|                         default=uuid.uuid4, |                         default=uuid.uuid4, | ||||||
|                         editable=False, |                         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""" | """invitation stage models""" | ||||||
|  | from uuid import uuid4 | ||||||
|  |  | ||||||
| from django.contrib.postgres.fields import JSONField | from django.contrib.postgres.fields import JSONField | ||||||
| from django.db import models | from django.db import models | ||||||
| from django.utils.translation import gettext_lazy as _ | from django.utils.translation import gettext_lazy as _ | ||||||
|  |  | ||||||
| from passbook.core.models import User | from passbook.core.models import User | ||||||
| from passbook.flows.models import Stage | from passbook.flows.models import Stage | ||||||
| from passbook.lib.models import UUIDModel |  | ||||||
|  |  | ||||||
|  |  | ||||||
| class InvitationStage(Stage): | class InvitationStage(Stage): | ||||||
| @ -34,15 +35,17 @@ class InvitationStage(Stage): | |||||||
|         verbose_name_plural = _("Invitation Stages") |         verbose_name_plural = _("Invitation Stages") | ||||||
|  |  | ||||||
|  |  | ||||||
| class Invitation(UUIDModel): | class Invitation(models.Model): | ||||||
|     """Single-use invitation link""" |     """Single-use invitation link""" | ||||||
|  |  | ||||||
|  |     invite_uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4) | ||||||
|  |  | ||||||
|     created_by = models.ForeignKey(User, on_delete=models.CASCADE) |     created_by = models.ForeignKey(User, on_delete=models.CASCADE) | ||||||
|     expires = models.DateTimeField(default=None, blank=True, null=True) |     expires = models.DateTimeField(default=None, blank=True, null=True) | ||||||
|     fixed_data = JSONField(default=dict) |     fixed_data = JSONField(default=dict) | ||||||
|  |  | ||||||
|     def __str__(self): |     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: |     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 | import django.db.models.deletion | ||||||
| from django.db import migrations, models | 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.contrib.postgres.fields | ||||||
| import django.db.models.deletion | import django.db.models.deletion | ||||||
| @ -11,7 +11,6 @@ class Migration(migrations.Migration): | |||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ("passbook_flows", "0001_initial"), |         ("passbook_flows", "0001_initial"), | ||||||
|         ("passbook_policies", "0001_initial"), |  | ||||||
|     ] |     ] | ||||||
|  |  | ||||||
|     operations = [ |     operations = [ | ||||||
| @ -37,10 +36,6 @@ class Migration(migrations.Migration): | |||||||
|                         size=None, |                         size=None, | ||||||
|                     ), |                     ), | ||||||
|                 ), |                 ), | ||||||
|                 ( |  | ||||||
|                     "password_policies", |  | ||||||
|                     models.ManyToManyField(blank=True, to="passbook_policies.Policy"), |  | ||||||
|                 ), |  | ||||||
|             ], |             ], | ||||||
|             options={ |             options={ | ||||||
|                 "verbose_name": "Password Stage", |                 "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 | import uuid | ||||||
|  |  | ||||||
| @ -11,8 +11,8 @@ class Migration(migrations.Migration): | |||||||
|     initial = True |     initial = True | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ("passbook_flows", "0005_auto_20200512_1158"), |  | ||||||
|         ("passbook_policies", "0001_initial"), |         ("passbook_policies", "0001_initial"), | ||||||
|  |         ("passbook_flows", "0001_initial"), | ||||||
|     ] |     ] | ||||||
|  |  | ||||||
|     operations = [ |     operations = [ | ||||||
| @ -20,7 +20,7 @@ class Migration(migrations.Migration): | |||||||
|             name="Prompt", |             name="Prompt", | ||||||
|             fields=[ |             fields=[ | ||||||
|                 ( |                 ( | ||||||
|                     "uuid", |                     "prompt_uuid", | ||||||
|                     models.UUIDField( |                     models.UUIDField( | ||||||
|                         default=uuid.uuid4, |                         default=uuid.uuid4, | ||||||
|                         editable=False, |                         editable=False, | ||||||
|  | |||||||
| @ -1,10 +1,11 @@ | |||||||
| """prompt models""" | """prompt models""" | ||||||
|  | from uuid import uuid4 | ||||||
|  |  | ||||||
| from django import forms | from django import forms | ||||||
| from django.db import models | from django.db import models | ||||||
| from django.utils.translation import gettext_lazy as _ | from django.utils.translation import gettext_lazy as _ | ||||||
|  |  | ||||||
| from passbook.flows.models import Stage | from passbook.flows.models import Stage | ||||||
| from passbook.lib.models import UUIDModel |  | ||||||
| from passbook.policies.models import PolicyBindingModel | from passbook.policies.models import PolicyBindingModel | ||||||
|  |  | ||||||
|  |  | ||||||
| @ -18,9 +19,11 @@ class FieldTypes(models.TextChoices): | |||||||
|     HIDDEN = "hidden" |     HIDDEN = "hidden" | ||||||
|  |  | ||||||
|  |  | ||||||
| class Prompt(UUIDModel): | class Prompt(models.Model): | ||||||
|     """Single Prompt, part of a prompt stage.""" |     """Single Prompt, part of a prompt stage.""" | ||||||
|  |  | ||||||
|  |     prompt_uuid = models.UUIDField(primary_key=True, editable=False, default=uuid4) | ||||||
|  |  | ||||||
|     field_key = models.SlugField( |     field_key = models.SlugField( | ||||||
|         help_text=_("Name of the form field, also used to store the value") |         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 | import django.db.models.deletion | ||||||
| from django.db import migrations, models | from django.db import migrations, models | ||||||
| @ -9,7 +9,7 @@ class Migration(migrations.Migration): | |||||||
|     initial = True |     initial = True | ||||||
|  |  | ||||||
|     dependencies = [ |     dependencies = [ | ||||||
|         ("passbook_flows", "0005_auto_20200512_1158"), |         ("passbook_flows", "0001_initial"), | ||||||
|     ] |     ] | ||||||
|  |  | ||||||
|     operations = [ |     operations = [ | ||||||
|  | |||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user
	 Jens L
					Jens L