forked from GithubBackups/healthchecks
Validate UUID, more tests.
This commit is contained in:
parent
89c3fad985
commit
969626c0fa
15
hc/api/decorators.py
Normal file
15
hc/api/decorators.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
from functools import wraps
|
||||||
|
from django.http import HttpResponseBadRequest
|
||||||
|
import uuid
|
||||||
|
|
||||||
|
|
||||||
|
def uuid_or_400(f):
|
||||||
|
@wraps(f)
|
||||||
|
def wrapper(request, *args, **kwds):
|
||||||
|
try:
|
||||||
|
uuid.UUID(args[0])
|
||||||
|
except ValueError:
|
||||||
|
return HttpResponseBadRequest()
|
||||||
|
|
||||||
|
return f(request, *args, **kwds)
|
||||||
|
return wrapper
|
@ -22,3 +22,7 @@ class PingTestCase(TestCase):
|
|||||||
csrf_client = Client(enforce_csrf_checks=True)
|
csrf_client = Client(enforce_csrf_checks=True)
|
||||||
r = csrf_client.post("/ping/%s/" % check.code)
|
r = csrf_client.post("/ping/%s/" % check.code)
|
||||||
assert r.status_code == 200
|
assert r.status_code == 200
|
||||||
|
|
||||||
|
def test_it_handles_bad_uuid(self):
|
||||||
|
r = self.client.get("/ping/not-uuid/")
|
||||||
|
assert r.status_code == 400
|
||||||
|
17
hc/api/tests/test_status.py
Normal file
17
hc/api/tests/test_status.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from hc.api.models import Check
|
||||||
|
|
||||||
|
|
||||||
|
class StatusTestCase(TestCase):
|
||||||
|
|
||||||
|
def test_it_works(self):
|
||||||
|
check = Check()
|
||||||
|
check.save()
|
||||||
|
|
||||||
|
r = self.client.get("/status/%s/" % check.code)
|
||||||
|
self.assertContains(r, "last_ping", status_code=200)
|
||||||
|
|
||||||
|
def test_it_handles_bad_uuid(self):
|
||||||
|
r = self.client.get("/status/not-uuid/")
|
||||||
|
assert r.status_code == 400
|
@ -3,7 +3,7 @@ from django.conf.urls import url
|
|||||||
from hc.api import views
|
from hc.api import views
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^ping/([\w-]+)/$', views.ping, name="hc-ping"),
|
url(r'^ping/([\w-]+)/$', views.ping, name="hc-ping-slash"),
|
||||||
url(r'^ping/([\w-]+)$', views.ping, name="hc-ping"),
|
url(r'^ping/([\w-]+)$', views.ping, name="hc-ping"),
|
||||||
url(r'^status/([\w-]+)/$', views.status, name="hc-status"),
|
url(r'^status/([\w-]+)/$', views.status, name="hc-status"),
|
||||||
]
|
]
|
||||||
|
@ -5,10 +5,12 @@ from django.http import HttpResponse, HttpResponseBadRequest
|
|||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
|
|
||||||
|
from hc.api.decorators import uuid_or_400
|
||||||
from hc.api.models import Check, Ping
|
from hc.api.models import Check, Ping
|
||||||
|
|
||||||
|
|
||||||
@csrf_exempt
|
@csrf_exempt
|
||||||
|
@uuid_or_400
|
||||||
def ping(request, code):
|
def ping(request, code):
|
||||||
try:
|
try:
|
||||||
check = Check.objects.get(code=code)
|
check = Check.objects.get(code=code)
|
||||||
@ -34,6 +36,7 @@ def ping(request, code):
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
@uuid_or_400
|
||||||
def status(request, code):
|
def status(request, code):
|
||||||
response = {
|
response = {
|
||||||
"last_ping": None,
|
"last_ping": None,
|
||||||
|
29
hc/front/tests/test_log.py
Normal file
29
hc/front/tests/test_log.py
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
from django.contrib.auth.models import User
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from hc.api.models import Check
|
||||||
|
|
||||||
|
|
||||||
|
class LogTestCase(TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.alice = User(username="alice")
|
||||||
|
self.alice.set_password("password")
|
||||||
|
self.alice.save()
|
||||||
|
|
||||||
|
self.check = Check(user=self.alice)
|
||||||
|
self.check.save()
|
||||||
|
|
||||||
|
def test_it_works(self):
|
||||||
|
url = "/checks/%s/log/" % self.check.code
|
||||||
|
|
||||||
|
self.client.login(username="alice", password="password")
|
||||||
|
r = self.client.get(url)
|
||||||
|
self.assertContains(r, "Log for", status_code=200)
|
||||||
|
|
||||||
|
def test_it_handles_bad_uuid(self):
|
||||||
|
url = "/checks/not-uuid/log/"
|
||||||
|
|
||||||
|
self.client.login(username="alice", password="password")
|
||||||
|
r = self.client.get(url)
|
||||||
|
assert r.status_code == 400
|
31
hc/front/tests/test_remove.py
Normal file
31
hc/front/tests/test_remove.py
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
from django.contrib.auth.models import User
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from hc.api.models import Check
|
||||||
|
|
||||||
|
|
||||||
|
class RemoveTestCase(TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.alice = User(username="alice")
|
||||||
|
self.alice.set_password("password")
|
||||||
|
self.alice.save()
|
||||||
|
|
||||||
|
self.check = Check(user=self.alice)
|
||||||
|
self.check.save()
|
||||||
|
|
||||||
|
def test_it_works(self):
|
||||||
|
url = "/checks/%s/remove/" % self.check.code
|
||||||
|
|
||||||
|
self.client.login(username="alice", password="password")
|
||||||
|
r = self.client.post(url)
|
||||||
|
assert r.status_code == 302
|
||||||
|
|
||||||
|
assert Check.objects.count() == 0
|
||||||
|
|
||||||
|
def test_it_handles_bad_uuid(self):
|
||||||
|
url = "/checks/not-uuid/remove/"
|
||||||
|
|
||||||
|
self.client.login(username="alice", password="password")
|
||||||
|
r = self.client.post(url)
|
||||||
|
assert r.status_code == 400
|
@ -37,3 +37,11 @@ class UpdateNameTestCase(TestCase):
|
|||||||
self.client.login(username="charlie", password="password")
|
self.client.login(username="charlie", password="password")
|
||||||
r = self.client.post(url, data=payload)
|
r = self.client.post(url, data=payload)
|
||||||
assert r.status_code == 403
|
assert r.status_code == 403
|
||||||
|
|
||||||
|
def test_it_handles_bad_uuid(self):
|
||||||
|
url = "/checks/not-uuid/name/"
|
||||||
|
payload = {"name": "Alice Was Here"}
|
||||||
|
|
||||||
|
self.client.login(username="alice", password="password")
|
||||||
|
r = self.client.post(url, data=payload)
|
||||||
|
assert r.status_code == 400
|
||||||
|
35
hc/front/tests/test_update_timeout.py
Normal file
35
hc/front/tests/test_update_timeout.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
from django.contrib.auth.models import User
|
||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
from hc.api.models import Check
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateTimeoutTestCase(TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.alice = User(username="alice")
|
||||||
|
self.alice.set_password("password")
|
||||||
|
self.alice.save()
|
||||||
|
|
||||||
|
self.check = Check(user=self.alice)
|
||||||
|
self.check.save()
|
||||||
|
|
||||||
|
def test_it_works(self):
|
||||||
|
url = "/checks/%s/timeout/" % self.check.code
|
||||||
|
payload = {"timeout": 3600, "grace": 60}
|
||||||
|
|
||||||
|
self.client.login(username="alice", password="password")
|
||||||
|
r = self.client.post(url, data=payload)
|
||||||
|
assert r.status_code == 302
|
||||||
|
|
||||||
|
check = Check.objects.get(code=self.check.code)
|
||||||
|
assert check.timeout.total_seconds() == 3600
|
||||||
|
assert check.grace.total_seconds() == 60
|
||||||
|
|
||||||
|
def test_it_handles_bad_uuid(self):
|
||||||
|
url = "/checks/not-uuid/timeout/"
|
||||||
|
payload = {"timeout": 3600, "grace": 60}
|
||||||
|
|
||||||
|
self.client.login(username="alice", password="password")
|
||||||
|
r = self.client.post(url, data=payload)
|
||||||
|
assert r.status_code == 400
|
@ -6,6 +6,7 @@ from django.http import HttpResponseForbidden
|
|||||||
from django.shortcuts import redirect, render
|
from django.shortcuts import redirect, render
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
|
from hc.api.decorators import uuid_or_400
|
||||||
from hc.api.models import Check, Ping
|
from hc.api.models import Check, Ping
|
||||||
from hc.front.forms import TimeoutForm
|
from hc.front.forms import TimeoutForm
|
||||||
|
|
||||||
@ -84,6 +85,7 @@ def add_check(request):
|
|||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
@uuid_or_400
|
||||||
def update_name(request, code):
|
def update_name(request, code):
|
||||||
assert request.method == "POST"
|
assert request.method == "POST"
|
||||||
|
|
||||||
@ -98,6 +100,7 @@ def update_name(request, code):
|
|||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
@uuid_or_400
|
||||||
def update_timeout(request, code):
|
def update_timeout(request, code):
|
||||||
assert request.method == "POST"
|
assert request.method == "POST"
|
||||||
|
|
||||||
@ -115,6 +118,7 @@ def update_timeout(request, code):
|
|||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
@uuid_or_400
|
||||||
def email_preview(request, code):
|
def email_preview(request, code):
|
||||||
""" A debug view to see how email will look.
|
""" A debug view to see how email will look.
|
||||||
|
|
||||||
@ -137,6 +141,7 @@ def email_preview(request, code):
|
|||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
@uuid_or_400
|
||||||
def remove(request, code):
|
def remove(request, code):
|
||||||
assert request.method == "POST"
|
assert request.method == "POST"
|
||||||
|
|
||||||
@ -150,6 +155,7 @@ def remove(request, code):
|
|||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
@uuid_or_400
|
||||||
def log(request, code):
|
def log(request, code):
|
||||||
|
|
||||||
check = Check.objects.get(code=code)
|
check = Check.objects.get(code=code)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user