diff --git a/CHANGELOG.md b/CHANGELOG.md index 23047a9f..71a1cf03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file. ### Improvements - Improved UI to invite users from account's other projects (#258) - Experimental Prometheus metrics endpoint (#300) +- Don't store user's current project in DB, put it explicitly in page URLs (#336) ### Bug Fixes - The "render_docs" command checks if markdown and pygments is installed (#329) diff --git a/hc/accounts/admin.py b/hc/accounts/admin.py index 36042780..73e354d9 100644 --- a/hc/accounts/admin.py +++ b/hc/accounts/admin.py @@ -22,7 +22,6 @@ class ProfileFieldset(Fieldset): name = "User Profile" fields = ( "email", - "current_project", "reports_allowed", "next_report_date", "nag_period", @@ -51,7 +50,6 @@ class ProfileAdmin(admin.ModelAdmin): css = {"all": ("css/admin/profiles.css",)} readonly_fields = ("user", "email") - raw_id_fields = ("current_project",) search_fields = ["id", "user__email"] list_per_page = 50 list_select_related = ("user",) diff --git a/hc/accounts/models.py b/hc/accounts/models.py index 6c9ddc41..c5a889b0 100644 --- a/hc/accounts/models.py +++ b/hc/accounts/models.py @@ -260,12 +260,6 @@ class Project(models.Model): def invite(self, user): Member.objects.create(user=user, project=self) - - # Switch the invited user over to the new team so they - # notice the new team on next visit: - user.profile.current_project = self - user.profile.save() - user.profile.send_instant_login_link(self) def set_next_nag_date(self): diff --git a/hc/accounts/tests/test_close_account.py b/hc/accounts/tests/test_close_account.py index b0e541c8..fe927dd5 100644 --- a/hc/accounts/tests/test_close_account.py +++ b/hc/accounts/tests/test_close_account.py @@ -21,10 +21,6 @@ class CloseAccountTestCase(BaseTestCase): alices = User.objects.filter(username="alice") self.assertFalse(alices.exists()) - # Bob's current team should now be None - self.bobs_profile.refresh_from_db() - self.assertIsNone(self.bobs_profile.current_project) - # Check should be gone self.assertFalse(Check.objects.exists()) diff --git a/hc/accounts/tests/test_profile.py b/hc/accounts/tests/test_profile.py index 36281bf5..6eef305d 100644 --- a/hc/accounts/tests/test_profile.py +++ b/hc/accounts/tests/test_profile.py @@ -117,7 +117,6 @@ class ProfileTestCase(BaseTestCase): self.assertNotContains(r, "Alice's Project") self.bobs_profile.refresh_from_db() - self.assertIsNone(self.bobs_profile.current_project) self.assertFalse(self.bob.memberships.exists()) def test_leaving_checks_membership(self): diff --git a/hc/accounts/tests/test_project.py b/hc/accounts/tests/test_project.py index 60cf6872..55bfde9c 100644 --- a/hc/accounts/tests/test_project.py +++ b/hc/accounts/tests/test_project.py @@ -76,8 +76,6 @@ class ProjectTestCase(BaseTestCase): project=self.project, user__email="frank@example.org" ) - profile = member.user.profile - self.assertEqual(profile.current_project, self.project) # The new user should not have their own project self.assertFalse(member.user.project_set.exists()) @@ -148,10 +146,7 @@ class ProjectTestCase(BaseTestCase): r = self.client.post(self.url, form) self.assertEqual(r.status_code, 200) - self.assertEqual(Member.objects.count(), 0) - - self.bobs_profile.refresh_from_db() - self.assertEqual(self.bobs_profile.current_project, None) + self.assertFalse(Member.objects.exists()) def test_it_requires_owner_to_remove_team_member(self): self.client.login(username="bob@example.org", password="password") @@ -161,9 +156,6 @@ class ProjectTestCase(BaseTestCase): self.assertEqual(r.status_code, 403) def test_it_checks_membership_when_removing_team_member(self): - self.profile.current_project = self.project - self.profile.save() - self.client.login(username="charlie@example.org", password="password") url = "/projects/%s/settings/" % self.charlies_project.code @@ -171,9 +163,6 @@ class ProjectTestCase(BaseTestCase): r = self.client.post(url, form) self.assertEqual(r.status_code, 400) - self.profile.refresh_from_db() - self.assertIsNotNone(self.profile.current_project) - def test_it_sets_project_name(self): self.client.login(username="alice@example.org", password="password") diff --git a/hc/accounts/tests/test_remove_project.py b/hc/accounts/tests/test_remove_project.py index 73842529..e4bd2d4d 100644 --- a/hc/accounts/tests/test_remove_project.py +++ b/hc/accounts/tests/test_remove_project.py @@ -15,10 +15,6 @@ class RemoveProjectTestCase(BaseTestCase): r = self.client.post(self.url) self.assertRedirects(r, "/") - # Alice's current project should be not set - self.profile.refresh_from_db() - self.assertEqual(self.profile.current_project, None) - # Alice should not own any projects self.assertFalse(self.alice.project_set.exists()) diff --git a/hc/accounts/views.py b/hc/accounts/views.py index ae242583..5f146bec 100644 --- a/hc/accounts/views.py +++ b/hc/accounts/views.py @@ -79,9 +79,7 @@ def _make_user(email, with_project=True): channel.checks.add(check) # Ensure a profile gets created - profile = Profile.objects.for_user(user) - profile.current_project = project - profile.save() + Profile.objects.for_user(user) return user @@ -222,10 +220,6 @@ def profile(request): except Project.DoesNotExist: return HttpResponseBadRequest() - if profile.current_project == project: - profile.current_project = None - profile.save() - Member.objects.filter(project=project, user=request.user).delete() ctx["left_project"] = project @@ -333,9 +327,6 @@ def project(request, code): if farewell_user is None: return HttpResponseBadRequest() - farewell_user.profile.current_project = None - farewell_user.profile.save() - Member.objects.filter(project=project, user=farewell_user).delete() ctx["team_member_removed"] = form.cleaned_data["email"] diff --git a/hc/front/tests/test_add_check.py b/hc/front/tests/test_add_check.py index 3da7396e..32501425 100644 --- a/hc/front/tests/test_add_check.py +++ b/hc/front/tests/test_add_check.py @@ -19,19 +19,6 @@ class AddCheckTestCase(BaseTestCase): redirect_url = "/checks/%s/details/?new" % check.code self.assertRedirects(r, redirect_url) - def test_it_handles_unset_current_project(self): - self.profile.current_project = None - self.profile.save() - - self.client.login(username="alice@example.org", password="password") - r = self.client.post(self.url) - - check = Check.objects.get() - self.assertEqual(check.project, self.project) - - redirect_url = "/checks/%s/details/?new" % check.code - self.assertRedirects(r, redirect_url) - def test_team_access_works(self): self.client.login(username="bob@example.org", password="password") self.client.post(self.url) diff --git a/hc/front/tests/test_details.py b/hc/front/tests/test_details.py index d3119134..befe12d4 100644 --- a/hc/front/tests/test_details.py +++ b/hc/front/tests/test_details.py @@ -37,9 +37,6 @@ class DetailsTestCase(BaseTestCase): self.assertContains(r, "Cron Expression", status_code=200) def test_it_allows_cross_team_access(self): - self.bobs_profile.current_project = None - self.bobs_profile.save() - self.client.login(username="bob@example.org", password="password") r = self.client.get(self.url) self.assertEqual(r.status_code, 200) diff --git a/hc/front/tests/test_log.py b/hc/front/tests/test_log.py index 3c4eb1d6..23554f78 100644 --- a/hc/front/tests/test_log.py +++ b/hc/front/tests/test_log.py @@ -91,9 +91,6 @@ class LogTestCase(BaseTestCase): self.assertContains(r, "Called webhook foo/$NAME", status_code=200) def test_it_allows_cross_team_access(self): - self.bobs_profile.current_project = None - self.bobs_profile.save() - self.client.login(username="bob@example.org", password="password") r = self.client.get(self.url) self.assertEqual(r.status_code, 200) diff --git a/hc/front/tests/test_pause.py b/hc/front/tests/test_pause.py index 081d6266..4452f6f2 100644 --- a/hc/front/tests/test_pause.py +++ b/hc/front/tests/test_pause.py @@ -26,9 +26,6 @@ class PauseTestCase(BaseTestCase): self.assertEqual(r.status_code, 405) def test_it_allows_cross_team_access(self): - self.bobs_profile.current_project = None - self.bobs_profile.save() - self.client.login(username="bob@example.org", password="password") r = self.client.post(self.url) self.assertRedirects(r, self.redirect_url) diff --git a/hc/front/tests/test_ping_details.py b/hc/front/tests/test_ping_details.py index 6761daf8..51a40770 100644 --- a/hc/front/tests/test_ping_details.py +++ b/hc/front/tests/test_ping_details.py @@ -43,9 +43,6 @@ class LastPingTestCase(BaseTestCase): self.assertContains(r, "bar-456", status_code=200) def test_it_allows_cross_team_access(self): - self.bobs_profile.current_project = None - self.bobs_profile.save() - check = Check.objects.create(project=self.project) Ping.objects.create(owner=check, body="this is body") diff --git a/hc/front/tests/test_remove_check.py b/hc/front/tests/test_remove_check.py index c1cd48a2..3fd113c0 100644 --- a/hc/front/tests/test_remove_check.py +++ b/hc/front/tests/test_remove_check.py @@ -48,9 +48,6 @@ class RemoveCheckTestCase(BaseTestCase): self.assertEqual(r.status_code, 405) def test_it_allows_cross_team_access(self): - self.bobs_profile.current_project = None - self.bobs_profile.save() - self.client.login(username="bob@example.org", password="password") r = self.client.post(self.remove_url) self.assertRedirects(r, self.redirect_url) diff --git a/hc/front/tests/test_status.py b/hc/front/tests/test_status.py index 17ddc3f5..9f84a361 100644 --- a/hc/front/tests/test_status.py +++ b/hc/front/tests/test_status.py @@ -25,17 +25,11 @@ class MyChecksTestCase(BaseTestCase): self.assertIn("Never", detail["last_ping"]) def test_it_allows_cross_team_access(self): - self.bobs_profile.current_project = None - self.bobs_profile.save() - self.client.login(username="bob@example.org", password="password") r = self.client.get(self.url) self.assertEqual(r.status_code, 200) def test_it_checks_ownership(self): - self.bobs_profile.current_project = None - self.bobs_profile.save() - self.client.login(username="charlie@example.org", password="password") r = self.client.get(self.url) self.assertEqual(r.status_code, 404) diff --git a/hc/front/tests/test_status_single.py b/hc/front/tests/test_status_single.py index 0889e361..85832520 100644 --- a/hc/front/tests/test_status_single.py +++ b/hc/front/tests/test_status_single.py @@ -47,9 +47,6 @@ class StatusSingleTestCase(BaseTestCase): self.assertFalse("events" in doc) def test_it_allows_cross_team_access(self): - self.bobs_profile.current_project = None - self.bobs_profile.save() - self.client.login(username="bob@example.org", password="password") r = self.client.get("/checks/%s/status/" % self.check.code) self.assertEqual(r.status_code, 200) diff --git a/hc/front/tests/test_switch_channel.py b/hc/front/tests/test_switch_channel.py index 0b74688d..c6b76cc2 100644 --- a/hc/front/tests/test_switch_channel.py +++ b/hc/front/tests/test_switch_channel.py @@ -48,9 +48,6 @@ class SwitchChannelTestCase(BaseTestCase): self.assertEqual(r.status_code, 400) def test_it_allows_cross_team_access(self): - self.bobs_profile.current_project = None - self.bobs_profile.save() - self.client.login(username="bob@example.org", password="password") r = self.client.post(self.url, {"state": "on"}) self.assertEqual(r.status_code, 200) diff --git a/hc/front/tests/test_update_name.py b/hc/front/tests/test_update_name.py index 55bb2d4e..de42b017 100644 --- a/hc/front/tests/test_update_name.py +++ b/hc/front/tests/test_update_name.py @@ -30,11 +30,6 @@ class UpdateNameTestCase(BaseTestCase): self.assertEqual(self.check.name, "Bob Was Here") def test_it_allows_cross_team_access(self): - # Bob's current profile is not set - self.bobs_profile.current_project = None - self.bobs_profile.save() - - # But this should still work: self.client.login(username="bob@example.org", password="password") r = self.client.post(self.url, data={"name": "Bob Was Here"}) self.assertRedirects(r, self.redirect_url) diff --git a/hc/front/tests/test_update_timeout.py b/hc/front/tests/test_update_timeout.py index d5f5f7b8..e28f6b20 100644 --- a/hc/front/tests/test_update_timeout.py +++ b/hc/front/tests/test_update_timeout.py @@ -175,9 +175,6 @@ class UpdateTimeoutTestCase(BaseTestCase): self.assertEqual(r.status_code, 405) def test_it_allows_cross_team_access(self): - self.bobs_profile.current_project = None - self.bobs_profile.save() - payload = {"kind": "simple", "timeout": 3600, "grace": 60} self.client.login(username="bob@example.org", password="password") diff --git a/hc/test.py b/hc/test.py index 105d7615..d6c47295 100644 --- a/hc/test.py +++ b/hc/test.py @@ -32,7 +32,6 @@ class BaseTestCase(TestCase): self.bobs_project.save() self.bobs_profile = Profile(user=self.bob) - self.bobs_profile.current_project = self.project self.bobs_profile.save() Member.objects.create(user=self.bob, project=self.project) @@ -47,7 +46,6 @@ class BaseTestCase(TestCase): self.charlies_project.save() self.charlies_profile = Profile(user=self.charlie) - self.charlies_profile.current_project = self.charlies_project self.charlies_profile.save() self.channels_url = "/projects/%s/integrations/" % self.project.code diff --git a/templates/front/projects.html b/templates/front/projects.html index a734b89d..42ffde80 100644 --- a/templates/front/projects.html +++ b/templates/front/projects.html @@ -40,7 +40,7 @@
-
+
New Project…