"""user field matcher models""" import re from django.db import models from django.utils.translation import gettext as _ from structlog import get_logger from passbook.policies.models import Policy from passbook.policies.types import PolicyRequest, PolicyResult LOGGER = get_logger() class PasswordPolicy(Policy): """Policy to make sure passwords have certain properties""" amount_uppercase = models.IntegerField(default=0) amount_lowercase = models.IntegerField(default=0) amount_symbols = models.IntegerField(default=0) length_min = models.IntegerField(default=0) symbol_charset = models.TextField(default=r"!\"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ ") error_message = models.TextField() form = "passbook.policies.password.forms.PasswordPolicyForm" def passes(self, request: PolicyRequest) -> PolicyResult: # Only check if password is being set if not hasattr(request.user, "__password__"): return PolicyResult(True) password = getattr(request.user, "__password__") filter_regex = r"" if self.amount_lowercase > 0: filter_regex += r"[a-z]{%d,}" % self.amount_lowercase if self.amount_uppercase > 0: filter_regex += r"[A-Z]{%d,}" % self.amount_uppercase if self.amount_symbols > 0: filter_regex += r"[%s]{%d,}" % (self.symbol_charset, self.amount_symbols) result = bool(re.compile(filter_regex).match(password)) if not result: return PolicyResult(result, self.error_message) return PolicyResult(result) class Meta: verbose_name = _("Password Policy") verbose_name_plural = _("Password Policies")