diff --git a/hc/front/tests/test_status.py b/hc/front/tests/test_status.py index 5dd3e4ec..6a128cb7 100644 --- a/hc/front/tests/test_status.py +++ b/hc/front/tests/test_status.py @@ -12,7 +12,8 @@ class MyChecksTestCase(BaseTestCase): def test_it_works(self): self.client.login(username="alice@example.org", password="password") - r = self.client.get("/checks/status/") + r = self.client.get("/teams/alice/checks/status/") + self.assertEqual(r.status_code, 200) doc = r.json() self.assertEqual(doc["tags"]["foo"], "up") @@ -21,3 +22,19 @@ class MyChecksTestCase(BaseTestCase): self.assertEqual(detail["code"], str(self.check.code)) self.assertEqual(detail["status"], "new") self.assertIn("Never", detail["last_ping"]) + + def test_it_allows_cross_team_access(self): + self.bobs_profile.current_team = None + self.bobs_profile.save() + + self.client.login(username="bob@example.org", password="password") + r = self.client.get("/teams/alice/checks/status/") + self.assertEqual(r.status_code, 200) + + def test_it_checks_ownership(self): + self.bobs_profile.current_team = None + self.bobs_profile.save() + + self.client.login(username="charlie@example.org", password="password") + r = self.client.get("/teams/alice/checks/status/") + self.assertEqual(r.status_code, 404) diff --git a/hc/front/urls.py b/hc/front/urls.py index be5e65dd..09670b1d 100644 --- a/hc/front/urls.py +++ b/hc/front/urls.py @@ -51,7 +51,7 @@ urlpatterns = [ path('checks/', views.my_checks, name="hc-checks"), path('checks/add/', views.add_check, name="hc-add-check"), path('checks/cron_preview/', views.cron_preview), - path('checks/status/', views.status), + path('teams//checks/status/', views.status, name="hc-status"), path('checks//', include(check_urls)), path('integrations/', include(channel_urls)), diff --git a/hc/front/views.py b/hc/front/views.py index 68fb1d99..bc956ba4 100644 --- a/hc/front/views.py +++ b/hc/front/views.py @@ -77,6 +77,19 @@ def _get_check_for_user(request, code): raise Http404("not found") +def _has_access(request, username): + """ Return true if current user has access to the specified account. """ + + if request.user.username == username: + return True + + if request.user.is_superuser: + return True + + mq = request.user.memberships + return mq.filter(team__user__username=username).exists() + + @login_required def my_checks(request): if request.GET.get("sort") in VALID_SORT_VALUES: @@ -130,8 +143,11 @@ def my_checks(request): @login_required -def status(request): - checks = list(Check.objects.filter(user_id=request.team.user_id)) +def status(request, username): + if not _has_access(request, username): + raise Http404("not found") + + checks = list(Check.objects.filter(user__username=username)) details = [] for check in checks: diff --git a/static/js/checks.js b/static/js/checks.js index 0ba29ba0..89564d7e 100644 --- a/static/js/checks.js +++ b/static/js/checks.js @@ -159,9 +159,10 @@ $(function () { // is active, every 60s otherwise var lastStatus = {}; var lastPing = {}; - adaptiveSetInterval(function() { + var statusUrl = $("#checks-table").data("status-url"); + function refreshStatus() { $.ajax({ - url: "/checks/status/", + url: statusUrl, dataType: "json", timeout: 2000, success: function(data) { @@ -192,7 +193,12 @@ $(function () { } } }); - }); + } + + // Schedule regular status updates: + if (statusUrl) { + adaptiveSetInterval(refreshStatus); + } // Copy to clipboard var clipboard = new Clipboard('button.copy-link'); diff --git a/templates/front/my_checks_desktop.html b/templates/front/my_checks_desktop.html index 564220f5..ee07540d 100644 --- a/templates/front/my_checks_desktop.html +++ b/templates/front/my_checks_desktop.html @@ -1,5 +1,8 @@ {% load hc_extras %} - +