From 933d3c967c8147b4a55685b9ef10eb6ed9ff8814 Mon Sep 17 00:00:00 2001 From: Charles Neill <1749665+cneill@users.noreply.github.com> Date: Tue, 29 Oct 2024 18:12:43 -0500 Subject: [PATCH 1/4] Adding some information to webhook payloads --- dojo/notifications/helper.py | 7 +++++++ .../templates/notifications/webhooks/subtemplates/base.tpl | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/dojo/notifications/helper.py b/dojo/notifications/helper.py index ce3f52bf1a5..7700d9c3269 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 (event_title := kwargs.get("title")) is not None: + kwargs.update({"event_title": event_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..ab2cc6a0b9f 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:'' }}" +event_title: "{{ event_title | default_if_none:'' }}" user: {{ user | default_if_none:'' }} {% if url %} url_ui: {{ url|full_url }} From 98de8a7eff69d7a5f2b78cb20caf0421e83d47fc Mon Sep 17 00:00:00 2001 From: Charles Neill <1749665+cneill@users.noreply.github.com> Date: Tue, 29 Oct 2024 18:27:47 -0500 Subject: [PATCH 2/4] Updating webhook docs --- .../integrations/notification_webhooks/_index.md | 14 +++++++------- .../notification_webhooks/engagement_added.md | 5 +++-- .../notification_webhooks/product_added.md | 5 +++-- .../notification_webhooks/product_type_added.md | 5 +++-- .../notification_webhooks/scan_added.md | 5 +++-- .../notification_webhooks/test_added.md | 5 +++-- 6 files changed, 22 insertions(+), 17 deletions(-) diff --git a/docs/content/en/integrations/notification_webhooks/_index.md b/docs/content/en/integrations/notification_webhooks/_index.md index d8fe606cffa..3eb7c8e2e4a 100644 --- a/docs/content/en/integrations/notification_webhooks/_index.md +++ b/docs/content/en/integrations/notification_webhooks/_index.md @@ -9,7 +9,7 @@ Webhooks are HTTP requests coming from the DefectDojo instance towards user-defi ## 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..af6fc218df4 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": "", + "event_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..00aa78e1376 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": "", + "event_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..42b6cde8fc7 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": "", + "event_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..ba3fc866732 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": "", + "event_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..c002df47015 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": "", + "event_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 +``` From 7ae03e01ef21070f8fe02642d2bca87435947239 Mon Sep 17 00:00:00 2001 From: Charles Neill <1749665+cneill@users.noreply.github.com> Date: Tue, 29 Oct 2024 18:41:15 -0500 Subject: [PATCH 3/4] Fixing unit tests --- unittests/test_notifications.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/unittests/test_notifications.py b/unittests/test_notifications.py index 7f5a2b76a4c..d085aed3b33 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.", + "event_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.", + "event_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.", + "event_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.", + "event_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.", + "event_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}", From 6b49c3b03074ec5941fe8b4d4e2dcd4f6165f56f Mon Sep 17 00:00:00 2001 From: Charles Neill <1749665+cneill@users.noreply.github.com> Date: Tue, 29 Oct 2024 19:20:15 -0500 Subject: [PATCH 4/4] Renaming 'event_title' to 'title' --- .../en/integrations/notification_webhooks/_index.md | 2 +- .../notification_webhooks/engagement_added.md | 2 +- .../notification_webhooks/product_added.md | 2 +- .../notification_webhooks/product_type_added.md | 2 +- .../integrations/notification_webhooks/scan_added.md | 2 +- .../integrations/notification_webhooks/test_added.md | 2 +- dojo/notifications/helper.py | 4 ++-- .../notifications/webhooks/subtemplates/base.tpl | 2 +- unittests/test_notifications.py | 10 +++++----- 9 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/content/en/integrations/notification_webhooks/_index.md b/docs/content/en/integrations/notification_webhooks/_index.md index 3eb7c8e2e4a..cbe9294041e 100644 --- a/docs/content/en/integrations/notification_webhooks/_index.md +++ b/docs/content/en/integrations/notification_webhooks/_index.md @@ -5,7 +5,7 @@ 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: diff --git a/docs/content/en/integrations/notification_webhooks/engagement_added.md b/docs/content/en/integrations/notification_webhooks/engagement_added.md index af6fc218df4..36e31586a50 100644 --- a/docs/content/en/integrations/notification_webhooks/engagement_added.md +++ b/docs/content/en/integrations/notification_webhooks/engagement_added.md @@ -13,7 +13,7 @@ X-DefectDojo-Event: engagement_added ```json { "description": "", - "event_title": "", + "title": "", "engagement": { "id": 7, "name": "notif eng", diff --git a/docs/content/en/integrations/notification_webhooks/product_added.md b/docs/content/en/integrations/notification_webhooks/product_added.md index 00aa78e1376..dea3cd27f2a 100644 --- a/docs/content/en/integrations/notification_webhooks/product_added.md +++ b/docs/content/en/integrations/notification_webhooks/product_added.md @@ -13,7 +13,7 @@ X-DefectDojo-Event: product_added ```json { "description": "", - "event_title": "", + "title": "", "product": { "id": 4, "name": "notif prod", 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 42b6cde8fc7..e5db4139297 100644 --- a/docs/content/en/integrations/notification_webhooks/product_type_added.md +++ b/docs/content/en/integrations/notification_webhooks/product_type_added.md @@ -13,7 +13,7 @@ X-DefectDojo-Event: product_type_added ```json { "description": "", - "event_title": "", + "title": "", "product_type": { "id": 4, "name": "notif prod type", diff --git a/docs/content/en/integrations/notification_webhooks/scan_added.md b/docs/content/en/integrations/notification_webhooks/scan_added.md index ba3fc866732..ea1a6bffa3d 100644 --- a/docs/content/en/integrations/notification_webhooks/scan_added.md +++ b/docs/content/en/integrations/notification_webhooks/scan_added.md @@ -20,7 +20,7 @@ X-DefectDojo-Event: scan_added_empty ```json { "description": "", - "event_title": "", + "title": "", "engagement": { "id": 7, "name": "notif eng", diff --git a/docs/content/en/integrations/notification_webhooks/test_added.md b/docs/content/en/integrations/notification_webhooks/test_added.md index c002df47015..bf6d71dc6f5 100644 --- a/docs/content/en/integrations/notification_webhooks/test_added.md +++ b/docs/content/en/integrations/notification_webhooks/test_added.md @@ -13,7 +13,7 @@ X-DefectDojo-Event: test_added ```json { "description": "", - "event_title": "", + "title": "", "engagement": { "id": 7, "name": "notif eng", diff --git a/dojo/notifications/helper.py b/dojo/notifications/helper.py index 7700d9c3269..46d0339dd33 100644 --- a/dojo/notifications/helper.py +++ b/dojo/notifications/helper.py @@ -154,8 +154,8 @@ def create_notification_message(event, user, notification_type, *args, **kwargs) notification_message = None - if (event_title := kwargs.get("title")) is not None: - kwargs.update({"event_title": event_title}) + 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)}) diff --git a/dojo/templates/notifications/webhooks/subtemplates/base.tpl b/dojo/templates/notifications/webhooks/subtemplates/base.tpl index ab2cc6a0b9f..3b6e30da989 100644 --- a/dojo/templates/notifications/webhooks/subtemplates/base.tpl +++ b/dojo/templates/notifications/webhooks/subtemplates/base.tpl @@ -1,7 +1,7 @@ {% load display_tags %} --- description: "{{ description | default_if_none:'' }}" -event_title: "{{ event_title | 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 d085aed3b33..cccdb2e3d6b 100644 --- a/unittests/test_notifications.py +++ b/unittests/test_notifications.py @@ -683,7 +683,7 @@ def test_events_messages(self, mock): self.maxDiff = None self.assertEqual(mock.call_args.kwargs["json"], { "description": "Product Type notif prod type has been created successfully.", - "event_title": "notif prod type", + "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}", @@ -701,7 +701,7 @@ def test_events_messages(self, mock): self.maxDiff = None self.assertEqual(mock.call_args.kwargs["json"], { "description": "Product notif prod has been created successfully.", - "event_title": "notif prod", + "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}", @@ -725,7 +725,7 @@ def test_events_messages(self, mock): self.maxDiff = None self.assertEqual(mock.call_args.kwargs["json"], { "description": "Event engagement_added has occurred.", - "event_title": "Engagement created for "notif prod": notif eng", + "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}", @@ -756,7 +756,7 @@ def test_events_messages(self, mock): self.maxDiff = None self.assertEqual(mock.call_args.kwargs["json"], { "description": "Event test_added has occurred.", - "event_title": "Test created for notif prod: notif eng: notif test (Acunetix Scan)", + "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}", @@ -792,7 +792,7 @@ def test_events_messages(self, mock): self.maxDiff = None self.assertEqual(mock.call_args.kwargs["json"], { "description": "Event scan_added_empty has occurred.", - "event_title": "Created/Updated 0 findings for notif prod: notif eng: notif test (Acunetix Scan)", + "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}",