forked from GithubBackups/healthchecks
Add tighter parameter checks in hc.front.views.serve_doc
This commit is contained in:
parent
b8f1bdaf96
commit
0f1abd3498
@ -1,6 +1,12 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
All notable changes to this project will be documented in this file.
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
## v1.19.0 - Unreleased
|
||||||
|
|
||||||
|
## Improvements
|
||||||
|
- Add tighter parameter checks in hc.front.views.serve_doc
|
||||||
|
|
||||||
|
|
||||||
## v1.18.0 - 2020-12-09
|
## v1.18.0 - 2020-12-09
|
||||||
|
|
||||||
## Improvements
|
## Improvements
|
||||||
|
31
hc/front/tests/test_serve_doc.py
Normal file
31
hc/front/tests/test_serve_doc.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
from unittest.mock import patch
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
|
||||||
|
class ServeDocTestCase(TestCase):
|
||||||
|
def test_it_serves_introduction(self):
|
||||||
|
r = self.client.get("/docs/")
|
||||||
|
self.assertEqual(r.status_code, 200)
|
||||||
|
|
||||||
|
self.assertContains(r, "<strong>keeps silent</strong>")
|
||||||
|
|
||||||
|
def test_it_serves_subpage(self):
|
||||||
|
r = self.client.get("/docs/reliability_tips/")
|
||||||
|
self.assertEqual(r.status_code, 200)
|
||||||
|
|
||||||
|
self.assertContains(r, "Pinging Reliability Tips")
|
||||||
|
|
||||||
|
def test_it_handles_bad_url(self):
|
||||||
|
r = self.client.get("/docs/does_not_exist/")
|
||||||
|
self.assertEqual(r.status_code, 404)
|
||||||
|
|
||||||
|
@patch("hc.front.views.os.path.exists")
|
||||||
|
def test_it_rejects_bad_characters(self, mock_exists):
|
||||||
|
r = self.client.get("/docs/NAUGHTY/")
|
||||||
|
self.assertEqual(r.status_code, 404)
|
||||||
|
|
||||||
|
# URL dispatcher's slug filter lets the uppercase letters through,
|
||||||
|
# but the view should still reject them, before any filesystem
|
||||||
|
# operations
|
||||||
|
|
||||||
|
self.assertFalse(mock_exists.called)
|
@ -1,6 +1,7 @@
|
|||||||
from datetime import datetime, timedelta as td
|
from datetime import datetime, timedelta as td
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
from secrets import token_urlsafe
|
from secrets import token_urlsafe
|
||||||
from urllib.parse import urlencode
|
from urllib.parse import urlencode
|
||||||
|
|
||||||
@ -314,6 +315,11 @@ def dashboard(request):
|
|||||||
|
|
||||||
|
|
||||||
def serve_doc(request, doc="introduction"):
|
def serve_doc(request, doc="introduction"):
|
||||||
|
# Filenames in /templates/docs/ consist of lowercase letters and underscores,
|
||||||
|
# -- make sure we don't accept anything else
|
||||||
|
if not re.match(r"^[a-z_]+$", doc):
|
||||||
|
raise Http404("not found")
|
||||||
|
|
||||||
path = os.path.join(settings.BASE_DIR, "templates/docs", doc + ".html")
|
path = os.path.join(settings.BASE_DIR, "templates/docs", doc + ".html")
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
raise Http404("not found")
|
raise Http404("not found")
|
||||||
|
Loading…
x
Reference in New Issue
Block a user