*: migrate from PolicyModel to PolicyBindingModel, move Policy to passbook_policies
This commit is contained in:
		| @ -5,8 +5,9 @@ from django.views.generic import TemplateView | ||||
|  | ||||
| from passbook import __version__ | ||||
| from passbook.admin.mixins import AdminRequiredMixin | ||||
| from passbook.core.models import Application, Policy, Provider, Source, User | ||||
| from passbook.core.models import Application, Provider, Source, User | ||||
| from passbook.flows.models import Flow, Stage | ||||
| from passbook.policies.models import Policy | ||||
| from passbook.root.celery import CELERY_APP | ||||
| from passbook.stages.invitation.models import Invitation | ||||
|  | ||||
|  | ||||
| @ -13,10 +13,10 @@ from django.views.generic.detail import DetailView | ||||
| from guardian.mixins import PermissionListMixin, PermissionRequiredMixin | ||||
|  | ||||
| from passbook.admin.forms.policies import PolicyTestForm | ||||
| from passbook.core.models import Policy | ||||
| from passbook.lib.utils.reflection import all_subclasses, path_to_class | ||||
| from passbook.lib.views import CreateAssignPermView | ||||
| from passbook.policies.engine import PolicyEngine | ||||
| from passbook.policies.models import Policy | ||||
|  | ||||
|  | ||||
| class PolicyListView(LoginRequiredMixin, PermissionListMixin, ListView): | ||||
|  | ||||
| @ -1,8 +1,8 @@ | ||||
| """permission classes for django restframework""" | ||||
| from rest_framework.permissions import BasePermission, DjangoObjectPermissions | ||||
|  | ||||
| from passbook.core.models import PolicyModel | ||||
| from passbook.policies.engine import PolicyEngine | ||||
| from passbook.policies.models import PolicyBindingModel | ||||
|  | ||||
|  | ||||
| class CustomObjectPermissions(DjangoObjectPermissions): | ||||
| @ -24,8 +24,7 @@ class PolicyPermissions(BasePermission): | ||||
|  | ||||
|     policy_engine: PolicyEngine | ||||
|  | ||||
|     def has_object_permission(self, request, view, obj: PolicyModel) -> bool: | ||||
|         # if not obj.po | ||||
|     def has_object_permission(self, request, view, obj: PolicyBindingModel) -> bool: | ||||
|         self.policy_engine = PolicyEngine(obj.policies, request.user, request) | ||||
|         self.policy_engine.request.obj = obj | ||||
|         return self.policy_engine.build().passing | ||||
|  | ||||
| @ -1,5 +1,4 @@ | ||||
| """api v2 urls""" | ||||
| from django.conf import settings | ||||
| from django.conf.urls import url | ||||
| from django.urls import path | ||||
| from drf_yasg import openapi | ||||
| @ -19,6 +18,7 @@ from passbook.core.api.users import UserViewSet | ||||
| from passbook.flows.api import FlowStageBindingViewSet, FlowViewSet, StageViewSet | ||||
| from passbook.lib.utils.reflection import get_apps | ||||
| from passbook.policies.api import PolicyBindingViewSet | ||||
| from passbook.policies.dummy.api import DummyPolicyViewSet | ||||
| from passbook.policies.expiry.api import PasswordExpiryPolicyViewSet | ||||
| from passbook.policies.expression.api import ExpressionPolicyViewSet | ||||
| from passbook.policies.hibp.api import HaveIBeenPwendPolicyViewSet | ||||
| @ -31,6 +31,7 @@ from passbook.providers.saml.api import SAMLPropertyMappingViewSet, SAMLProvider | ||||
| from passbook.sources.ldap.api import LDAPPropertyMappingViewSet, LDAPSourceViewSet | ||||
| from passbook.sources.oauth.api import OAuthSourceViewSet | ||||
| from passbook.stages.captcha.api import CaptchaStageViewSet | ||||
| from passbook.stages.dummy.api import DummyStageViewSet | ||||
| from passbook.stages.email.api import EmailStageViewSet | ||||
| from passbook.stages.identification.api import IdentificationStageViewSet | ||||
| from passbook.stages.invitation.api import InvitationStageViewSet, InvitationViewSet | ||||
| @ -97,12 +98,8 @@ router.register("stages/user_write", UserWriteStageViewSet) | ||||
| router.register("flows/instances", FlowViewSet) | ||||
| router.register("flows/bindings", FlowStageBindingViewSet) | ||||
|  | ||||
| if settings.DEBUG: | ||||
|     from passbook.stages.dummy.api import DummyStageViewSet | ||||
|     from passbook.policies.dummy.api import DummyPolicyViewSet | ||||
|  | ||||
|     router.register("stages/dummy", DummyStageViewSet) | ||||
|     router.register("policies/dummy", DummyPolicyViewSet) | ||||
| router.register("stages/dummy", DummyStageViewSet) | ||||
| router.register("policies/dummy", DummyPolicyViewSet) | ||||
|  | ||||
| info = openapi.Info( | ||||
|     title="passbook API", | ||||
|  | ||||
| @ -5,7 +5,7 @@ from django.test import TestCase | ||||
| from guardian.shortcuts import get_anonymous_user | ||||
|  | ||||
| from passbook.audit.models import Event, EventAction | ||||
| from passbook.core.models import Policy | ||||
| from passbook.policies.dummy.models import DummyPolicy | ||||
|  | ||||
|  | ||||
| class TestAuditEvent(TestCase): | ||||
| @ -23,7 +23,7 @@ class TestAuditEvent(TestCase): | ||||
|  | ||||
|     def test_new_with_uuid_model(self): | ||||
|         """Create a new Event passing a model (with UUID PK) as kwarg""" | ||||
|         temp_model = Policy.objects.create() | ||||
|         temp_model = DummyPolicy.objects.create(name="test", result=True) | ||||
|         event = Event.new(EventAction.CUSTOM, model=temp_model) | ||||
|         event.save()  # We save to ensure nothing is un-saveable | ||||
|         model_content_type = ContentType.objects.get_for_model(temp_model) | ||||
|  | ||||
| @ -2,8 +2,8 @@ | ||||
| from rest_framework.serializers import ModelSerializer, SerializerMethodField | ||||
| from rest_framework.viewsets import ReadOnlyModelViewSet | ||||
|  | ||||
| from passbook.core.models import Policy | ||||
| from passbook.policies.forms import GENERAL_FIELDS | ||||
| from passbook.policies.models import Policy | ||||
|  | ||||
|  | ||||
| class PolicySerializer(ModelSerializer): | ||||
|  | ||||
| @ -19,6 +19,7 @@ class Migration(migrations.Migration): | ||||
|  | ||||
|     dependencies = [ | ||||
|         ("auth", "0011_update_proxy_permissions"), | ||||
|         ("passbook_policies", "0001_initial"), | ||||
|     ] | ||||
|  | ||||
|     operations = [ | ||||
| @ -158,7 +159,7 @@ class Migration(migrations.Migration): | ||||
|                 ), | ||||
|                 ( | ||||
|                     "policies", | ||||
|                     models.ManyToManyField(blank=True, to="passbook_core.Policy"), | ||||
|                     models.ManyToManyField(blank=True, to="passbook_policies.Policy"), | ||||
|                 ), | ||||
|             ], | ||||
|             options={"abstract": False,}, | ||||
| @ -182,30 +183,6 @@ class Migration(migrations.Migration): | ||||
|                 "verbose_name_plural": "Property Mappings", | ||||
|             }, | ||||
|         ), | ||||
|         migrations.CreateModel( | ||||
|             name="DebugPolicy", | ||||
|             fields=[ | ||||
|                 ( | ||||
|                     "policy_ptr", | ||||
|                     models.OneToOneField( | ||||
|                         auto_created=True, | ||||
|                         on_delete=django.db.models.deletion.CASCADE, | ||||
|                         parent_link=True, | ||||
|                         primary_key=True, | ||||
|                         serialize=False, | ||||
|                         to="passbook_core.Policy", | ||||
|                     ), | ||||
|                 ), | ||||
|                 ("result", models.BooleanField(default=False)), | ||||
|                 ("wait_min", models.IntegerField(default=5)), | ||||
|                 ("wait_max", models.IntegerField(default=30)), | ||||
|             ], | ||||
|             options={ | ||||
|                 "verbose_name": "Debug Policy", | ||||
|                 "verbose_name_plural": "Debug Policies", | ||||
|             }, | ||||
|             bases=("passbook_core.policy",), | ||||
|         ), | ||||
|         migrations.CreateModel( | ||||
|             name="Factor", | ||||
|             fields=[ | ||||
| @ -217,7 +194,7 @@ class Migration(migrations.Migration): | ||||
|                         parent_link=True, | ||||
|                         primary_key=True, | ||||
|                         serialize=False, | ||||
|                         to="passbook_core.PolicyModel", | ||||
|                         to="passbook_policies.PolicyBindingModel", | ||||
|                     ), | ||||
|                 ), | ||||
|                 ("name", models.TextField()), | ||||
| @ -226,7 +203,7 @@ class Migration(migrations.Migration): | ||||
|                 ("enabled", models.BooleanField(default=True)), | ||||
|             ], | ||||
|             options={"abstract": False,}, | ||||
|             bases=("passbook_core.policymodel",), | ||||
|             bases=("passbook_policies.policybindingmodel",), | ||||
|         ), | ||||
|         migrations.CreateModel( | ||||
|             name="Source", | ||||
| @ -239,7 +216,7 @@ class Migration(migrations.Migration): | ||||
|                         parent_link=True, | ||||
|                         primary_key=True, | ||||
|                         serialize=False, | ||||
|                         to="passbook_core.PolicyModel", | ||||
|                         to="passbook_policies.PolicyBindingModel", | ||||
|                     ), | ||||
|                 ), | ||||
|                 ("name", models.TextField()), | ||||
| @ -247,7 +224,7 @@ class Migration(migrations.Migration): | ||||
|                 ("enabled", models.BooleanField(default=True)), | ||||
|             ], | ||||
|             options={"abstract": False,}, | ||||
|             bases=("passbook_core.policymodel",), | ||||
|             bases=("passbook_policies.policybindingmodel",), | ||||
|         ), | ||||
|         migrations.CreateModel( | ||||
|             name="Provider", | ||||
| @ -418,7 +395,7 @@ class Migration(migrations.Migration): | ||||
|                         parent_link=True, | ||||
|                         primary_key=True, | ||||
|                         serialize=False, | ||||
|                         to="passbook_core.PolicyModel", | ||||
|                         to="passbook_policies.PolicyBindingModel", | ||||
|                     ), | ||||
|                 ), | ||||
|                 ("name", models.TextField()), | ||||
| @ -438,7 +415,7 @@ class Migration(migrations.Migration): | ||||
|                 ), | ||||
|             ], | ||||
|             options={"abstract": False,}, | ||||
|             bases=("passbook_core.policymodel",), | ||||
|             bases=("passbook_policies.policybindingmodel",), | ||||
|         ), | ||||
|         migrations.AddField( | ||||
|             model_name="user", | ||||
|  | ||||
| @ -6,11 +6,7 @@ from django.db import migrations | ||||
| class Migration(migrations.Migration): | ||||
|  | ||||
|     dependencies = [ | ||||
|         ("passbook_policies", "0003_auto_20200508_1642"), | ||||
|         ("passbook_stages_password", "0001_initial"), | ||||
|         ("passbook_core", "0012_delete_factor"), | ||||
|     ] | ||||
|  | ||||
|     operations = [ | ||||
|         migrations.DeleteModel(name="DebugPolicy",), | ||||
|     ] | ||||
|     operations = [] | ||||
|  | ||||
							
								
								
									
										48
									
								
								passbook/core/migrations/0016_auto_20200516_1446.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								passbook/core/migrations/0016_auto_20200516_1446.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,48 @@ | ||||
| # 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",), | ||||
|     ] | ||||
| @ -22,8 +22,7 @@ from passbook.core.exceptions import PropertyMappingExpressionException | ||||
| from passbook.core.signals import password_changed | ||||
| from passbook.core.types import UILoginButton, UIUserSettings | ||||
| from passbook.lib.models import CreatedUpdatedModel, UUIDModel | ||||
| from passbook.policies.exceptions import PolicyException | ||||
| from passbook.policies.types import PolicyRequest, PolicyResult | ||||
| from passbook.policies.models import PolicyBindingModel | ||||
|  | ||||
| LOGGER = get_logger() | ||||
| NATIVE_ENVIRONMENT = NativeEnvironment() | ||||
| @ -94,13 +93,7 @@ class Provider(ExportModelOperationsMixin("provider"), models.Model): | ||||
|         return super().__str__() | ||||
|  | ||||
|  | ||||
| class PolicyModel(UUIDModel, CreatedUpdatedModel): | ||||
|     """Base model which can have policies applied to it""" | ||||
|  | ||||
|     policies = models.ManyToManyField("Policy", blank=True) | ||||
|  | ||||
|  | ||||
| class Application(ExportModelOperationsMixin("application"), PolicyModel): | ||||
| class Application(ExportModelOperationsMixin("application"), PolicyBindingModel): | ||||
|     """Every Application which uses passbook for authentication/identification/authorization | ||||
|     needs an Application record. Other authentication types can subclass this Model to | ||||
|     add custom fields and other properties""" | ||||
| @ -129,7 +122,7 @@ class Application(ExportModelOperationsMixin("application"), PolicyModel): | ||||
|         return self.name | ||||
|  | ||||
|  | ||||
| class Source(ExportModelOperationsMixin("source"), PolicyModel): | ||||
| class Source(ExportModelOperationsMixin("source"), PolicyBindingModel): | ||||
|     """Base Authentication source, i.e. an OAuth Provider, SAML Remote or LDAP Server""" | ||||
|  | ||||
|     name = models.TextField(help_text=_("Source's display Name.")) | ||||
| @ -176,25 +169,6 @@ class UserSourceConnection(CreatedUpdatedModel): | ||||
|         unique_together = (("user", "source"),) | ||||
|  | ||||
|  | ||||
| class Policy(ExportModelOperationsMixin("policy"), UUIDModel, CreatedUpdatedModel): | ||||
|     """Policies which specify if a user is authorized to use an Application. Can be overridden by | ||||
|     other types to add other fields, more logic, etc.""" | ||||
|  | ||||
|     name = models.TextField(blank=True, null=True) | ||||
|     negate = models.BooleanField(default=False) | ||||
|     order = models.IntegerField(default=0) | ||||
|     timeout = models.IntegerField(default=30) | ||||
|  | ||||
|     objects = InheritanceManager() | ||||
|  | ||||
|     def __str__(self): | ||||
|         return f"Policy {self.name}" | ||||
|  | ||||
|     def passes(self, request: PolicyRequest) -> PolicyResult: | ||||
|         """Check if user instance passes this policy""" | ||||
|         raise PolicyException() | ||||
|  | ||||
|  | ||||
| class Token(ExportModelOperationsMixin("token"), UUIDModel): | ||||
|     """One-time link for password resets/sign-up-confirmations""" | ||||
|  | ||||
|  | ||||
| @ -17,7 +17,7 @@ password_changed = Signal(providing_args=["user", "password"]) | ||||
| # pylint: disable=unused-argument | ||||
| def invalidate_policy_cache(sender, instance, **_): | ||||
|     """Invalidate Policy cache when policy is updated""" | ||||
|     from passbook.core.models import Policy | ||||
|     from passbook.policies.models import Policy | ||||
|     from passbook.policies.process import cache_key | ||||
|  | ||||
|     if isinstance(instance, Policy): | ||||
|  | ||||
| @ -11,7 +11,7 @@ class Migration(migrations.Migration): | ||||
|     initial = True | ||||
|  | ||||
|     dependencies = [ | ||||
|         ("passbook_policies", "0003_auto_20200508_1642"), | ||||
|         # ("passbook_policies", "0001_initial"), | ||||
|     ] | ||||
|  | ||||
|     operations = [ | ||||
|  | ||||
| @ -9,8 +9,7 @@ class Migration(migrations.Migration): | ||||
|     initial = True | ||||
|  | ||||
|     dependencies = [ | ||||
|         ("passbook_policies", "0003_auto_20200508_1642"), | ||||
|         ("passbook_core", "0013_delete_debugpolicy"), | ||||
|         ("passbook_policies", "0001_initial"), | ||||
|     ] | ||||
|  | ||||
|     operations = [ | ||||
| @ -25,7 +24,7 @@ class Migration(migrations.Migration): | ||||
|                         parent_link=True, | ||||
|                         primary_key=True, | ||||
|                         serialize=False, | ||||
|                         to="passbook_core.Policy", | ||||
|                         to="passbook_policies.Policy", | ||||
|                     ), | ||||
|                 ), | ||||
|                 ("result", models.BooleanField(default=False)), | ||||
| @ -36,6 +35,6 @@ class Migration(migrations.Migration): | ||||
|                 "verbose_name": "Dummy Policy", | ||||
|                 "verbose_name_plural": "Dummy Policies", | ||||
|             }, | ||||
|             bases=("passbook_core.policy",), | ||||
|             bases=("passbook_policies.policy",), | ||||
|         ), | ||||
|     ] | ||||
|  | ||||
| @ -6,7 +6,7 @@ from django.db import models | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
| from structlog import get_logger | ||||
|  | ||||
| from passbook.core.models import Policy | ||||
| from passbook.policies.models import Policy | ||||
| from passbook.policies.types import PolicyRequest, PolicyResult | ||||
|  | ||||
| LOGGER = get_logger() | ||||
|  | ||||
| @ -7,7 +7,8 @@ from django.core.cache import cache | ||||
| from django.http import HttpRequest | ||||
| from structlog import get_logger | ||||
|  | ||||
| from passbook.core.models import Policy, User | ||||
| from passbook.core.models import User | ||||
| from passbook.policies.models import Policy | ||||
| from passbook.policies.process import PolicyProcess, cache_key | ||||
| from passbook.policies.types import PolicyRequest, PolicyResult | ||||
|  | ||||
|  | ||||
| @ -9,7 +9,7 @@ class Migration(migrations.Migration): | ||||
|     initial = True | ||||
|  | ||||
|     dependencies = [ | ||||
|         ("passbook_core", "0001_initial"), | ||||
|         ("passbook_policies", "0001_initial"), | ||||
|     ] | ||||
|  | ||||
|     operations = [ | ||||
| @ -24,7 +24,7 @@ class Migration(migrations.Migration): | ||||
|                         parent_link=True, | ||||
|                         primary_key=True, | ||||
|                         serialize=False, | ||||
|                         to="passbook_core.Policy", | ||||
|                         to="passbook_policies.Policy", | ||||
|                     ), | ||||
|                 ), | ||||
|                 ("deny_only", models.BooleanField(default=False)), | ||||
| @ -34,6 +34,6 @@ class Migration(migrations.Migration): | ||||
|                 "verbose_name": "Password Expiry Policy", | ||||
|                 "verbose_name_plural": "Password Expiry Policies", | ||||
|             }, | ||||
|             bases=("passbook_core.policy",), | ||||
|             bases=("passbook_policies.policy",), | ||||
|         ), | ||||
|     ] | ||||
|  | ||||
| @ -6,7 +6,7 @@ from django.utils.timezone import now | ||||
| from django.utils.translation import gettext as _ | ||||
| from structlog import get_logger | ||||
|  | ||||
| from passbook.core.models import Policy | ||||
| from passbook.policies.models import Policy | ||||
| from passbook.policies.types import PolicyRequest, PolicyResult | ||||
|  | ||||
| LOGGER = get_logger() | ||||
|  | ||||
| @ -9,7 +9,7 @@ class Migration(migrations.Migration): | ||||
|     initial = True | ||||
|  | ||||
|     dependencies = [ | ||||
|         ("passbook_core", "0007_auto_20200217_1934"), | ||||
|         ("passbook_policies", "0001_initial"), | ||||
|     ] | ||||
|  | ||||
|     operations = [ | ||||
| @ -24,7 +24,7 @@ class Migration(migrations.Migration): | ||||
|                         parent_link=True, | ||||
|                         primary_key=True, | ||||
|                         serialize=False, | ||||
|                         to="passbook_core.Policy", | ||||
|                         to="passbook_policies.Policy", | ||||
|                     ), | ||||
|                 ), | ||||
|                 ("expression", models.TextField()), | ||||
| @ -33,6 +33,6 @@ class Migration(migrations.Migration): | ||||
|                 "verbose_name": "Expression Policy", | ||||
|                 "verbose_name_plural": "Expression Policies", | ||||
|             }, | ||||
|             bases=("passbook_core.policy",), | ||||
|             bases=("passbook_policies.policy",), | ||||
|         ), | ||||
|     ] | ||||
|  | ||||
| @ -2,8 +2,8 @@ | ||||
| from django.db import models | ||||
| from django.utils.translation import gettext as _ | ||||
|  | ||||
| from passbook.core.models import Policy | ||||
| from passbook.policies.expression.evaluator import Evaluator | ||||
| from passbook.policies.models import Policy | ||||
| from passbook.policies.types import PolicyRequest, PolicyResult | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -9,7 +9,7 @@ class Migration(migrations.Migration): | ||||
|     initial = True | ||||
|  | ||||
|     dependencies = [ | ||||
|         ("passbook_core", "0001_initial"), | ||||
|         ("passbook_policies", "0001_initial"), | ||||
|     ] | ||||
|  | ||||
|     operations = [ | ||||
| @ -24,7 +24,7 @@ class Migration(migrations.Migration): | ||||
|                         parent_link=True, | ||||
|                         primary_key=True, | ||||
|                         serialize=False, | ||||
|                         to="passbook_core.Policy", | ||||
|                         to="passbook_policies.Policy", | ||||
|                     ), | ||||
|                 ), | ||||
|                 ("allowed_count", models.IntegerField(default=0)), | ||||
| @ -33,6 +33,6 @@ class Migration(migrations.Migration): | ||||
|                 "verbose_name": "Have I Been Pwned Policy", | ||||
|                 "verbose_name_plural": "Have I Been Pwned Policies", | ||||
|             }, | ||||
|             bases=("passbook_core.policy",), | ||||
|             bases=("passbook_policies.policy",), | ||||
|         ), | ||||
|     ] | ||||
|  | ||||
| @ -6,7 +6,8 @@ from django.utils.translation import gettext as _ | ||||
| from requests import get | ||||
| from structlog import get_logger | ||||
|  | ||||
| from passbook.core.models import Policy, PolicyResult, User | ||||
| from passbook.core.models import User | ||||
| from passbook.policies.models import Policy, PolicyResult | ||||
|  | ||||
| LOGGER = get_logger() | ||||
|  | ||||
|  | ||||
| @ -10,11 +10,28 @@ class Migration(migrations.Migration): | ||||
|  | ||||
|     initial = True | ||||
|  | ||||
|     dependencies = [ | ||||
|         ("passbook_core", "0011_auto_20200222_1822"), | ||||
|     ] | ||||
|  | ||||
|     operations = [ | ||||
|         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)), | ||||
|                 ("negate", models.BooleanField(default=False)), | ||||
|                 ("order", models.IntegerField(default=0)), | ||||
|                 ("timeout", models.IntegerField(default=30)), | ||||
|             ], | ||||
|             options={"abstract": False,}, | ||||
|         ), | ||||
|         migrations.CreateModel( | ||||
|             name="PolicyBinding", | ||||
|             fields=[ | ||||
| @ -34,7 +51,7 @@ class Migration(migrations.Migration): | ||||
|                     models.ForeignKey( | ||||
|                         on_delete=django.db.models.deletion.CASCADE, | ||||
|                         related_name="+", | ||||
|                         to="passbook_core.Policy", | ||||
|                         to="passbook_policies.Policy", | ||||
|                     ), | ||||
|                 ), | ||||
|             ], | ||||
| @ -60,7 +77,7 @@ class Migration(migrations.Migration): | ||||
|                     models.ManyToManyField( | ||||
|                         related_name="_policybindingmodel_policies_+", | ||||
|                         through="passbook_policies.PolicyBinding", | ||||
|                         to="passbook_core.Policy", | ||||
|                         to="passbook_policies.Policy", | ||||
|                     ), | ||||
|                 ), | ||||
|             ], | ||||
|  | ||||
| @ -1,4 +1,4 @@ | ||||
| # Generated by Django 3.0.3 on 2020-05-08 16:42 | ||||
| # Generated by Django 3.0.5 on 2020-05-16 15:16 | ||||
| 
 | ||||
