def test_it_formats_complex_slack_value(self): ch = Channel(kind="slack", user=self.alice) ch.value = json.dumps({ "ok": True, "team_name": "foo-team", "incoming_webhook": { "url": "http://example.org", "channel": "#bar" } }) ch.save() self.client.login(username="******", password="******") r = self.client.get("/integrations/") self.assertContains(r, "foo-team", status_code=200) self.assertContains(r, "#bar")
def add_opsgenie(request): if request.method == "POST": form = AddOpsGenieForm(request.POST) if form.is_valid(): channel = Channel(project=request.project, kind="opsgenie") v = {"region": form.cleaned_data["region"], "key": form.cleaned_data["key"]} channel.value = json.dumps(v) channel.save() channel.assign_all_checks() return redirect("hc-channels") else: form = AddOpsGenieForm() ctx = {"page": "channels", "project": request.project, "form": form} return render(request, "integrations/add_opsgenie.html", ctx)
def add_email(request): if request.method == "POST": form = AddEmailForm(request.POST) if form.is_valid(): channel = Channel(user=request.team.user, kind="email") channel.value = form.cleaned_data["value"] channel.save() channel.assign_all_checks() channel.send_verify_link() return redirect("hc-channels") else: form = AddEmailForm() ctx = {"page": "channels", "form": form} return render(request, "integrations/add_email.html", ctx)
def _setup_data(self, notify_up=True, notify_down=True): self.check = Check(project=self.project) self.check.status = "down" self.check.last_ping = now() - td(minutes=61) self.check.save() definition = { "value": "+1234567890", "up": notify_up, "down": notify_down } self.channel = Channel(project=self.project, kind="whatsapp") self.channel.value = json.dumps(definition) self.channel.save() self.channel.checks.add(self.check)
def add_mattermost(request): if request.method == "POST": form = AddUrlForm(request.POST) if form.is_valid(): channel = Channel(project=request.project, kind="mattermost") channel.value = form.cleaned_data["value"] channel.save() channel.assign_all_checks() return redirect("hc-channels") else: form = AddUrlForm() ctx = {"page": "channels", "form": form, "project": request.project} return render(request, "integrations/add_mattermost.html", ctx)
def test_it_shows_email_notification(self): ch = Channel(kind="email", project=self.project) ch.value = json.dumps({ "value": "*****@*****.**", "up": True, "down": True }) ch.save() Notification(owner=self.check, channel=ch, check_status="down").save() self.client.login(username="******", password="******") r = self.client.get(self.url) self.assertContains(r, "Sent email to [email protected]", status_code=200)
def add_discord(request): if settings.DISCORD_CLIENT_ID is None: raise Http404("discord integration is not available") redirect_uri = settings.SITE_ROOT + reverse("hc-add-discord") if "code" in request.GET: code = _get_validated_code(request, "discord") if code is None: return HttpResponseBadRequest() result = requests.post( "https://discordapp.com/api/oauth2/token", { "client_id": settings.DISCORD_CLIENT_ID, "client_secret": settings.DISCORD_CLIENT_SECRET, "code": code, "grant_type": "authorization_code", "redirect_uri": redirect_uri, }, ) doc = result.json() if "access_token" in doc: channel = Channel(kind="discord", project=request.project) channel.user = request.project.owner channel.value = result.text channel.save() channel.assign_all_checks() messages.success(request, "The Discord integration has been added!") else: messages.warning(request, "Something went wrong") return redirect("hc-channels") auth_url = "https://discordapp.com/api/oauth2/authorize?" + urlencode( { "client_id": settings.DISCORD_CLIENT_ID, "scope": "webhook.incoming", "redirect_uri": redirect_uri, "response_type": "code", "state": _prepare_state(request, "discord"), } ) ctx = {"page": "channels", "project": request.project, "authorize_url": auth_url} return render(request, "integrations/add_discord.html", ctx)
def _setup_data(self, kind, value, status="down", email_verified=True): self.check = Check() self.check.status = status self.check.user = self.alice self.check.save() self.channel = Channel(user=self.alice) self.channel.kind = kind self.channel.value = value self.channel.email_verified = email_verified self.channel.save() self.channel.checks.add(self.check) if kind == 'email': self.notify_user = UserToNotify(check_id=self.check, recepient=self.alice) self.notify_user.save()
def add_pushbullet(request): if settings.PUSHBULLET_CLIENT_ID is None: raise Http404("pushbullet integration is not available") if "code" in request.GET: code = _get_validated_code(request, "pushbullet") if code is None: return HttpResponseBadRequest() result = requests.post( "https://api.pushbullet.com/oauth2/token", { "client_id": settings.PUSHBULLET_CLIENT_ID, "client_secret": settings.PUSHBULLET_CLIENT_SECRET, "code": code, "grant_type": "authorization_code" }) doc = result.json() if "access_token" in doc: channel = Channel(kind="pushbullet", project=request.project) channel.user = request.project.owner channel.value = doc["access_token"] channel.save() channel.assign_all_checks() messages.success(request, "The Pushbullet integration has been added!") else: messages.warning(request, "Something went wrong") return redirect("hc-channels") redirect_uri = settings.SITE_ROOT + reverse("hc-add-pushbullet") authorize_url = "https://www.pushbullet.com/authorize?" + urlencode( { "client_id": settings.PUSHBULLET_CLIENT_ID, "redirect_uri": redirect_uri, "response_type": "code", "state": _prepare_state(request, "pushbullet") }) ctx = { "page": "channels", "project": request.project, "authorize_url": authorize_url } return render(request, "integrations/add_pushbullet.html", ctx)
def test_it_checks_check_owner(self): charlies_project = Project.objects.create(owner=self.charlie) url = f"/projects/{charlies_project.code}/integrations/" charlies_channel = Channel(project=charlies_project, kind="email") charlies_channel.email = "*****@*****.**" charlies_channel.save() payload = { "channel": charlies_channel.code, "check-%s" % self.check.code: True } self.client.login(username="******", password="******") r = self.client.post(url, data=payload) # charlies_channel belongs to charlie but self.check does not-- self.assertEqual(r.status_code, 403)
def test_channel_assignment(self): check = Check() check.status = "up" check.user = self.alice check.save() channel = Channel(user=self.alice) channel.save() channel.checks.add(check) count_before = channel.checks.count() resp = self.post({ "api_key": "abc", "channels": "*" }) count_after = channel.checks.count() self.assertEqual((count_after - count_before), 1)
def _make_user(email): username = str(uuid.uuid4())[:30] user = User(username=username, email=email) user.set_unusable_password() user.save() # Ensure a profile gets created Profile.objects.for_user(user) channel = Channel() channel.user = user channel.kind = "email" channel.value = email channel.email_verified = True channel.save() return user
def setUp(self): super().setUp() self.check = Check(project=self.project) self.check.name = "Foo" self.check.status = "down" self.check.last_ping = now() - td(minutes=61) self.check.save() self.channel = Channel(project=self.project) self.channel.kind = "gotify" self.channel.value = json.dumps({ "url": "https://example.org", "token": "abc" }) self.channel.save() self.channel.checks.add(self.check)
def add_pagertree(request, code): project = _get_project_for_user(request, code) if request.method == "POST": form = AddUrlForm(request.POST) if form.is_valid(): channel = Channel(project=project, kind="pagertree") channel.value = form.cleaned_data["value"] channel.save() channel.assign_all_checks() return redirect("hc-p-channels", project.code) else: form = AddUrlForm() ctx = {"page": "channels", "project": project, "form": form} return render(request, "integrations/add_pagertree.html", ctx)
def _make_user(email): username = str(uuid.uuid4())[:30] user = User(username=username, email=email) user.set_unusable_password() user.save() profile = Profile(user=user) profile.save() channel = Channel() channel.user = user channel.kind = "email" channel.value = email channel.email_verified = True channel.save() return user
def test_it_shows_webhook_notification(self): ch = Channel(kind="webhook", project=self.project) ch.value = json.dumps( { "method_down": "GET", "url_down": "foo/$NAME", "body_down": "", "headers_down": {}, } ) ch.save() Notification(owner=self.check, channel=ch, check_status="down").save() self.client.login(username="******", password="******") r = self.client.get(self.url) self.assertContains(r, "Called webhook foo/$NAME", status_code=200)
def add_sms(request): if settings.TWILIO_AUTH is None: raise Http404("sms integration is not available") if request.method == "POST": form = AddSmsForm(request.POST) if form.is_valid(): channel = Channel(user=request.team.user, kind="sms") channel.value = form.cleaned_data["value"] channel.save() channel.assign_all_checks() return redirect("hc-channels") else: form = AddSmsForm() ctx = {"page": "channels", "form": form, "profile": request.team} return render(request, "integrations/add_sms.html", ctx)
def test_it_checks_check_user(self): mallory = User(username="******") mallory.set_password("password") mallory.save() mc = Channel(user=mallory, kind="email") mc.email = "*****@*****.**" mc.save() payload = { "channel": mc.code, "check-%s" % self.check.code: True } self.client.login(username="******", password="******") r = self.client.post("/integrations/", data=payload) # mc belongs to mallorym but self.check does not-- assert r.status_code == 403
def add_webhook(request): if request.method == "POST": form = AddWebhookForm(request.POST) if form.is_valid(): channel = Channel(user=request.team.user, kind="webhook") channel.value = form.get_value() channel.save() channel.assign_all_checks() return redirect("hc-channels") else: form = AddWebhookForm() ctx = { "page": "channels", "form": form, "now": timezone.now().replace(microsecond=0).isoformat() } return render(request, "integrations/add_webhook.html", ctx)
def add_apprise(request): if not settings.APPRISE_ENABLED: raise Http404("apprise integration is not available") if request.method == "POST": form = AddAppriseForm(request.POST) if form.is_valid(): channel = Channel(project=request.project, kind="apprise") channel.value = form.cleaned_data["url"] channel.save() channel.assign_all_checks() messages.success(request, "The Apprise integration has been added!") return redirect("hc-channels") else: form = AddAppriseForm() ctx = {"page": "channels", "project": request.project, "form": form} return render(request, "integrations/add_apprise.html", ctx)
def test_webhook_spec_handles_plain_single_address(self): c = Channel(kind="webhook") c.value = "http://example.org" self.assertEqual( c.down_webhook_spec, { "method": "GET", "url": "http://example.org", "body": "", "headers": {} }, ) self.assertEqual(c.up_webhook_spec, { "method": "GET", "url": "", "body": "", "headers": {} })
def add_pdc(request, state=None): if settings.PD_VENDOR_KEY is None: raise Http404("pagerduty integration is not available") if state and request.user.is_authenticated: if "pd" not in request.session: return HttpResponseBadRequest() session_state = request.session.pop("pd") if session_state != state: return HttpResponseBadRequest() if request.GET.get("error") == "cancelled": messages.warning(request, "PagerDuty setup was cancelled") return redirect("hc-channels") channel = Channel(kind="pd", project=request.project) channel.user = request.project.owner channel.value = json.dumps({ "service_key": request.GET.get("service_key"), "account": request.GET.get("account"), }) channel.save() channel.assign_all_checks() messages.success(request, "The PagerDuty integration has been added!") return redirect("hc-channels") state = _prepare_state(request, "pd") callback = settings.SITE_ROOT + reverse("hc-add-pdc-state", args=[state]) connect_url = "https://connect.pagerduty.com/connect?" + urlencode( { "vendor": settings.PD_VENDOR_KEY, "callback": callback }) ctx = { "page": "channels", "project": request.project, "connect_url": connect_url } return render(request, "integrations/add_pdc.html", ctx)
def setUp(self): super().setUp() self.check = Check(project=self.project) self.check.name = "Foo" self.check.status = "down" self.check.last_ping = now() - td(minutes=61) self.check.save() self.channel = Channel(project=self.project) self.channel.kind = "trello" self.channel.value = json.dumps({ "token": "fake-token", "board_name": "My Board", "list_name": "My List", "list_id": "fake-list-id", }) self.channel.save() self.channel.checks.add(self.check)
def add_email(request, code): project = _get_project_for_user(request, code) if request.method == "POST": form = AddEmailForm(request.POST) if form.is_valid(): channel = Channel(project=project, kind="email") channel.value = json.dumps( { "value": form.cleaned_data["value"], "up": form.cleaned_data["up"], "down": form.cleaned_data["down"], } ) channel.save() channel.assign_all_checks() is_own_email = form.cleaned_data["value"] == request.user.email if is_own_email or not settings.EMAIL_USE_VERIFICATION: # If user is subscribing *their own* address # we can skip the verification step. # Additionally, in self-hosted setting, administator has the # option to disable the email verification step altogether. channel.email_verified = True channel.save() else: channel.send_verify_link() return redirect("hc-p-channels", project.code) else: form = AddEmailForm() ctx = { "page": "channels", "project": project, "use_verification": settings.EMAIL_USE_VERIFICATION, "form": form, } return render(request, "integrations/add_email.html", ctx)
def setUp(self): super().setUp() self.check = Check(project=self.project) self.check.name = "Foobar" self.check.status = "down" self.check.last_ping = now() - td(minutes=61) self.check.save() definition = { "bot_email": "*****@*****.**", "api_key": "fake-key", "mtype": "stream", "to": "general", } self.channel = Channel(project=self.project) self.channel.kind = "zulip" self.channel.value = json.dumps(definition) self.channel.save() self.channel.checks.add(self.check)
def test_webhook_spec_handles_mixed(self): c = Channel(kind="webhook") c.value = json.dumps({ "method_down": "GET", "url_down": "http://example.org", "body_down": "", "headers_down": { "X-Status": "X" }, "method_up": "POST", "url_up": "http://example.org/up/", "body_up": "hello world", "headers_up": { "X-Status": "OK" }, }) self.assertEqual( c.down_webhook_spec, { "method": "GET", "url": "http://example.org", "body": "", "headers": { "X-Status": "X" }, }, ) self.assertEqual( c.up_webhook_spec, { "method": "POST", "url": "http://example.org/up/", "body": "hello world", "headers": { "X-Status": "OK" }, }, )
def test_webhook_spec_handles_plain_post(self): c = Channel(kind="webhook") c.value = "http://example.org\n\nhello world" self.assertEqual( c.down_webhook_spec, { "method": "POST", "url": "http://example.org", "body": "hello world", "headers": {}, }, ) self.assertEqual( c.up_webhook_spec, { "method": "POST", "url": "", "body": "hello world", "headers": {} }, )
def test_webhook_spec_handles_plain_pair(self): c = Channel(kind="webhook") c.value = "http://example.org\nhttp://example.com/up/" self.assertEqual( c.down_webhook_spec, { "method": "GET", "url": "http://example.org", "body": "", "headers": {} }, ) self.assertEqual( c.up_webhook_spec, { "method": "GET", "url": "http://example.com/up/", "body": "", "headers": {}, }, )
def test_it_shows_webhook_post_data(self): ch = Channel(kind="webhook", project=self.project) ch.value = json.dumps({ "method_down": "POST", "url_down": "http://down.example.com", "body_down": "foobar", "headers_down": {}, "method_up": "GET", "url_up": "http://up.example.com", "body_up": "", "headers_up": {}, }) ch.save() self.client.login(username="******", password="******") r = self.client.get("/integrations/") self.assertEqual(r.status_code, 200) # These are inside a modal: self.assertContains(r, "http://down.example.com") self.assertContains(r, "http://up.example.com") self.assertContains(r, "foobar")
def add_webhook(request, code): project = _get_project_for_user(request, code) if request.method == "POST": form = AddWebhookForm(request.POST) if form.is_valid(): channel = Channel(project=project, kind="webhook") channel.value = form.get_value() channel.save() channel.assign_all_checks() return redirect("hc-p-channels", project.code) else: form = AddWebhookForm() ctx = { "page": "channels", "project": project, "form": form, "now": timezone.now().replace(microsecond=0).isoformat(), } return render(request, "integrations/add_webhook.html", ctx)