diff --git a/docs/content/en/integrations/notification_webhooks/_index.md b/docs/content/en/integrations/notification_webhooks/_index.md index d8fe606cffa..cbe9294041e 100644 --- a/docs/content/en/integrations/notification_webhooks/_index.md +++ b/docs/content/en/integrations/notification_webhooks/_index.md @@ -5,11 +5,11 @@ weight: 7 chapter: true --- -Webhooks are HTTP requests coming from the DefectDojo instance towards user-defined webserver which expects this kind of incoming traffic. +Webhooks are HTTP requests coming from the DefectDojo instance towards a user-defined webserver which expects this kind of incoming traffic. ## Transition graph: -It is not unusual that in some cases webhook can not be performed. It is usually connected to network issues, server misconfiguration, or running upgrades on the server. DefectDojo needs to react to these outages. It might temporarily or permanently disable related endpoints. The following graph shows how it might change the status of the webhook definition based on HTTP responses (or manual user interaction). +It is not unusual that in some cases a webhook can not be delivered. It is usually connected to network issues, server misconfiguration, or running upgrades on the server. DefectDojo needs to react to these outages. It might temporarily or permanently disable related endpoints. The following graph shows how it might change the status of the webhook definition based on HTTP responses (or manual user interaction). ```mermaid flowchart TD @@ -53,7 +53,7 @@ Notes: The body of each request is JSON which contains data about related events like names and IDs of affected elements. Examples of bodies are on pages related to each event (see below). -Each request contains the following headers. They might be useful for better handling of events by server this process events. +Each request contains the following headers. They might be useful for better handling of events by the server receiving them. ```yaml User-Agent: DefectDojo- @@ -62,18 +62,18 @@ X-DefectDojo-Instance: ``` ## Disclaimer -This functionality is new and in experimental mode. This means Functionality might generate breaking changes in following DefectDojo releases and might not be considered final. +This functionality is new and in experimental mode. This means functionality might generate breaking changes in following DefectDojo releases and might not be considered final. -However, the community is open to feedback to make this functionality better and transform it stable as soon as possible. +However, the community is open to feedback to make this functionality better and get it stable as soon as possible. ## Roadmap -There are a couple of known issues that are expected to be implemented as soon as core functionality is considered ready. +There are a couple of known issues that are expected to be resolved as soon as core functionality is considered ready. - Support events - Not only adding products, product types, engagements, tests, or upload of new scans but also events around SLA -- User webhook - right now only admins can define webhooks; in the future also users will be able to define their own +- User webhook - right now only admins can define webhooks; in the future, users will also be able to define their own - Improvement in UI - add filtering and pagination of webhook endpoints ## Events - \ No newline at end of file + diff --git a/docs/content/en/integrations/notification_webhooks/engagement_added.md b/docs/content/en/integrations/notification_webhooks/engagement_added.md index 64fd7746ec2..36e31586a50 100644 --- a/docs/content/en/integrations/notification_webhooks/engagement_added.md +++ b/docs/content/en/integrations/notification_webhooks/engagement_added.md @@ -12,7 +12,8 @@ X-DefectDojo-Event: engagement_added ## Event HTTP body ```json { - "description": null, + "description": "", + "title": "", "engagement": { "id": 7, "name": "notif eng", @@ -35,4 +36,4 @@ X-DefectDojo-Event: engagement_added "url_ui": "http://localhost:8080/engagement/7", "user": null } -``` \ No newline at end of file +``` diff --git a/docs/content/en/integrations/notification_webhooks/product_added.md b/docs/content/en/integrations/notification_webhooks/product_added.md index 2d90a6a681f..dea3cd27f2a 100644 --- a/docs/content/en/integrations/notification_webhooks/product_added.md +++ b/docs/content/en/integrations/notification_webhooks/product_added.md @@ -12,7 +12,8 @@ X-DefectDojo-Event: product_added ## Event HTTP body ```json { - "description": null, + "description": "", + "title": "", "product": { "id": 4, "name": "notif prod", @@ -29,4 +30,4 @@ X-DefectDojo-Event: product_added "url_ui": "http://localhost:8080/product/4", "user": null } -``` \ No newline at end of file +``` diff --git a/docs/content/en/integrations/notification_webhooks/product_type_added.md b/docs/content/en/integrations/notification_webhooks/product_type_added.md index 1171f513831..e5db4139297 100644 --- a/docs/content/en/integrations/notification_webhooks/product_type_added.md +++ b/docs/content/en/integrations/notification_webhooks/product_type_added.md @@ -12,7 +12,8 @@ X-DefectDojo-Event: product_type_added ## Event HTTP body ```json { - "description": null, + "description": "", + "title": "", "product_type": { "id": 4, "name": "notif prod type", @@ -23,4 +24,4 @@ X-DefectDojo-Event: product_type_added "url_ui": "http://localhost:8080/product/type/4", "user": null } -``` \ No newline at end of file +``` diff --git a/docs/content/en/integrations/notification_webhooks/scan_added.md b/docs/content/en/integrations/notification_webhooks/scan_added.md index 27a40e6cab1..ea1a6bffa3d 100644 --- a/docs/content/en/integrations/notification_webhooks/scan_added.md +++ b/docs/content/en/integrations/notification_webhooks/scan_added.md @@ -19,7 +19,8 @@ X-DefectDojo-Event: scan_added_empty ## Event HTTP body ```json { - "description": null, + "description": "", + "title": "", "engagement": { "id": 7, "name": "notif eng", @@ -87,4 +88,4 @@ X-DefectDojo-Event: scan_added_empty "url_ui": "http://localhost:8080/test/90", "user": null } -``` \ No newline at end of file +``` diff --git a/docs/content/en/integrations/notification_webhooks/test_added.md b/docs/content/en/integrations/notification_webhooks/test_added.md index 8614a80e0a6..bf6d71dc6f5 100644 --- a/docs/content/en/integrations/notification_webhooks/test_added.md +++ b/docs/content/en/integrations/notification_webhooks/test_added.md @@ -12,7 +12,8 @@ X-DefectDojo-Event: test_added ## Event HTTP body ```json { - "description": null, + "description": "", + "title": "", "engagement": { "id": 7, "name": "notif eng", @@ -41,4 +42,4 @@ X-DefectDojo-Event: test_added "url_ui": "http://localhost:8080/test/90", "user": null } -``` \ No newline at end of file +``` diff --git a/dojo/notifications/helper.py b/dojo/notifications/helper.py index ce3f52bf1a5..46d0339dd33 100644 --- a/dojo/notifications/helper.py +++ b/dojo/notifications/helper.py @@ -153,6 +153,13 @@ def create_notification_message(event, user, notification_type, *args, **kwargs) kwargs.update({"user": user}) notification_message = None + + if (title := kwargs.get("title")) is not None: + kwargs.update({"title": title}) + + if kwargs.get("description") is None: + kwargs.update({"description": create_description(event, *args, **kwargs)}) + try: notification_message = render_to_string(template, kwargs) logger.debug("Rendering from the template %s", template) diff --git a/dojo/templates/notifications/webhooks/subtemplates/base.tpl b/dojo/templates/notifications/webhooks/subtemplates/base.tpl index 44946cd8dd3..3b6e30da989 100644 --- a/dojo/templates/notifications/webhooks/subtemplates/base.tpl +++ b/dojo/templates/notifications/webhooks/subtemplates/base.tpl @@ -1,6 +1,7 @@ {% load display_tags %} --- -description: {{ description | default_if_none:'' }} +description: "{{ description | default_if_none:'' }}" +title: "{{ title | default_if_none:'' }}" user: {{ user | default_if_none:'' }} {% if url %} url_ui: {{ url|full_url }} diff --git a/unittests/test_notifications.py b/unittests/test_notifications.py index 7f5a2b76a4c..cccdb2e3d6b 100644 --- a/unittests/test_notifications.py +++ b/unittests/test_notifications.py @@ -680,8 +680,10 @@ def test_events_messages(self, mock): with self.subTest("product_type_added"): prod_type = Product_Type.objects.create(name="notif prod type") self.assertEqual(mock.call_args.kwargs["headers"]["X-DefectDojo-Event"], "product_type_added") + self.maxDiff = None self.assertEqual(mock.call_args.kwargs["json"], { - "description": None, + "description": "Product Type notif prod type has been created successfully.", + "title": "notif prod type", "user": None, "url_api": f"http://localhost:8080/api/v2/product_types/{prod_type.pk}/", "url_ui": f"http://localhost:8080/product/type/{prod_type.pk}", @@ -696,8 +698,10 @@ def test_events_messages(self, mock): with self.subTest("product_added"): prod = Product.objects.create(name="notif prod", prod_type=prod_type) self.assertEqual(mock.call_args.kwargs["headers"]["X-DefectDojo-Event"], "product_added") + self.maxDiff = None self.assertEqual(mock.call_args.kwargs["json"], { - "description": None, + "description": "Product notif prod has been created successfully.", + "title": "notif prod", "user": None, "url_api": f"http://localhost:8080/api/v2/products/{prod.pk}/", "url_ui": f"http://localhost:8080/product/{prod.pk}", @@ -718,8 +722,10 @@ def test_events_messages(self, mock): with self.subTest("engagement_added"): eng = Engagement.objects.create(name="notif eng", product=prod, target_start=timezone.now(), target_end=timezone.now()) self.assertEqual(mock.call_args.kwargs["headers"]["X-DefectDojo-Event"], "engagement_added") + self.maxDiff = None self.assertEqual(mock.call_args.kwargs["json"], { - "description": None, + "description": "Event engagement_added has occurred.", + "title": "Engagement created for "notif prod": notif eng", "user": None, "url_api": f"http://localhost:8080/api/v2/engagements/{eng.pk}/", "url_ui": f"http://localhost:8080/engagement/{eng.pk}", @@ -747,8 +753,10 @@ def test_events_messages(self, mock): test = Test.objects.create(title="notif test", engagement=eng, target_start=timezone.now(), target_end=timezone.now(), test_type_id=Test_Type.objects.first().id) notifications_helper.notify_test_created(test) self.assertEqual(mock.call_args.kwargs["headers"]["X-DefectDojo-Event"], "test_added") + self.maxDiff = None self.assertEqual(mock.call_args.kwargs["json"], { - "description": None, + "description": "Event test_added has occurred.", + "title": "Test created for notif prod: notif eng: notif test (Acunetix Scan)", "user": None, "url_api": f"http://localhost:8080/api/v2/tests/{test.pk}/", "url_ui": f"http://localhost:8080/test/{test.pk}", @@ -781,8 +789,10 @@ def test_events_messages(self, mock): with self.subTest("scan_added_empty"): notifications_helper.notify_scan_added(test, updated_count=0) self.assertEqual(mock.call_args.kwargs["headers"]["X-DefectDojo-Event"], "scan_added_empty") + self.maxDiff = None self.assertEqual(mock.call_args.kwargs["json"], { - "description": None, + "description": "Event scan_added_empty has occurred.", + "title": "Created/Updated 0 findings for notif prod: notif eng: notif test (Acunetix Scan)", "user": None, "url_api": f"http://localhost:8080/api/v2/tests/{test.pk}/", "url_ui": f"http://localhost:8080/test/{test.pk}",