Projet

Général

Profil

0001-errors-hide-credentials-in-urls-in-error-messages-34.patch

Lauréline Guérin, 11 octobre 2019 09:44

Télécharger (4,13 ko)

Voir les différences:

Subject: [PATCH] errors: hide credentials in urls in error messages (#34793)

 passerelle/base/models.py | 10 ++++++++++
 tests/test_proxylogger.py | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+)
passerelle/base/models.py
19 19
from django.test import override_settings
20 20
from django.utils.text import slugify
21 21
from django.utils import timezone, six
22
from django.utils.six.moves.urllib.parse import urlparse
22 23
from django.utils.translation import ugettext_lazy as _
23 24
from django.utils.timezone import now
24 25
from django.core.files.base import ContentFile
......
750 751
        if self.connector.down() and not force:
751 752
            # don't log if the connector is known to be down
752 753
            return
754

  
755
        # hide credentials in urls
756
        for url in re.findall(r'(https?://\S+)', message):
757
            parsed = urlparse(url)
758
            if not parsed.username and not parsed.password:
759
                continue
760
            replaced = parsed._replace(netloc="{}:{}@{}".format('***', '***', parsed.hostname))
761
            message = message.replace(url, replaced.geturl())
762

  
753 763
        levelno = getattr(logging, levelname)
754 764
        if self._logger.level <= levelno:
755 765

  
tests/test_proxylogger.py
8 8
from httmock import HTTMock
9 9

  
10 10
from django.core.exceptions import ValidationError
11
from django.utils.log import AdminEmailHandler
11 12

  
12 13
from passerelle.base.models import ProxyLogger, ResourceLog
13 14
from passerelle.apps.feeds.models import Feed
......
24 25
    return connector
25 26

  
26 27

  
28
@pytest.fixture
29
def email_handler():
30
    root = logging.getLogger()
31
    handler = AdminEmailHandler(include_html=True)
32
    handler.level = logging.ERROR
33
    root.handlers.append(handler)
34
    try:
35
        yield
36
    finally:
37
        root.handlers.remove(handler)
38

  
39

  
27 40
def test_proxy_logger_basic(db, connector):
28 41
    pr = ProxyLogger(connector)
29 42
    pr.debug(u'some message')
......
61 74
    pr.debug(u'some message')
62 75
    assert len(ResourceLog.objects.all()) == 0
63 76

  
77

  
64 78
def test_proxy_logger_ignore_when_down(db, connector):
65 79
    with HTTMock(down_mock):  # set connector as down
66 80
        connector.availability()
......
71 85
    assert len(ResourceLog.objects.all()) == 0
72 86

  
73 87

  
88
@pytest.mark.parametrize('error_msg, expected', [
89
    ('GET http://tcl.example.net/tclpassagearret (=> 502)',
90
     'GET http://tcl.example.net/tclpassagearret (=> 502)'),
91
    ('GET https://tcl.example.net/tclpassagearret (=> 502)',
92
     'GET https://tcl.example.net/tclpassagearret (=> 502)'),
93
    ('GET http://username:password@tcl.example.net/tclpassagearret (=> 502)',
94
     'GET http://***:***@tcl.example.net/tclpassagearret (=> 502)'),
95
    ('GET https://username:password@tcl.example.net/tclpassagearret (=> 502)',
96
     'GET https://***:***@tcl.example.net/tclpassagearret (=> 502)'),
97
])
98
def test_proxy_logger_hide_url_credentials(db, settings, email_handler, mailoutbox,
99
                                           connector, error_msg, expected):
100
    settings.ADMINS = [('admin', 'admin@example.net')]
101

  
102
    pr = ProxyLogger(connector)
103
    pr.error(error_msg)
104
    assert len(mailoutbox) == 1
105
    msg = mailoutbox[0]
106
    assert msg.to == ['admin@example.net']
107
    assert msg.subject == '[Django] ERROR: %s' % expected
108
    assert expected in msg.body
109
    rl = ResourceLog.objects.latest('pk')
110
    assert rl.message == expected
111

  
112

  
74 113
def test_validate_notification_delays(db, connector):
75 114
    def take(iterator, count):
76 115
        return list(itertools.compress(iterator, range(1, count + 1)))
77
-