예제 #1
0
def add_slack_btn(request):
    code = request.GET.get("code", "")
    if len(code) < 8:
        return HttpResponseBadRequest()

    result = requests.post("https://slack.com/api/oauth.access", {
        "client_id": settings.SLACK_CLIENT_ID,
        "client_secret": settings.SLACK_CLIENT_SECRET,
        "code": code
    })

    doc = result.json()
    if doc.get("ok"):
        channel = Channel()
        channel.user = request.team.user
        channel.kind = "slack"
        channel.value = result.text
        channel.save()
        channel.assign_all_checks()
        messages.success(request, "The Slack integration has been added!")
    else:
        s = doc.get("error")
        messages.warning(request, "Error message from slack: %s" % s)

    return redirect("hc-channels")
class UnsubscribeEmailTestCase(BaseTestCase):

    def setUp(self):
        super(UnsubscribeEmailTestCase, self).setUp()
        self.channel = Channel(user=self.alice, kind="email")
        self.channel.value = "*****@*****.**"
        self.channel.save()

    def test_it_works(self):
        token = self.channel.make_token()
        url = "/integrations/%s/unsub/%s/" % (self.channel.code, token)

        r = self.client.get(url)
        self.assertContains(r, "has been unsubscribed", status_code=200)

        q = Channel.objects.filter(code=self.channel.code)
        self.assertEqual(q.count(), 0)

    def test_it_checks_token(self):
        url = "/integrations/%s/unsub/faketoken/" % self.channel.code

        r = self.client.get(url)
        self.assertContains(r, "link you just used is incorrect",
                            status_code=200)

    def test_it_checks_channel_kind(self):
        self.channel.kind = "webhook"
        self.channel.save()

        token = self.channel.make_token()
        url = "/integrations/%s/unsub/%s/" % (self.channel.code, token)

        r = self.client.get(url)
        self.assertEqual(r.status_code, 400)
예제 #3
0
class ChannelChecksTestCase(BaseTestCase):

    def setUp(self):
        super(ChannelChecksTestCase, self).setUp()
        self.channel = Channel(user=self.alice, kind="email")
        self.channel.value = "*****@*****.**"
        self.channel.save()

    def test_it_works(self):
        url = "/integrations/%s/checks/" % self.channel.code

        self.client.login(username="******", password="******")
        r = self.client.get(url)
        self.assertContains(r, "*****@*****.**", status_code=200)

    def test_it_checks_owner(self):
        mallory = User(username="******", email="*****@*****.**")
        mallory.set_password("password")
        mallory.save()

        # channel does not belong to mallory so this should come back
        # with 403 Forbidden:
        url = "/integrations/%s/checks/" % self.channel.code
        self.client.login(username="******", password="******")
        r = self.client.get(url)
        assert r.status_code == 403

    def test_missing_channel(self):
        # Valid UUID but there is no channel for it:
        url = "/integrations/6837d6ec-fc08-4da5-a67f-08a9ed1ccf62/checks/"

        self.client.login(username="******", password="******")
        r = self.client.get(url)
        assert r.status_code == 404
예제 #4
0
class VerifyEmailTestCase(BaseTestCase):

    def setUp(self):
        super(VerifyEmailTestCase, self).setUp()
        self.channel = Channel(user=self.alice, kind="email")
        self.channel.value = "*****@*****.**"
        self.channel.save()

    def test_it_works(self):
        token = self.channel.make_token()
        url = "/integrations/%s/verify/%s/" % (self.channel.code, token)

        r = self.client.post(url)
        assert r.status_code == 200, r.status_code

        channel = Channel.objects.get(code=self.channel.code)
        assert channel.email_verified

    def test_it_handles_bad_token(self):
        url = "/integrations/%s/verify/bad-token/" % self.channel.code

        r = self.client.post(url)
        assert r.status_code == 200, r.status_code

        channel = Channel.objects.get(code=self.channel.code)
        assert not channel.email_verified

    def test_missing_channel(self):
        # Valid UUID, and even valid token but there is no channel for it:
        code = "6837d6ec-fc08-4da5-a67f-08a9ed1ccf62"
        token = self.channel.make_token()
        url = "/integrations/%s/verify/%s/" % (code, token)

        r = self.client.post(url)
        assert r.status_code == 404
