summaryrefslogtreecommitdiff
path: root/tests/view_tests/tests/test_csrf.py
blob: fdd9715476150441a159b1a35e17037fcda03abf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
from django.template import TemplateDoesNotExist
from django.test import (
    Client, RequestFactory, SimpleTestCase, override_settings,
)
from django.test.utils import ignore_warnings
from django.utils.deprecation import RemovedInDjango20Warning
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(CsrfViewTests, self).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):
        """
        Test that 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)

    @ignore_warnings(category=RemovedInDjango20Warning)
    @override_settings(
        USE_I18N=True,
        MIDDLEWARE=None,
        MIDDLEWARE_CLASSES=[
            'django.middleware.locale.LocaleMiddleware',
            'django.middleware.common.CommonMiddleware',
            'django.middleware.csrf.CsrfViewMiddleware',
        ],
    )
    def test_translation_middleware_classes(self):
        """
        Test that 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('/', HTTP_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)

    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)

    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")