"""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()) policy_engine.for_user(sender).build() passing, messages = policy_engine.result if not passing: raise PasswordPolicyInvalid(*messages)