예제 #5
0
def add_telegram(request):
    chat_id, chat_type, chat_name = None, None, None
    qs = request.META["QUERY_STRING"]
    if qs:
        chat_id, chat_type, chat_name = signing.loads(qs, max_age=600)

    if request.method == "POST":
        channel = Channel(user=request.team.user, kind="telegram")
        channel.value = json.dumps({
            "id": chat_id,
            "type": chat_type,
            "name": chat_name
        })
        channel.save()

        channel.assign_all_checks()
        messages.success(request, "The Telegram integration has been added!")
        return redirect("hc-channels")

    ctx = {
        "chat_id": chat_id,
        "chat_type": chat_type,
        "chat_name": chat_name,
        "bot_name": settings.TELEGRAM_BOT_NAME
    }

    return render(request, "integrations/add_telegram.html", ctx)
예제 #6
0
def add_hipchat(request):
    if "installable_url" in request.GET:
        url = request.GET["installable_url"]
        assert url.startswith("https://api.hipchat.com")
        response = requests.get(url)
        if "oauthId" not in response.json():
            messages.warning(request, "Something went wrong!")
            return redirect("hc-channels")

        channel = Channel(kind="hipchat")
        channel.user = request.team.user
        channel.value = response.text
        channel.save()

        channel.refresh_hipchat_access_token()
        channel.assign_all_checks()
        messages.success(request, "The HipChat integration has been added!")
        return redirect("hc-channels")

    install_url = "https://www.hipchat.com/addons/install?" + urlencode({
        "url": settings.SITE_ROOT + reverse("hc-hipchat-capabilities")
    })

    ctx = {
        "page": "channels",
        "install_url": install_url
    }
    return render(request, "integrations/add_hipchat.html", ctx)
예제 #7
0
def add_slack(request):
    if not settings.SLACK_CLIENT_ID and not request.user.is_authenticated:
        return redirect("hc-login")

    if request.method == "POST":
        form = AddUrlForm(request.POST)
        if form.is_valid():
            channel = Channel(user=request.team.user, kind="slack")
            channel.value = form.cleaned_data["value"]
            channel.save()

            channel.assign_all_checks()
            return redirect("hc-channels")
    else:
        form = AddUrlForm()

    ctx = {
        "page": "channels",
        "form": form,
        "slack_client_id": settings.SLACK_CLIENT_ID
    }

    if settings.SLACK_CLIENT_ID:
        ctx["state"] = _prepare_state(request, "slack")

    return render(request, "integrations/add_slack.html", ctx)
예제 #8
0
def add_pushover(request):
    if settings.PUSHOVER_API_TOKEN is None or settings.PUSHOVER_SUBSCRIPTION_URL is None:
        raise Http404("pushover integration is not available")

    if request.method == "POST":
        # Initiate the subscription
        nonce = get_random_string()
        request.session["po_nonce"] = nonce

        failure_url = settings.SITE_ROOT + reverse("hc-channels")
        success_url = settings.SITE_ROOT + reverse("hc-add-pushover") + "?" + urlencode({
            "nonce": nonce,
            "prio": request.POST.get("po_priority", "0"),
        })
        subscription_url = settings.PUSHOVER_SUBSCRIPTION_URL + "?" + urlencode({
            "success": success_url,
            "failure": failure_url,
        })

        return redirect(subscription_url)

    # Handle successful subscriptions
    if "pushover_user_key" in request.GET:
        if "nonce" not in request.GET or "prio" not in request.GET:
            return HttpResponseBadRequest()

        # Validate nonce
        if request.GET["nonce"] != request.session.get("po_nonce"):
            return HttpResponseForbidden()

        # Validate priority
        if request.GET["prio"] not in ("-2", "-1", "0", "1", "2"):
            return HttpResponseBadRequest()

        # All looks well--
        del request.session["po_nonce"]

        if request.GET.get("pushover_unsubscribed") == "1":
            # Unsubscription: delete all Pushover channels for this user
            Channel.objects.filter(user=request.user, kind="po").delete()
            return redirect("hc-channels")
        else:
            # Subscription
            user_key = request.GET["pushover_user_key"]
            priority = int(request.GET["prio"])

            channel = Channel(user=request.team.user, kind="po")
            channel.value = "%s|%d" % (user_key, priority)
            channel.save()
            channel.assign_all_checks()
            return redirect("hc-channels")

    # Show Integration Settings form
    ctx = {
        "page": "channels",
        "po_retry_delay": td(seconds=settings.PUSHOVER_EMERGENCY_RETRY_DELAY),
        "po_expiration": td(seconds=settings.PUSHOVER_EMERGENCY_EXPIRATION),
    }
    return render(request, "integrations/add_pushover.html", ctx)
