Opened 2 days ago
Closed 9 minutes ago
#36015 closed New feature (wontfix)
Separate the validation process of password validators.
Reported by: | Antoliny | Owned by: | Antoliny |
---|---|---|---|
Component: | contrib.auth | Version: | 5.1 |
Severity: | Normal | Keywords: | password validators |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
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(#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
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.
Change History (4)
comment:1 by , 2 days ago
Owner: | set to |
---|---|
Status: | new → assigned |
comment:2 by , 2 days ago
Description: | modified (diff) |
---|
comment:3 by , 2 days ago
Description: | modified (diff) |
---|
comment:4 by , 9 minutes ago
Resolution: | → wontfix |
---|---|
Status: | assigned → closed |
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:
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.