policies: change .form() and .serializer() to properties, add tests
This commit is contained in:
parent
5da4ff4ff1
commit
9724ded194
|
@ -64,7 +64,7 @@ class InheritanceUpdateView(UpdateView):
|
||||||
return kwargs
|
return kwargs
|
||||||
|
|
||||||
def get_form_class(self):
|
def get_form_class(self):
|
||||||
return self.get_object().form()
|
return self.get_object().form
|
||||||
|
|
||||||
def get_object(self, queryset=None):
|
def get_object(self, queryset=None):
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -136,6 +136,7 @@ class Provider(models.Model):
|
||||||
Can return None for providers that are not URL-based"""
|
Can return None for providers that are not URL-based"""
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
"""Return Form class used to edit this object"""
|
"""Return Form class used to edit this object"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
@ -220,6 +221,7 @@ class Source(PolicyBindingModel):
|
||||||
|
|
||||||
objects = InheritanceManager()
|
objects = InheritanceManager()
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
"""Return Form class used to edit this object"""
|
"""Return Form class used to edit this object"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
@ -321,6 +323,7 @@ class PropertyMapping(models.Model):
|
||||||
|
|
||||||
objects = InheritanceManager()
|
objects = InheritanceManager()
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
"""Return Form class used to edit this object"""
|
"""Return Form class used to edit this object"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
|
@ -62,6 +62,6 @@ class ServerErrorView(TemplateView):
|
||||||
template_name = "error/generic.html"
|
template_name = "error/generic.html"
|
||||||
|
|
||||||
# pylint: disable=useless-super-delegation
|
# pylint: disable=useless-super-delegation
|
||||||
def dispatch(self, *args, **kwargs):
|
def dispatch(self, *args, **kwargs): # pragma: no cover
|
||||||
"""Little wrapper so django accepts this function"""
|
"""Little wrapper so django accepts this function"""
|
||||||
return super().dispatch(*args, **kwargs)
|
return super().dispatch(*args, **kwargs)
|
||||||
|
|
|
@ -50,6 +50,7 @@ class Stage(SerializerModel):
|
||||||
|
|
||||||
objects = InheritanceManager()
|
objects = InheritanceManager()
|
||||||
|
|
||||||
|
@property
|
||||||
def type(self) -> Type["StageView"]:
|
def type(self) -> Type["StageView"]:
|
||||||
"""Return StageView class that implements logic for this stage"""
|
"""Return StageView class that implements logic for this stage"""
|
||||||
# This is a bit of a workaround, since we can't set class methods with setattr
|
# This is a bit of a workaround, since we can't set class methods with setattr
|
||||||
|
@ -57,6 +58,7 @@ class Stage(SerializerModel):
|
||||||
return getattr(self, "__in_memory_type")
|
return getattr(self, "__in_memory_type")
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
"""Return Form class used to edit this object"""
|
"""Return Form class used to edit this object"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
"""flow model tests"""
|
||||||
|
from typing import Callable, Type
|
||||||
|
|
||||||
|
from django.forms import ModelForm
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from passbook.flows.models import Stage
|
||||||
|
from passbook.flows.stage import StageView
|
||||||
|
|
||||||
|
|
||||||
|
class TestStageProperties(TestCase):
|
||||||
|
"""Generic model properties tests"""
|
||||||
|
|
||||||
|
|
||||||
|
def stage_tester_factory(model: Type[Stage]) -> Callable:
|
||||||
|
"""Test a form"""
|
||||||
|
|
||||||
|
def tester(self: TestStageProperties):
|
||||||
|
model_inst = model()
|
||||||
|
self.assertTrue(issubclass(model_inst.form, ModelForm))
|
||||||
|
self.assertTrue(issubclass(model_inst.type, StageView))
|
||||||
|
|
||||||
|
return tester
|
||||||
|
|
||||||
|
|
||||||
|
for stage_type in Stage.__subclasses__():
|
||||||
|
setattr(
|
||||||
|
TestStageProperties,
|
||||||
|
f"test_stage_{stage_type.__name__}",
|
||||||
|
stage_tester_factory(stage_type),
|
||||||
|
)
|
|
@ -96,7 +96,7 @@ class FlowExecutorView(View):
|
||||||
current_stage=self.current_stage,
|
current_stage=self.current_stage,
|
||||||
flow_slug=self.flow.slug,
|
flow_slug=self.flow.slug,
|
||||||
)
|
)
|
||||||
stage_cls = self.current_stage.type()
|
stage_cls = self.current_stage.type
|
||||||
self.current_stage_view = stage_cls(self)
|
self.current_stage_view = stage_cls(self)
|
||||||
self.current_stage_view.args = self.args
|
self.current_stage_view.args = self.args
|
||||||
self.current_stage_view.kwargs = self.kwargs
|
self.current_stage_view.kwargs = self.kwargs
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
"""base model tests"""
|
||||||
|
from typing import Callable, Type
|
||||||
|
|
||||||
|
from django.test import TestCase
|
||||||
|
from rest_framework.serializers import BaseSerializer
|
||||||
|
|
||||||
|
from passbook.flows.models import Stage
|
||||||
|
from passbook.lib.models import SerializerModel
|
||||||
|
from passbook.lib.utils.reflection import all_subclasses
|
||||||
|
|
||||||
|
|
||||||
|
class TestModels(TestCase):
|
||||||
|
"""Generic model properties tests"""
|
||||||
|
|
||||||
|
|
||||||
|
def model_tester_factory(test_model: Type[Stage]) -> Callable:
|
||||||
|
"""Test a form"""
|
||||||
|
|
||||||
|
def tester(self: TestModels):
|
||||||
|
model_inst = test_model()
|
||||||
|
try:
|
||||||
|
self.assertTrue(issubclass(model_inst.serializer, BaseSerializer))
|
||||||
|
except NotImplementedError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return tester
|
||||||
|
|
||||||
|
|
||||||
|
for model in all_subclasses(SerializerModel):
|
||||||
|
setattr(TestModels, f"test_model_{model.__name__}", model_tester_factory(model))
|
|
@ -31,6 +31,7 @@ class DummyPolicy(Policy):
|
||||||
|
|
||||||
return DummyPolicySerializer
|
return DummyPolicySerializer
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.policies.dummy.forms import DummyPolicyForm
|
from passbook.policies.dummy.forms import DummyPolicyForm
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ class PolicyEngine:
|
||||||
def __init__(
|
def __init__(
|
||||||
self, pbm: PolicyBindingModel, user: User, request: HttpRequest = None
|
self, pbm: PolicyBindingModel, user: User, request: HttpRequest = None
|
||||||
):
|
):
|
||||||
if not isinstance(pbm, PolicyBindingModel):
|
if not isinstance(pbm, PolicyBindingModel): # pragma: no cover
|
||||||
raise ValueError(f"{pbm} is not instance of PolicyBindingModel")
|
raise ValueError(f"{pbm} is not instance of PolicyBindingModel")
|
||||||
self.__pbm = pbm
|
self.__pbm = pbm
|
||||||
self.request = PolicyRequest(user)
|
self.request = PolicyRequest(user)
|
||||||
|
|
|
@ -28,6 +28,7 @@ class PasswordExpiryPolicy(Policy):
|
||||||
|
|
||||||
return PasswordExpiryPolicySerializer
|
return PasswordExpiryPolicySerializer
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.policies.expiry.forms import PasswordExpiryPolicyForm
|
from passbook.policies.expiry.forms import PasswordExpiryPolicyForm
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ class ExpressionPolicy(Policy):
|
||||||
|
|
||||||
return ExpressionPolicySerializer
|
return ExpressionPolicySerializer
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.policies.expression.forms import ExpressionPolicyForm
|
from passbook.policies.expression.forms import ExpressionPolicyForm
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ class GroupMembershipPolicy(Policy):
|
||||||
|
|
||||||
return GroupMembershipPolicySerializer
|
return GroupMembershipPolicySerializer
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.policies.group_membership.forms import GroupMembershipPolicyForm
|
from passbook.policies.group_membership.forms import GroupMembershipPolicyForm
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ class HaveIBeenPwendPolicy(Policy):
|
||||||
|
|
||||||
return HaveIBeenPwendPolicySerializer
|
return HaveIBeenPwendPolicySerializer
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.policies.hibp.forms import HaveIBeenPwnedPolicyForm
|
from passbook.policies.hibp.forms import HaveIBeenPwnedPolicyForm
|
||||||
|
|
||||||
|
|
|
@ -83,14 +83,15 @@ class Policy(SerializerModel, CreatedUpdatedModel):
|
||||||
|
|
||||||
objects = InheritanceAutoManager()
|
objects = InheritanceAutoManager()
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
"""Return Form class used to edit this object"""
|
"""Return Form class used to edit this object"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return f"Policy {self.name}"
|
return f"{self.__class__.__name__} {self.name}"
|
||||||
|
|
||||||
def passes(self, request: PolicyRequest) -> PolicyResult:
|
def passes(self, request: PolicyRequest) -> PolicyResult: # pragma: no cover
|
||||||
"""Check if user instance passes this policy"""
|
"""Check if user instance passes this policy"""
|
||||||
raise PolicyException()
|
raise PolicyException()
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,7 @@ class PasswordPolicy(Policy):
|
||||||
|
|
||||||
return PasswordPolicySerializer
|
return PasswordPolicySerializer
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.policies.password.forms import PasswordPolicyForm
|
from passbook.policies.password.forms import PasswordPolicyForm
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ class ReputationPolicy(Policy):
|
||||||
|
|
||||||
return ReputationPolicySerializer
|
return ReputationPolicySerializer
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.policies.reputation.forms import ReputationPolicyForm
|
from passbook.policies.reputation.forms import ReputationPolicyForm
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
"""flow model tests"""
|
||||||
|
from typing import Callable, Type
|
||||||
|
|
||||||
|
from django.forms import ModelForm
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from passbook.lib.utils.reflection import all_subclasses
|
||||||
|
from passbook.policies.models import Policy
|
||||||
|
|
||||||
|
|
||||||
|
class TestPolicyProperties(TestCase):
|
||||||
|
"""Generic model properties tests"""
|
||||||
|
|
||||||
|
|
||||||
|
def policy_tester_factory(model: Type[Policy]) -> Callable:
|
||||||
|
"""Test a form"""
|
||||||
|
|
||||||
|
def tester(self: TestPolicyProperties):
|
||||||
|
model_inst = model()
|
||||||
|
self.assertTrue(issubclass(model_inst.form, ModelForm))
|
||||||
|
|
||||||
|
return tester
|
||||||
|
|
||||||
|
|
||||||
|
for policy_type in all_subclasses(Policy):
|
||||||
|
setattr(
|
||||||
|
TestPolicyProperties,
|
||||||
|
f"test_policy_{policy_type.__name__}",
|
||||||
|
policy_tester_factory(policy_type),
|
||||||
|
)
|
|
@ -102,6 +102,7 @@ class ScopeMapping(PropertyMapping):
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.providers.oauth2.forms import ScopeMappingForm
|
from passbook.providers.oauth2.forms import ScopeMappingForm
|
||||||
|
|
||||||
|
@ -264,6 +265,7 @@ class OAuth2Provider(Provider):
|
||||||
launch_url = urlparse(main_url)
|
launch_url = urlparse(main_url)
|
||||||
return main_url.replace(launch_url.path, "")
|
return main_url.replace(launch_url.path, "")
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.providers.oauth2.forms import OAuth2ProviderForm
|
from passbook.providers.oauth2.forms import OAuth2ProviderForm
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,7 @@ class ProxyProvider(OutpostModel, OAuth2Provider):
|
||||||
|
|
||||||
cookie_secret = models.TextField(default=get_cookie_secret)
|
cookie_secret = models.TextField(default=get_cookie_secret)
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.providers.proxy.forms import ProxyProviderForm
|
from passbook.providers.proxy.forms import ProxyProviderForm
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
"""Test Controllers"""
|
||||||
|
import yaml
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from passbook.flows.models import Flow
|
||||||
|
from passbook.outposts.models import Outpost, OutpostDeploymentType, OutpostType
|
||||||
|
from passbook.providers.proxy.controllers.kubernetes import KubernetesController
|
||||||
|
from passbook.providers.proxy.models import ProxyProvider
|
||||||
|
|
||||||
|
|
||||||
|
class TestControllers(TestCase):
|
||||||
|
"""Test Controllers"""
|
||||||
|
|
||||||
|
def test_kubernetes_controller(self):
|
||||||
|
"""Test Kubernetes Controller"""
|
||||||
|
provider: ProxyProvider = ProxyProvider.objects.create(
|
||||||
|
name="test",
|
||||||
|
internal_host="http://localhost",
|
||||||
|
external_host="http://localhost",
|
||||||
|
authorization_flow=Flow.objects.first(),
|
||||||
|
)
|
||||||
|
outpost: Outpost = Outpost.objects.create(
|
||||||
|
name="test",
|
||||||
|
type=OutpostType.PROXY,
|
||||||
|
deployment_type=OutpostDeploymentType.CUSTOM,
|
||||||
|
)
|
||||||
|
outpost.providers.add(provider)
|
||||||
|
outpost.save()
|
||||||
|
|
||||||
|
controller = KubernetesController(outpost.pk)
|
||||||
|
manifest = controller.get_static_deployment()
|
||||||
|
self.assertEqual(len(list(yaml.load_all(manifest, Loader=yaml.SafeLoader))), 3)
|
|
@ -109,6 +109,7 @@ class SAMLProvider(Provider):
|
||||||
launch_url = urlparse(self.acs_url)
|
launch_url = urlparse(self.acs_url)
|
||||||
return self.acs_url.replace(launch_url.path, "")
|
return self.acs_url.replace(launch_url.path, "")
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.providers.saml.forms import SAMLProviderForm
|
from passbook.providers.saml.forms import SAMLProviderForm
|
||||||
|
|
||||||
|
@ -154,6 +155,7 @@ class SAMLPropertyMapping(PropertyMapping):
|
||||||
saml_name = models.TextField(verbose_name="SAML Name")
|
saml_name = models.TextField(verbose_name="SAML Name")
|
||||||
friendly_name = models.TextField(default=None, blank=True, null=True)
|
friendly_name = models.TextField(default=None, blank=True, null=True)
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.providers.saml.forms import SAMLPropertyMappingForm
|
from passbook.providers.saml.forms import SAMLPropertyMappingForm
|
||||||
|
|
||||||
|
|
|
@ -67,6 +67,7 @@ class LDAPSource(Source):
|
||||||
Group, blank=True, null=True, default=None, on_delete=models.SET_DEFAULT
|
Group, blank=True, null=True, default=None, on_delete=models.SET_DEFAULT
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.sources.ldap.forms import LDAPSourceForm
|
from passbook.sources.ldap.forms import LDAPSourceForm
|
||||||
|
|
||||||
|
@ -116,6 +117,7 @@ class LDAPPropertyMapping(PropertyMapping):
|
||||||
|
|
||||||
object_field = models.TextField()
|
object_field = models.TextField()
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.sources.ldap.forms import LDAPPropertyMappingForm
|
from passbook.sources.ldap.forms import LDAPPropertyMappingForm
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ class OAuthSource(Source):
|
||||||
consumer_key = models.TextField()
|
consumer_key = models.TextField()
|
||||||
consumer_secret = models.TextField()
|
consumer_secret = models.TextField()
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.sources.oauth.forms import OAuthSourceForm
|
from passbook.sources.oauth.forms import OAuthSourceForm
|
||||||
|
|
||||||
|
@ -83,6 +84,7 @@ class OAuthSource(Source):
|
||||||
class GitHubOAuthSource(OAuthSource):
|
class GitHubOAuthSource(OAuthSource):
|
||||||
"""Social Login using GitHub.com or a GitHub-Enterprise Instance."""
|
"""Social Login using GitHub.com or a GitHub-Enterprise Instance."""
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.sources.oauth.forms import GitHubOAuthSourceForm
|
from passbook.sources.oauth.forms import GitHubOAuthSourceForm
|
||||||
|
|
||||||
|
@ -98,6 +100,7 @@ class GitHubOAuthSource(OAuthSource):
|
||||||
class TwitterOAuthSource(OAuthSource):
|
class TwitterOAuthSource(OAuthSource):
|
||||||
"""Social Login using Twitter.com"""
|
"""Social Login using Twitter.com"""
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.sources.oauth.forms import TwitterOAuthSourceForm
|
from passbook.sources.oauth.forms import TwitterOAuthSourceForm
|
||||||
|
|
||||||
|
@ -113,6 +116,7 @@ class TwitterOAuthSource(OAuthSource):
|
||||||
class FacebookOAuthSource(OAuthSource):
|
class FacebookOAuthSource(OAuthSource):
|
||||||
"""Social Login using Facebook.com."""
|
"""Social Login using Facebook.com."""
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.sources.oauth.forms import FacebookOAuthSourceForm
|
from passbook.sources.oauth.forms import FacebookOAuthSourceForm
|
||||||
|
|
||||||
|
@ -128,6 +132,7 @@ class FacebookOAuthSource(OAuthSource):
|
||||||
class DiscordOAuthSource(OAuthSource):
|
class DiscordOAuthSource(OAuthSource):
|
||||||
"""Social Login using Discord."""
|
"""Social Login using Discord."""
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.sources.oauth.forms import DiscordOAuthSourceForm
|
from passbook.sources.oauth.forms import DiscordOAuthSourceForm
|
||||||
|
|
||||||
|
@ -143,6 +148,7 @@ class DiscordOAuthSource(OAuthSource):
|
||||||
class GoogleOAuthSource(OAuthSource):
|
class GoogleOAuthSource(OAuthSource):
|
||||||
"""Social Login using Google or Gsuite."""
|
"""Social Login using Google or Gsuite."""
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.sources.oauth.forms import GoogleOAuthSourceForm
|
from passbook.sources.oauth.forms import GoogleOAuthSourceForm
|
||||||
|
|
||||||
|
@ -158,6 +164,7 @@ class GoogleOAuthSource(OAuthSource):
|
||||||
class AzureADOAuthSource(OAuthSource):
|
class AzureADOAuthSource(OAuthSource):
|
||||||
"""Social Login using Azure AD."""
|
"""Social Login using Azure AD."""
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.sources.oauth.forms import AzureADOAuthSourceForm
|
from passbook.sources.oauth.forms import AzureADOAuthSourceForm
|
||||||
|
|
||||||
|
@ -173,6 +180,7 @@ class AzureADOAuthSource(OAuthSource):
|
||||||
class OpenIDOAuthSource(OAuthSource):
|
class OpenIDOAuthSource(OAuthSource):
|
||||||
"""Login using a Generic OpenID-Connect compliant provider."""
|
"""Login using a Generic OpenID-Connect compliant provider."""
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.sources.oauth.forms import OAuthSourceForm
|
from passbook.sources.oauth.forms import OAuthSourceForm
|
||||||
|
|
||||||
|
|
|
@ -103,6 +103,7 @@ class SAMLSource(Source):
|
||||||
on_delete=models.PROTECT,
|
on_delete=models.PROTECT,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.sources.saml.forms import SAMLSourceForm
|
from passbook.sources.saml.forms import SAMLSourceForm
|
||||||
|
|
||||||
|
|
|
@ -30,11 +30,13 @@ class CaptchaStage(Stage):
|
||||||
|
|
||||||
return CaptchaStageSerializer
|
return CaptchaStageSerializer
|
||||||
|
|
||||||
|
@property
|
||||||
def type(self) -> Type[View]:
|
def type(self) -> Type[View]:
|
||||||
from passbook.stages.captcha.stage import CaptchaStageView
|
from passbook.stages.captcha.stage import CaptchaStageView
|
||||||
|
|
||||||
return CaptchaStageView
|
return CaptchaStageView
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.stages.captcha.forms import CaptchaStageForm
|
from passbook.stages.captcha.forms import CaptchaStageForm
|
||||||
|
|
||||||
|
|
|
@ -44,11 +44,13 @@ class ConsentStage(Stage):
|
||||||
|
|
||||||
return ConsentStageSerializer
|
return ConsentStageSerializer
|
||||||
|
|
||||||
|
@property
|
||||||
def type(self) -> Type[View]:
|
def type(self) -> Type[View]:
|
||||||
from passbook.stages.consent.stage import ConsentStageView
|
from passbook.stages.consent.stage import ConsentStageView
|
||||||
|
|
||||||
return ConsentStageView
|
return ConsentStageView
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.stages.consent.forms import ConsentStageForm
|
from passbook.stages.consent.forms import ConsentStageForm
|
||||||
|
|
||||||
|
|
|
@ -20,11 +20,13 @@ class DummyStage(Stage):
|
||||||
|
|
||||||
return DummyStageSerializer
|
return DummyStageSerializer
|
||||||
|
|
||||||
|
@property
|
||||||
def type(self) -> Type[View]:
|
def type(self) -> Type[View]:
|
||||||
from passbook.stages.dummy.stage import DummyStageView
|
from passbook.stages.dummy.stage import DummyStageView
|
||||||
|
|
||||||
return DummyStageView
|
return DummyStageView
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.stages.dummy.forms import DummyStageForm
|
from passbook.stages.dummy.forms import DummyStageForm
|
||||||
|
|
||||||
|
|
|
@ -51,11 +51,13 @@ class EmailStage(Stage):
|
||||||
|
|
||||||
return EmailStageSerializer
|
return EmailStageSerializer
|
||||||
|
|
||||||
|
@property
|
||||||
def type(self) -> Type[View]:
|
def type(self) -> Type[View]:
|
||||||
from passbook.stages.email.stage import EmailStageView
|
from passbook.stages.email.stage import EmailStageView
|
||||||
|
|
||||||
return EmailStageView
|
return EmailStageView
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.stages.email.forms import EmailStageForm
|
from passbook.stages.email.forms import EmailStageForm
|
||||||
|
|
||||||
|
|
|
@ -63,11 +63,13 @@ class IdentificationStage(Stage):
|
||||||
|
|
||||||
return IdentificationStageSerializer
|
return IdentificationStageSerializer
|
||||||
|
|
||||||
|
@property
|
||||||
def type(self) -> Type[View]:
|
def type(self) -> Type[View]:
|
||||||
from passbook.stages.identification.stage import IdentificationStageView
|
from passbook.stages.identification.stage import IdentificationStageView
|
||||||
|
|
||||||
return IdentificationStageView
|
return IdentificationStageView
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.stages.identification.forms import IdentificationStageForm
|
from passbook.stages.identification.forms import IdentificationStageForm
|
||||||
|
|
||||||
|
|
|
@ -33,11 +33,13 @@ class InvitationStage(Stage):
|
||||||
|
|
||||||
return InvitationStageSerializer
|
return InvitationStageSerializer
|
||||||
|
|
||||||
|
@property
|
||||||
def type(self) -> Type[View]:
|
def type(self) -> Type[View]:
|
||||||
from passbook.stages.invitation.stage import InvitationStageView
|
from passbook.stages.invitation.stage import InvitationStageView
|
||||||
|
|
||||||
return InvitationStageView
|
return InvitationStageView
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.stages.invitation.forms import InvitationStageForm
|
from passbook.stages.invitation.forms import InvitationStageForm
|
||||||
|
|
||||||
|
|
|
@ -23,11 +23,13 @@ class OTPStaticStage(ConfigurableStage, Stage):
|
||||||
|
|
||||||
return OTPStaticStageSerializer
|
return OTPStaticStageSerializer
|
||||||
|
|
||||||
|
@property
|
||||||
def type(self) -> Type[View]:
|
def type(self) -> Type[View]:
|
||||||
from passbook.stages.otp_static.stage import OTPStaticStageView
|
from passbook.stages.otp_static.stage import OTPStaticStageView
|
||||||
|
|
||||||
return OTPStaticStageView
|
return OTPStaticStageView
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.stages.otp_static.forms import OTPStaticStageForm
|
from passbook.stages.otp_static.forms import OTPStaticStageForm
|
||||||
|
|
||||||
|
|
|
@ -30,11 +30,13 @@ class OTPTimeStage(ConfigurableStage, Stage):
|
||||||
|
|
||||||
return OTPTimeStageSerializer
|
return OTPTimeStageSerializer
|
||||||
|
|
||||||
|
@property
|
||||||
def type(self) -> Type[View]:
|
def type(self) -> Type[View]:
|
||||||
from passbook.stages.otp_time.stage import OTPTimeStageView
|
from passbook.stages.otp_time.stage import OTPTimeStageView
|
||||||
|
|
||||||
return OTPTimeStageView
|
return OTPTimeStageView
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.stages.otp_time.forms import OTPTimeStageForm
|
from passbook.stages.otp_time.forms import OTPTimeStageForm
|
||||||
|
|
||||||
|
|
|
@ -23,11 +23,13 @@ class OTPValidateStage(Stage):
|
||||||
|
|
||||||
return OTPValidateStageSerializer
|
return OTPValidateStageSerializer
|
||||||
|
|
||||||
|
@property
|
||||||
def type(self) -> Type[View]:
|
def type(self) -> Type[View]:
|
||||||
from passbook.stages.otp_validate.stage import OTPValidateStageView
|
from passbook.stages.otp_validate.stage import OTPValidateStageView
|
||||||
|
|
||||||
return OTPValidateStageView
|
return OTPValidateStageView
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.stages.otp_validate.forms import OTPValidateStageForm
|
from passbook.stages.otp_validate.forms import OTPValidateStageForm
|
||||||
|
|
||||||
|
|
|
@ -38,11 +38,13 @@ class PasswordStage(ConfigurableStage, Stage):
|
||||||
|
|
||||||
return PasswordStageSerializer
|
return PasswordStageSerializer
|
||||||
|
|
||||||
|
@property
|
||||||
def type(self) -> Type[View]:
|
def type(self) -> Type[View]:
|
||||||
from passbook.stages.password.stage import PasswordStageView
|
from passbook.stages.password.stage import PasswordStageView
|
||||||
|
|
||||||
return PasswordStageView
|
return PasswordStageView
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.stages.password.forms import PasswordStageForm
|
from passbook.stages.password.forms import PasswordStageForm
|
||||||
|
|
||||||
|
|
|
@ -145,11 +145,13 @@ class PromptStage(Stage):
|
||||||
|
|
||||||
return PromptStageSerializer
|
return PromptStageSerializer
|
||||||
|
|
||||||
|
@property
|
||||||
def type(self) -> Type[View]:
|
def type(self) -> Type[View]:
|
||||||
from passbook.stages.prompt.stage import PromptStageView
|
from passbook.stages.prompt.stage import PromptStageView
|
||||||
|
|
||||||
return PromptStageView
|
return PromptStageView
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.stages.prompt.forms import PromptStageForm
|
from passbook.stages.prompt.forms import PromptStageForm
|
||||||
|
|
||||||
|
|
|
@ -19,11 +19,13 @@ class UserDeleteStage(Stage):
|
||||||
|
|
||||||
return UserDeleteStageSerializer
|
return UserDeleteStageSerializer
|
||||||
|
|
||||||
|
@property
|
||||||
def type(self) -> Type[View]:
|
def type(self) -> Type[View]:
|
||||||
from passbook.stages.user_delete.stage import UserDeleteStageView
|
from passbook.stages.user_delete.stage import UserDeleteStageView
|
||||||
|
|
||||||
return UserDeleteStageView
|
return UserDeleteStageView
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.stages.user_delete.forms import UserDeleteStageForm
|
from passbook.stages.user_delete.forms import UserDeleteStageForm
|
||||||
|
|
||||||
|
|
|
@ -27,11 +27,13 @@ class UserLoginStage(Stage):
|
||||||
|
|
||||||
return UserLoginStageSerializer
|
return UserLoginStageSerializer
|
||||||
|
|
||||||
|
@property
|
||||||
def type(self) -> Type[View]:
|
def type(self) -> Type[View]:
|
||||||
from passbook.stages.user_login.stage import UserLoginStageView
|
from passbook.stages.user_login.stage import UserLoginStageView
|
||||||
|
|
||||||
return UserLoginStageView
|
return UserLoginStageView
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.stages.user_login.forms import UserLoginStageForm
|
from passbook.stages.user_login.forms import UserLoginStageForm
|
||||||
|
|
||||||
|
|
|
@ -18,11 +18,13 @@ class UserLogoutStage(Stage):
|
||||||
|
|
||||||
return UserLogoutStageSerializer
|
return UserLogoutStageSerializer
|
||||||
|
|
||||||
|
@property
|
||||||
def type(self) -> Type[View]:
|
def type(self) -> Type[View]:
|
||||||
from passbook.stages.user_logout.stage import UserLogoutStageView
|
from passbook.stages.user_logout.stage import UserLogoutStageView
|
||||||
|
|
||||||
return UserLogoutStageView
|
return UserLogoutStageView
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.stages.user_logout.forms import UserLogoutStageForm
|
from passbook.stages.user_logout.forms import UserLogoutStageForm
|
||||||
|
|
||||||
|
|
|
@ -19,11 +19,13 @@ class UserWriteStage(Stage):
|
||||||
|
|
||||||
return UserWriteStageSerializer
|
return UserWriteStageSerializer
|
||||||
|
|
||||||
|
@property
|
||||||
def type(self) -> Type[View]:
|
def type(self) -> Type[View]:
|
||||||
from passbook.stages.user_write.stage import UserWriteStageView
|
from passbook.stages.user_write.stage import UserWriteStageView
|
||||||
|
|
||||||
return UserWriteStageView
|
return UserWriteStageView
|
||||||
|
|
||||||
|
@property
|
||||||
def form(self) -> Type[ModelForm]:
|
def form(self) -> Type[ModelForm]:
|
||||||
from passbook.stages.user_write.forms import UserWriteStageForm
|
from passbook.stages.user_write.forms import UserWriteStageForm
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
[pytest]
|
[pytest]
|
||||||
DJANGO_SETTINGS_MODULE = passbook.root.settings
|
DJANGO_SETTINGS_MODULE = passbook.root.settings
|
||||||
# -- recommended but optional:
|
|
||||||
python_files = tests.py test_*.py *_tests.py
|
python_files = tests.py test_*.py *_tests.py
|
||||||
junit_family = xunit2
|
junit_family = xunit2
|
||||||
addopts = -p no:celery --junitxml=unittest.xml
|
addopts = -p no:celery --junitxml=unittest.xml
|
||||||
|
|
Reference in New Issue