diff --git a/passbook/policies/dummy/models.py b/passbook/policies/dummy/models.py index a8172157a..497f7a0fb 100644 --- a/passbook/policies/dummy/models.py +++ b/passbook/policies/dummy/models.py @@ -1,8 +1,10 @@ """Dummy policy""" from random import SystemRandom from time import sleep +from typing import Type from django.db import models +from django.forms import ModelForm from django.utils.translation import gettext_lazy as _ from structlog import get_logger @@ -22,7 +24,10 @@ class DummyPolicy(Policy): wait_min = models.IntegerField(default=5) wait_max = models.IntegerField(default=30) - form = "passbook.policies.dummy.forms.DummyPolicyForm" + def form(self) -> Type[ModelForm]: + from passbook.policies.dummy.forms import DummyPolicyForm + + return DummyPolicyForm def passes(self, request: PolicyRequest) -> PolicyResult: """Wait random time then return result""" diff --git a/passbook/policies/expiry/models.py b/passbook/policies/expiry/models.py index dfba3b4b9..f476c4dc0 100644 --- a/passbook/policies/expiry/models.py +++ b/passbook/policies/expiry/models.py @@ -1,7 +1,9 @@ """passbook password_expiry_policy Models""" from datetime import timedelta +from typing import Type from django.db import models +from django.forms import ModelForm from django.utils.timezone import now from django.utils.translation import gettext as _ from structlog import get_logger @@ -19,7 +21,10 @@ class PasswordExpiryPolicy(Policy): deny_only = models.BooleanField(default=False) days = models.IntegerField() - form = "passbook.policies.expiry.forms.PasswordExpiryPolicyForm" + def form(self) -> Type[ModelForm]: + from passbook.policies.expiry.forms import PasswordExpiryPolicyForm + + return PasswordExpiryPolicyForm def passes(self, request: PolicyRequest) -> PolicyResult: """If password change date is more than x days in the past, call set_unusable_password diff --git a/passbook/policies/expression/models.py b/passbook/policies/expression/models.py index 67137d0b6..31c3c398e 100644 --- a/passbook/policies/expression/models.py +++ b/passbook/policies/expression/models.py @@ -1,5 +1,8 @@ """passbook expression Policy Models""" +from typing import Type + from django.db import models +from django.forms import ModelForm from django.utils.translation import gettext as _ from passbook.policies.expression.evaluator import PolicyEvaluator @@ -12,7 +15,10 @@ class ExpressionPolicy(Policy): expression = models.TextField() - form = "passbook.policies.expression.forms.ExpressionPolicyForm" + def form(self) -> Type[ModelForm]: + from passbook.policies.expression.forms import ExpressionPolicyForm + + return ExpressionPolicyForm def passes(self, request: PolicyRequest) -> PolicyResult: """Evaluate and render expression. Returns PolicyResult(false) on error.""" diff --git a/passbook/policies/group_membership/models.py b/passbook/policies/group_membership/models.py index 730b49a9e..7f87a9a00 100644 --- a/passbook/policies/group_membership/models.py +++ b/passbook/policies/group_membership/models.py @@ -1,5 +1,8 @@ """user field matcher models""" +from typing import Type + from django.db import models +from django.forms import ModelForm from django.utils.translation import gettext as _ from passbook.core.models import Group @@ -12,7 +15,10 @@ class GroupMembershipPolicy(Policy): group = models.ForeignKey(Group, null=True, blank=True, on_delete=models.SET_NULL) - form = "passbook.policies.group_membership.forms.GroupMembershipPolicyForm" + def form(self) -> Type[ModelForm]: + from passbook.policies.group_membership.forms import GroupMembershipPolicyForm + + return GroupMembershipPolicyForm def passes(self, request: PolicyRequest) -> PolicyResult: return PolicyResult(self.group.user_set.filter(pk=request.user.pk).exists()) diff --git a/passbook/policies/hibp/models.py b/passbook/policies/hibp/models.py index 90407321d..f9a27fd19 100644 --- a/passbook/policies/hibp/models.py +++ b/passbook/policies/hibp/models.py @@ -1,7 +1,9 @@ """passbook HIBP Models""" from hashlib import sha1 +from typing import Type from django.db import models +from django.forms import ModelForm from django.utils.translation import gettext as _ from requests import get from structlog import get_logger @@ -25,7 +27,10 @@ class HaveIBeenPwendPolicy(Policy): allowed_count = models.IntegerField(default=0) - form = "passbook.policies.hibp.forms.HaveIBeenPwnedPolicyForm" + def form(self) -> Type[ModelForm]: + from passbook.policies.hibp.forms import HaveIBeenPwnedPolicyForm + + return HaveIBeenPwnedPolicyForm def passes(self, request: PolicyRequest) -> PolicyResult: """Check if password is in HIBP DB. Hashes given Password with SHA1, uses the first 5 diff --git a/passbook/policies/models.py b/passbook/policies/models.py index 826938f51..06c096ec7 100644 --- a/passbook/policies/models.py +++ b/passbook/policies/models.py @@ -1,7 +1,9 @@ """Policy base models""" +from typing import Type from uuid import uuid4 from django.db import models +from django.forms import ModelForm from django.utils.translation import gettext_lazy as _ from model_utils.managers import InheritanceManager @@ -73,6 +75,10 @@ class Policy(CreatedUpdatedModel): objects = InheritanceAutoManager() + def form(self) -> Type[ModelForm]: + """Return Form class used to edit this object""" + raise NotImplementedError + def __str__(self): return f"Policy {self.name}" diff --git a/passbook/policies/password/models.py b/passbook/policies/password/models.py index f0250a2f4..bdd40bd92 100644 --- a/passbook/policies/password/models.py +++ b/passbook/policies/password/models.py @@ -1,7 +1,9 @@ """user field matcher models""" import re +from typing import Type from django.db import models +from django.forms import ModelForm from django.utils.translation import gettext as _ from structlog import get_logger @@ -28,7 +30,10 @@ class PasswordPolicy(Policy): symbol_charset = models.TextField(default=r"!\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ ") error_message = models.TextField() - form = "passbook.policies.password.forms.PasswordPolicyForm" + def form(self) -> Type[ModelForm]: + from passbook.policies.password.forms import PasswordPolicyForm + + return PasswordPolicyForm def passes(self, request: PolicyRequest) -> PolicyResult: if self.password_field not in request.context: diff --git a/passbook/policies/reputation/models.py b/passbook/policies/reputation/models.py index aa4326129..9ed0366a4 100644 --- a/passbook/policies/reputation/models.py +++ b/passbook/policies/reputation/models.py @@ -1,6 +1,9 @@ """passbook reputation request policy""" +from typing import Type + from django.core.cache import cache from django.db import models +from django.forms import ModelForm from django.utils.translation import gettext as _ from passbook.core.models import User @@ -19,7 +22,10 @@ class ReputationPolicy(Policy): check_username = models.BooleanField(default=True) threshold = models.IntegerField(default=-5) - form = "passbook.policies.reputation.forms.ReputationPolicyForm" + def form(self) -> Type[ModelForm]: + from passbook.policies.reputation.forms import ReputationPolicyForm + + return ReputationPolicyForm def passes(self, request: PolicyRequest) -> PolicyResult: remote_ip = get_client_ip(request.http_request) or "255.255.255.255"