Browse Source

Validate channel values. Don't allow ftp addresses, http://localhost addresses, invalid email addresses

pull/109/head
Pēteris Caune 8 years ago
parent
commit
ac4ba079d3
20 changed files with 439 additions and 182 deletions
  1. +6
    -2
      hc/api/models.py
  2. +24
    -5
      hc/front/forms.py
  3. +0
    -58
      hc/front/tests/test_add_channel.py
  4. +49
    -0
      hc/front/tests/test_add_email.py
  5. +38
    -0
      hc/front/tests/test_add_hipchat.py
  6. +31
    -0
      hc/front/tests/test_add_pd.py
  7. +5
    -0
      hc/front/tests/test_add_pushbover.py
  8. +9
    -3
      hc/front/tests/test_add_pushbullet.py
  9. +14
    -52
      hc/front/tests/test_add_slack.py
  10. +64
    -0
      hc/front/tests/test_add_slack_btn.py
  11. +29
    -0
      hc/front/tests/test_add_victorops.py
  12. +25
    -8
      hc/front/tests/test_add_webhook.py
  13. +0
    -1
      hc/front/urls.py
  14. +14
    -0
      hc/front/validators.py
  15. +73
    -32
      hc/front/views.py
  16. +10
    -4
      templates/integrations/add_email.html
  17. +10
    -4
      templates/integrations/add_hipchat.html
  18. +10
    -4
      templates/integrations/add_pd.html
  19. +18
    -5
      templates/integrations/add_slack.html
  20. +10
    -4
      templates/integrations/add_victorops.html

+ 6
- 2
hc/api/models.py View File