예제 #9
0
    def test_it_shows_channel_list_with_pushbullet(self):
        self.client.login(username="******", password="******")

        ch = Channel(user=self.alice, kind="pushbullet", value="test-token")
        ch.save()

        r = self.client.get("/admin/api/channel/")
        self.assertContains(r, "Pushbullet")
예제 #10
0
    def test_it_assigns_channels(self):
        channel = Channel(user=self.alice)
        channel.save()

        r = self.post({"api_key": "abc", "channels": "*"})

        self.assertEqual(r.status_code, 201)
        check = Check.objects.get()
        self.assertEqual(check.channel_set.get(), channel)
예제 #11
0
class NotifyTestCase(TestCase):

    def _setup_data(self, channel_kind, channel_value, email_verified=True):
        self.alice = User(username="******")
        self.alice.save()

        self.check = Check()
        self.check.status = "down"
        self.check.save()

        self.channel = Channel(user=self.alice)
        self.channel.kind = channel_kind
        self.channel.value = channel_value
        self.channel.email_verified = email_verified
        self.channel.save()
        self.channel.checks.add(self.check)

    @patch("hc.api.models.requests.get")
    def test_webhook(self, mock_get):
        self._setup_data("webhook", "http://example")
        mock_get.return_value.status_code = 200

        self.channel.notify(self.check)
        mock_get.assert_called_with(u"http://example", timeout=5)

    @patch("hc.api.models.requests.get", side_effect=ReadTimeout)
    def test_webhooks_handle_timeouts(self, mock_get):
        self._setup_data("webhook", "http://example")
        self.channel.notify(self.check)
        assert Notification.objects.count() == 1

    def test_email(self):
        self._setup_data("email", "*****@*****.**")
        self.channel.notify(self.check)
        assert Notification.objects.count() == 1

        # And email should have been sent
        self.assertEqual(len(mail.outbox), 1)

    def test_it_skips_unverified_email(self):
        self._setup_data("email", "*****@*****.**", email_verified=False)
        self.channel.notify(self.check)

        assert Notification.objects.count() == 0
        self.assertEqual(len(mail.outbox), 0)

    @patch("hc.api.models.requests.post")
    def test_pd(self, mock_post):
        self._setup_data("pd", "123")
        mock_post.return_value.status_code = 200

        self.channel.notify(self.check)
        assert Notification.objects.count() == 1

        args, kwargs = mock_post.call_args
        assert "trigger" in kwargs["data"]
예제 #12
0
def add_zendesk(request):
    if settings.ZENDESK_CLIENT_ID is None:
        raise Http404("zendesk integration is not available")

    if request.method == "POST":
        domain = request.POST.get("subdomain")
        request.session["subdomain"] = domain
        redirect_uri = settings.SITE_ROOT + reverse("hc-add-zendesk")
        auth_url = "https://%s.zendesk.com/oauth/authorizations/new?" % domain
        auth_url += urlencode({
            "client_id": settings.ZENDESK_CLIENT_ID,
            "redirect_uri": redirect_uri,
            "response_type": "code",
            "scope": "requests:read requests:write",
            "state": _prepare_state(request, "zendesk")
        })

        return redirect(auth_url)

    if "code" in request.GET:
        code = _get_validated_code(request, "zendesk")
        if code is None:
            return HttpResponseBadRequest()

        domain = request.session.pop("subdomain")
        url = "https://%s.zendesk.com/oauth/tokens" % domain

        redirect_uri = settings.SITE_ROOT + reverse("hc-add-zendesk")
        result = requests.post(url, {
            "client_id": settings.ZENDESK_CLIENT_ID,
            "client_secret": settings.ZENDESK_CLIENT_SECRET,
            "code": code,
            "grant_type": "authorization_code",
            "redirect_uri": redirect_uri,
            "scope": "read"
        })

        doc = result.json()
        if "access_token" in doc:
            doc["subdomain"] = domain

            channel = Channel(kind="zendesk")
            channel.user = request.team.user
            channel.value = json.dumps(doc)
            channel.save()
            channel.assign_all_checks()
            messages.success(request,
                             "The Zendesk integration has been added!")
        else:
            messages.warning(request, "Something went wrong")

        return redirect("hc-channels")

    ctx = {"page": "channels"}
    return render(request, "integrations/add_zendesk.html", ctx)
예제 #13
0
    def test_it_shows_pushover_notifications(self):
        ch = Channel(kind="po", user=self.alice)
        ch.save()

        Notification(owner=self.check, channel=ch, check_status="down").save()

        url = "/checks/%s/log/" % self.check.code

        self.client.login(username="******", password="******")
        r = self.client.get(url)
        self.assertContains(r, "Sent a Pushover notification", status_code=200)
