summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBouke Haarsma <bouke@webatoom.nl>2013-11-02 09:30:39 +0100
committerClaude Paroz <claude@2xlibre.net>2013-11-02 11:22:30 +0100
commit61074353864293d3ea51e51e09cf4deedee12963 (patch)
tree190b539659fe77a3d4700222ba0e703f0e90ab56
parent090315f5dfb9b0a6539daaec6cb88ad93e6e77af (diff)
Fixed #21324 -- Translate CSRF failure view
Thanks to Claude Paroz for the original patch.
-rw-r--r--django/middleware/csrf.py5
-rw-r--r--django/views/csrf.py45
-rw-r--r--tests/view_tests/locale/nl/LC_MESSAGES/django.mobin0 -> 515 bytes
-rw-r--r--tests/view_tests/locale/nl/LC_MESSAGES/django.po25
-rw-r--r--tests/view_tests/tests/test_csrf.py33
5 files changed, 89 insertions, 19 deletions
diff --git a/django/middleware/csrf.py b/django/middleware/csrf.py
index 1089153538..46b1891615 100644
--- a/django/middleware/csrf.py
+++ b/django/middleware/csrf.py
@@ -92,8 +92,7 @@ class CsrfViewMiddleware(object):
return None
def _reject(self, request, reason):
- logger.warning('Forbidden (%s): %s',
- reason, request.path,
+ logger.warning('Forbidden (%s): %s', reason, request.path,
extra={
'status_code': 403,
'request': request,
@@ -184,7 +183,7 @@ class CsrfViewMiddleware(object):
return response
# If CSRF_COOKIE is unset, then CsrfViewMiddleware.process_view was
- # never called, probaby because a request middleware returned a response
+ # never called, probably because a request middleware returned a response
# (for example, contrib.auth redirecting to a login page).
if request.META.get("CSRF_COOKIE") is None:
return response
diff --git a/django/views/csrf.py b/django/views/csrf.py
index c95d19d56d..f942917e4b 100644
--- a/django/views/csrf.py
+++ b/django/views/csrf.py
@@ -1,11 +1,16 @@
+from django.conf import settings
from django.http import HttpResponseForbidden
from django.template import Context, Template
-from django.conf import settings
+from django.utils.translation import ugettext as _
# We include the template inline since we need to be able to reliably display
# this error message, especially for the sake of developers, and there isn't any
# other way of making it available independent of what is in the settings file.
+# Only the text appearing with DEBUG=False is translated. Normal translation
+# tags cannot be used with this inline templates as makemessages would not be
+# able to discover the strings.
+
CSRF_FAILURE_TEMPLATE = """
<!DOCTYPE html>
<html lang="en">
@@ -30,17 +35,11 @@ CSRF_FAILURE_TEMPLATE = """
</head>
<body>
<div id="summary">
- <h1>Forbidden <span>(403)</span></h1>
- <p>CSRF verification failed. Request aborted.</p>
+ <h1>{{ title }} <span>(403)</span></h1>
+ <p>{{ main }}</p>
{% if no_referer %}
- <p>You are seeing this message because this HTTPS site requires a 'Referer
- header' to be sent by your Web browser, but none was sent. This header is
- required for security reasons, to ensure that your browser is not being
- hijacked by third parties.</p>
-
- <p>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.</p>
+ <p>{{ no_referer1 }}</p>
+ <p>{{ no_referer2 }}</p>
{% endif %}
</div>
{% if DEBUG %}
@@ -84,21 +83,35 @@ CSRF_FAILURE_TEMPLATE = """
</div>
{% else %}
<div id="explanation">
- <p><small>More information is available with DEBUG=True.</small></p>
+ <p><small>{{ more }}</small></p>
</div>
{% endif %}
</body>
</html>
"""
+
def csrf_failure(request, reason=""):
"""
Default view used when request fails CSRF protection
"""
from django.middleware.csrf import REASON_NO_REFERER
t = Template(CSRF_FAILURE_TEMPLATE)
- c = Context({'DEBUG': settings.DEBUG,
- 'reason': reason,
- 'no_referer': reason == REASON_NO_REFERER
- })
+ c = Context({
+ 'title': _("Forbidden"),
+ 'main': _("CSRF verification failed. Request aborted."),
+ 'reason': reason,
+ 'no_referer': reason == REASON_NO_REFERER,
+ 'no_referer1': _(
+ "You are seeing this message because this HTTPS site requires a "
+ "'Referer header' to be sent by your Web browser, but none was "
+ "sent. This header is required for security reasons, to ensure "
+ "that your browser is not being hijacked by third parties."),
+ 'no_referer2': _(
+ "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."),
+ 'DEBUG': settings.DEBUG,
+ 'more': _("More information is available with DEBUG=True."),
+ })
return HttpResponseForbidden(t.render(c), content_type='text/html')
diff --git a/tests/view_tests/locale/nl/LC_MESSAGES/django.mo b/tests/view_tests/locale/nl/LC_MESSAGES/django.mo
new file mode 100644
index 0000000000..90066d70ec
--- /dev/null
+++ b/tests/view_tests/locale/nl/LC_MESSAGES/django.mo
Binary files differ
diff --git a/tests/view_tests/locale/nl/LC_MESSAGES/django.po b/tests/view_tests/locale/nl/LC_MESSAGES/django.po
new file mode 100644
index 0000000000..e85f08ee80
--- /dev/null
+++ b/tests/view_tests/locale/nl/LC_MESSAGES/django.po
@@ -0,0 +1,25 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2007-09-15 19:15+0200\n"
+"PO-Revision-Date: 2010-05-12 12:41-0300\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: views/csrf.py:98
+msgid "Forbidden"
+msgstr "Verboden"
+
+#: views/csrf.py:99
+msgid "CSRF verification failed. Request aborted."
+msgstr "CSRF-verificatie mislukt. Verzoek afgebroken."
diff --git a/tests/view_tests/tests/test_csrf.py b/tests/view_tests/tests/test_csrf.py
new file mode 100644
index 0000000000..8e5c7f950a
--- /dev/null
+++ b/tests/view_tests/tests/test_csrf.py
@@ -0,0 +1,33 @@
+from django.test import TestCase, override_settings, Client
+from django.utils.translation import override
+
+
+class CsrfViewTests(TestCase):
+ urls = "view_tests.urls"
+
+ @override_settings(
+ USE_I18N=True,
+ MIDDLEWARE_CLASSES=(
+ 'django.middleware.locale.LocaleMiddleware',
+ 'django.middleware.common.CommonMiddleware',
+ 'django.middleware.csrf.CsrfViewMiddleware',
+ ),
+ )
+ def test_translation(self):
+ """
+ Test that an invalid request is rejected with a localized error message.
+ """
+ self.client = Client(enforce_csrf_checks=True)
+
+ response = self.client.post('/', HTTP_HOST='www.example.com')
+ 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('/', HTTP_HOST='www.example.com')
+ self.assertContains(response, "Verboden", status_code=403)
+ self.assertContains(response,
+ "CSRF-verificatie mislukt. Verzoek afgebroken.",
+ status_code=403)