[2.0.x] Fixed #29206 -- Fixed PasswordResetConfirmView crash when the URL contains a non-UUID where one is expected.

Backport of aeb8c38178 from master
This commit is contained in:
Mattia Procopio 2018-03-14 10:36:22 +01:00 committed by Tim Graham
parent 9bf8664bfd
commit 72667bc6ee
4 changed files with 16 additions and 1 deletions

View File

@ -544,6 +544,7 @@ answer newbie questions, and generally made Django that much better:
Matt Riggott
Matt Robenolt <m@robenolt.com>
Mattia Larentis <mattia@laretis.eu>
Mattia Procopio <promat85@gmail.com>
Mattias Loverot <mattias@stubin.se>
mattycakes@gmail.com
Max Burstein <http://maxburstein.com>

View File

@ -13,6 +13,7 @@ from django.contrib.auth.forms import (
)
from django.contrib.auth.tokens import default_token_generator
from django.contrib.sites.shortcuts import get_current_site
from django.core.exceptions import ValidationError
from django.http import HttpResponseRedirect, QueryDict
from django.shortcuts import resolve_url
from django.template.response import TemplateResponse
@ -472,7 +473,7 @@ class PasswordResetConfirmView(PasswordContextMixin, FormView):
# urlsafe_base64_decode() decodes to bytestring
uid = urlsafe_base64_decode(uidb64).decode()
user = UserModel._default_manager.get(pk=uid)
except (TypeError, ValueError, OverflowError, UserModel.DoesNotExist):
except (TypeError, ValueError, OverflowError, UserModel.DoesNotExist, ValidationError):
user = None
return user

View File

@ -17,3 +17,7 @@ Bugfixes
* Corrected admin's autocomplete widget to add a space after custom classes
(:ticket:`29221`).
* Fixed ``PasswordResetConfirmView`` crash when using a user model with a
``UUIDField`` primary key and the reset URL contains an encoded primary key
value that decodes to a non-UUID (:ticket:`29206`).

View File

@ -30,6 +30,7 @@ from django.test.utils import patch_logger
from django.urls import NoReverseMatch, reverse, reverse_lazy
from django.utils.deprecation import RemovedInDjango21Warning
from django.utils.encoding import force_text
from django.utils.http import urlsafe_base64_encode
from django.utils.translation import LANGUAGE_SESSION_KEY
from .client import PasswordResetConfirmClient
@ -439,6 +440,14 @@ class UUIDUserPasswordResetTest(CustomUserPasswordResetTest):
)
return super()._test_confirm_start()
def test_confirm_invalid_uuid(self):
"""A uidb64 that decodes to a non-UUID doesn't crash."""
_, path = self._test_confirm_start()
invalid_uidb64 = urlsafe_base64_encode('INVALID_UUID'.encode()).decode()
first, _uuidb64_, second = path.strip('/').split('/')
response = self.client.get('/' + '/'.join((first, invalid_uidb64, second)) + '/')
self.assertContains(response, 'The password reset link was invalid')
class ChangePasswordTest(AuthViewsTestCase):