예제 #14
0
    def test_it_shows_webhook_notifications(self):
        ch = Channel(kind="webhook", user=self.alice, value="foo/$NAME")
        ch.save()

        Notification(owner=self.check, channel=ch, check_status="down").save()

        url = "/checks/%s/log/" % self.check.code

        self.client.login(username="******", password="******")
        r = self.client.get(url)
        self.assertContains(r, "Called webhook foo/$NAME", status_code=200)
예제 #15
0
def _make_user(email):
    username = str(uuid.uuid4())[:30]
    user = User(username=username, email=email)
    user.save()

    channel = Channel()
    channel.user = user
    channel.kind = "email"
    channel.value = email
    channel.email_verified = True
    channel.save()

    return user
예제 #16
0
class RemoveChannelTestCase(BaseTestCase):

    def setUp(self):
        super(RemoveChannelTestCase, self).setUp()
        self.channel = Channel(user=self.alice, kind="email")
        self.channel.value = "*****@*****.**"
        self.channel.save()

    def test_it_works(self):
        url = "/integrations/%s/remove/" % self.channel.code

        self.client.login(username="******", password="******")
        r = self.client.post(url)
        self.assertRedirects(r, "/integrations/")

        assert Channel.objects.count() == 0

    def test_team_access_works(self):
        url = "/integrations/%s/remove/" % self.channel.code

        self.client.login(username="******", password="******")
        self.client.post(url)
        assert Channel.objects.count() == 0

    def test_it_handles_bad_uuid(self):
        url = "/integrations/not-uuid/remove/"

        self.client.login(username="******", password="******")
        r = self.client.post(url)
        assert r.status_code == 400

    def test_it_checks_owner(self):
        url = "/integrations/%s/remove/" % self.channel.code

        self.client.login(username="******", password="******")
        r = self.client.post(url)
        assert r.status_code == 403

    def test_it_handles_missing_uuid(self):
        # Valid UUID but there is no channel for it:
        url = "/integrations/6837d6ec-fc08-4da5-a67f-08a9ed1ccf62/remove/"

        self.client.login(username="******", password="******")
        r = self.client.post(url)
        assert r.status_code == 302

    def test_it_rejects_get(self):
        url = "/integrations/%s/remove/" % self.channel.code
        self.client.login(username="******", password="******")
        r = self.client.get(url)
        self.assertEqual(r.status_code, 405)
예제 #17
0
    def test_it_unassigns_channels(self):
        channel = Channel(user=self.alice)
        channel.save()

        self.check.assign_all_channels()

        r = self.post(self.check.code, {
            "api_key": "abc",
            "channels": ""
        })

        self.assertEqual(r.status_code, 200)
        check = Check.objects.get()
        self.assertEqual(check.channel_set.count(), 0)
예제 #18
0
    def test_it_checks_check_user(self):
        charlies_channel = Channel(user=self.charlie, 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("/integrations/", data=payload)

        # mc belongs to charlie but self.check does not--
        assert r.status_code == 403
예제 #19
0
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}
    return render(request, "integrations/add_webhook.html", ctx)
예제 #20
0
def add_victorops(request):
    if request.method == "POST":
        form = AddUrlForm(request.POST)
        if form.is_valid():
            channel = Channel(user=request.team.user, kind="victorops")
            channel.value = form.cleaned_data["value"]
            channel.save()

            channel.assign_all_checks()
            return redirect("hc-channels")
    else:
        form = AddUrlForm()

    ctx = {"page": "channels", "form": form}
    return render(request, "integrations/add_victorops.html", ctx)
예제 #21
0
    def handle(self, *args, **options):

        for user in User.objects.all():
            q = Channel.objects.filter(user=user)
            q = q.filter(kind="email", email_verified=True, value=user.email)
            if q.count() > 0:
                continue

            print("Creating default channel for %s" % user.email)
            channel = Channel(user=user)
            channel.kind = "email"
            channel.value = user.email
            channel.email_verified = True
            channel.save()

            channel.checks.add(*Check.objects.filter(user=user))
예제 #22
0
    def test_it_formats_complex_slack_value(self):
        ch = Channel(kind="slack", project=self.project)
        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(self.channels_url)
        self.assertContains(r, "foo-team", status_code=200)
        self.assertContains(r, "#bar")
예제 #23
0
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)
예제 #24
0
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)
예제 #25
0
    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")
