mirror of
https://github.com/django/django.git
synced 2025-03-16 12:20:46 +00:00
147 lines
5.6 KiB
Python
147 lines
5.6 KiB
Python
from unittest import mock
|
|
|
|
from django.template import TemplateDoesNotExist
|
|
from django.test import Client, RequestFactory, SimpleTestCase, override_settings
|
|
from django.utils.translation import override
|
|
from django.views.csrf import CSRF_FAILURE_TEMPLATE_NAME, csrf_failure
|
|
|
|
|
|
@override_settings(ROOT_URLCONF="view_tests.urls")
|
|
class CsrfViewTests(SimpleTestCase):
|
|
def setUp(self):
|
|
super().setUp()
|
|
self.client = Client(enforce_csrf_checks=True)
|
|
|
|
@override_settings(
|
|
USE_I18N=True,
|
|
MIDDLEWARE=[
|
|
"django.middleware.locale.LocaleMiddleware",
|
|
"django.middleware.common.CommonMiddleware",
|
|
"django.middleware.csrf.CsrfViewMiddleware",
|
|
],
|
|
)
|
|
def test_translation(self):
|
|
"""An invalid request is rejected with a localized error message."""
|
|
response = self.client.post("/")
|
|
self.assertContains(response, "Forbidden", status_code=403)
|
|
self.assertContains(
|
|
response, "CSRF verification failed. Request aborted.", status_code=403
|
|
)
|
|
|
|
with self.settings(LANGUAGE_CODE="nl"), override("en-us"):
|
|
response = self.client.post("/")
|
|
self.assertContains(response, "Verboden", status_code=403)
|
|
self.assertContains(
|
|
response,
|
|
"CSRF-verificatie mislukt. Verzoek afgebroken.",
|
|
status_code=403,
|
|
)
|
|
|
|
@override_settings(SECURE_PROXY_SSL_HEADER=("HTTP_X_FORWARDED_PROTO", "https"))
|
|
def test_no_referer(self):
|
|
"""
|
|
Referer header is strictly checked for POST over HTTPS. Trigger the
|
|
exception by sending an incorrect referer.
|
|
"""
|
|
response = self.client.post("/", headers={"x-forwarded-proto": "https"})
|
|
self.assertContains(
|
|
response,
|
|
"You are seeing this message because this HTTPS site requires a "
|
|
"“Referer header” to be sent by your web browser, but "
|
|
"none was sent.",
|
|
status_code=403,
|
|
)
|
|
self.assertContains(
|
|
response,
|
|
"If you have configured your browser to disable “Referer” "
|
|
"headers, please re-enable them, at least for this site, or for "
|
|
"HTTPS connections, or for “same-origin” requests.",
|
|
status_code=403,
|
|
)
|
|
self.assertContains(
|
|
response,
|
|
"If you are using the <meta name="referrer" "
|
|
"content="no-referrer"> tag or including the "
|
|
"“Referrer-Policy: no-referrer” header, please remove them.",
|
|
status_code=403,
|
|
)
|
|
|
|
def test_no_cookies(self):
|
|
"""
|
|
The CSRF cookie is checked for POST. Failure to send this cookie should
|
|
provide a nice error message.
|
|
"""
|
|
response = self.client.post("/")
|
|
self.assertContains(
|
|
response,
|
|
"You are seeing this message because this site requires a CSRF "
|
|
"cookie when submitting forms. This cookie is required for "
|
|
"security reasons, to ensure that your browser is not being "
|
|
"hijacked by third parties.",
|
|
status_code=403,
|
|
)
|
|
|
|
@override_settings(TEMPLATES=[])
|
|
def test_no_django_template_engine(self):
|
|
"""
|
|
The CSRF view doesn't depend on the TEMPLATES configuration (#24388).
|
|
"""
|
|
response = self.client.post("/")
|
|
self.assertContains(response, "Forbidden", status_code=403)
|
|
|
|
@override_settings(
|
|
TEMPLATES=[
|
|
{
|
|
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
|
"OPTIONS": {
|
|
"loaders": [
|
|
(
|
|
"django.template.loaders.locmem.Loader",
|
|
{
|
|
CSRF_FAILURE_TEMPLATE_NAME: (
|
|
"Test template for CSRF failure"
|
|
)
|
|
},
|
|
),
|
|
],
|
|
},
|
|
}
|
|
]
|
|
)
|
|
def test_custom_template(self):
|
|
"""A custom CSRF_FAILURE_TEMPLATE_NAME is used."""
|
|
response = self.client.post("/")
|
|
self.assertContains(response, "Test template for CSRF failure", status_code=403)
|
|
self.assertIs(response.wsgi_request, response.context.request)
|
|
|
|
def test_custom_template_does_not_exist(self):
|
|
"""An exception is raised if a nonexistent template is supplied."""
|
|
factory = RequestFactory()
|
|
request = factory.post("/")
|
|
with self.assertRaises(TemplateDoesNotExist):
|
|
csrf_failure(request, template_name="nonexistent.html")
|
|
|
|
def test_template_encoding(self):
|
|
"""
|
|
The template is loaded directly, not via a template loader, and should
|
|
be opened as utf-8 charset as is the default specified on template
|
|
engines.
|
|
"""
|
|
from django.views.csrf import Path
|
|
|
|
with mock.patch.object(Path, "open") as m:
|
|
csrf_failure(mock.MagicMock(), mock.Mock())
|
|
m.assert_called_once_with(encoding="utf-8")
|
|
|
|
@override_settings(DEBUG=True)
|
|
@mock.patch("django.views.csrf.get_docs_version", return_value="4.2")
|
|
def test_doc_links(self, mocked_get_complete_version):
|
|
response = self.client.post("/")
|
|
self.assertContains(response, "Forbidden", status_code=403)
|
|
self.assertNotContains(
|
|
response, "https://docs.djangoproject.com/en/dev/", status_code=403
|
|
)
|
|
self.assertContains(
|
|
response, "https://docs.djangoproject.com/en/4.2/", status_code=403
|
|
)
|