sunscrapers / djoser

REST implementation of Django authentication system.
MIT License
2.55k stars 458 forks source link

User create Django password validators problem #539

Open ghost opened 4 years ago

ghost commented 4 years ago

Hey guys, awesome work on djoser!

I encountered an error in django==3.0.9 + djoser==2.0.3.

Django MinimumLengthValidator throws the following error (applicable to other Django validators as well):

Server Error: /v1/auth/users/
django_1         | Traceback (most recent call last):
django_1         |   File "/pyroot/lib/python3.8/site-packages/djoser/serializers.py", line 54, in validate
django_1         |     validate_password(password, user)
django_1         |   File "/pyroot/lib/python3.8/site-packages/django/contrib/auth/password_validation.py", line 51, in validate_password
django_1         |     raise ValidationError(errors)
django_1         | django.core.exceptions.ValidationError: ['This password is too short. It must contain at least 8 characters.']
django_1         | 
django_1         | During handling of the above exception, another exception occurred:
django_1         | 
django_1         | Traceback (most recent call last):
django_1         |   File "/pyroot/lib/python3.8/site-packages/django/core/handlers/exception.py", line 34, in inner
django_1         |     response = get_response(request)
django_1         |   File "/pyroot/lib/python3.8/site-packages/django/core/handlers/base.py", line 115, in _get_response
django_1         |     response = self.process_exception_by_middleware(e, request)
django_1         |   File "/pyroot/lib/python3.8/site-packages/django/core/handlers/base.py", line 113, in _get_response
django_1         |     response = wrapped_callback(request, *callback_args, **callback_kwargs)
django_1         |   File "/pyroot/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
django_1         |     return view_func(*args, **kwargs)
django_1         |   File "/pyroot/lib/python3.8/site-packages/rest_framework/viewsets.py", line 114, in view
django_1         |     return self.dispatch(request, *args, **kwargs)
django_1         |   File "/pyroot/lib/python3.8/site-packages/rest_framework/views.py", line 505, in dispatch
django_1         |     response = self.handle_exception(exc)
django_1         |   File "/pyroot/lib/python3.8/site-packages/rest_framework/views.py", line 465, in handle_exception
django_1         |     self.raise_uncaught_exception(exc)
django_1         |   File "/pyroot/lib/python3.8/site-packages/rest_framework/views.py", line 476, in raise_uncaught_exception
django_1         |     raise exc
django_1         |   File "/pyroot/lib/python3.8/site-packages/rest_framework/views.py", line 502, in dispatch
django_1         |     response = handler(request, *args, **kwargs)
django_1         |   File "/pyroot/lib/python3.8/site-packages/rest_framework/mixins.py", line 18, in create
django_1         |     serializer.is_valid(raise_exception=True)
django_1         |   File "/pyroot/lib/python3.8/site-packages/rest_framework/serializers.py", line 234, in is_valid
django_1         |     self._validated_data = self.run_validation(self.initial_data)
django_1         |   File "/pyroot/lib/python3.8/site-packages/rest_framework/serializers.py", line 436, in run_validation
django_1         |     value = self.validate(value)
django_1         |   File "/pyroot/lib/python3.8/site-packages/djoser/serializers.py", line 58, in validate
django_1         |     {"password": serializer_error["non_field_errors"]}
django_1         | KeyError: 'non_field_errors'

One way to go around this for now is:

# common.password_validation.py

from django.contrib.auth import password_validation as pv
from django.core.exceptions import ValidationError as DjangoValidationError

class MinimumLengthValidator(pv.MinimumLengthValidator):
    def validate(self, password, user=None):
        try:
            super().validate(password, user)
        except DjangoValidationError as cause:
            raise ValidationError(
                detail=cause.messages[0] % {"min_length": cause.params["min_length"]},
            )
ghost commented 4 years ago

We found out that the error was due to the NON_FIELD_ERRORS_KEY setting in our settings.py file. This is still an error, because this should be handled in some way 😅.

DBlek commented 3 years ago

Is this going to be fixed? I have run into the same problem now in my app

EDIT: just noticed that this was created by a deleted user - @zefciu so sb can look into this and he is acquaintance of mine?

roshanabdullah commented 2 years ago

so what is the alternative of using NON_FIELD_ERRORS_KEY???