예제 #26
0
    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)
예제 #27
0
class NotifyPdTestCase(BaseTestCase):
    def _setup_data(self, 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 = "pd"
        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_pd(self, mock_post):
        self._setup_data("123")
        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["json"]
        self.assertEqual(payload["event_type"], "trigger")
        self.assertEqual(payload["service_key"], "123")

    @patch("hc.api.transports.requests.request")
    def test_pd_complex(self, mock_post):
        self._setup_data(json.dumps({"service_key": "456"}))
        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["json"]
        self.assertEqual(payload["event_type"], "trigger")
        self.assertEqual(payload["service_key"], "456")

    @override_settings(PD_ENABLED=False)
    def test_it_requires_pd_enabled(self):
        self._setup_data("123")
        self.channel.notify(self.check)

        n = Notification.objects.get()
        self.assertEqual(n.error, "PagerDuty notifications are not enabled.")
예제 #28
0
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)
예제 #29
0
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")
            channel.user = request.team.user
            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",
        "authorize_url": auth_url
    }

    return render(request, "integrations/add_discord.html", ctx)
예제 #30
0
class BounceTestCase(BaseTestCase):

    def setUp(self):
        super(BounceTestCase, self).setUp()

        self.check = Check(project=self.project, status="up")
        self.check.save()

        self.channel = Channel(project=self.project, kind="email")
        self.channel.value = "*****@*****.**"
        self.channel.email_verified = True
        self.channel.save()

        self.n = Notification(owner=self.check, channel=self.channel)
        self.n.save()

    def test_it_works(self):
        url = "/api/v1/notifications/%s/bounce" % self.n.code
        r = self.client.post(url, "foo", content_type="text/plain")
        self.assertEqual(r.status_code, 200)

        self.n.refresh_from_db()
        self.assertEqual(self.n.error, "foo")

        self.channel.refresh_from_db()
        self.assertFalse(self.channel.email_verified)

    def test_it_checks_ttl(self):
        self.n.created = self.n.created - timedelta(minutes=60)
        self.n.save()

        url = "/api/v1/notifications/%s/bounce" % self.n.code
        r = self.client.post(url, "foo", content_type="text/plain")
        self.assertEqual(r.status_code, 403)

    def test_it_handles_long_payload(self):
        url = "/api/v1/notifications/%s/bounce" % self.n.code
        payload = "A" * 500
        r = self.client.post(url, payload, content_type="text/plain")
        self.assertEqual(r.status_code, 200)

    def test_it_handles_missing_notification(self):
        fake_code = "07c2f548-9850-4b27-af5d-6c9dc157ec02"
        url = "/api/v1/notifications/%s/bounce" % fake_code
        r = self.client.post(url, "", content_type="text/plain")
        self.assertEqual(r.status_code, 404)
    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)
예제 #32
0
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
예제 #33
0
    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)
예제 #34
0
class RemoveChannelTestCase(TestCase):

    def setUp(self):
        super(RemoveChannelTestCase, self).setUp()
        self.alice = User(username="******", email="*****@*****.**")
        self.alice.set_password("password")
        self.alice.save()

        self.channel = Channel(user=self.alice, kind="email")
        self.channel.value = "*****@*****.**"
        self.channel.save()

    def test_it_works(self):
        url = "/integrations/%s/remove/" % self.channel.code

        self.client.login(username="******", password="******")
        r = self.client.post(url)
        self.assertRedirects(r, "/integrations/")

        assert Channel.objects.count() == 0

    def test_it_handles_bad_uuid(self):
        url = "/integrations/not-uuid/remove/"

        self.client.login(username="******", password="******")
        r = self.client.post(url)
        assert r.status_code == 400

    def test_it_checks_owner(self):
        url = "/integrations/%s/remove/" % self.channel.code

        mallory = User(username="******", email="*****@*****.**")
        mallory.set_password("password")
        mallory.save()

        self.client.login(username="******", password="******")
        r = self.client.post(url)
        assert r.status_code == 403

    def test_it_handles_missing_uuid(self):
        # Valid UUID but there is no channel for it:
        url = "/integrations/6837d6ec-fc08-4da5-a67f-08a9ed1ccf62/remove/"

        self.client.login(username="******", password="******")
        r = self.client.post(url)
        assert r.status_code == 404
예제 #35
0
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
예제 #36
0
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
예제 #37
0
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)
예제 #38
0
    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)
