Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix allauth reset password bug #276

Merged
merged 2 commits into from
Jul 2, 2021
Merged

Conversation

LanceMoe
Copy link
Contributor

No description provided.

@LanceMoe
Copy link
Contributor Author

When the project uses allauth, the reset password email will generate an incorrect token(because allauth use it self token_generator), which prevents the user from resetting the password.

This is a serious problem, please merge as soon as possible. Thanks!

@LanceMoe LanceMoe mentioned this pull request Jun 30, 2021
@LanceMoe
Copy link
Contributor Author

And, I provide a temporary workaround:

from dj_rest_auth.serializers import \
    PasswordResetSerializer as DefaultPasswordResetSerializer

...

class PasswordResetSerializer(DefaultPasswordResetSerializer):
    '''Workaround'''

    def save(self):
        if 'allauth' in settings.INSTALLED_APPS:
            from allauth.account.forms import default_token_generator
        else:
            from django.contrib.auth.tokens import default_token_generator
        request = self.context.get('request')
        # Set some values to trigger the send_email method.
        opts = {
            'use_https': request.is_secure(),
            'from_email': getattr(settings, 'DEFAULT_FROM_EMAIL'),
            'request': request,
            'token_generator': default_token_generator,
        }

        opts.update(self.get_email_options())
        self.reset_form.save(**opts)

Then add in settings.py:

REST_AUTH_SERIALIZERS = {
    ...
    # workaround
    'PASSWORD_RESET_SERIALIZER': 'ucenter.serializers.PasswordResetSerializer',
    ...
}

@LanceMoe
Copy link
Contributor Author

LanceMoe commented Jul 1, 2021

I found another problem. Because allauth uses base36 to encrypt uid, but django uses base64 by default, it will prompt Invalid value when resetting the password. This problem can be solved by using the commit I just submitted.

Fix allauth verify url not match

Fix unit test: test_password_reset_with_invalid_email
@iMerica iMerica merged commit 82bd8b1 into iMerica:master Jul 2, 2021
@iMerica
Copy link
Owner

iMerica commented Jul 10, 2021

This change is in the latest release
https://pypi.org/project/dj-rest-auth/

@steverecio
Copy link
Contributor

Which version of allauth was this tested against? Running dj-rest-auth==2.1.9 and django-allauth==0.45.0 gives me the following error on this line:

django.urls.exceptions.NoReverseMatch: Reverse for 'password_reset_confirm' not found. 'password_reset_confirm' is not a valid view function or pattern name.

@LanceMoe
Copy link
Contributor Author

Which version of allauth was this tested against? Running dj-rest-auth==2.1.9 and django-allauth==0.45.0 gives me the following error on this line:

django.urls.exceptions.NoReverseMatch: Reverse for 'password_reset_confirm' not found. 'password_reset_confirm' is not a valid view function or pattern name.

Please see faq no.2 first: https://dj-rest-auth.readthedocs.io/en/latest/faq.html

@psacawa
Copy link

psacawa commented Jul 27, 2021

This is broken, at least in the demo project. When I try to reset a password in the demo, I get the follow stacktrace

Internal Server Error: /dj-rest-auth/password/reset/
Traceback (most recent call last):
  File "/home/psacawa/.pyenv/versions/garbage/lib/python3.9/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/home/psacawa/.pyenv/versions/garbage/lib/python3.9/site-packages/django/core/handlers/base.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/home/psacawa/.pyenv/versions/garbage/lib/python3.9/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/home/psacawa/.pyenv/versions/garbage/lib/python3.9/site-packages/django/views/generic/base.py", line 70, in view
    return self.dispatch(request, *args, **kwargs)
  File "/home/psacawa/.pyenv/versions/garbage/lib/python3.9/site-packages/rest_framework/views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "/home/psacawa/.pyenv/versions/garbage/lib/python3.9/site-packages/rest_framework/views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/home/psacawa/.pyenv/versions/garbage/lib/python3.9/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception
    raise exc
  File "/home/psacawa/.pyenv/versions/garbage/lib/python3.9/site-packages/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "/home/psacawa/.pyenv/versions/garbage/lib/python3.9/site-packages/dj_rest_auth/views.py", line 250, in post
    serializer.save()
  File "/home/psacawa/.pyenv/versions/garbage/lib/python3.9/site-packages/dj_rest_auth/serializers.py", line 257, in save
    self.reset_form.save(**opts)
  File "/home/psacawa/.pyenv/versions/garbage/lib/python3.9/site-packages/dj_rest_auth/forms.py", line 42, in save
    path = reverse(
  File "/home/psacawa/.pyenv/versions/garbage/lib/python3.9/site-packages/django/urls/base.py", line 86, in reverse
    return resolver._reverse_with_prefix(view, prefix, *args, **kwargs)
  File "/home/psacawa/.pyenv/versions/garbage/lib/python3.9/site-packages/django/urls/resolvers.py", line 694, in _reverse_with_prefix
    raise NoReverseMatch(msg)
django.urls.exceptions.NoReverseMatch: Reverse for 'password_reset_confirm' with arguments '('1', 'aqgote-811cbd70336d82d5c64fc32276480a1d')' not found. 1 pattern(s) tried: ['password-reset/confirm/(?P<uidb64>[0-9A-Za-z_\\-]+)/(?P<token>[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$']
[27/Jul/2021 20:27:14] "POST /dj-rest-auth/password/reset/ HTTP/1.1" 500 135469

The same when I implement the instuction of the FAQ in my own project

@psacawa
Copy link

psacawa commented Jul 27, 2021

Indeed the generated reset token has a form like aqgql8-43444d5efff4898b06c1938a01fd8d9d. The second part has 32 characters length, while the demo project which the FAQ referes to use a regex that matches up to 20 chars.

psacawa pushed a commit to psacawa/dj-rest-auth that referenced this pull request Jul 27, 2021
This causes
```
path = reverse(
        'password_reset_confirm',
        args=[user_pk_to_url_str(user), temp_key],
)
```
in  `AllAuthPasswordResetForm` to fail and return `django.urls.exceptions.NoReverseMatch`.
See: iMerica#276 (comment)
iMerica pushed a commit that referenced this pull request Jul 31, 2021
This causes
```
path = reverse(
        'password_reset_confirm',
        args=[user_pk_to_url_str(user), temp_key],
)
```
in  `AllAuthPasswordResetForm` to fail and return `django.urls.exceptions.NoReverseMatch`.
See: #276 (comment)
onlinehub0808 added a commit to onlinehub0808/dj_rest_auth that referenced this pull request Jan 30, 2023
This causes
```
path = reverse(
        'password_reset_confirm',
        args=[user_pk_to_url_str(user), temp_key],
)
```
in  `AllAuthPasswordResetForm` to fail and return `django.urls.exceptions.NoReverseMatch`.
See: iMerica/dj-rest-auth#276 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants