forked from GithubBackups/healthchecks
Created an improved interface for arbitrary headers and simplified
header storage.
This commit is contained in:
parent
077bc45b12
commit
5781ddfe4d
@ -174,8 +174,8 @@ class NotifyTestCase(BaseTestCase):
|
||||
@patch("hc.api.transports.requests.request")
|
||||
def test_webhooks_handle_headers(self, mock_request):
|
||||
self._setup_data("webhook", '{"url_down": "http://foo.com", '
|
||||
'"url_up": "", "post_data": "data", "headers": '
|
||||
'"{\\\"Content-Type\\\": \\\"application/json\\\"}"}')
|
||||
'"url_up": "", "post_data": "data", '
|
||||
'"headers": {"Content-Type": "application/json"}}')
|
||||
self.channel.notify(self.check)
|
||||
|
||||
headers = {
|
||||
|
@ -167,7 +167,7 @@ class Webhook(HttpTransport):
|
||||
payload = self.prepare(self.channel.post_data, check)
|
||||
headers = {}
|
||||
if self.channel.headers:
|
||||
headers = json.loads(self.channel.headers)
|
||||
headers = self.channel.headers
|
||||
return self.post(url, data=payload.encode("utf-8"), headers=headers)
|
||||
else:
|
||||
return self.get(url)
|
||||
|
@ -66,10 +66,22 @@ class AddWebhookForm(forms.Form):
|
||||
|
||||
post_data = forms.CharField(max_length=1000, required=False)
|
||||
|
||||
headers = forms.CharField(max_length=1000, required=False)
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.headers = {}
|
||||
if all(k in kwargs for k in ("header_keys", "header_values")):
|
||||
header_keys = kwargs.pop("header_keys")
|
||||
header_values = kwargs.pop("header_values")
|
||||
|
||||
for i, (key, val) in enumerate(zip(header_keys, header_values)):
|
||||
if key:
|
||||
self.headers[key] = val
|
||||
|
||||
super(AddWebhookForm, self).__init__(*args, **kwargs)
|
||||
|
||||
def get_value(self):
|
||||
return json.dumps(self.cleaned_data, sort_keys=True)
|
||||
val = dict(self.cleaned_data)
|
||||
val["headers"] = self.headers
|
||||
return json.dumps(val, sort_keys=True)
|
||||
|
||||
|
||||
phone_validator = RegexValidator(regex='^\+\d{5,15}$',
|
||||
|
@ -18,7 +18,7 @@ class AddWebhookTestCase(BaseTestCase):
|
||||
self.assertRedirects(r, "/integrations/")
|
||||
|
||||
c = Channel.objects.get()
|
||||
self.assertEqual(c.value, '{"headers": "", "post_data": "", "url_down": "http://foo.com", "url_up": "https://bar.com"}')
|
||||
self.assertEqual(c.value, '{"headers": {}, "post_data": "", "url_down": "http://foo.com", "url_up": "https://bar.com"}')
|
||||
|
||||
def test_it_adds_webhook_using_team_access(self):
|
||||
form = {"url_down": "http://foo.com", "url_up": "https://bar.com"}
|
||||
@ -30,7 +30,7 @@ class AddWebhookTestCase(BaseTestCase):
|
||||
|
||||
c = Channel.objects.get()
|
||||
self.assertEqual(c.user, self.alice)
|
||||
self.assertEqual(c.value, '{"headers": "", "post_data": "", "url_down": "http://foo.com", "url_up": "https://bar.com"}')
|
||||
self.assertEqual(c.value, '{"headers": {}, "post_data": "", "url_down": "http://foo.com", "url_up": "https://bar.com"}')
|
||||
|
||||
def test_it_rejects_bad_urls(self):
|
||||
urls = [
|
||||
@ -59,7 +59,7 @@ class AddWebhookTestCase(BaseTestCase):
|
||||
self.client.post(self.url, form)
|
||||
|
||||
c = Channel.objects.get()
|
||||
self.assertEqual(c.value, '{"headers": "", "post_data": "", "url_down": "", "url_up": "http://foo.com"}')
|
||||
self.assertEqual(c.value, '{"headers": {}, "post_data": "", "url_down": "", "url_up": "http://foo.com"}')
|
||||
|
||||
def test_it_adds_post_data(self):
|
||||
form = {"url_down": "http://foo.com", "post_data": "hello"}
|
||||
@ -69,15 +69,15 @@ class AddWebhookTestCase(BaseTestCase):
|
||||
self.assertRedirects(r, "/integrations/")
|
||||
|
||||
c = Channel.objects.get()
|
||||
self.assertEqual(c.value, '{"headers": "", "post_data": "hello", "url_down": "http://foo.com", "url_up": ""}')
|
||||
self.assertEqual(c.value, '{"headers": {}, "post_data": "hello", "url_down": "http://foo.com", "url_up": ""}')
|
||||
|
||||
def test_it_adds_headers(self):
|
||||
form = {"url_down": "http://foo.com", "headers": '{"test": "123"}'}
|
||||
form = {"url_down": "http://foo.com", "header_key[]": ["test", "test2"], "header_value[]": ["123", "abc"]}
|
||||
|
||||
self.client.login(username="alice@example.org", password="password")
|
||||
r = self.client.post(self.url, form)
|
||||
self.assertRedirects(r, "/integrations/")
|
||||
|
||||
c = Channel.objects.get()
|
||||
self.assertEqual(c.value, '{"headers": "{\\\"test\\\": \\\"123\\\"}", "post_data": "", "url_down": "http://foo.com", "url_up": ""}')
|
||||
self.assertEqual(c.value, '{"headers": {"test": "123", "test2": "abc"}, "post_data": "", "url_down": "http://foo.com", "url_up": ""}')
|
||||
|
||||
|
@ -437,7 +437,10 @@ def add_email(request):
|
||||
@login_required
|
||||
def add_webhook(request):
|
||||
if request.method == "POST":
|
||||
form = AddWebhookForm(request.POST)
|
||||
header_keys = request.POST.getlist('header_key[]')
|
||||
header_values = request.POST.getlist('header_value[]')
|
||||
form = AddWebhookForm(request.POST or None,
|
||||
header_keys=header_keys, header_values=header_values)
|
||||
if form.is_valid():
|
||||
channel = Channel(user=request.team.user, kind="webhook")
|
||||
channel.value = form.get_value()
|
||||
|
26
static/js/webhook.js
Normal file
26
static/js/webhook.js
Normal file
@ -0,0 +1,26 @@
|
||||
$(function() {
|
||||
$("#webhook_headers").on("click", ".webhook_header_btn.btn-danger", function(e) {
|
||||
e.preventDefault();
|
||||
$(this).closest("div.row").remove();
|
||||
});
|
||||
|
||||
$("#webhook_headers").on("click", ".webhook_header_btn.btn-info", function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
// Add new header form
|
||||
$("#webhook_headers").append(
|
||||
'<div class="row">\
|
||||
<div class="col-xs-6 col-sm-6" style="padding-right: 0px;">\
|
||||
<input type="text" class="form-control" name="header_key[]" placeholder="Key">\
|
||||
</div>\
|
||||
<div class="col-xs-6 col-sm-6" style="padding-left: 0px;">\
|
||||
<div class="input-group">\
|
||||
<input type="text" class="form-control" name="header_value[]" placeholder="Value">\
|
||||
<span class="input-group-btn">\
|
||||
<button class="webhook_header_btn btn btn-danger" type="button" class="btn">X</button>\
|
||||
</span>\
|
||||
</div>\
|
||||
</div>\
|
||||
</div>');
|
||||
});
|
||||
});
|
@ -106,20 +106,28 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group {{ form.headers.css_classes }}">
|
||||
<label class="col-sm-2 control-label">Custom Headers</label>
|
||||
<div class="col-sm-10">
|
||||
<input
|
||||
<label class="col-sm-2 control-label">Headers</label>
|
||||
<div id="webhook_headers" class="col-xs-12 col-sm-10">
|
||||
<div class="row">
|
||||
<div class="col-xs-6 col-sm-6" style="padding-right: 0px;">
|
||||
<input type="text" class="form-control" name="header_key[]" placeholder="Key">
|
||||
</div>
|
||||
<div class="col-xs-6 col-sm-6" style="padding-left: 0px;">
|
||||
<div class="input-group">
|
||||
<input type="text" class="form-control" name="header_value[]" placeholder="Value">
|
||||
<span class="input-group-btn">
|
||||
<button class="webhook_header_btn btn btn-info" type="button" class="btn">+</button>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<input type="hidden"
|
||||
type="text"
|
||||
class="form-control"
|
||||
name="headers"
|
||||
placeholder='{"Content-Type": "application/json"}'
|
||||
value="{{ form.headers.value|default:"" }}">
|
||||
{% if form.headers.errors %}
|
||||
<div class="help-block">
|
||||
{{ form.headers.errors|join:"" }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
@ -130,3 +138,11 @@
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
{% compress js %}
|
||||
<script src="{% static 'js/jquery-2.1.4.min.js' %}"></script>
|
||||
<script src="{% static 'js/bootstrap.min.js' %}"></script>
|
||||
<script src="{% static 'js/webhook.js' %}"></script>
|
||||
{% endcompress %}
|
||||
{% endblock %}
|
||||
|
Loading…
x
Reference in New Issue
Block a user