예제 #39
0
파일: views.py 프로젝트: niti15/heroku
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
예제 #40
0
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)
예제 #41
0
class RemoveChannelTestCase(TestCase):
    def setUp(self):
        super(RemoveChannelTestCase, self).setUp()
        self.alice = User(username="******", email="*****@*****.**")
        self.alice.set_password("password")
        self.alice.save()

        self.channel = Channel(user=self.alice, kind="email")
        self.channel.value = "*****@*****.**"
        self.channel.save()

    def test_it_works(self):
        url = "/integrations/%s/remove/" % self.channel.code

        self.client.login(username="******", password="******")
        r = self.client.post(url)
        self.assertRedirects(r, "/integrations/")

        assert Channel.objects.count() == 0

    def test_it_handles_bad_uuid(self):
        url = "/integrations/not-uuid/remove/"

        self.client.login(username="******", password="******")
        r = self.client.post(url)
        assert r.status_code == 400

    def test_it_checks_owner(self):
        url = "/integrations/%s/remove/" % self.channel.code

        mallory = User(username="******", email="*****@*****.**")
        mallory.set_password("password")
        mallory.save()

        self.client.login(username="******", password="******")
        r = self.client.post(url)
        assert r.status_code == 403

    def test_it_handles_missing_uuid(self):
        # Valid UUID but there is no channel for it:
        url = "/integrations/6837d6ec-fc08-4da5-a67f-08a9ed1ccf62/remove/"

        self.client.login(username="******", password="******")
        r = self.client.post(url)
        assert r.status_code == 404
class NotifyPagertreeTestCase(BaseTestCase):
    def setUp(self):
        super().setUp()

        self.check = Check(project=self.project)
        self.check.status = "down"
        self.check.last_ping = now() - td(minutes=61)
        self.check.save()

        self.channel = Channel(project=self.project)
        self.channel.kind = "pagertree"
        self.channel.value = "123"
        self.channel.save()
        self.channel.checks.add(self.check)

    @patch("hc.api.transports.requests.request")
    def test_it_works(self, mock_post):
        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["json"]
        self.assertEqual(payload["event_type"], "trigger")

    @override_settings(PAGERTREE_ENABLED=False)
    def test_it_requires_pagertree_enabled(self):
        self.channel.notify(self.check)

        n = Notification.objects.get()
        self.assertEqual(n.error, "PagerTree notifications are not enabled.")

    @patch("hc.api.transports.requests.request")
    def test_it_does_not_escape_title(self, mock_post):
        mock_post.return_value.status_code = 200

        self.check.name = "Foo & Bar"
        self.check.save()

        self.channel.notify(self.check)

        args, kwargs = mock_post.call_args
        payload = kwargs["json"]
        self.assertEqual(payload["title"], "Foo & Bar is DOWN")
예제 #43
0
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)
예제 #44
0
def add_opsgenie(request, code):
    project = _get_project_for_user(request, code)

    if request.method == "POST":
        form = AddOpsGenieForm(request.POST)
        if form.is_valid():
            channel = Channel(project=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-p-channels", project.code)
    else:
        form = AddOpsGenieForm()

    ctx = {"page": "channels", "project": project, "form": form}
    return render(request, "integrations/add_opsgenie.html", ctx)
예제 #45
0
    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
예제 #46
0
    def test_it_checks_check_user(self):
        mallory = User(username="******", email="*****@*****.**")
        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
예제 #47
0
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)
예제 #48
0
class SwitchChannelTestCase(BaseTestCase):
    def setUp(self):
        super(SwitchChannelTestCase, self).setUp()
        self.check = Check(user=self.alice)
        self.check.save()

        self.channel = Channel(user=self.alice, kind="email")
        self.channel.value = "*****@*****.**"
        self.channel.save()

        self.url = "/checks/%s/channels/%s/enabled" % (self.check.code,
                                                       self.channel.code)

    def test_it_enables(self):
        self.client.login(username="******", password="******")
        self.client.post(self.url, {"state": "on"})

        self.assertTrue(self.channel in self.check.channel_set.all())

    def test_it_disables(self):
        self.check.channel_set.add(self.channel)

        self.client.login(username="******", password="******")
        self.client.post(self.url, {"state": "off"})

        self.assertFalse(self.channel in self.check.channel_set.all())

    def test_it_checks_ownership(self):
        self.client.login(username="******", password="******")
        r = self.client.post(self.url, {"state": "on"})
        self.assertEqual(r.status_code, 403)

    def test_it_checks_channels_ownership(self):
        cc = Check(user=self.charlie)
        cc.save()

        # Charlie will try to assign Alice's channel to his check:
        self.url = "/checks/%s/channels/%s/enabled" % (cc.code,
                                                       self.channel.code)

        self.client.login(username="******", password="******")
        r = self.client.post(self.url, {"state": "on"})
        self.assertEqual(r.status_code, 403)