@ -21,9 +21,13 @@ STATUSES = (
) )
DEFAULT_TIMEOUT = td(days=1) DEFAULT_TIMEOUT = td(days=1)
DEFAULT_GRACE = td(hours=1) DEFAULT_GRACE = td(hours=1)
CHANNEL_KINDS = (("email", "Email"), ("webhook", "Webhook"),
CHANNEL_KINDS = (("email", "Email"),
("webhook", "Webhook"),
("hipchat", "HipChat"), ("hipchat", "HipChat"),
("slack", "Slack"), ("pd", "PagerDuty"), ("po", "Pushover"),
("slack", "Slack"),
("pd", "PagerDuty"),
("po", "Pushover"),
("pushbullet", "Pushbullet"),
("victorops", "VictorOps")) ("victorops", "VictorOps"))
PO_PRIORITIES = { PO_PRIORITIES = {


+ 24
- 5
hc/front/forms.py View File

@ -1,4 +1,5 @@
from django import forms from django import forms
from hc.front.validators import WebhookValidator
from hc.api.models import Channel from hc.api.models import Channel
@ -7,14 +8,14 @@ class NameTagsForm(forms.Form):
tags = forms.CharField(max_length=500, required=False) tags = forms.CharField(max_length=500, required=False)
def clean_tags(self): def clean_tags(self):
l = []
result = []
for part in self.cleaned_data["tags"].split(" "): for part in self.cleaned_data["tags"].split(" "):
part = part.strip() part = part.strip()
if part != "": if part != "":
l.append(part)
result.append(part)
return " ".join(l)
return " ".join(result)
class TimeoutForm(forms.Form): class TimeoutForm(forms.Form):
@ -33,11 +34,29 @@ class AddChannelForm(forms.ModelForm):
return value.strip() return value.strip()
class AddPdForm(forms.Form):
error_css_class = "has-error"
value = forms.CharField(max_length=20)
class AddEmailForm(forms.Form):
error_css_class = "has-error"
value = forms.EmailField(max_length=100)
class AddUrlForm(forms.Form):
error_css_class = "has-error"
value = forms.URLField(max_length=1000, validators=[WebhookValidator()])
class AddWebhookForm(forms.Form): class AddWebhookForm(forms.Form):
error_css_class = "has-error" error_css_class = "has-error"
value_down = forms.URLField(max_length=1000, required=False)
value_up = forms.URLField(max_length=1000, required=False)
value_down = forms.URLField(max_length=1000, required=False,
validators=[WebhookValidator()])
value_up = forms.URLField(max_length=1000, required=False,
validators=[WebhookValidator()])
def get_value(self): def get_value(self):
return "{value_down}\n{value_up}".format(**self.cleaned_data) return "{value_down}\n{value_up}".format(**self.cleaned_data)

+ 0
- 58
hc/front/tests/test_add_channel.py View File

@ -1,58 +0,0 @@
from django.test.utils import override_settings
from hc.api.models import Channel
from hc.test import BaseTestCase
@override_settings(PUSHOVER_API_TOKEN="token", PUSHOVER_SUBSCRIPTION_URL="url")
class AddChannelTestCase(BaseTestCase):
def test_it_adds_email(self):
url = "/integrations/add/"
form = {"kind": "email", "value": "[email protected]"}
self.client.login(username="[email protected]", password="password")
r = self.client.post(url, form)
self.assertRedirects(r, "/integrations/")
assert Channel.objects.count() == 1
def test_team_access_works(self):
url = "/integrations/add/"
form = {"kind": "email", "value": "[email protected]"}
self.client.login(username="[email protected]", password="password")
self.client.post(url, form)
ch = Channel.objects.get()
# Added by bob, but should belong to alice (bob has team access)
self.assertEqual(ch.user, self.alice)
def test_it_trims_whitespace(self):
""" Leading and trailing whitespace should get trimmed. """
url = "/integrations/add/"
form = {"kind": "email", "value": " [email protected] "}
self.client.login(username="[email protected]", password="password")
self.client.post(url, form)
q = Channel.objects.filter(value="[email protected]")
self.assertEqual(q.count(), 1)
def test_it_rejects_bad_kind(self):
url = "/integrations/add/"
form = {"kind": "dog", "value": "Lassie"}
self.client.login(username="[email protected]", password="password")
r = self.client.post(url, form)
assert r.status_code == 400, r.status_code
def test_instructions_work(self):
self.client.login(username="[email protected]", password="password")
kinds = ("email", "webhook", "pd", "pushover", "hipchat", "victorops")
for frag in kinds:
url = "/integrations/add_%s/" % frag
r = self.client.get(url)
self.assertContains(r, "Integration Settings", status_code=200)

+ 49
- 0
hc/front/tests/test_add_email.py View File

@ -0,0 +1,49 @@
from hc.api.models import Channel
from hc.test import BaseTestCase
class AddPdTestCase(BaseTestCase):
url = "/integrations/add_email/"
def test_instructions_work(self):
self.client.login(username="[email protected]", password="password")
r = self.client.get(self.url)
self.assertContains(r, "Get an email message")
def test_it_creates_channel(self):
form = {"value": "[email protected]"}
self.client.login(username="[email protected]", password="password")
r = self.client.post(self.url, form)
self.assertRedirects(r, "/integrations/")
c = Channel.objects.get()
self.assertEqual(c.kind, "email")
self.assertEqual(c.value, "[email protected]")
self.assertFalse(c.email_verified)
def test_team_access_works(self):
form = {"value": "[email protected]"}
self.client.login(username="[email protected]", password="password")
self.client.post(self.url, form)
ch = Channel.objects.get()
# Added by bob, but should belong to alice (bob has team access)
self.assertEqual(ch.user, self.alice)
def test_it_rejects_bad_email(self):
form = {"value": "not an email address"}
self.client.login(username="[email protected]", password="password")
r = self.client.post(self.url, form)
self.assertContains(r, "Enter a valid email address.")
def test_it_trims_whitespace(self):
form = {"value": " [email protected] "}
self.client.login(username="[email protected]", password="password")
self.client.post(self.url, form)
c = Channel.objects.get()
self.assertEqual(c.value, "[email protected]")

+ 38
- 0
hc/front/tests/test_add_hipchat.py View File

@ -0,0 +1,38 @@
from hc.api.models import Channel
from hc.test import BaseTestCase
class AddHipChatTestCase(BaseTestCase):
url = "/integrations/add_hipchat/"
def test_instructions_work(self):
self.client.login(username="[email protected]", password="password")
r = self.client.get(self.url)
self.assertContains(r, "appropriate HipChat room")
def test_it_works(self):
form = {"value": "http://example.org"}
self.client.login(username="[email protected]", password="password")
r = self.client.post(self.url, form)
self.assertRedirects(r, "/integrations/")
c = Channel.objects.get()
self.assertEqual(c.kind, "hipchat")
self.assertEqual(c.value, "http://example.org")
def test_it_rejects_bad_url(self):
form = {"value": "not an URL"}
self.client.login(username="[email protected]", password="password")
r = self.client.post(self.url, form)
self.assertContains(r, "Enter a valid URL")
def test_it_trims_whitespace(self):
form = {"value": " http://example.org "}
self.client.login(username="[email protected]", password="password")
self.client.post(self.url, form)
c = Channel.objects.get()
self.assertEqual(c.value, "http://example.org")

+ 31
- 0
hc/front/tests/test_add_pd.py View File

@ -0,0 +1,31 @@
from hc.api.models import Channel
from hc.test import BaseTestCase
class AddPdTestCase(BaseTestCase):
url = "/integrations/add_pd/"
def test_instructions_work(self):
self.client.login(username="[email protected]", password="password")
r = self.client.get(self.url)
self.assertContains(r, "incident management system")
def test_it_works(self):
form = {"value": "123456"}
self.client.login(username="[email protected]", password="password")
r = self.client.post(self.url, form)
self.assertRedirects(r, "/integrations/")
c = Channel.objects.get()
self.assertEqual(c.kind, "pd")
self.assertEqual(c.value, "123456")
def test_it_trims_whitespace(self):
form = {"value": " 123456 "}
self.client.login(username="[email protected]", password="password")
self.client.post(self.url, form)
c = Channel.objects.get()
self.assertEqual(c.value, "123456")

+ 5
- 0
hc/front/tests/test_add_pushbover.py View File

@ -5,6 +5,11 @@ from hc.test import BaseTestCase
@override_settings(PUSHOVER_API_TOKEN="token", PUSHOVER_SUBSCRIPTION_URL="url") @override_settings(PUSHOVER_API_TOKEN="token", PUSHOVER_SUBSCRIPTION_URL="url")
class AddPushoverTestCase(BaseTestCase): class AddPushoverTestCase(BaseTestCase):
def test_instructions_work(self):
self.client.login(username="[email protected]", password="password")
r = self.client.get("/integrations/add_pushover/")
self.assertContains(r, "Subscribe with Pushover")
def test_it_adds_channel(self): def test_it_adds_channel(self):
self.client.login(username="[email protected]", password="password") self.client.login(username="[email protected]", password="password")


+ 9
- 3
hc/front/tests/test_add_pushbullet.py View File

@ -8,16 +8,22 @@ from mock import patch
@override_settings(PUSHBULLET_CLIENT_ID="t1", PUSHBULLET_CLIENT_SECRET="s1") @override_settings(PUSHBULLET_CLIENT_ID="t1", PUSHBULLET_CLIENT_SECRET="s1")
class AddPushbulletTestCase(BaseTestCase): class AddPushbulletTestCase(BaseTestCase):
url = "/integrations/add_pushbullet/"
def test_instructions_work(self):
self.client.login(username="[email protected]", password="password")
r = self.client.get(self.url)
self.assertContains(r, "Connect Pushbullet")
def test_it_shows_instructions(self): def test_it_shows_instructions(self):
self.client.login(username="[email protected]", password="password") self.client.login(username="[email protected]", password="password")
r = self.client.get("/integrations/add_pushbullet/")
r = self.client.get(self.url)
self.assertContains(r, "www.pushbullet.com/authorize", status_code=200) self.assertContains(r, "www.pushbullet.com/authorize", status_code=200)
@override_settings(PUSHBULLET_CLIENT_ID=None) @override_settings(PUSHBULLET_CLIENT_ID=None)
def test_it_requires_client_id(self): def test_it_requires_client_id(self):
self.client.login(username="[email protected]", password="password") self.client.login(username="[email protected]", password="password")
r = self.client.get("/integrations/add_pushbullet/")
r = self.client.get(self.url)
self.assertEqual(r.status_code, 404) self.assertEqual(r.status_code, 404)
@patch("hc.front.views.requests.post") @patch("hc.front.views.requests.post")
@ -27,7 +33,7 @@ class AddPushbulletTestCase(BaseTestCase):
mock_post.return_value.text = json.dumps(oauth_response) mock_post.return_value.text = json.dumps(oauth_response)
mock_post.return_value.json.return_value = oauth_response mock_post.return_value.json.return_value = oauth_response
url = "/integrations/add_pushbullet/?code=12345678"
url = self.url + "?code=12345678"
self.client.login(username="[email protected]", password="password") self.client.login(username="[email protected]", password="password")
r = self.client.get(url, follow=True) r = self.client.get(url, follow=True)


+ 14
- 52
hc/front/tests/test_add_slack.py View File

@ -1,70 +1,32 @@
import json
from django.test.utils import override_settings from django.test.utils import override_settings
from hc.api.models import Channel from hc.api.models import Channel
from hc.test import BaseTestCase from hc.test import BaseTestCase
from mock import patch
class AddSlackTestCase(BaseTestCase): class AddSlackTestCase(BaseTestCase):
@override_settings(SLACK_CLIENT_ID=None) @override_settings(SLACK_CLIENT_ID=None)
def test_webhook_instructions_work(self):
def test_instructions_work(self):
self.client.login(username="[email protected]", password="password") self.client.login(username="[email protected]", password="password")
r = self.client.get("/integrations/add_slack/") r = self.client.get("/integrations/add_slack/")
self.assertContains(r, "Integration Settings", status_code=200) self.assertContains(r, "Integration Settings", status_code=200)
@override_settings(SLACK_CLIENT_ID="foo")
def test_slack_button(self):
self.client.login(username="[email protected]", password="password")
r = self.client.get("/integrations/add_slack/")
self.assertContains(r, "slack.com/oauth/authorize", status_code=200)
@override_settings(SLACK_CLIENT_ID="foo")
def test_landing_page(self):
r = self.client.get("/integrations/add_slack/")
self.assertContains(r, "Before adding Slack integration",
status_code=200)
@patch("hc.front.views.requests.post")
def test_it_handles_oauth_response(self, mock_post):
oauth_response = {
"ok": True,
"team_name": "foo",
"incoming_webhook": {
"url": "http://example.org",
"channel": "bar"
}
}
mock_post.return_value.text = json.dumps(oauth_response)
mock_post.return_value.json.return_value = oauth_response
url = "/integrations/add_slack_btn/?code=12345678"
@override_settings(SLACK_CLIENT_ID=None)
def test_it_works(self):
form = {"value": "http://example.org"}
self.client.login(username="[email protected]", password="password") self.client.login(username="[email protected]", password="password")
r = self.client.get(url, follow=True)
r = self.client.post("/integrations/add_slack/", form)
self.assertRedirects(r, "/integrations/") self.assertRedirects(r, "/integrations/")
self.assertContains(r, "The Slack integration has been added!")
ch = Channel.objects.get()
self.assertEqual(ch.slack_team, "foo")
self.assertEqual(ch.slack_channel, "bar")
self.assertEqual(ch.slack_webhook_url, "http://example.org")
@patch("hc.front.views.requests.post")
def test_it_handles_oauth_error(self, mock_post):
oauth_response = {
"ok": False,
"error": "something went wrong"
}
c = Channel.objects.get()
self.assertEqual(c.kind, "slack")
self.assertEqual(c.value, "http://example.org")
mock_post.return_value.text = json.dumps(oauth_response)
mock_post.return_value.json.return_value = oauth_response
url = "/integrations/add_slack_btn/?code=12345678"
@override_settings(SLACK_CLIENT_ID=None)
def test_it_rejects_bad_url(self):
form = {"value": "not an URL"}
self.client.login(username="[email protected]", password="password") self.client.login(username="[email protected]", password="password")
r = self.client.get(url, follow=True)
self.assertRedirects(r, "/integrations/")
self.assertContains(r, "something went wrong")
r = self.client.post("/integrations/add_slack/", form)
self.assertContains(r, "Enter a valid URL")

+ 64
- 0
hc/front/tests/test_add_slack_btn.py View File

@ -0,0 +1,64 @@
import json
from django.test.utils import override_settings
from hc.api.models import Channel
from hc.test import BaseTestCase
from mock import patch
class AddSlackBtnTestCase(BaseTestCase):
@override_settings(SLACK_CLIENT_ID="foo")
def test_instructions_work(self):
r = self.client.get("/integrations/add_slack/")
self.assertContains(r, "Before adding Slack integration",
status_code=200)
@override_settings(SLACK_CLIENT_ID="foo")
def test_slack_button(self):
self.client.login(username="[email protected]", password="password")
r = self.client.get("/integrations/add_slack/")
self.assertContains(r, "slack.com/oauth/authorize", status_code=200)
@patch("hc.front.views.requests.post")
def test_it_handles_oauth_response(self, mock_post):
oauth_response = {
"ok": True,
"team_name": "foo",
"incoming_webhook": {
"url": "http://example.org",
"channel": "bar"
}
}
mock_post.return_value.text = json.dumps(oauth_response)
mock_post.return_value.json.return_value = oauth_response
url = "/integrations/add_slack_btn/?code=12345678"
self.client.login(username="[email protected]", password="password")
r = self.client.get(url, follow=True)
self.assertRedirects(r, "/integrations/")
self.assertContains(r, "The Slack integration has been added!")
ch = Channel.objects.get()
self.assertEqual(ch.slack_team, "foo")
self.assertEqual(ch.slack_channel, "bar")
self.assertEqual(ch.slack_webhook_url, "http://example.org")
@patch("hc.front.views.requests.post")
def test_it_handles_oauth_error(self, mock_post):
oauth_response = {
"ok": False,
"error": "something went wrong"
}
mock_post.return_value.text = json.dumps(oauth_response)
mock_post.return_value.json.return_value = oauth_response
url = "/integrations/add_slack_btn/?code=12345678"
self.client.login(username="[email protected]", password="password")
r = self.client.get(url, follow=True)
self.assertRedirects(r, "/integrations/")
self.assertContains(r, "something went wrong")

+ 29
- 0
hc/front/tests/test_add_victorops.py View File

@ -0,0 +1,29 @@
from hc.api.models import Channel
from hc.test import BaseTestCase
class AddVictorOpsTestCase(BaseTestCase):
url = "/integrations/add_victorops/"
def test_instructions_work(self):
self.client.login(username="[email protected]", password="password")
r = self.client.get(self.url)
self.assertContains(r, "incident management system")
def test_it_works(self):
form = {"value": "http://example.org"}
self.client.login(username="[email protected]", password="password")
r = self.client.post(self.url, form)
self.assertRedirects(r, "/integrations/")
c = Channel.objects.get()
self.assertEqual(c.kind, "victorops")
self.assertEqual(c.value, "http://example.org")
def test_it_rejects_bad_url(self):
form = {"value": "not an URL"}
self.client.login(username="[email protected]", password="password")
r = self.client.post(self.url, form)
self.assertContains(r, "Enter a valid URL")

+ 25
- 8
hc/front/tests/test_add_webhook.py View File

@ -3,12 +3,18 @@ from hc.test import BaseTestCase
class AddWebhookTestCase(BaseTestCase): class AddWebhookTestCase(BaseTestCase):
url = "/integrations/add_webhook/"
def test_instructions_work(self):
self.client.login(username="[email protected]", password="password")
r = self.client.get(self.url)
self.assertContains(r, "Webhooks are a simple way")
def test_it_adds_two_webhook_urls_and_redirects(self): def test_it_adds_two_webhook_urls_and_redirects(self):
form = {"value_down": "http://foo.com", "value_up": "https://bar.com"} form = {"value_down": "http://foo.com", "value_up": "https://bar.com"}
self.client.login(username="[email protected]", password="password") self.client.login(username="[email protected]", password="password")
r = self.client.post("/integrations/add_webhook/", form)
r = self.client.post(self.url, form)
self.assertRedirects(r, "/integrations/") self.assertRedirects(r, "/integrations/")
c = Channel.objects.get() c = Channel.objects.get()
@ -20,26 +26,37 @@ class AddWebhookTestCase(BaseTestCase):
# Logging in as bob, not alice. Bob has team access so this # Logging in as bob, not alice. Bob has team access so this
# should work. # should work.
self.client.login(username="[email protected]", password="password") self.client.login(username="[email protected]", password="password")
self.client.post("/integrations/add_webhook/", form)
self.client.post(self.url, form)
c = Channel.objects.get() c = Channel.objects.get()
self.assertEqual(c.user, self.alice) self.assertEqual(c.user, self.alice)
self.assertEqual(c.value, "http://foo.com\nhttps://bar.com") self.assertEqual(c.value, "http://foo.com\nhttps://bar.com")
def test_it_rejects_non_http_webhook_urls(self):
form = {"value_down": "foo", "value_up": "bar"}
def test_it_rejects_bad_urls(self):
urls = [
# clearly not an URL
"foo",
# FTP addresses not allowed
"ftp://example.org",
# no loopback
"http://localhost:1234/endpoint",
"http://127.0.0.1/endpoint"
]
self.client.login(username="[email protected]", password="password") self.client.login(username="[email protected]", password="password")
r = self.client.post("/integrations/add_webhook/", form)
self.assertContains(r, "Enter a valid URL.")
for url in urls:
form = {"value_down": url, "value_up": ""}
r = self.client.post(self.url, form)
self.assertContains(r, "Enter a valid URL.", msg_prefix=url)
self.assertEqual(Channel.objects.count(), 0)
self.assertEqual(Channel.objects.count(), 0)
def test_it_handles_empty_down_url(self): def test_it_handles_empty_down_url(self):
form = {"value_down": "", "value_up": "http://foo.com"} form = {"value_down": "", "value_up": "http://foo.com"}
self.client.login(username="[email protected]", password="password") self.client.login(username="[email protected]", password="password")
self.client.post("/integrations/add_webhook/", form)
self.client.post(self.url, form)
c = Channel.objects.get() c = Channel.objects.get()
self.assertEqual(c.value, "\nhttp://foo.com") self.assertEqual(c.value, "\nhttp://foo.com")

+ 0
- 1
hc/front/urls.py View File

@ -12,7 +12,6 @@ check_urls = [
channel_urls = [ channel_urls = [
url(r'^$', views.channels, name="hc-channels"), url(r'^$', views.channels, name="hc-channels"),
url(r'^add/$', views.add_channel, name="hc-add-channel"),
url(r'^add_email/$', views.add_email, name="hc-add-email"), url(r'^add_email/$', views.add_email, name="hc-add-email"),
url(r'^add_webhook/$', views.add_webhook, name="hc-add-webhook"), url(r'^add_webhook/$', views.add_webhook, name="hc-add-webhook"),
url(r'^add_pd/$', views.add_pd, name="hc-add-pd"), url(r'^add_pd/$', views.add_pd, name="hc-add-pd"),


+ 14
- 0
hc/front/validators.py View File

@ -0,0 +1,14 @@
from django.core.exceptions import ValidationError
from six.moves.urllib_parse import urlparse
class WebhookValidator(object):
message = "Enter a valid URL."
def __call__(self, value):
parsed = urlparse(value)
if parsed.scheme not in ("http", "https"):
raise ValidationError(message=self.message)
if parsed.hostname in ("127.0.0.1", "localhost"):
raise ValidationError(message=self.message)

+ 73
- 32
hc/front/views.py View File

@ -16,7 +16,7 @@ from django.utils.six.moves.urllib.parse import urlencode
from hc.api.decorators import uuid_or_400 from hc.api.decorators import uuid_or_400
from hc.api.models import DEFAULT_GRACE, DEFAULT_TIMEOUT, Channel, Check, Ping from hc.api.models import DEFAULT_GRACE, DEFAULT_TIMEOUT, Channel, Check, Ping
from hc.front.forms import (AddChannelForm, AddWebhookForm, NameTagsForm, from hc.front.forms import (AddChannelForm, AddWebhookForm, NameTagsForm,
TimeoutForm)
TimeoutForm, AddUrlForm, AddPdForm, AddEmailForm)
# from itertools recipes: # from itertools recipes:
@ -291,29 +291,6 @@ def channels(request):
return render(request, "front/channels.html", ctx) return render(request, "front/channels.html", ctx)
def do_add_channel(request, data):
form = AddChannelForm(data)
if form.is_valid():
channel = form.save(commit=False)
channel.user = request.team.user
channel.save()
channel.assign_all_checks()
if channel.kind == "email":
channel.send_verify_link()
return redirect("hc-channels")
else:
return HttpResponseBadRequest()
@login_required
def add_channel(request):
assert request.method == "POST"
return do_add_channel(request, request.POST)
@login_required @login_required
@uuid_or_400 @uuid_or_400
def channel_checks(request, code): def channel_checks(request, code):
@ -361,7 +338,20 @@ def remove_channel(request, code):
@login_required @login_required
def add_email(request): def add_email(request):
ctx = {"page": "channels"}
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) return render(request, "integrations/add_email.html", ctx)
@ -385,7 +375,19 @@ def add_webhook(request):
@login_required @login_required
def add_pd(request): def add_pd(request):
ctx = {"page": "channels"}
if request.method == "POST":
form = AddPdForm(request.POST)
if form.is_valid():
channel = Channel(user=request.team.user, kind="pd")
channel.value = form.cleaned_data["value"]
channel.save()
channel.assign_all_checks()
return redirect("hc-channels")
else:
form = AddPdForm()
ctx = {"page": "channels", "form": form}
return render(request, "integrations/add_pd.html", ctx) return render(request, "integrations/add_pd.html", ctx)
@ -393,10 +395,24 @@ def add_slack(request):
if not settings.SLACK_CLIENT_ID and not request.user.is_authenticated: if not settings.SLACK_CLIENT_ID and not request.user.is_authenticated:
return redirect("hc-login") 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 = { ctx = {
"page": "channels", "page": "channels",
"form": form,
"slack_client_id": settings.SLACK_CLIENT_ID "slack_client_id": settings.SLACK_CLIENT_ID
} }
return render(request, "integrations/add_slack.html", ctx) return render(request, "integrations/add_slack.html", ctx)
@ -430,7 +446,19 @@ def add_slack_btn(request):
@login_required @login_required
def add_hipchat(request): def add_hipchat(request):
ctx = {"page": "channels"}
if request.method == "POST":
form = AddUrlForm(request.POST)
if form.is_valid():
channel = Channel(user=request.team.user, kind="hipchat")
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_hipchat.html", ctx) return render(request, "integrations/add_hipchat.html", ctx)
@ -526,10 +554,11 @@ def add_pushover(request):
user_key = request.GET["pushover_user_key"] user_key = request.GET["pushover_user_key"]
priority = int(request.GET["prio"]) priority = int(request.GET["prio"])
return do_add_channel(request, {
"kind": "po",
"value": "%s|%d" % (user_key, priority),
})
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 # Show Integration Settings form
ctx = { ctx = {
@ -542,7 +571,19 @@ def add_pushover(request):
@login_required @login_required
def add_victorops(request): def add_victorops(request):
ctx = {"page": "channels"}
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) return render(request, "integrations/add_victorops.html", ctx)


+ 10
- 4
templates/integrations/add_email.html View File

@ -24,10 +24,9 @@
<h2>Integration Settings</h2> <h2>Integration Settings</h2>
<form method="post" class="form-horizontal" action="{% url 'hc-add-channel' %}">
<form method="post" class="form-horizontal" action="{% url 'hc-add-email' %}">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="kind" value="email" />
<div class="form-group">
<div class="form-group {{ form.value.css_classes }}">
<label for="id_email" class="col-sm-2 control-label">Email</label> <label for="id_email" class="col-sm-2 control-label">Email</label>
<div class="col-sm-3"> <div class="col-sm-3">
<input <input
@ -35,7 +34,14 @@
type="email" type="email"
class="form-control" class="form-control"
name="value" name="value"
placeholder="[email protected]">
placeholder="[email protected]"
value="{{ form.value.value|default:"" }}">
{% if form.value.errors %}
<div class="help-block">
{{ form.value.errors|join:"" }}
</div>
{% endif %}
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">


+ 10
- 4
templates/integrations/add_hipchat.html View File

@ -64,10 +64,9 @@
<h2>Integration Settings</h2> <h2>Integration Settings</h2>
<form method="post" class="form-horizontal" action="{% url 'hc-add-channel' %}">
<form method="post" class="form-horizontal" action="{% url 'hc-add-hipchat' %}">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="kind" value="hipchat" />
<div class="form-group">
<div class="form-group {{ form.value.css_classes }}">
<label for="callback-url" class="col-sm-2 control-label">Callback URL</label> <label for="callback-url" class="col-sm-2 control-label">Callback URL</label>
<div class="col-sm-10"> <div class="col-sm-10">
<input <input
@ -75,7 +74,14 @@
type="text" type="text"
class="form-control" class="form-control"
name="value" name="value"
placeholder="">
placeholder="https://"
value="{{ form.value.value|default:"" }}">
{% if form.value.errors %}
<div class="help-block">
{{ form.value.errors|join:"" }}
</div>
{% endif %}
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">


+ 10
- 4
templates/integrations/add_pd.html View File

@ -63,10 +63,9 @@
<h2>Integration Settings</h2> <h2>Integration Settings</h2>
<form method="post" class="form-horizontal" action="{% url 'hc-add-channel' %}">
<form method="post" class="form-horizontal" action="{% url 'hc-add-pd' %}">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="kind" value="pd" />
<div class="form-group">
<div class="form-group {{ form.value.css_classes }}">
<label for="api-key" class="col-sm-2 control-label">API Key</label> <label for="api-key" class="col-sm-2 control-label">API Key</label>
<div class="col-sm-3"> <div class="col-sm-3">
<input <input
@ -74,7 +73,14 @@
type="text" type="text"
class="form-control" class="form-control"
name="value" name="value"
placeholder="">
placeholder=""
value="{{ form.value.value|default:"" }}">
{% if form.value.errors %}
<div class="help-block">
{{ form.value.errors|join:"" }}
</div>
{% endif %}
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">


+ 18
- 5
templates/integrations/add_slack.html View File

@ -156,13 +156,26 @@
<h2>Integration Settings</h2> <h2>Integration Settings</h2>
<form method="post" class="form-horizontal" action="{% url 'hc-add-channel' %}">
<form method="post" class="form-horizontal" action="{% url 'hc-add-slack' %}">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="kind" value="slack" />
<div class="form-group">
<label class="col-sm-2 control-label">Callback URL</label>
<div class="form-group {{ form.value.css_classes }}">
<label for="callback-url" class="col-sm-2 control-label">
Callback URL
</label>
<div class="col-sm-10"> <div class="col-sm-10">
<input type="text" class="form-control" name="value" placeholder="">
<input
id="callback-url"
type="text"
class="form-control"
name="value"
placeholder="https://"
value="{{ form.value.value|default:"" }}">
{% if form.value.errors %}
<div class="help-block">
{{ form.value.errors|join:"" }}
</div>
{% endif %}
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">


+ 10
- 4
templates/integrations/add_victorops.html View File

@ -77,10 +77,9 @@
<h2>Integration Settings</h2> <h2>Integration Settings</h2>
<form method="post" class="form-horizontal" action="{% url 'hc-add-channel' %}">
<form method="post" class="form-horizontal" action="{% url 'hc-add-victorops' %}">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="kind" value="victorops" />
<div class="form-group">
<div class="form-group {{ form.value.css_classes }}">
<label for="post-url" class="col-sm-2 control-label">Post URL</label> <label for="post-url" class="col-sm-2 control-label">Post URL</label>
<div class="col-sm-10"> <div class="col-sm-10">
<input <input
@ -88,7 +87,14 @@
type="text" type="text"
class="form-control" class="form-control"
name="value" name="value"
placeholder="">
placeholder="https://"
value="{{ form.value.value|default:"" }}">
{% if form.value.errors %}
<div class="help-block">
{{ form.value.errors|join:"" }}
</div>
{% endif %}
</div> </div>
</div> </div>
<div class="form-group"> <div class="form-group">


Loading…
Cancel
Save