| from django.db import migrations, models | ||||
| 
 | ||||
| @ -6,7 +6,6 @@ from django.db import migrations, models | ||||
| class Migration(migrations.Migration): | ||||
| 
 | ||||
|     dependencies = [ | ||||
|         ("passbook_core", "0011_auto_20200222_1822"), | ||||
|         ("passbook_policies", "0002_auto_20200508_1230"), | ||||
|     ] | ||||
| 
 | ||||
| @ -18,7 +17,7 @@ class Migration(migrations.Migration): | ||||
|                 blank=True, | ||||
|                 related_name="_policybindingmodel_policies_+", | ||||
|                 through="passbook_policies.PolicyBinding", | ||||
|                 to="passbook_core.Policy", | ||||
|                 to="passbook_policies.Policy", | ||||
|             ), | ||||
|         ), | ||||
|     ] | ||||
| @ -1,16 +1,18 @@ | ||||
| """Policy base models""" | ||||
| from django.db import models | ||||
| from django.utils.translation import gettext_lazy as _ | ||||
| from model_utils.managers import InheritanceManager | ||||
|  | ||||
| from passbook.core.models import Policy | ||||
| from passbook.lib.models import UUIDModel | ||||
| from passbook.lib.models import CreatedUpdatedModel, UUIDModel | ||||
| from passbook.policies.exceptions import PolicyException | ||||
| from passbook.policies.types import PolicyRequest, PolicyResult | ||||
|  | ||||
|  | ||||
| class PolicyBindingModel(models.Model): | ||||
|     """Base Model for objects that have policies applied to them.""" | ||||
|  | ||||
|     policies = models.ManyToManyField( | ||||
|         Policy, through="PolicyBinding", related_name="+", blank=True | ||||
|         "Policy", through="PolicyBinding", related_name="+", blank=True | ||||
|     ) | ||||
|  | ||||
|     class Meta: | ||||
| @ -24,7 +26,7 @@ class PolicyBinding(UUIDModel): | ||||
|  | ||||
|     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="+") | ||||
|     target = models.ForeignKey( | ||||
|         PolicyBindingModel, on_delete=models.CASCADE, related_name="+" | ||||
|     ) | ||||
| @ -39,3 +41,22 @@ class PolicyBinding(UUIDModel): | ||||
|  | ||||
|         verbose_name = _("Policy Binding") | ||||
|         verbose_name_plural = _("Policy Bindings") | ||||
|  | ||||
|  | ||||
| class Policy(UUIDModel, CreatedUpdatedModel): | ||||
|     """Policies which specify if a user is authorized to use an Application. Can be overridden by | ||||
|     other types to add other fields, more logic, etc.""" | ||||
|  | ||||
|     name = models.TextField(blank=True, null=True) | ||||
|     negate = models.BooleanField(default=False) | ||||
|     order = models.IntegerField(default=0) | ||||
|     timeout = models.IntegerField(default=30) | ||||
|  | ||||
|     objects = InheritanceManager() | ||||
|  | ||||
|     def __str__(self): | ||||
|         return f"Policy {self.name}" | ||||
|  | ||||
|     def passes(self, request: PolicyRequest) -> PolicyResult: | ||||
|         """Check if user instance passes this policy""" | ||||
|         raise PolicyException() | ||||
|  | ||||
| @ -9,7 +9,7 @@ class Migration(migrations.Migration): | ||||
|     initial = True | ||||
|  | ||||
|     dependencies = [ | ||||
|         ("passbook_core", "0001_initial"), | ||||
|         ("passbook_policies", "0001_initial"), | ||||
|     ] | ||||
|  | ||||
|     operations = [ | ||||
| @ -24,7 +24,7 @@ class Migration(migrations.Migration): | ||||
|                         parent_link=True, | ||||
|                         primary_key=True, | ||||
|                         serialize=False, | ||||
|                         to="passbook_core.Policy", | ||||
|                         to="passbook_policies.Policy", | ||||
|                     ), | ||||
|                 ), | ||||
|                 ("amount_uppercase", models.IntegerField(default=0)), | ||||
| @ -41,6 +41,6 @@ class Migration(migrations.Migration): | ||||
|                 "verbose_name": "Password Policy", | ||||
|                 "verbose_name_plural": "Password Policies", | ||||
|             }, | ||||
|             bases=("passbook_core.policy",), | ||||
|             bases=("passbook_policies.policy",), | ||||
|         ), | ||||
|     ] | ||||
|  | ||||
| @ -5,7 +5,7 @@ from django.db import models | ||||
| from django.utils.translation import gettext as _ | ||||
| from structlog import get_logger | ||||
|  | ||||
| from passbook.core.models import Policy | ||||
| from passbook.policies.models import Policy | ||||
| from passbook.policies.types import PolicyRequest, PolicyResult | ||||
|  | ||||
| LOGGER = get_logger() | ||||
|  | ||||
| @ -6,8 +6,9 @@ from typing import Optional | ||||
| from django.core.cache import cache | ||||
| from structlog import get_logger | ||||
|  | ||||
| from passbook.core.models import Policy, User | ||||
| from passbook.core.models import User | ||||
| from passbook.policies.exceptions import PolicyException | ||||
| from passbook.policies.models import Policy | ||||
| from passbook.policies.types import PolicyRequest, PolicyResult | ||||
|  | ||||
| LOGGER = get_logger() | ||||
|  | ||||
| @ -10,7 +10,7 @@ class Migration(migrations.Migration): | ||||
|     initial = True | ||||
|  | ||||
|     dependencies = [ | ||||
|         ("passbook_core", "0001_initial"), | ||||
|         ("passbook_policies", "0001_initial"), | ||||
|         migrations.swappable_dependency(settings.AUTH_USER_MODEL), | ||||
|     ] | ||||
|  | ||||
| @ -43,7 +43,7 @@ class Migration(migrations.Migration): | ||||
|                         parent_link=True, | ||||
|                         primary_key=True, | ||||
|                         serialize=False, | ||||
|                         to="passbook_core.Policy", | ||||
|                         to="passbook_policies.Policy", | ||||
|                     ), | ||||
|                 ), | ||||
|                 ("check_ip", models.BooleanField(default=True)), | ||||
| @ -54,7 +54,7 @@ class Migration(migrations.Migration): | ||||
|                 "verbose_name": "Reputation Policy", | ||||
|                 "verbose_name_plural": "Reputation Policies", | ||||
|             }, | ||||
|             bases=("passbook_core.policy",), | ||||
|             bases=("passbook_policies.policy",), | ||||
|         ), | ||||
|         migrations.CreateModel( | ||||
|             name="UserReputation", | ||||
|  | ||||
| @ -2,8 +2,9 @@ | ||||
| from django.db import models | ||||
| from django.utils.translation import gettext as _ | ||||
|  | ||||
| from passbook.core.models import Policy, User | ||||
| from passbook.core.models import User | ||||
| from passbook.lib.utils.http import get_client_ip | ||||
| from passbook.policies.models import Policy | ||||
| from passbook.policies.types import PolicyRequest, PolicyResult | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -2,9 +2,10 @@ | ||||
| from django.core.cache import cache | ||||
| from django.test import TestCase | ||||
|  | ||||
| from passbook.core.models import Policy, User | ||||
| from passbook.core.models import User | ||||
| from passbook.policies.dummy.models import DummyPolicy | ||||
| from passbook.policies.engine import PolicyEngine | ||||
| from passbook.policies.models import Policy | ||||
|  | ||||
|  | ||||
| class PolicyTestEngine(TestCase): | ||||
|  | ||||
| @ -11,6 +11,7 @@ class Migration(migrations.Migration): | ||||
|  | ||||
|     dependencies = [ | ||||
|         ("passbook_core", "0001_initial"), | ||||
|         ("passbook_policies", "0001_initial"), | ||||
|     ] | ||||
|  | ||||
|     operations = [ | ||||
| @ -87,7 +88,7 @@ class Migration(migrations.Migration): | ||||
|                 ), | ||||
|                 ( | ||||
|                     "conditions", | ||||
|                     models.ManyToManyField(blank=True, to="passbook_core.Policy"), | ||||
|                     models.ManyToManyField(blank=True, to="passbook_policies.Policy"), | ||||
|                 ), | ||||
|             ], | ||||
|             options={ | ||||
|  | ||||
| @ -11,7 +11,7 @@ class Migration(migrations.Migration): | ||||
|  | ||||
|     dependencies = [ | ||||
|         ("passbook_flows", "0001_initial"), | ||||
|         ("passbook_core", "0012_delete_factor"), | ||||
|         ("passbook_policies", "0001_initial"), | ||||
|     ] | ||||
|  | ||||
|     operations = [ | ||||
| @ -39,7 +39,7 @@ class Migration(migrations.Migration): | ||||
|                 ), | ||||
|                 ( | ||||
|                     "password_policies", | ||||
|                     models.ManyToManyField(blank=True, to="passbook_core.Policy"), | ||||
|                     models.ManyToManyField(blank=True, to="passbook_policies.Policy"), | ||||
|                 ), | ||||
|             ], | ||||
|             options={ | ||||
|  | ||||
| @ -12,7 +12,7 @@ class Migration(migrations.Migration): | ||||
|  | ||||
|     dependencies = [ | ||||
|         ("passbook_flows", "0005_auto_20200512_1158"), | ||||
|         ("passbook_policies", "0003_auto_20200508_1642"), | ||||
|         ("passbook_policies", "0001_initial"), | ||||
|     ] | ||||
|  | ||||
|     operations = [ | ||||
|  | ||||
							
								
								
									
										60
									
								
								swagger.yaml
									
									
									
									
									
								
							
							
						
						
									
										60
									
								
								swagger.yaml
									
									
									
									
									
								
							| @ -154,7 +154,7 @@ paths: | ||||
|       tags: | ||||
|         - core | ||||
|     parameters: [] | ||||
|   /core/applications/{uuid}/: | ||||
|   /core/applications/{id}/: | ||||
|     get: | ||||
|       operationId: core_applications_read | ||||
|       description: Application Viewset | ||||
| @ -208,12 +208,11 @@ paths: | ||||
|       tags: | ||||
|         - core | ||||
|     parameters: | ||||
|       - name: uuid | ||||
|       - name: id | ||||
|         in: path | ||||
|         description: A UUID string identifying this application. | ||||
|         description: A unique integer value identifying this application. | ||||
|         required: true | ||||
|         type: string | ||||
|         format: uuid | ||||
|         type: integer | ||||
|   /core/groups/: | ||||
|     get: | ||||
|       operationId: core_groups_list | ||||
| @ -2658,7 +2657,7 @@ paths: | ||||
|       tags: | ||||
|         - sources | ||||
|     parameters: [] | ||||
|   /sources/all/{uuid}/: | ||||
|   /sources/all/{id}/: | ||||
|     get: | ||||
|       operationId: sources_all_read | ||||
|       description: Source Viewset | ||||
| @ -2671,12 +2670,11 @@ paths: | ||||
|       tags: | ||||
|         - sources | ||||
|     parameters: | ||||
|       - name: uuid | ||||
|       - name: id | ||||
|         in: path | ||||
|         description: A UUID string identifying this source. | ||||
|         description: A unique integer value identifying this source. | ||||
|         required: true | ||||
|         type: string | ||||
|         format: uuid | ||||
|         type: integer | ||||
|   /sources/ldap/: | ||||
|     get: | ||||
|       operationId: sources_ldap_list | ||||
| @ -2744,7 +2742,7 @@ paths: | ||||
|       tags: | ||||
|         - sources | ||||
|     parameters: [] | ||||
|   /sources/ldap/{uuid}/: | ||||
|   /sources/ldap/{id}/: | ||||
|     get: | ||||
|       operationId: sources_ldap_read | ||||
|       description: LDAP Source Viewset | ||||
| @ -2798,12 +2796,11 @@ paths: | ||||
|       tags: | ||||
|         - sources | ||||
|     parameters: | ||||
|       - name: uuid | ||||
|       - name: id | ||||
|         in: path | ||||
|         description: A UUID string identifying this LDAP Source. | ||||
|         description: A unique integer value identifying this LDAP Source. | ||||
|         required: true | ||||
|         type: string | ||||
|         format: uuid | ||||
|         type: integer | ||||
|   /sources/oauth/: | ||||
|     get: | ||||
|       operationId: sources_oauth_list | ||||
| @ -2871,7 +2868,7 @@ paths: | ||||
|       tags: | ||||
|         - sources | ||||
|     parameters: [] | ||||
|   /sources/oauth/{uuid}/: | ||||
|   /sources/oauth/{id}/: | ||||
|     get: | ||||
|       operationId: sources_oauth_read | ||||
|       description: Source Viewset | ||||
| @ -2925,12 +2922,11 @@ paths: | ||||
|       tags: | ||||
|         - sources | ||||
|     parameters: | ||||
|       - name: uuid | ||||
|       - name: id | ||||
|         in: path | ||||
|         description: A UUID string identifying this Generic OAuth Source. | ||||
|         description: A unique integer value identifying this Generic OAuth Source. | ||||
|         required: true | ||||
|         type: string | ||||
|         format: uuid | ||||
|         type: integer | ||||
|   /stages/all/: | ||||
|     get: | ||||
|       operationId: stages_all_list | ||||
| @ -4837,9 +4833,8 @@ definitions: | ||||
|     type: object | ||||
|     properties: | ||||
|       pk: | ||||
|         title: Uuid | ||||
|         type: string | ||||
|         format: uuid | ||||
|         title: ID | ||||
|         type: integer | ||||
|         readOnly: true | ||||
|       name: | ||||
|         title: Name | ||||
| @ -4878,8 +4873,8 @@ definitions: | ||||
|       policies: | ||||
|         type: array | ||||
|         items: | ||||
|           type: string | ||||
|           format: uuid | ||||
|           type: integer | ||||
|         readOnly: true | ||||
|         uniqueItems: true | ||||
|   Group: | ||||
|     required: | ||||
| @ -5610,9 +5605,8 @@ definitions: | ||||
|     type: object | ||||
|     properties: | ||||
|       pk: | ||||
|         title: Uuid | ||||
|         type: string | ||||
|         format: uuid | ||||
|         title: ID | ||||
|         type: integer | ||||
|         readOnly: true | ||||
|       name: | ||||
|         title: Name | ||||
| @ -5647,9 +5641,8 @@ definitions: | ||||
|     type: object | ||||
|     properties: | ||||
|       pk: | ||||
|         title: Uuid | ||||
|         type: string | ||||
|         format: uuid | ||||
|         title: ID | ||||
|         type: integer | ||||
|         readOnly: true | ||||
|       name: | ||||
|         title: Name | ||||
| @ -5743,9 +5736,8 @@ definitions: | ||||
|     type: object | ||||
|     properties: | ||||
|       pk: | ||||
|         title: Uuid | ||||
|         type: string | ||||
|         format: uuid | ||||
|         title: ID | ||||
|         type: integer | ||||
|         readOnly: true | ||||
|       name: | ||||
|         title: Name | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Jens Langhammer
					Jens Langhammer