예제 #49
0
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)
예제 #50
0
class NotifyPushbulletTestCase(BaseTestCase):
    def setUp(self):
        super().setUp()

        self.check = Check(project=self.project)
        self.check.name = "Foo"
        self.check.status = "up"
        self.check.last_ping = now() - td(minutes=61)
        self.check.save()

        self.channel = Channel(project=self.project)
        self.channel.kind = "pushbullet"
        self.channel.value = "fake-token"
        self.channel.save()
        self.channel.checks.add(self.check)

    @patch("hc.api.transports.requests.request")
    def test_it_works(self, mock_post):
        mock_post.return_value.status_code = 200

        self.channel.notify(self.check)
        assert Notification.objects.count() == 1

        _, kwargs = mock_post.call_args
        self.assertEqual(kwargs["json"]["type"], "note")
        self.assertEqual(
            kwargs["json"]["body"], 'The check "Foo" received a ping and is now UP.'
        )
        self.assertEqual(kwargs["headers"]["Access-Token"], "fake-token")

    @patch("hc.api.transports.requests.request")
    def test_it_escapes_body(self, mock_post):
        mock_post.return_value.status_code = 200
        self.check.name = "Foo & Bar"
        self.check.save()

        self.channel.notify(self.check)

        _, kwargs = mock_post.call_args
        self.assertEqual(
            kwargs["json"]["body"],
            'The check "Foo & Bar" received a ping and is now UP.',
        )
예제 #51
0
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)
예제 #52
0
def add_pushbullet(request):
    if settings.PUSHBULLET_CLIENT_ID is None:
        raise Http404("pushbullet integration is not available")

    if "code" in request.GET:
        code = request.GET.get("code", "")
        if len(code) < 8:
            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")
            channel.user = request.team.user
            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"
    })

    ctx = {
        "page": "channels",
        "authorize_url": authorize_url
    }
    return render(request, "integrations/add_pushbullet.html", ctx)
예제 #53
0
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)
class UnsubscribeEmailTestCase(BaseTestCase):
    def setUp(self):
        super(UnsubscribeEmailTestCase, self).setUp()
        self.channel = Channel(project=self.project, kind="email")
        self.channel.value = "*****@*****.**"
        self.channel.save()

    def test_it_works(self):
        token = self.channel.make_token()
        url = "/integrations/%s/unsub/%s/" % (self.channel.code, token)

        r = self.client.post(url)
        self.assertContains(r, "has been unsubscribed", status_code=200)

        q = Channel.objects.filter(code=self.channel.code)
        self.assertEqual(q.count(), 0)

    def test_it_checks_token(self):
        url = "/integrations/%s/unsub/faketoken/" % self.channel.code

        r = self.client.get(url)
        self.assertContains(r,
                            "link you just used is incorrect",
                            status_code=200)

    def test_it_checks_channel_kind(self):
        self.channel.kind = "webhook"
        self.channel.save()

        token = self.channel.make_token()
        url = "/integrations/%s/unsub/%s/" % (self.channel.code, token)

        r = self.client.get(url)
        self.assertEqual(r.status_code, 400)

    def test_it_serves_confirmation_form(self):
        token = self.channel.make_token()
        url = "/integrations/%s/unsub/%s/" % (self.channel.code, token)

        r = self.client.get(url)
        self.assertContains(r, "Please press the button below")
예제 #55
0
class NotifyLineTestCase(BaseTestCase):
    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 = "linenotify"
        self.channel.value = "fake-token"
        self.channel.save()
        self.channel.checks.add(self.check)

    @patch("hc.api.transports.requests.request")
    def test_it_works(self, mock_post):
        mock_post.return_value.status_code = 200

        self.channel.notify(self.check)
        assert Notification.objects.count() == 1

        args, kwargs = mock_post.call_args
        headers = kwargs["headers"]
        params = kwargs["params"]
        self.assertEqual(headers["Authorization"], "Bearer fake-token")
        self.assertIn("""The check "Foo" is DOWN""", params["message"])

    @patch("hc.api.transports.requests.request")
    def test_it_does_not_escape_message(self, mock_post):
        mock_post.return_value.status_code = 200
        self.check.name = "Foo & Bar"
        self.check.status = "up"
        self.check.save()

        self.channel.notify(self.check)

        args, kwargs = mock_post.call_args
        params = kwargs["params"]
        self.assertEqual(params["message"], 'The check "Foo & Bar" is now UP.')
