Refs #32508 -- Raised ImproperlyConfigured/TypeError instead of using "assert" in various code.
This commit is contained in:
parent
64839512a6
commit
8a7ac78b70
|
@ -12,7 +12,7 @@ from django.contrib.auth.forms import (
|
||||||
)
|
)
|
||||||
from django.contrib.auth.tokens import default_token_generator
|
from django.contrib.auth.tokens import default_token_generator
|
||||||
from django.contrib.sites.shortcuts import get_current_site
|
from django.contrib.sites.shortcuts import get_current_site
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ImproperlyConfigured, ValidationError
|
||||||
from django.http import HttpResponseRedirect, QueryDict
|
from django.http import HttpResponseRedirect, QueryDict
|
||||||
from django.shortcuts import resolve_url
|
from django.shortcuts import resolve_url
|
||||||
from django.urls import reverse_lazy
|
from django.urls import reverse_lazy
|
||||||
|
@ -261,7 +261,10 @@ class PasswordResetConfirmView(PasswordContextMixin, FormView):
|
||||||
@method_decorator(sensitive_post_parameters())
|
@method_decorator(sensitive_post_parameters())
|
||||||
@method_decorator(never_cache)
|
@method_decorator(never_cache)
|
||||||
def dispatch(self, *args, **kwargs):
|
def dispatch(self, *args, **kwargs):
|
||||||
assert 'uidb64' in kwargs and 'token' in kwargs
|
if 'uidb64' not in kwargs or 'token' not in kwargs:
|
||||||
|
raise ImproperlyConfigured(
|
||||||
|
"The URL path must contain 'uidb64' and 'token' parameters."
|
||||||
|
)
|
||||||
|
|
||||||
self.validlink = False
|
self.validlink = False
|
||||||
self.user = self.get_user(kwargs['uidb64'])
|
self.user = self.get_user(kwargs['uidb64'])
|
||||||
|
|
|
@ -80,8 +80,8 @@ class Signal:
|
||||||
|
|
||||||
# If DEBUG is on, check that we got a good receiver
|
# If DEBUG is on, check that we got a good receiver
|
||||||
if settings.configured and settings.DEBUG:
|
if settings.configured and settings.DEBUG:
|
||||||
assert callable(receiver), "Signal receivers must be callable."
|
if not callable(receiver):
|
||||||
|
raise TypeError('Signal receivers must be callable.')
|
||||||
# Check for **kwargs
|
# Check for **kwargs
|
||||||
if not func_accepts_kwargs(receiver):
|
if not func_accepts_kwargs(receiver):
|
||||||
raise ValueError("Signal receivers must accept keyword arguments (**kwargs).")
|
raise ValueError("Signal receivers must accept keyword arguments (**kwargs).")
|
||||||
|
|
|
@ -77,11 +77,12 @@ def sensitive_post_parameters(*parameters):
|
||||||
def decorator(view):
|
def decorator(view):
|
||||||
@functools.wraps(view)
|
@functools.wraps(view)
|
||||||
def sensitive_post_parameters_wrapper(request, *args, **kwargs):
|
def sensitive_post_parameters_wrapper(request, *args, **kwargs):
|
||||||
assert isinstance(request, HttpRequest), (
|
if not isinstance(request, HttpRequest):
|
||||||
"sensitive_post_parameters didn't receive an HttpRequest. "
|
raise TypeError(
|
||||||
"If you are decorating a classmethod, be sure to use "
|
"sensitive_post_parameters didn't receive an HttpRequest "
|
||||||
"@method_decorator."
|
"object. If you are decorating a classmethod, make sure "
|
||||||
)
|
"to use @method_decorator."
|
||||||
|
)
|
||||||
if parameters:
|
if parameters:
|
||||||
request.sensitive_post_parameters = parameters
|
request.sensitive_post_parameters = parameters
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -23,6 +23,7 @@ from django.contrib.contenttypes.models import ContentType
|
||||||
from django.contrib.sessions.middleware import SessionMiddleware
|
from django.contrib.sessions.middleware import SessionMiddleware
|
||||||
from django.contrib.sites.requests import RequestSite
|
from django.contrib.sites.requests import RequestSite
|
||||||
from django.core import mail
|
from django.core import mail
|
||||||
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
from django.http import HttpRequest, HttpResponse
|
from django.http import HttpRequest, HttpResponse
|
||||||
from django.middleware.csrf import CsrfViewMiddleware, get_token
|
from django.middleware.csrf import CsrfViewMiddleware, get_token
|
||||||
|
@ -386,6 +387,11 @@ class PasswordResetTest(AuthViewsTestCase):
|
||||||
response = Client().get('/reset/%s/set-password/' % uuidb64)
|
response = Client().get('/reset/%s/set-password/' % uuidb64)
|
||||||
self.assertContains(response, 'The password reset link was invalid')
|
self.assertContains(response, 'The password reset link was invalid')
|
||||||
|
|
||||||
|
def test_missing_kwargs(self):
|
||||||
|
msg = "The URL path must contain 'uidb64' and 'token' parameters."
|
||||||
|
with self.assertRaisesMessage(ImproperlyConfigured, msg):
|
||||||
|
self.client.get('/reset/missing_parameters/')
|
||||||
|
|
||||||
|
|
||||||
@override_settings(AUTH_USER_MODEL='auth_tests.CustomUser')
|
@override_settings(AUTH_USER_MODEL='auth_tests.CustomUser')
|
||||||
class CustomUserPasswordResetTest(AuthViewsTestCase):
|
class CustomUserPasswordResetTest(AuthViewsTestCase):
|
||||||
|
|
|
@ -133,6 +133,7 @@ urlpatterns = auth_urlpatterns + [
|
||||||
post_reset_login_backend='django.contrib.auth.backends.AllowAllUsersModelBackend',
|
post_reset_login_backend='django.contrib.auth.backends.AllowAllUsersModelBackend',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
path('reset/missing_parameters/', views.PasswordResetConfirmView.as_view()),
|
||||||
path('password_change/custom/',
|
path('password_change/custom/',
|
||||||
views.PasswordChangeView.as_view(success_url='/custom/')),
|
views.PasswordChangeView.as_view(success_url='/custom/')),
|
||||||
path('password_change/custom/named/',
|
path('password_change/custom/named/',
|
||||||
|
|
|
@ -58,7 +58,7 @@ class DispatcherTests(SimpleTestCase):
|
||||||
@override_settings(DEBUG=True)
|
@override_settings(DEBUG=True)
|
||||||
def test_cannot_connect_non_callable(self):
|
def test_cannot_connect_non_callable(self):
|
||||||
msg = 'Signal receivers must be callable.'
|
msg = 'Signal receivers must be callable.'
|
||||||
with self.assertRaisesMessage(AssertionError, msg):
|
with self.assertRaisesMessage(TypeError, msg):
|
||||||
a_signal.connect(object())
|
a_signal.connect(object())
|
||||||
self.assertTestIsClean(a_signal)
|
self.assertTestIsClean(a_signal)
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ from unittest import mock
|
||||||
from django.core import mail
|
from django.core import mail
|
||||||
from django.core.files.uploadedfile import SimpleUploadedFile
|
from django.core.files.uploadedfile import SimpleUploadedFile
|
||||||
from django.db import DatabaseError, connection
|
from django.db import DatabaseError, connection
|
||||||
from django.http import Http404
|
from django.http import Http404, HttpRequest, HttpResponse
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
from django.template import TemplateDoesNotExist
|
from django.template import TemplateDoesNotExist
|
||||||
from django.test import RequestFactory, SimpleTestCase, override_settings
|
from django.test import RequestFactory, SimpleTestCase, override_settings
|
||||||
|
@ -1635,3 +1635,17 @@ class DecoratorsTests(SimpleTestCase):
|
||||||
@sensitive_post_parameters
|
@sensitive_post_parameters
|
||||||
def test_func(request):
|
def test_func(request):
|
||||||
return index_page(request)
|
return index_page(request)
|
||||||
|
|
||||||
|
def test_sensitive_post_parameters_http_request(self):
|
||||||
|
class MyClass:
|
||||||
|
@sensitive_post_parameters()
|
||||||
|
def a_view(self, request):
|
||||||
|
return HttpResponse()
|
||||||
|
|
||||||
|
msg = (
|
||||||
|
"sensitive_post_parameters didn't receive an HttpRequest object. "
|
||||||
|
"If you are decorating a classmethod, make sure to use "
|
||||||
|
"@method_decorator."
|
||||||
|
)
|
||||||
|
with self.assertRaisesMessage(TypeError, msg):
|
||||||
|
MyClass().a_view(HttpRequest())
|
||||||
|
|
Loading…
Reference in New Issue