"""passbook password factor signals""" from django.dispatch import receiver from passbook.core.signals import password_changed from passbook.factors.password.exceptions import PasswordPolicyInvalid @receiver(password_changed) def password_policy_checker(sender, password, **_): """Run password through all password policies which are applied to the user""" from passbook.factors.password.models import PasswordFactor from passbook.policies.engine import PolicyEngine setattr(sender, "__password__", password) _all_factors = PasswordFactor.objects.filter(enabled=True).order_by("order") for factor in _all_factors: policy_engine = PolicyEngine( factor.password_policies.all().select_subclasses(), sender ) policy_engine.build() passing, messages = policy_engine.result if not passing: raise PasswordPolicyInvalid(*messages)