[Django] #36015: Separate the validation process of password validators.

8 views
Skip to first unread message

Django

unread,
Dec 16, 2024, 4:03:05 AM12/16/24
to django-...@googlegroups.com
#36015: Separate the validation process of password validators.
-------------------------------------+-------------------------------------
Reporter: Antoliny | Type: New
| feature
Status: new | Component:
| contrib.auth
Version: 5.1 | Severity: Normal
Keywords: password validators | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Currently, password validators serve the same role as Django's standard
validators but are categorized separately.
The reason for this, in my opinion, is that password validators receive
the user instance when performing validation.
Therefore, the validation process of password validators is actually
called during the Form's `_post_clean` stage when it is invoked.
{{{
class SetPasswordMixin:
...
def validate_password_for_user(self, user,
password_field_name="password2"):
password = self.cleaned_data.get(password_field_name)
if password:
try:
password_validation.validate_password(password, user) #
run password validation
except ValidationError as error:
self.add_error(password_field_name, error)
}}}
I think that among the password validators provided by Django, the only
validator that requires an instance during the validation process is
`UserAttributeSimilarityValidator`. The other validators can be fully
integrated into standard validators and should be provided as customized
versions of standard validators.
Integrating the password validator into the standard validator will
improve consistency([https://code.djangoproject.com/ticket/35693 #35693])
and enhance reusability.

e.g.)
`CharField(..., validators=[MinimumLengthValidator()])`
Although it can be used as shown below, it would be better for consistency
if it could be called through `__call__`, making it more user friendly.
`CharField(..., validators=[MinimumLengthValidator().validate])`

**pre validation(Validated through `is_valid()`.)**
* MinimumLengthValidator
* CommonPasswordValidator
* NumericPasswordValidator

**post validation(Validated through
`password_validation.validate_password()`.)**
* UserAttributeSimilarityValidator

If integrated into the standard validator, the integrated validator will
perform validation through is_valid, while validators that require an
instance and cannot be integrated will be handled in the existing
validation step, the `_post_clean` method.
Therefore, it is necessary to distinguish the validators that will perform
the validation in the validate_password function where the password
validators are executed.
{{{
def validate_password(password, user=None, password_validators=None):
"""
Validate that the password meets all validator requirements.

If the password is valid, return ``None``.
If the password is invalid, raise ValidationError with all error
messages.
"""
errors = []
if password_validators is None:
password_validators = get_default_password_validators()
for validator in password_validators:
try:
validator.validate(password, user) # -> Perform validation
only for post password validators.
except ValidationError as error:
errors.append(error)
if errors:
raise ValidationError(errors)
}}}
-----------------
**Conclusion**

It would be beneficial to integrate password validators that do not
require an instance into a customized form of the standard validator,
allowing validation to be performed through the `is_valid` call, while
validators that require an instance continue to be called in the existing
way.
--
Ticket URL: <https://code.djangoproject.com/ticket/36015>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Dec 16, 2024, 4:03:15 AM12/16/24
to django-...@googlegroups.com
#36015: Separate the validation process of password validators.
-------------------------------------+-------------------------------------
Reporter: Antoliny | Owner: Antoliny
Type: New feature | Status: assigned
Component: contrib.auth | Version: 5.1
Severity: Normal | Resolution:
Keywords: password validators | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Antoliny):

* owner: (none) => Antoliny
* status: new => assigned

--
Ticket URL: <https://code.djangoproject.com/ticket/36015#comment:1>

Django

unread,
Dec 16, 2024, 4:09:07 AM12/16/24
to django-...@googlegroups.com
#36015: Separate the validation process of password validators.
-------------------------------------+-------------------------------------
Reporter: Antoliny | Owner: Antoliny
Type: New feature | Status: assigned
Component: contrib.auth | Version: 5.1
Severity: Normal | Resolution:
Keywords: password validators | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by Antoliny:

Old description:
New description:
It would be good to integrate password validators that do not require an
instance into a customized form of the standard validator, allowing
validation to be performed through the `is_valid` call, while validators
that require an instance continue to be called in the existing way.

--
--
Ticket URL: <https://code.djangoproject.com/ticket/36015#comment:2>

Django

unread,
Dec 16, 2024, 4:10:46 AM12/16/24
to django-...@googlegroups.com
My thought is that it would be better to integrate password validators
that do not require an instance into a customized form of the standard
validator, allowing them to be validated through is_valid, while
validators that require an instance should continue to be called in the
existing way.

--
--
Ticket URL: <https://code.djangoproject.com/ticket/36015#comment:3>

Django

unread,
Dec 18, 2024, 7:34:40 AM12/18/24
to django-...@googlegroups.com
#36015: Separate the validation process of password validators.
-------------------------------------+-------------------------------------
Reporter: Antoliny | Owner: Antoliny
Type: New feature | Status: closed
Component: contrib.auth | Version: 5.1
Severity: Normal | Resolution: wontfix
Keywords: password validators | Triage Stage:
| Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Sarah Boyce):

* resolution: => wontfix
* status: assigned => closed

Comment:

For others, this is a forum discussion which touched on this topic:
https://forum.djangoproject.com/t/improving-consistency-between-field-
validators-and-password-validators/37040/7

I like the direction this is going and I agree with what you're saying

The main question mark I have is what would that mean for the setting
`AUTH_PASSWORD_VALIDATORS` (which has no split between ones that need a
user and do not need a user).
Bare in mind folks can have written their own password validators which
would need migrating to a new format.

I think:
- what would be the end state
- how could folks customize it
- what would be the migration path

This has been around so long and might include breaking changes, so I even
tempted for this to consider a DEP or certainly needs more input than what
we have right now.
--
Ticket URL: <https://code.djangoproject.com/ticket/36015#comment:4>
Reply all
Reply to author
Forward
0 new messages