예제 #56
0
class ChannelChecksTestCase(BaseTestCase):
    def setUp(self):
        super().setUp()
        self.channel = Channel(project=self.project, kind="email")
        self.channel.value = "*****@*****.**"
        self.channel.save()

        Check.objects.create(project=self.project, name="Database Backups")

    def test_it_works(self):
        url = "/integrations/%s/checks/" % self.channel.code

        self.client.login(username="******", password="******")
        r = self.client.get(url)
        self.assertContains(r, "Database Backups")
        self.assertContains(r, "Assign Checks to Integration", 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="******", password="******")
        r = self.client.get(url)
        self.assertContains(r, "Assign Checks to Integration", status_code=200)

    def test_it_checks_owner(self):
        # channel does not belong to mallory so this should come back
        # with 403 Forbidden:
        url = "/integrations/%s/checks/" % self.channel.code
        self.client.login(username="******", password="******")
        r = self.client.get(url)
        self.assertEqual(r.status_code, 404)

    def test_missing_channel(self):
        # Valid UUID but there is no channel for it:
        url = "/integrations/6837d6ec-fc08-4da5-a67f-08a9ed1ccf62/checks/"

        self.client.login(username="******", password="******")
        r = self.client.get(url)
        self.assertEqual(r.status_code, 404)
예제 #57
0
class NotifyMattermostTestCase(BaseTestCase):
    def setUp(self):
        super().setUp()

        self.check = Check(project=self.project)
        self.check.status = "down"
        self.check.last_ping = now() - td(minutes=61)
        self.check.save()

        self.channel = Channel(project=self.project)
        self.channel.kind = "mattermost"
        self.channel.value = "123"
        self.channel.save()
        self.channel.checks.add(self.check)

    @override_settings(MATTERMOST_ENABLED=False)
    def test_it_requires_mattermost_enabled(self):
        self.channel.notify(self.check)

        n = Notification.objects.get()
        self.assertEqual(n.error, "Mattermost notifications are not enabled.")
예제 #58
0
class NotifyTestCase(BaseTestCase):
    def _setup_data(self, 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 = "apprise"
        self.channel.value = value
        self.channel.email_verified = email_verified
        self.channel.save()
        self.channel.checks.add(self.check)

    @patch("apprise.Apprise")
    @override_settings(APPRISE_ENABLED=True)
    def test_apprise_enabled(self, mock_apprise):
        self._setup_data("123")

        mock_aobj = Mock()
        mock_aobj.add.return_value = True
        mock_aobj.notify.return_value = True
        mock_apprise.return_value = mock_aobj
        self.channel.notify(self.check)
        self.assertEqual(Notification.objects.count(), 1)

        self.check.status = "up"
        self.assertEqual(Notification.objects.count(), 1)

    @patch("apprise.Apprise")
    @override_settings(APPRISE_ENABLED=False)
    def test_apprise_disabled(self, mock_apprise):
        self._setup_data("123")

        mock_aobj = Mock()
        mock_aobj.add.return_value = True
        mock_aobj.notify.return_value = True
        mock_apprise.return_value = mock_aobj
        self.channel.notify(self.check)
        self.assertEqual(Notification.objects.count(), 1)
예제 #59
0
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)
예제 #60
0
class ChannelChecksTestCase(BaseTestCase):

    def setUp(self):
        super(ChannelChecksTestCase, self).setUp()
        self.channel = Channel(user=self.alice, kind="email")
        self.channel.value = "*****@*****.**"
        self.channel.save()

    def test_it_works(self):
        url = "/integrations/%s/checks/" % self.channel.code

        self.client.login(username="******", password="******")
        r = self.client.get(url)
        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="******", password="******")
        r = self.client.get(url)
        self.assertContains(r, "Assign Checks to Channel", status_code=200)

    def test_it_checks_owner(self):
        # channel does not belong to mallory so this should come back
        # with 403 Forbidden:
        url = "/integrations/%s/checks/" % self.channel.code
        self.client.login(username="******", password="******")
        r = self.client.get(url)
        assert r.status_code == 403

    def test_missing_channel(self):
        # Valid UUID but there is no channel for it:
        url = "/integrations/6837d6ec-fc08-4da5-a67f-08a9ed1ccf62/checks/"

        self.client.login(username="******", password="******")
        r = self.client.get(url)
        assert r.status_code == 404