switch to PolicyEngine everywhere

This commit is contained in:
Jens Langhammer 2019-02-27 15:49:20 +01:00
parent 2ce6f5a714
commit 5584f5bda8
4 changed files with 13 additions and 16 deletions

View file

@ -8,6 +8,7 @@ from django.utils.http import urlencode
from django.views.generic import View from django.views.generic import View
from passbook.core.models import Factor, User from passbook.core.models import Factor, User
from passbook.core.policies import PolicyEngine
from passbook.core.views.utils import PermissionDeniedView from passbook.core.views.utils import PermissionDeniedView
from passbook.lib.utils.reflection import class_to_path, path_to_class from passbook.lib.utils.reflection import class_to_path, path_to_class
from passbook.lib.utils.urls import is_url_absolute from passbook.lib.utils.urls import is_url_absolute
@ -63,7 +64,9 @@ class AuthenticationView(UserPassesTestMixin, View):
_all_factors = Factor.objects.filter(enabled=True).order_by('order').select_subclasses() _all_factors = Factor.objects.filter(enabled=True).order_by('order').select_subclasses()
self.pending_factors = [] self.pending_factors = []
for factor in _all_factors: for factor in _all_factors:
if factor.passes(self.pending_user): policy_engine = PolicyEngine(factor.policies.all())
policy_engine.for_user(self.pending_user)
if policy_engine.result[0]:
self.pending_factors.append((factor.uuid.hex, factor.type)) self.pending_factors.append((factor.uuid.hex, factor.type))
# Read and instantiate factor from session # Read and instantiate factor from session
factor_uuid, factor_class = None, None factor_uuid, factor_class = None, None

View file

@ -73,14 +73,6 @@ class PolicyModel(UUIDModel, CreatedUpdatedModel):
policies = models.ManyToManyField('Policy', blank=True) policies = models.ManyToManyField('Policy', blank=True)
def passes(self, user: User) -> Union[bool, Tuple[bool, str]]:
"""Return False, str if a user fails where str is a
reasons shown to the user. Return True if user succeeds."""
for policy in self.policies.all():
if not policy.passes(user):
return False
return True
class Factor(PolicyModel): class Factor(PolicyModel):
"""Authentication factor, multiple instances of the same Factor can be used""" """Authentication factor, multiple instances of the same Factor can be used"""

View file

@ -19,9 +19,8 @@ def password_policy_checker(sender, password, **kwargs):
setattr(sender, '__password__', password) setattr(sender, '__password__', password)
_all_factors = PasswordFactor.objects.filter(enabled=True).order_by('order') _all_factors = PasswordFactor.objects.filter(enabled=True).order_by('order')
for factor in _all_factors: for factor in _all_factors:
if factor.passes(sender): policy_engine = PolicyEngine(factor.password_policies.all().select_subclasses())
policy_engine = PolicyEngine(factor.password_policies.all().select_subclasses()) policy_engine.for_user(sender)
policy_engine.for_user(sender) passing, messages = policy_engine.result
passing, messages = policy_engine.result if not passing:
if not passing: raise PasswordPolicyInvalid(*messages)
raise PasswordPolicyInvalid(*messages)

View file

@ -3,6 +3,7 @@
from django import template from django import template
from passbook.core.models import Factor from passbook.core.models import Factor
from passbook.core.policies import PolicyEngine
register = template.Library() register = template.Library()
@ -14,6 +15,8 @@ def user_factors(context):
matching_factors = [] matching_factors = []
for factor in _all_factors: for factor in _all_factors:
_link = factor.has_user_settings() _link = factor.has_user_settings()
if factor.passes(user) and _link: policy_engine = PolicyEngine(factor.policies.all())
policy_engine.for_user(user)
if policy_engine.result[0] and _link:
matching_factors.append(_link) matching_factors.append(_link)
return matching_factors return matching_factors