2019-10-07 14:33:48 +00:00
|
|
|
"""user field matcher models"""
|
|
|
|
import re
|
|
|
|
|
|
|
|
from django.db import models
|
|
|
|
from django.utils.translation import gettext as _
|
|
|
|
from structlog import get_logger
|
|
|
|
|
2020-05-16 14:02:42 +00:00
|
|
|
from passbook.core.models import Policy
|
2020-02-20 12:52:05 +00:00
|
|
|
from passbook.policies.types import PolicyRequest, PolicyResult
|
2019-10-07 14:33:48 +00:00
|
|
|
|
|
|
|
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()
|
|
|
|
|
2019-12-31 11:51:16 +00:00
|
|
|
form = "passbook.policies.password.forms.PasswordPolicyForm"
|
2019-10-07 14:33:48 +00:00
|
|
|
|
|
|
|
def passes(self, request: PolicyRequest) -> PolicyResult:
|
|
|
|
# Only check if password is being set
|
2019-12-31 11:51:16 +00:00
|
|
|
if not hasattr(request.user, "__password__"):
|
2019-10-07 14:33:48 +00:00
|
|
|
return PolicyResult(True)
|
2019-12-31 11:51:16 +00:00
|
|
|
password = getattr(request.user, "__password__")
|
2019-10-07 14:33:48 +00:00
|
|
|
|
2019-12-31 11:51:16 +00:00
|
|
|
filter_regex = r""
|
2019-10-07 14:33:48 +00:00
|
|
|
if self.amount_lowercase > 0:
|
2019-12-31 11:51:16 +00:00
|
|
|
filter_regex += r"[a-z]{%d,}" % self.amount_lowercase
|
2019-10-07 14:33:48 +00:00
|
|
|
if self.amount_uppercase > 0:
|
2019-12-31 11:51:16 +00:00
|
|
|
filter_regex += r"[A-Z]{%d,}" % self.amount_uppercase
|
2019-10-07 14:33:48 +00:00
|
|
|
if self.amount_symbols > 0:
|
2019-12-31 11:51:16 +00:00
|
|
|
filter_regex += r"[%s]{%d,}" % (self.symbol_charset, self.amount_symbols)
|
2019-10-07 14:33:48 +00:00
|
|
|
result = bool(re.compile(filter_regex).match(password))
|
|
|
|
if not result:
|
|
|
|
return PolicyResult(result, self.error_message)
|
|
|
|
return PolicyResult(result)
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
2019-12-31 11:51:16 +00:00
|
|
|
verbose_name = _("Password Policy")
|
|
|
|
verbose_name_plural = _("Password Policies")
|