Django Валидаторы паролей: если какие-либо из трех проверок пройдены, пользователь может go вперед - PullRequest
2 голосов
/ 28 апреля 2020

Я смотрю, как мы можем установить количество проверок, которые должны пройти, чтобы позволить пользователю установить пароль.

Например, у нас есть 5 валидаторов:

AUTH_PASSWORD_VALIDATORS = [
    {
       'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
       'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
       'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
       'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
    {  'NAME': 'registration.validators.CustomPasswordValidator',}
]

Мы хотим, чтобы пароль пользователя проходил по любому из 3 требований. Пользователи могут создать учетную запись. Любая идея, как мы можем сделать это в Django?

1 Ответ

2 голосов
/ 28 апреля 2020

Вы можете обернуть другие валидаторы в специальный валидатор:

# pw.py
class WrapPasswordValidator:
    def __init__(self, validators=None, num=3):
        self.validators = validators or []
        self.num = num

    def validate(self, password, user=None):
        errors, passed = [], 0
        for v in self.validators:
            try:
                v.validate(password, user)
            except ValidationError as e:
                errors.append(e)
            else:
                passed += 1
        if passed < self.num:
            errors.insert(0, ValidationError("Fix at least {} of the following errors:".format(
                self.num-passed)))
            raise ValidationError(errors)

    def get_help_text(self):
        text = ngettext(
            "Password must comply with at least %(num)d rule of:",
            "Password must comply with at least %(num)d rules of:",
            self.num
        ) % {'num': self.num}
        for v in self.validators:
            text += '<br>' + v.get_help_text()
        return mark_safe(text)

и использовать его в своих настройках:

AUTH_PASSWORD_VALIDATORS = [
    {
        "NAME": "pw.WrapPasswordValidator",
        "OPTIONS": {
            "num": 3,
            "validators": [
                UserAttributeSimilarityValidator(),
                MinimumLengthValidator(),
                CommonPasswordValidator(),
                NumericPasswordValidator(),
            ]
        }
    },
]
...