diff --git a/CHANGELOG.md b/CHANGELOG.md index 13505378..2841b32e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,8 @@ All notable changes to this project will be documented in this file. ### Improvements - Rate limiting for Telegram notifications (10 notifications per chat per minute) - Use Slack V2 OAuth flow -- "Edit" function for webhook integrations (#176) +- Users can edit their existing webhook integrations (#176) +- Add a "Transfer Ownership" feature in Project Settings ### Bug Fixes - "Get a single check" API call now supports read-only API keys (#346) diff --git a/hc/accounts/models.py b/hc/accounts/models.py index afdc13df..c70fd648 100644 --- a/hc/accounts/models.py +++ b/hc/accounts/models.py @@ -96,6 +96,19 @@ class Profile(models.Model): } emails.login(self.user.email, ctx) + def send_transfer_request(self, project): + token = self.prepare_token("login") + settings_path = reverse("hc-project-settings", args=[project.code]) + path = reverse("hc-check-token", args=[self.user.username, token]) + path += "?next=%s" % settings_path + + ctx = { + "button_text": "Project Settings", + "button_url": settings.SITE_ROOT + path, + "project": project, + } + emails.transfer_request(self.user.email, ctx) + def send_set_password_link(self): token = self.prepare_token("set-password") path = reverse("hc-set-password", args=[token]) diff --git a/hc/accounts/tests/test_transfer_project.py b/hc/accounts/tests/test_transfer_project.py index 48643eed..ad94f77b 100644 --- a/hc/accounts/tests/test_transfer_project.py +++ b/hc/accounts/tests/test_transfer_project.py @@ -1,3 +1,4 @@ +from django.core import mail from django.utils.timezone import now from hc.api.models import Check from hc.test import BaseTestCase @@ -21,6 +22,11 @@ class ProjectTestCase(BaseTestCase): self.bobs_membership.refresh_from_db() self.assertIsNotNone(self.bobs_membership.transfer_request_date) + # Bob should receive an email notification + self.assertEqual(len(mail.outbox), 1) + body = mail.outbox[0].body + self.assertTrue("/?next=" + self.url in body) + def test_transfer_project_checks_ownership(self): self.client.login(username="bob@example.org", password="password") diff --git a/hc/accounts/views.py b/hc/accounts/views.py index dd4e083a..43a1a652 100644 --- a/hc/accounts/views.py +++ b/hc/accounts/views.py @@ -34,6 +34,7 @@ NEXT_WHITELIST = ( "hc-add-slack", "hc-add-pushover", "hc-add-telegram", + "hc-project-settings", ) @@ -350,7 +351,8 @@ def project(request, code): ctx["transfer_initiated"] = True ctx["transfer_status"] = "success" - # FIXME send email + profile = Profile.objects.get(user__email=email) + profile.send_transfer_request(project) elif "cancel_transfer" in request.POST: if not is_owner: diff --git a/hc/lib/emails.py b/hc/lib/emails.py index f0e3a940..cb2c78fa 100644 --- a/hc/lib/emails.py +++ b/hc/lib/emails.py @@ -41,6 +41,10 @@ def login(to, ctx): send("login", to, ctx) +def transfer_request(to, ctx): + send("transfer-request", to, ctx) + + def set_password(to, ctx): send("set-password", to, ctx) diff --git a/templates/accounts/project.html b/templates/accounts/project.html index 835da63a..ed307765 100644 --- a/templates/accounts/project.html +++ b/templates/accounts/project.html @@ -460,6 +460,7 @@
+ This project currently has no team members. + To transfer the ownership of this project, please start by + inviting the new owner as a team member. +
+ {% endif %}