Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #21324 -- Translate CSRF failure view

Thanks to Claude Paroz for the original patch.
  • Loading branch information...
commit 61074353864293d3ea51e51e09cf4deedee12963 1 parent 090315f
Bouke Haarsma authored November 02, 2013 claudep committed November 02, 2013
5  django/middleware/csrf.py
@@ -92,8 +92,7 @@ def _accept(self, request):
92 92
         return None
93 93
 
94 94
     def _reject(self, request, reason):
95  
-        logger.warning('Forbidden (%s): %s',
96  
-                       reason, request.path,
  95
+        logger.warning('Forbidden (%s): %s', reason, request.path,
97 96
             extra={
98 97
                 'status_code': 403,
99 98
                 'request': request,
@@ -184,7 +183,7 @@ def process_response(self, request, response):
184 183
             return response
185 184
 
186 185
         # If CSRF_COOKIE is unset, then CsrfViewMiddleware.process_view was
187  
-        # never called, probaby because a request middleware returned a response
  186
+        # never called, probably because a request middleware returned a response
188 187
         # (for example, contrib.auth redirecting to a login page).
189 188
         if request.META.get("CSRF_COOKIE") is None:
190 189
             return response
45  django/views/csrf.py
... ...
@@ -1,11 +1,16 @@
  1
+from django.conf import settings
1 2
 from django.http import HttpResponseForbidden
2 3
 from django.template import Context, Template
3  
-from django.conf import settings
  4
+from django.utils.translation import ugettext as _
4 5
 
5 6
 # We include the template inline since we need to be able to reliably display
6 7
 # this error message, especially for the sake of developers, and there isn't any
7 8
 # other way of making it available independent of what is in the settings file.
8 9
 
  10
+# Only the text appearing with DEBUG=False is translated. Normal translation
  11
+# tags cannot be used with this inline templates as makemessages would not be
  12
+# able to discover the strings.
  13
+
9 14
 CSRF_FAILURE_TEMPLATE = """
10 15
 <!DOCTYPE html>
11 16
 <html lang="en">
@@ -30,17 +35,11 @@
30 35
 </head>
31 36
 <body>
32 37
 <div id="summary">
33  
-  <h1>Forbidden <span>(403)</span></h1>
34  
-  <p>CSRF verification failed. Request aborted.</p>
  38
+  <h1>{{ title }} <span>(403)</span></h1>
  39
+  <p>{{ main }}</p>
35 40
 {% if no_referer %}
36  
-  <p>You are seeing this message because this HTTPS site requires a 'Referer
37  
-   header' to be sent by your Web browser, but none was sent. This header is
38  
-   required for security reasons, to ensure that your browser is not being
39  
-   hijacked by third parties.</p>
40  
-
41  
-  <p>If you have configured your browser to disable 'Referer' headers, please
42  
-   re-enable them, at least for this site, or for HTTPS connections, or for
43  
-   'same-origin' requests.</p>
  41
+  <p>{{ no_referer1 }}</p>
  42
+  <p>{{ no_referer2 }}</p>
44 43
 {% endif %}
45 44
 </div>
46 45
 {% if DEBUG %}
@@ -84,21 +83,35 @@
84 83
 </div>
85 84
 {% else %}
86 85
 <div id="explanation">
87  
-  <p><small>More information is available with DEBUG=True.</small></p>
  86
+  <p><small>{{ more }}</small></p>
88 87
 </div>
89 88
 {% endif %}
90 89
 </body>
91 90
 </html>
92 91
 """
93 92
 
  93
+
94 94
 def csrf_failure(request, reason=""):
95 95
     """
96 96
     Default view used when request fails CSRF protection
97 97
     """
98 98
     from django.middleware.csrf import REASON_NO_REFERER
99 99
     t = Template(CSRF_FAILURE_TEMPLATE)
100  
-    c = Context({'DEBUG': settings.DEBUG,
101  
-                 'reason': reason,
102  
-                 'no_referer': reason == REASON_NO_REFERER
103  
-                 })
  100
+    c = Context({
  101
+        'title': _("Forbidden"),
  102
+        'main': _("CSRF verification failed. Request aborted."),
  103
+        'reason': reason,
  104
+        'no_referer': reason == REASON_NO_REFERER,
  105
+        'no_referer1': _(
  106
+            "You are seeing this message because this HTTPS site requires a "
  107
+            "'Referer header' to be sent by your Web browser, but none was "
  108
+            "sent. This header is required for security reasons, to ensure "
  109
+            "that your browser is not being hijacked by third parties."),
  110
+        'no_referer2': _(
  111
+            "If you have configured your browser to disable 'Referer' headers, "
  112
+            "please re-enable them, at least for this site, or for HTTPS "
  113
+            "connections, or for 'same-origin' requests."),
  114
+        'DEBUG': settings.DEBUG,
  115
+        'more': _("More information is available with DEBUG=True."),
  116
+    })
104 117
     return HttpResponseForbidden(t.render(c), content_type='text/html')
BIN  tests/view_tests/locale/nl/LC_MESSAGES/django.mo
Binary file not shown
25  tests/view_tests/locale/nl/LC_MESSAGES/django.po
... ...
@@ -0,0 +1,25 @@
  1
+# SOME DESCRIPTIVE TITLE.
  2
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
  3
+# This file is distributed under the same license as the PACKAGE package.
  4
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
  5
+#
  6
+#, fuzzy
  7
+msgid ""
  8
+msgstr ""
  9
+"Project-Id-Version: PACKAGE VERSION\n"
  10
+"Report-Msgid-Bugs-To: \n"
  11
+"POT-Creation-Date: 2007-09-15 19:15+0200\n"
  12
+"PO-Revision-Date: 2010-05-12 12:41-0300\n"
  13
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
  14
+"Language-Team: LANGUAGE <LL@li.org>\n"
  15
+"MIME-Version: 1.0\n"
  16
+"Content-Type: text/plain; charset=UTF-8\n"
  17
+"Content-Transfer-Encoding: 8bit\n"
  18
+
  19
+#: views/csrf.py:98
  20
+msgid "Forbidden"
  21
+msgstr "Verboden"
  22
+
  23
+#: views/csrf.py:99
  24
+msgid "CSRF verification failed. Request aborted."
  25
+msgstr "CSRF-verificatie mislukt. Verzoek afgebroken."
33  tests/view_tests/tests/test_csrf.py
... ...
@@ -0,0 +1,33 @@
  1
+from django.test import TestCase, override_settings, Client
  2
+from django.utils.translation import override
  3
+
  4
+
  5
+class CsrfViewTests(TestCase):
  6
+    urls = "view_tests.urls"
  7
+
  8
+    @override_settings(
  9
+        USE_I18N=True,
  10
+        MIDDLEWARE_CLASSES=(
  11
+            'django.middleware.locale.LocaleMiddleware',
  12
+            'django.middleware.common.CommonMiddleware',
  13
+            'django.middleware.csrf.CsrfViewMiddleware',
  14
+        ),
  15
+    )
  16
+    def test_translation(self):
  17
+        """
  18
+        Test that an invalid request is rejected with a localized error message.
  19
+        """
  20
+        self.client = Client(enforce_csrf_checks=True)
  21
+
  22
+        response = self.client.post('/', HTTP_HOST='www.example.com')
  23
+        self.assertContains(response, "Forbidden", status_code=403)
  24
+        self.assertContains(response,
  25
+                            "CSRF verification failed. Request aborted.",
  26
+                            status_code=403)
  27
+
  28
+        with self.settings(LANGUAGE_CODE='nl'), override('en-us'):
  29
+            response = self.client.post('/', HTTP_HOST='www.example.com')
  30
+            self.assertContains(response, "Verboden", status_code=403)
  31
+            self.assertContains(response,
  32
+                                "CSRF-verificatie mislukt. Verzoek afgebroken.",
  33
+                                status_code=403)

0 notes on commit 6107435

Please sign in to comment.
Something went wrong with that request. Please try again.