From d45dc2f6a34e5423f575ff27daf893dd1cc38230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C4=93teris=20Caune?= Date: Tue, 19 Jan 2021 11:04:38 +0200 Subject: [PATCH] Change Zulip onboarding, ask for the zuliprc file Fixes: #202 --- CHANGELOG.md | 1 + hc/api/models.py | 12 +++ hc/api/tests/test_notify.py | 35 --------- hc/api/tests/test_notify_zulip.py | 86 ++++++++++++++++++++++ hc/api/transports.py | 3 +- hc/front/forms.py | 1 + hc/front/tests/test_add_zulip.py | 76 +++++++++---------- static/img/integrations/setup_zulip_3.png | Bin 22813 -> 34618 bytes static/js/add_zulip.js | 21 ++++++ templates/integrations/add_zulip.html | 48 ++++-------- 10 files changed, 173 insertions(+), 110 deletions(-) create mode 100644 hc/api/tests/test_notify_zulip.py diff --git a/CHANGELOG.md b/CHANGELOG.md index c7e373fc..eeb57a6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ All notable changes to this project will be documented in this file. - Update the email notification template to include more check and last ping details - Improve the crontab snippet in the "Check Details" page (#465) - Add Signal integration (#428) +- Change Zulip onboarding, ask for the zuliprc file (#202) ## Bug Fixes - Fix unwanted HTML escaping in SMS and WhatsApp notifications diff --git a/hc/api/models.py b/hc/api/models.py index 8d7ea80a..0e684001 100644 --- a/hc/api/models.py +++ b/hc/api/models.py @@ -754,6 +754,18 @@ class Channel(models.Model): doc = json.loads(self.value) return doc["bot_email"] + @property + def zulip_site(self): + assert self.kind == "zulip" + doc = json.loads(self.value) + if "site" in doc: + return doc["site"] + + # Fallback if we don't have the site value: + # derive it from bot's email + _, domain = doc["bot_email"].split("@") + return "https://" + domain + @property def zulip_api_key(self): assert self.kind == "zulip" diff --git a/hc/api/tests/test_notify.py b/hc/api/tests/test_notify.py index acb730fd..ec7dca5b 100644 --- a/hc/api/tests/test_notify.py +++ b/hc/api/tests/test_notify.py @@ -783,38 +783,3 @@ class NotifyTestCase(BaseTestCase): n = Notification.objects.get() self.assertEqual(n.error, "Shell commands are not enabled") - - @patch("hc.api.transports.requests.request") - def test_zulip(self, mock_post): - definition = { - "bot_email": "bot@example.org", - "api_key": "fake-key", - "mtype": "stream", - "to": "general", - } - self._setup_data("zulip", json.dumps(definition)) - mock_post.return_value.status_code = 200 - - self.channel.notify(self.check) - assert Notification.objects.count() == 1 - - args, kwargs = mock_post.call_args - payload = kwargs["data"] - self.assertIn("DOWN", payload["topic"]) - - @patch("hc.api.transports.requests.request") - def test_zulip_returns_error(self, mock_post): - definition = { - "bot_email": "bot@example.org", - "api_key": "fake-key", - "mtype": "stream", - "to": "general", - } - self._setup_data("zulip", json.dumps(definition)) - mock_post.return_value.status_code = 403 - mock_post.return_value.json.return_value = {"msg": "Nice try"} - - self.channel.notify(self.check) - - n = Notification.objects.first() - self.assertEqual(n.error, 'Received status code 403 with a message: "Nice try"') diff --git a/hc/api/tests/test_notify_zulip.py b/hc/api/tests/test_notify_zulip.py new file mode 100644 index 00000000..b4a44ab9 --- /dev/null +++ b/hc/api/tests/test_notify_zulip.py @@ -0,0 +1,86 @@ +# coding: utf-8 + +from datetime import timedelta as td +import json +from unittest.mock import patch + +from django.utils.timezone import now +from hc.api.models import Channel, Check, Notification +from hc.test import BaseTestCase + + +class NotifyTestCase(BaseTestCase): + def _setup_data(self, kind, value, status="down", email_verified=True): + self.check = Check(project=self.project) + self.check.status = status + self.check.last_ping = now() - td(minutes=61) + self.check.save() + + self.channel = Channel(project=self.project) + self.channel.kind = kind + self.channel.value = value + self.channel.email_verified = email_verified + self.channel.save() + self.channel.checks.add(self.check) + + @patch("hc.api.transports.requests.request") + def test_zulip(self, mock_post): + definition = { + "bot_email": "bot@example.org", + "api_key": "fake-key", + "mtype": "stream", + "to": "general", + } + self._setup_data("zulip", json.dumps(definition)) + mock_post.return_value.status_code = 200 + + self.channel.notify(self.check) + assert Notification.objects.count() == 1 + + args, kwargs = mock_post.call_args + + method, url = args + self.assertEqual(url, "https://example.org/api/v1/messages") + + payload = kwargs["data"] + self.assertIn("DOWN", payload["topic"]) + + @patch("hc.api.transports.requests.request") + def test_zulip_returns_error(self, mock_post): + definition = { + "bot_email": "bot@example.org", + "api_key": "fake-key", + "mtype": "stream", + "to": "general", + } + self._setup_data("zulip", json.dumps(definition)) + mock_post.return_value.status_code = 403 + mock_post.return_value.json.return_value = {"msg": "Nice try"} + + self.channel.notify(self.check) + + n = Notification.objects.first() + self.assertEqual(n.error, 'Received status code 403 with a message: "Nice try"') + + @patch("hc.api.transports.requests.request") + def test_zulip_uses_site_parameter(self, mock_post): + definition = { + "bot_email": "bot@example.org", + "site": "https://custom.example.org", + "api_key": "fake-key", + "mtype": "stream", + "to": "general", + } + self._setup_data("zulip", json.dumps(definition)) + mock_post.return_value.status_code = 200 + + self.channel.notify(self.check) + assert Notification.objects.count() == 1 + + args, kwargs = mock_post.call_args + + method, url = args + self.assertEqual(url, "https://custom.example.org/api/v1/messages") + + payload = kwargs["data"] + self.assertIn("DOWN", payload["topic"]) diff --git a/hc/api/transports.py b/hc/api/transports.py index 4b241af5..4b6c3c34 100644 --- a/hc/api/transports.py +++ b/hc/api/transports.py @@ -629,8 +629,7 @@ class Zulip(HttpTransport): pass def notify(self, check): - _, domain = self.channel.zulip_bot_email.split("@") - url = "https://%s/api/v1/messages" % domain + url = self.channel.zulip_site + "/api/v1/messages" auth = (self.channel.zulip_bot_email, self.channel.zulip_api_key) data = { "type": self.channel.zulip_type, diff --git a/hc/front/forms.py b/hc/front/forms.py index 8978eb57..8babe1d0 100644 --- a/hc/front/forms.py +++ b/hc/front/forms.py @@ -274,6 +274,7 @@ class AddZulipForm(forms.Form): error_css_class = "has-error" bot_email = forms.EmailField(max_length=100) api_key = forms.CharField(max_length=50) + site = forms.URLField(max_length=100, validators=[WebhookValidator()]) mtype = forms.ChoiceField(choices=ZULIP_TARGETS) to = forms.CharField(max_length=100) diff --git a/hc/front/tests/test_add_zulip.py b/hc/front/tests/test_add_zulip.py index 860a5082..aac10089 100644 --- a/hc/front/tests/test_add_zulip.py +++ b/hc/front/tests/test_add_zulip.py @@ -2,6 +2,19 @@ from hc.api.models import Channel from hc.test import BaseTestCase +def _get_payload(**kwargs): + payload = { + "bot_email": "foo@example.org", + "api_key": "fake-key", + "site": "https://example.org", + "mtype": "stream", + "to": "general", + } + + payload.update(kwargs) + return payload + + class AddZulipTestCase(BaseTestCase): def setUp(self): super().setUp() @@ -13,15 +26,8 @@ class AddZulipTestCase(BaseTestCase): self.assertContains(r, "open-source group chat app") def test_it_works(self): - form = { - "bot_email": "foo@example.org", - "api_key": "fake-key", - "mtype": "stream", - "to": "general", - } - self.client.login(username="alice@example.org", password="password") - r = self.client.post(self.url, form) + r = self.client.post(self.url, _get_payload()) self.assertRedirects(r, self.channels_url) c = Channel.objects.get() @@ -32,51 +38,39 @@ class AddZulipTestCase(BaseTestCase): self.assertEqual(c.zulip_to, "general") def test_it_rejects_bad_email(self): - form = { - "bot_email": "not@an@email", - "api_key": "fake-key", - "mtype": "stream", - "to": "general", - } - + payload = _get_payload(bot_email="not@an@email") self.client.login(username="alice@example.org", password="password") - r = self.client.post(self.url, form) - self.assertContains(r, "Enter a valid email address.") + r = self.client.post(self.url, payload) + self.assertContains(r, "Invalid file format.") def test_it_rejects_missing_api_key(self): - form = { - "bot_email": "foo@example.org", - "api_key": "", - "mtype": "stream", - "to": "general", - } + payload = _get_payload(api_key="") + self.client.login(username="alice@example.org", password="password") + r = self.client.post(self.url, payload) + self.assertContains(r, "Invalid file format.") + def test_it_rejects_missing_site(self): + payload = _get_payload(site="") self.client.login(username="alice@example.org", password="password") - r = self.client.post(self.url, form) - self.assertContains(r, "This field is required.") + r = self.client.post(self.url, payload) + self.assertContains(r, "Invalid file format.") - def test_it_rejects_bad_mtype(self): - form = { - "bot_email": "foo@example.org", - "api_key": "fake-key", - "mtype": "this-should-not-work", - "to": "general", - } + def test_it_rejects_malformed_site(self): + payload = _get_payload(site="not-an-url") + self.client.login(username="alice@example.org", password="password") + r = self.client.post(self.url, payload) + self.assertContains(r, "Invalid file format.") + def test_it_rejects_bad_mtype(self): + payload = _get_payload(mtype="this-should-not-work") self.client.login(username="alice@example.org", password="password") - r = self.client.post(self.url, form) + r = self.client.post(self.url, payload) self.assertEqual(r.status_code, 200) def test_it_rejects_missing_stream_name(self): - form = { - "bot_email": "foo@example.org", - "api_key": "fake-key", - "mtype": "stream", - "to": "", - } - + payload = _get_payload(to="") self.client.login(username="alice@example.org", password="password") - r = self.client.post(self.url, form) + r = self.client.post(self.url, payload) self.assertContains(r, "This field is required.") def test_it_requires_rw_access(self): diff --git a/static/img/integrations/setup_zulip_3.png b/static/img/integrations/setup_zulip_3.png index f55077317f62eefea68169290b6662f06fb9b0ac..c4e557a539db84fa6b2a661e1aa1816eefb33789 100644 GIT binary patch literal 34618 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 G;eP|snDn0j literal 22813 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 DlYH0S diff --git a/static/js/add_zulip.js b/static/js/add_zulip.js index 0c18e6a4..7a4dc018 100644 --- a/static/js/add_zulip.js +++ b/static/js/add_zulip.js @@ -14,4 +14,25 @@ $(function() { // Update form labels when user clicks on radio buttons $('input[type=radio][name=mtype]').change(updateForm); + $("#zuliprc").change(function() { + this.files[0].text().then(function(contents) { + var keyMatch = contents.match(/key=(.*)/); + var emailMatch = contents.match(/email=(.*@.*)/); + var siteMatch = contents.match(/site=(.*)/); + + if (!keyMatch || !emailMatch || !siteMatch) { + $("#zuliprc-help").text("Invalid file format."); + $("#save-integration").prop("disabled", true); + return + } + + $("#zulip-api-key").val(keyMatch[1]); + $("#zulip-bot-email").val(emailMatch[1]); + $("#zulip-site").val(siteMatch[1]); + $("#zuliprc-help").text(""); + + $("#save-integration").prop("disabled", false); + }); + }) + }); diff --git a/templates/integrations/add_zulip.html b/templates/integrations/add_zulip.html index 154c9472..1f4dc582 100644 --- a/templates/integrations/add_zulip.html +++ b/templates/integrations/add_zulip.html @@ -67,7 +67,8 @@

- Copy the displayed bot's credentials into the form below. + Download the bot's zuliprc file by clicking on the + cyan download icon, and upload it in the form below. Also specify the stream or the private user you want {{ site_name }} to post notifications to.

@@ -87,44 +88,23 @@
{% csrf_token %} + + + -
- +
+
- - -
- {% if form.bot_email.errors %} - {{ form.bot_email.errors|join:"" }} - {% else %} - Example: healthchecks-bot@zulip.mycompany.com + +
+ {% if form.api_key.errors or form.bot_email.errors or form.site.errors %} + Invalid file format. {% endif %}
-
- -
- - {% if form.api_key.errors %} -
- {{ form.api_key.errors|join:"" }} -
- {% endif %} -
-
@@ -178,7 +158,11 @@
- +