Merge pull request #222 from taigaio/adding-name-to-webhooks-and-logs-counter-to-API
Adding name to webhooks and logs_counter to webhooks APIremotes/origin/enhancement/email-actions
commit
00d94cdeca
|
@ -0,0 +1,20 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import models, migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('webhooks', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='webhook',
|
||||||
|
name='name',
|
||||||
|
field=models.CharField(max_length=250, default='webhook', verbose_name='name'),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,40 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import models, migrations
|
||||||
|
import datetime
|
||||||
|
import django_pgjson.fields
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('webhooks', '0002_webhook_name'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='webhooklog',
|
||||||
|
name='created',
|
||||||
|
field=models.DateTimeField(default=datetime.datetime(2015, 1, 22, 10, 21, 17, 188643), auto_now_add=True),
|
||||||
|
preserve_default=False,
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='webhooklog',
|
||||||
|
name='duration',
|
||||||
|
field=models.FloatField(default=0, verbose_name='Duration'),
|
||||||
|
preserve_default=True,
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='webhooklog',
|
||||||
|
name='request_headers',
|
||||||
|
field=django_pgjson.fields.JsonField(default={}, verbose_name='Request headers'),
|
||||||
|
preserve_default=True,
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='webhooklog',
|
||||||
|
name='response_headers',
|
||||||
|
field=django_pgjson.fields.JsonField(default={}, verbose_name='Response headers'),
|
||||||
|
preserve_default=True,
|
||||||
|
),
|
||||||
|
]
|
|
@ -23,6 +23,8 @@ from django_pgjson.fields import JsonField
|
||||||
class Webhook(models.Model):
|
class Webhook(models.Model):
|
||||||
project = models.ForeignKey("projects.Project", null=False, blank=False,
|
project = models.ForeignKey("projects.Project", null=False, blank=False,
|
||||||
related_name="webhooks")
|
related_name="webhooks")
|
||||||
|
name = models.CharField(max_length=250, null=False, blank=False,
|
||||||
|
verbose_name=_("name"))
|
||||||
url = models.URLField(null=False, blank=False, verbose_name=_("URL"))
|
url = models.URLField(null=False, blank=False, verbose_name=_("URL"))
|
||||||
key = models.TextField(null=False, blank=False, verbose_name=_("secret key"))
|
key = models.TextField(null=False, blank=False, verbose_name=_("secret key"))
|
||||||
|
|
||||||
|
@ -33,4 +35,8 @@ class WebhookLog(models.Model):
|
||||||
url = models.URLField(null=False, blank=False, verbose_name=_("URL"))
|
url = models.URLField(null=False, blank=False, verbose_name=_("URL"))
|
||||||
status = models.IntegerField(null=False, blank=False, verbose_name=_("Status code"))
|
status = models.IntegerField(null=False, blank=False, verbose_name=_("Status code"))
|
||||||
request_data = JsonField(null=False, blank=False, verbose_name=_("Request data"))
|
request_data = JsonField(null=False, blank=False, verbose_name=_("Request data"))
|
||||||
|
request_headers = JsonField(null=False, blank=False, verbose_name=_("Request headers"), default={})
|
||||||
response_data = models.TextField(null=False, blank=False, verbose_name=_("Response data"))
|
response_data = models.TextField(null=False, blank=False, verbose_name=_("Response data"))
|
||||||
|
response_headers = JsonField(null=False, blank=False, verbose_name=_("Response headers"), default={})
|
||||||
|
duration = models.FloatField(null=False, blank=False, verbose_name=_("Duration"), default=0)
|
||||||
|
created = models.DateTimeField(auto_now_add=True)
|
||||||
|
|
|
@ -34,9 +34,14 @@ class HistoryDiffField(serializers.Field):
|
||||||
|
|
||||||
|
|
||||||
class WebhookSerializer(serializers.ModelSerializer):
|
class WebhookSerializer(serializers.ModelSerializer):
|
||||||
|
logs_counter = serializers.SerializerMethodField("get_logs_counter")
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Webhook
|
model = Webhook
|
||||||
|
|
||||||
|
def get_logs_counter(self, obj):
|
||||||
|
return obj.logs.count()
|
||||||
|
|
||||||
|
|
||||||
class WebhookLogSerializer(serializers.ModelSerializer):
|
class WebhookLogSerializer(serializers.ModelSerializer):
|
||||||
request_data = JsonField()
|
request_data = JsonField()
|
||||||
|
|
||||||
|
|
|
@ -62,17 +62,29 @@ def _send_request(webhook_id, url, key, data):
|
||||||
signature = _generate_signature(serialized_data, key)
|
signature = _generate_signature(serialized_data, key)
|
||||||
headers = {
|
headers = {
|
||||||
"X-TAIGA-WEBHOOK-SIGNATURE": signature,
|
"X-TAIGA-WEBHOOK-SIGNATURE": signature,
|
||||||
|
"Content-Type": "application/json"
|
||||||
}
|
}
|
||||||
|
request = requests.Request('POST', url, data=serialized_data, headers=headers)
|
||||||
|
prepared_request = request.prepare()
|
||||||
|
|
||||||
|
session = requests.Session()
|
||||||
try:
|
try:
|
||||||
response = requests.post(url, data=serialized_data, headers=headers)
|
response = session.send(prepared_request)
|
||||||
WebhookLog.objects.create(webhook_id=webhook_id, url=url,
|
WebhookLog.objects.create(webhook_id=webhook_id, url=url,
|
||||||
status=response.status_code,
|
status=response.status_code,
|
||||||
request_data=data,
|
request_data=data,
|
||||||
response_data=response.content)
|
request_headers=dict(prepared_request.headers),
|
||||||
except RequestException:
|
response_data=response.content,
|
||||||
|
response_headers=dict(response.headers),
|
||||||
|
duration=response.elapsed.total_seconds())
|
||||||
|
except RequestException as e:
|
||||||
WebhookLog.objects.create(webhook_id=webhook_id, url=url, status=0,
|
WebhookLog.objects.create(webhook_id=webhook_id, url=url, status=0,
|
||||||
request_data=data,
|
request_data=data,
|
||||||
response_data="error-in-request")
|
request_headers=dict(prepared_request.headers),
|
||||||
|
response_data="error-in-request: {}".format(str(e)),
|
||||||
|
response_headers={},
|
||||||
|
duration=0)
|
||||||
|
session.close()
|
||||||
|
|
||||||
ids = [webhook_log.id for webhook_log in WebhookLog.objects.filter(webhook_id=webhook_id).order_by("-id")[10:]]
|
ids = [webhook_log.id for webhook_log in WebhookLog.objects.filter(webhook_id=webhook_id).order_by("-id")[10:]]
|
||||||
WebhookLog.objects.filter(id__in=ids).delete()
|
WebhookLog.objects.filter(id__in=ids).delete()
|
||||||
|
|
|
@ -205,6 +205,7 @@ class WebhookFactory(Factory):
|
||||||
project = factory.SubFactory("tests.factories.ProjectFactory")
|
project = factory.SubFactory("tests.factories.ProjectFactory")
|
||||||
url = "http://localhost:8080/test"
|
url = "http://localhost:8080/test"
|
||||||
key = "factory-key"
|
key = "factory-key"
|
||||||
|
name = "Factory-name"
|
||||||
|
|
||||||
|
|
||||||
class WebhookLogFactory(Factory):
|
class WebhookLogFactory(Factory):
|
||||||
|
|
|
@ -137,6 +137,7 @@ def test_webhook_create(client, data):
|
||||||
]
|
]
|
||||||
|
|
||||||
create_data = json.dumps({
|
create_data = json.dumps({
|
||||||
|
"name": "Test",
|
||||||
"url": "http://test.com",
|
"url": "http://test.com",
|
||||||
"key": "test",
|
"key": "test",
|
||||||
"project": data.project1.pk,
|
"project": data.project1.pk,
|
||||||
|
@ -145,6 +146,7 @@ def test_webhook_create(client, data):
|
||||||
assert results == [401, 403, 201]
|
assert results == [401, 403, 201]
|
||||||
|
|
||||||
create_data = json.dumps({
|
create_data = json.dumps({
|
||||||
|
"name": "Test",
|
||||||
"url": "http://test.com",
|
"url": "http://test.com",
|
||||||
"key": "test",
|
"key": "test",
|
||||||
"project": data.project2.pk,
|
"project": data.project2.pk,
|
||||||
|
|
Loading…
Reference in New Issue