Ticket #18923: 0001-Ticket-18923-Add-test-for-ensitive_post_parameters.patch

File 0001-Ticket-18923-Add-test-for-ensitive_post_parameters.patch, 8.1 KB (added by zbohm, 12 years ago)
  • django/test/testcases.py

    diff --git a/django/test/testcases.py b/django/test/testcases.py
    index f12c431..357a126 100644
    a b try:  
    1212except ImportError:     # Python 2
    1313    from urlparse import urlsplit, urlunsplit
    1414from xml.dom.minidom import parseString, Node
     15from lxml import etree
    1516import select
    1617import socket
    1718import threading
    class TransactionTestCase(SimpleTestCase):  
    625626            msg_prefix + "Response redirected to '%s', expected '%s'" %
    626627                (url, expected_url))
    627628
     629
     630    def parseHtml(self, body, encoding="utf-8"):
     631        "Get XML Element"
     632        content = re.sub(".*?<", "<", body, 1, re.DOTALL)
     633        reader = etree.HTMLParser(recover=True, encoding=encoding)
     634        return etree.fromstring(content, reader)
     635
     636
    628637    def assertContains(self, response, text, count=None, status_code=200,
    629638                       msg_prefix='', html=False):
    630639        """
  • tests/regressiontests/views/tests/debug.py

    diff --git a/tests/regressiontests/views/tests/debug.py b/tests/regressiontests/views/tests/debug.py
    index 56383ac..a399093 100644
    a b from django.test import TestCase, RequestFactory  
    1010from django.test.utils import (setup_test_template_loader,
    1111                               restore_template_loaders)
    1212from django.core.urlresolvers import reverse
    13 from django.views.debug import ExceptionReporter
     13from django.views.debug import ExceptionReporter, CLEANSED_SUBSTITUTE
    1414from django.core import mail
    1515
    1616from .. import BrokenException, except_args
    1717from ..views import (sensitive_view, non_sensitive_view, paranoid_view,
    18     custom_exception_reporter_filter_view, sensitive_method_view)
     18    custom_exception_reporter_filter_view, sensitive_method_view,
     19    sensitive_post_method_view)
    1920
    2021
    2122class DebugViewTests(TestCase):
    class ExceptionReportTestMixin(object):  
    237238                      'hash-brown-key': 'hash-brown-value',
    238239                      'bacon-key': 'bacon-value',}
    239240
     241    unsafe_post_data = (
     242        ('username', repr(u'myname')),
     243        ('password', repr(u'secret')),
     244        ('secret-key', repr(u'identifier')),
     245    )
     246    safe_post_data = (
     247        ('username', repr(u'myname')),
     248        ('password', repr(CLEANSED_SUBSTITUTE)),
     249        ('secret-key', repr(CLEANSED_SUBSTITUTE)),
     250    )
     251
     252
    240253    def verify_unsafe_response(self, view, check_for_vars=True,
    241254                               check_for_POST_params=True):
    242255        """
    class ExceptionReportTestMixin(object):  
    370383                self.assertNotIn(v, email.body)
    371384
    372385
     386    def _get_xml_doc_from_response(self, response):
     387        "Get XML from response"
     388        if (hasattr(response, 'render') and callable(response.render)
     389            and not response.is_rendered):
     390            response.render()
     391
     392        content = response.content.decode(response._charset)
     393        return self.parseHtml(content, response._charset)
     394
     395
     396    def _get_xml_doc(self, view):
     397        "Make response from view"
     398        request = self.rf.post('/some_url/', self.breakfast_data)
     399        response = view(request)
     400        return self._get_xml_doc_from_response(response)
     401
     402
     403    def _get_post_element(self, view):
     404        """
     405        Parse table after:
     406
     407        <h3 id="post-info">POST</h3>
     408        <table class="req">
     409        """
     410        xmldoc = self._get_xml_doc(view)
     411        return xmldoc.xpath("//h3[@id='post-info']/following-sibling::table[1]")[0]
     412
     413
     414    def _verify_post_response(self, post, post_data):
     415        """
     416        Check POST values:
     417
     418          <tr>
     419            <td>username</td>
     420            <td class="code"><pre>u&#39;myname&#39;</pre></td>
     421          </tr>
     422
     423          <tr>
     424            <td>password</td>
     425            <td class="code"><pre>u&#39;********************&#39;</pre></td>
     426          </tr>
     427        """
     428        for name, value in post_data:
     429            text = post.xpath("//td[text()='%s']/following-sibling::td/pre" % name)[0].text
     430            self.assertEqual(value, text)
     431
     432
     433    def verify_unsafe_post_response(self, view):
     434        """
     435        Asserts that potentially sensitive info are displayed in the response.
     436        """
     437        return self._verify_post_response(self._get_post_element(view),
     438                                          self.unsafe_post_data)
     439
     440
     441    def verify_safe_post_response(self, view):
     442        """
     443        Asserts that certain sensitive info are not displayed in the response.
     444        """
     445        return self._verify_post_response(self._get_post_element(view),
     446                                          self.safe_post_data)
     447
     448
     449    def verify_unsafe_post_email(self, view):
     450        """
     451        Asserts that potentially sensitive info are displayed in the email report.
     452        """
     453        with self.settings(ADMINS=(('Admin', 'admin@fattie-breakie.com'),)):
     454            mail.outbox = [] # Empty outbox
     455            request = self.rf.post('/some_url/', self.breakfast_data)
     456            response = view(request)
     457            self.assertEqual(len(mail.outbox), 1)
     458            email = mail.outbox[0]
     459            self._verify_post_response(self._get_xml_doc_from_response(response),
     460                                       self.unsafe_post_data)
     461
     462
     463    def verify_safe_post_email(self, view):
     464        """
     465        Asserts that certain sensitive info are not displayed in the email report.
     466        """
     467        with self.settings(ADMINS=(('Admin', 'admin@fattie-breakie.com'),)):
     468            mail.outbox = [] # Empty outbox
     469            request = self.rf.post('/some_url/', self.breakfast_data)
     470            response = view(request)
     471            self.assertEqual(len(mail.outbox), 1)
     472            email = mail.outbox[0]
     473            self._verify_post_response(self._get_xml_doc_from_response(response),
     474                                       self.safe_post_data)
     475
     476
     477
    373478class ExceptionReporterFilterTests(TestCase, ExceptionReportTestMixin):
    374479    """
    375480    Ensure that sensitive information can be filtered out of error reports.
    class ExceptionReporterFilterTests(TestCase, ExceptionReportTestMixin):  
    440545                                        check_for_POST_params=False)
    441546            self.verify_unsafe_email(sensitive_method_view,
    442547                                     check_for_POST_params=False)
     548            self.verify_unsafe_post_response(sensitive_post_method_view)
     549            self.verify_unsafe_post_email(sensitive_post_method_view)
     550
    443551
    444552        with self.settings(DEBUG=False):
    445553            self.verify_safe_response(sensitive_method_view,
    446554                                      check_for_POST_params=False)
    447555            self.verify_safe_email(sensitive_method_view,
    448556                                   check_for_POST_params=False)
     557            self.verify_safe_post_response(sensitive_post_method_view)
     558            self.verify_safe_post_email(sensitive_post_method_view)
    449559
    450560
    451561class AjaxResponseExceptionReporterFilter(TestCase, ExceptionReportTestMixin):
  • tests/regressiontests/views/views.py

    diff --git a/tests/regressiontests/views/views.py b/tests/regressiontests/views/views.py
    index 2836d1b..17872ee 100644
    a b class Klass(object):  
    226226            send_log(request, exc_info)
    227227            return technical_500_response(request, *exc_info)
    228228
     229    @sensitive_post_parameters("password", "secret-key")
     230    def method_post(self, request):
     231        request.method = 'POST'
     232        request.POST._mutable = True
     233        request.POST["username"] = ''.join(('m', 'y', 'n', 'a', 'm', 'e'))
     234        request.POST["password"] = ''.join(('s', 'e', 'c', 'r', 'e', 't'))
     235        request.POST["secret-key"] = ''.join(('i', 'd', 'e', 'n', 't', 'i', 'f', 'i', 'e', 'r'))
     236        request.POST._mutable = False
     237        try:
     238            raise Exception
     239        except Exception:
     240            exc_info = sys.exc_info()
     241            send_log(request, exc_info)
     242            return technical_500_response(request, *exc_info)
     243
     244
    229245def sensitive_method_view(request):
    230     return Klass().method(request)
    231  No newline at end of file
     246    return Klass().method(request)
     247
     248def sensitive_post_method_view(request):
     249    return Klass().method_post(request)
Back to Top