diff --git a/src/documents/migrations/1063_alter_workflowactionwebhook_url.py b/src/documents/migrations/1063_alter_workflowactionwebhook_url.py new file mode 100644 index 000000000..e24928717 --- /dev/null +++ b/src/documents/migrations/1063_alter_workflowactionwebhook_url.py @@ -0,0 +1,22 @@ +# Generated by Django 5.1.6 on 2025-02-16 16:31 + +from django.db import migrations +from django.db import models + + +class Migration(migrations.Migration): + dependencies = [ + ("documents", "1062_alter_savedviewfilterrule_rule_type"), + ] + + operations = [ + migrations.AlterField( + model_name="workflowactionwebhook", + name="url", + field=models.CharField( + help_text="The destination URL for the notification.", + max_length=256, + verbose_name="webhook url", + ), + ), + ] diff --git a/src/documents/models.py b/src/documents/models.py index 4c644c14c..4f9d3cb0e 100644 --- a/src/documents/models.py +++ b/src/documents/models.py @@ -1203,9 +1203,12 @@ class WorkflowActionEmail(models.Model): class WorkflowActionWebhook(models.Model): - url = models.URLField( + # We dont use the built-in URLField because it is not flexible enough + # validation is handled in the serializer + url = models.CharField( _("webhook url"), null=False, + max_length=256, help_text=_("The destination URL for the notification."), ) diff --git a/src/documents/serialisers.py b/src/documents/serialisers.py index 6a0a1eec1..b62e8dd48 100644 --- a/src/documents/serialisers.py +++ b/src/documents/serialisers.py @@ -1949,6 +1949,10 @@ class WorkflowActionEmailSerializer(serializers.ModelSerializer): class WorkflowActionWebhookSerializer(serializers.ModelSerializer): id = serializers.IntegerField(allow_null=True, required=False) + def validate_url(self, url): + uri_validator(url) + return url + class Meta: model = WorkflowActionWebhook fields = [ diff --git a/src/documents/tests/test_api_workflows.py b/src/documents/tests/test_api_workflows.py index 9a13021c3..40ecaca86 100644 --- a/src/documents/tests/test_api_workflows.py +++ b/src/documents/tests/test_api_workflows.py @@ -588,3 +588,40 @@ class TestApiWorkflows(DirectoriesMixin, APITestCase): content_type="application/json", ) self.assertEqual(response.status_code, status.HTTP_201_CREATED) + + def test_webhook_action_url_validation(self): + """ + GIVEN: + - API request to create a workflow with a notification action + WHEN: + - API is called + THEN: + - Correct HTTP response + """ + response = self.client.post( + self.ENDPOINT, + json.dumps( + { + "name": "Workflow 2", + "order": 1, + "triggers": [ + { + "type": WorkflowTrigger.WorkflowTriggerType.CONSUMPTION, + "sources": [DocumentSource.ApiUpload], + "filter_filename": "*", + }, + ], + "actions": [ + { + "type": WorkflowAction.WorkflowActionType.WEBHOOK, + "webhook": { + "url": "https://examplewithouttld:3000/path", + "include_document": False, + }, + }, + ], + }, + ), + content_type="application/json", + ) + self.assertEqual(response.status_code, status.HTTP_201_CREATED)