Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Fixed #21324 -- Translate CSRF failure view

Thanks to Claude Paroz for the original patch.
  • Loading branch information...
commit 61074353864293d3ea51e51e09cf4deedee12963 1 parent 090315f
@Bouke Bouke authored claudep committed
View
5 django/middleware/csrf.py
@@ -92,8 +92,7 @@ def _accept(self, request):
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 @@ def process_response(self, request, response):
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
View
45 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 @@
</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 @@
</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')
View
BIN  tests/view_tests/locale/nl/LC_MESSAGES/django.mo
Binary file not shown
View
25 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."
View
33 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)
Please sign in to comment.
Something went wrong with that request. Please try again.