Tests for team access.

This commit is contained in:
Pēteris Caune 2016-05-09 17:29:41 +03:00
parent 00d18e86bd
commit feb2294a7e
15 changed files with 152 additions and 46 deletions

View File

@ -62,13 +62,16 @@ class ProfileTestCase(BaseTestCase):
def test_it_adds_team_member(self): def test_it_adds_team_member(self):
self.client.login(username="alice@example.org", password="password") self.client.login(username="alice@example.org", password="password")
form = {"invite_team_member": "1", "email": "bob@example.org"} form = {"invite_team_member": "1", "email": "frank@example.org"}
r = self.client.post("/accounts/profile/", form) r = self.client.post("/accounts/profile/", form)
assert r.status_code == 200 assert r.status_code == 200
member = self.alice.profile.member_set.get() member_emails = set()
for member in self.alice.profile.member_set.all():
member_emails.add(member.user.email)
self.assertEqual(member.user.email, "bob@example.org") self.assertEqual(len(member_emails), 2)
self.assertTrue("frank@example.org" in member_emails)
# And an email should have been sent # And an email should have been sent
subj = ('You have been invited to join' subj = ('You have been invited to join'
@ -78,18 +81,15 @@ class ProfileTestCase(BaseTestCase):
def test_it_removes_team_member(self): def test_it_removes_team_member(self):
self.client.login(username="alice@example.org", password="password") self.client.login(username="alice@example.org", password="password")
bob = User(username="bob", email="bob@example.org")
bob.save()
m = Member(team=self.alice.profile, user=bob)
m.save()
form = {"remove_team_member": "1", "email": "bob@example.org"} form = {"remove_team_member": "1", "email": "bob@example.org"}
r = self.client.post("/accounts/profile/", form) r = self.client.post("/accounts/profile/", form)
assert r.status_code == 200 assert r.status_code == 200
self.assertEqual(Member.objects.count(), 0) self.assertEqual(Member.objects.count(), 0)
self.bobs_profile.refresh_from_db()
self.assertEqual(self.bobs_profile.current_team, None)
def test_it_sets_team_name(self): def test_it_sets_team_name(self):
self.client.login(username="alice@example.org", password="password") self.client.login(username="alice@example.org", password="password")

View File

@ -1,37 +1,23 @@
from django.contrib.auth.models import User
from hc.test import BaseTestCase from hc.test import BaseTestCase
from hc.accounts.models import Member, Profile from hc.api.models import Check
class SwitchTeamTestCase(BaseTestCase): class SwitchTeamTestCase(BaseTestCase):
def setUp(self):
super(SwitchTeamTestCase, self).setUp()
self.bob = User(username="bob", email="bob@example.org")
self.bob.set_password("password")
self.bob.save()
bobs_profile = Profile(user=self.bob)
bobs_profile.save()
m = Member(team=bobs_profile, user=self.alice)
m.save()
def test_it_switches(self): def test_it_switches(self):
self.client.login(username="alice@example.org", password="password") c = Check(user=self.alice, name="This belongs to Alice")
c.save()
url = "/accounts/switch_team/%s/" % self.bob.username self.client.login(username="bob@example.org", password="password")
url = "/accounts/switch_team/%s/" % self.alice.username
r = self.client.get(url, follow=True) r = self.client.get(url, follow=True)
self.assertContains(r, "bob@example.org") self.assertContains(r, "This belongs to Alice")
def test_it_checks_team_membership(self): def test_it_checks_team_membership(self):
self.client.login(username="charlie@example.org", password="password") self.client.login(username="charlie@example.org", password="password")
url = "/accounts/switch_team/%s/" % self.bob.username url = "/accounts/switch_team/%s/" % self.alice.username
r = self.client.get(url) r = self.client.get(url)
self.assertEqual(r.status_code, 403) self.assertEqual(r.status_code, 403)

View File

@ -160,7 +160,13 @@ def profile(request):
if form.is_valid(): if form.is_valid():
email = form.cleaned_data["email"] email = form.cleaned_data["email"]
Member.objects.filter(team=profile, user__email=email).delete() farewell_user = User.objects.get(email=email)
farewell_user.profile.current_team = None
farewell_user.profile.save()
Member.objects.filter(team=profile,
user=farewell_user).delete()
messages.info(request, "%s removed from team!" % email) messages.info(request, "%s removed from team!" % email)
elif "set_team_name" in request.POST: elif "set_team_name" in request.POST:
form = TeamNameForm(request.POST) form = TeamNameForm(request.POST)

View File

@ -1,7 +1,7 @@
import json import json
from datetime import timedelta as td from datetime import timedelta as td
from hc.api.models import Check, User from hc.api.models import Check
from hc.test import BaseTestCase from hc.test import BaseTestCase
@ -36,13 +36,12 @@ class ListChecksTestCase(BaseTestCase):
self.assertEqual(checks["Alice 2"]["ping_url"], self.checks[1].url()) self.assertEqual(checks["Alice 2"]["ping_url"], self.checks[1].url())
def test_it_shows_only_users_checks(self): def test_it_shows_only_users_checks(self):
bob = User(username="bob", email="bob@example.com") bobs_check = Check(user=self.bob, name="Bob 1")
bob.save() bobs_check.save()
bob_check = Check(user=bob, name="Bob 1")
bob_check.save()
r = self.get("/api/v1/checks/", {"api_key": "abc"}) r = self.get("/api/v1/checks/", {"api_key": "abc"})
self.assertEqual(len(r.json()["checks"]), 2) data = r.json()
checks = { check["name"]: check for check in r.json()["checks"] } self.assertEqual(len(data["checks"]), 2)
self.assertNotIn("Bob 1", checks) for check in data["checks"]:
self.assertNotEqual(check["name"], "Bob 1")

View File

@ -17,6 +17,17 @@ class AddChannelTestCase(BaseTestCase):
self.assertRedirects(r, "/integrations/") self.assertRedirects(r, "/integrations/")
assert Channel.objects.count() == 1 assert Channel.objects.count() == 1
def test_team_access_works(self):
url = "/integrations/add/"
form = {"kind": "email", "value": "bob@example.org"}
self.client.login(username="bob@example.org", password="password")
self.client.post(url, form)
ch = Channel.objects.get()
# Added by bob, but should belong to alice (bob has team access)
self.assertEqual(ch.user, self.alice)
def test_it_trims_whitespace(self): def test_it_trims_whitespace(self):
""" Leading and trailing whitespace should get trimmed. """ """ Leading and trailing whitespace should get trimmed. """
@ -92,6 +103,18 @@ class AddChannelTestCase(BaseTestCase):
c = Channel.objects.get() c = Channel.objects.get()
self.assertEqual(c.value, "http://foo.com\nhttps://bar.com") self.assertEqual(c.value, "http://foo.com\nhttps://bar.com")
def test_it_adds_webhook_using_team_access(self):
form = {"value_down": "http://foo.com", "value_up": "https://bar.com"}
# Logging in as bob, not alice. Bob has team access so this
# should work.
self.client.login(username="bob@example.org", password="password")
self.client.post("/integrations/add_webhook/", form)
c = Channel.objects.get()
self.assertEqual(c.user, self.alice)
self.assertEqual(c.value, "http://foo.com\nhttps://bar.com")
def test_it_rejects_non_http_webhook_urls(self): def test_it_rejects_non_http_webhook_urls(self):
form = {"value_down": "foo", "value_up": "bar"} form = {"value_down": "foo", "value_up": "bar"}

View File

@ -10,3 +10,12 @@ class AddCheckTestCase(BaseTestCase):
r = self.client.post(url) r = self.client.post(url)
self.assertRedirects(r, "/checks/") self.assertRedirects(r, "/checks/")
assert Check.objects.count() == 1 assert Check.objects.count() == 1
def test_team_access_works(self):
url = "/checks/add/"
self.client.login(username="bob@example.org", password="password")
self.client.post(url)
check = Check.objects.get()
# Added by bob, but should belong to alice (bob has team access)
self.assertEqual(check.user, self.alice)

View File

@ -17,6 +17,15 @@ class ChannelChecksTestCase(BaseTestCase):
r = self.client.get(url) r = self.client.get(url)
self.assertContains(r, "Assign Checks to Channel", status_code=200) self.assertContains(r, "Assign Checks to Channel", status_code=200)
def test_team_access_works(self):
url = "/integrations/%s/checks/" % self.channel.code
# Logging in as bob, not alice. Bob has team access so this
# should work.
self.client.login(username="bob@example.org", password="password")
r = self.client.get(url)
self.assertContains(r, "Assign Checks to Channel", status_code=200)
def test_it_checks_owner(self): def test_it_checks_owner(self):
# channel does not belong to mallory so this should come back # channel does not belong to mallory so this should come back
# with 403 Forbidden: # with 403 Forbidden:

View File

@ -19,6 +19,15 @@ class LogTestCase(BaseTestCase):
r = self.client.get(url) r = self.client.get(url)
self.assertContains(r, "Dates and times are", status_code=200) self.assertContains(r, "Dates and times are", status_code=200)
def test_team_access_works(self):
url = "/checks/%s/log/" % self.check.code
# Logging in as bob, not alice. Bob has team access so this
# should work.
self.client.login(username="bob@example.org", password="password")
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
def test_it_handles_bad_uuid(self): def test_it_handles_bad_uuid(self):
url = "/checks/not-uuid/log/" url = "/checks/not-uuid/log/"

View File

@ -10,6 +10,7 @@ class MyChecksTestCase(BaseTestCase):
self.check.save() self.check.save()
def test_it_works(self): def test_it_works(self):
self.client.login(username="alice@example.org", password="password") for email in ("alice@example.org", "bob@example.org"):
self.client.login(username=email, password="password")
r = self.client.get("/checks/") r = self.client.get("/checks/")
self.assertContains(r, "Alice Was Here", status_code=200) self.assertContains(r, "Alice Was Here", status_code=200)

View File

@ -19,6 +19,13 @@ class RemoveChannelTestCase(BaseTestCase):
assert Channel.objects.count() == 0 assert Channel.objects.count() == 0
def test_team_access_works(self):
url = "/integrations/%s/remove/" % self.channel.code
self.client.login(username="bob@example.org", password="password")
self.client.post(url)
assert Channel.objects.count() == 0
def test_it_handles_bad_uuid(self): def test_it_handles_bad_uuid(self):
url = "/integrations/not-uuid/remove/" url = "/integrations/not-uuid/remove/"

View File

@ -18,6 +18,15 @@ class RemoveCheckTestCase(BaseTestCase):
assert Check.objects.count() == 0 assert Check.objects.count() == 0
def test_team_access_works(self):
url = "/checks/%s/remove/" % self.check.code
# Logging in as bob, not alice. Bob has team access so this
# should work.
self.client.login(username="bob@example.org", password="password")
self.client.post(url)
assert Check.objects.count() == 0
def test_it_handles_bad_uuid(self): def test_it_handles_bad_uuid(self):
url = "/checks/not-uuid/remove/" url = "/checks/not-uuid/remove/"

View File

@ -28,6 +28,18 @@ class UpdateChannelTestCase(BaseTestCase):
assert len(checks) == 1 assert len(checks) == 1
assert checks[0].code == self.check.code assert checks[0].code == self.check.code
def test_team_access_works(self):
payload = {
"channel": self.channel.code,
"check-%s" % self.check.code: True
}
# Logging in as bob, not alice. Bob has team access so this
# should work.
self.client.login(username="bob@example.org", password="password")
r = self.client.post("/integrations/", data=payload, follow=True)
self.assertEqual(r.status_code, 200)
def test_it_checks_channel_user(self): def test_it_checks_channel_user(self):
payload = {"channel": self.channel.code} payload = {"channel": self.channel.code}

View File

@ -20,6 +20,18 @@ class UpdateNameTestCase(BaseTestCase):
check = Check.objects.get(code=self.check.code) check = Check.objects.get(code=self.check.code)
assert check.name == "Alice Was Here" assert check.name == "Alice Was Here"
def test_team_access_works(self):
url = "/checks/%s/name/" % self.check.code
payload = {"name": "Bob Was Here"}
# Logging in as bob, not alice. Bob has team access so this
# should work.
self.client.login(username="bob@example.org", password="password")
self.client.post(url, data=payload)
check = Check.objects.get(code=self.check.code)
assert check.name == "Bob Was Here"
def test_it_checks_ownership(self): def test_it_checks_ownership(self):
url = "/checks/%s/name/" % self.check.code url = "/checks/%s/name/" % self.check.code
payload = {"name": "Charlie Sent This"} payload = {"name": "Charlie Sent This"}

View File

@ -21,6 +21,18 @@ class UpdateTimeoutTestCase(BaseTestCase):
assert check.timeout.total_seconds() == 3600 assert check.timeout.total_seconds() == 3600
assert check.grace.total_seconds() == 60 assert check.grace.total_seconds() == 60
def test_team_access_works(self):
url = "/checks/%s/timeout/" % self.check.code
payload = {"timeout": 7200, "grace": 60}
# Logging in as bob, not alice. Bob has team access so this
# should work.
self.client.login(username="bob@example.org", password="password")
self.client.post(url, data=payload)
check = Check.objects.get(code=self.check.code)
assert check.timeout.total_seconds() == 7200
def test_it_handles_bad_uuid(self): def test_it_handles_bad_uuid(self):
url = "/checks/not-uuid/timeout/" url = "/checks/not-uuid/timeout/"
payload = {"timeout": 3600, "grace": 60} payload = {"timeout": 3600, "grace": 60}

View File

@ -1,7 +1,7 @@
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.test import TestCase from django.test import TestCase
from hc.accounts.models import Profile from hc.accounts.models import Member, Profile
class BaseTestCase(TestCase): class BaseTestCase(TestCase):
@ -9,7 +9,7 @@ class BaseTestCase(TestCase):
def setUp(self): def setUp(self):
super(BaseTestCase, self).setUp() super(BaseTestCase, self).setUp()
# Normal user for tests # Alice is a normal user for tests
self.alice = User(username="alice", email="alice@example.org") self.alice = User(username="alice", email="alice@example.org")
self.alice.set_password("password") self.alice.set_password("password")
self.alice.save() self.alice.save()
@ -17,7 +17,19 @@ class BaseTestCase(TestCase):
self.profile = Profile(user=self.alice, api_key="abc") self.profile = Profile(user=self.alice, api_key="abc")
self.profile.save() self.profile.save()
# "malicious user for tests # Bob is on Alice's team and should have access to her stuff
self.bob = User(username="bob", email="bob@example.org")
self.bob.set_password("password")
self.bob.save()
self.bobs_profile = Profile(user=self.bob)
self.bobs_profile.current_team = self.profile
self.bobs_profile.save()
m = Member(team=self.profile, user=self.bob)
m.save()
# Charlie should have no access to Alice's stuff
self.charlie = User(username="charlie", email="charlie@example.org") self.charlie = User(username="charlie", email="charlie@example.org")
self.charlie.set_password("password") self.charlie.set_password("password")
self.charlie.save() self.charlie.save()