diff --git a/docs/webhook_events.md b/docs/webhook_events.md index 7e61a5c83d..c4baee6846 100644 --- a/docs/webhook_events.md +++ b/docs/webhook_events.md @@ -15,6 +15,8 @@ Each event will be submitted via HTTP POST to the user provided URL. }, "event_id": "00000000-0000-0000-0000-000000000000", "event_type": "ping", + "instance_id": "00000000-0000-0000-0000-000000000000", + "instance_name": "example", "webhook_id": "00000000-0000-0000-0000-000000000000" } ``` @@ -4016,6 +4018,15 @@ Each event will be submitted via HTTP POST to the user provided URL. "event_type": { "$ref": "#/definitions/EventType" }, + "instance_id": { + "format": "uuid", + "title": "Instance Id", + "type": "string" + }, + "instance_name": { + "title": "Instance Name", + "type": "string" + }, "webhook_id": { "format": "uuid", "title": "Webhook Id", @@ -4025,6 +4036,8 @@ Each event will be submitted via HTTP POST to the user provided URL. "required": [ "event_type", "event", + "instance_id", + "instance_name", "webhook_id" ], "title": "WebhookMessage", diff --git a/src/api-service/__app__/onefuzzlib/events.py b/src/api-service/__app__/onefuzzlib/events.py index efe3220a3d..f89e7dd867 100644 --- a/src/api-service/__app__/onefuzzlib/events.py +++ b/src/api-service/__app__/onefuzzlib/events.py @@ -10,6 +10,7 @@ from onefuzztypes.events import Event, EventMessage, get_event_type +from .azure.creds import get_instance_id, get_instance_name from .webhooks import Webhook EVENTS: Queue = Queue() @@ -35,6 +36,11 @@ def get_events() -> Optional[str]: def send_event(event: Event) -> None: event_type = get_event_type(event) logging.info("sending event: %s - %s", event_type, event) - event_message = EventMessage(event_type=event_type, event=event) + event_message = EventMessage( + event_type=event_type, + event=event, + instance_id=get_instance_id(), + instance_name=get_instance_name(), + ) EVENTS.put(event_message) Webhook.send_event(event_message) diff --git a/src/api-service/__app__/onefuzzlib/webhooks.py b/src/api-service/__app__/onefuzzlib/webhooks.py index 5f3d99a58c..34e4583d9f 100644 --- a/src/api-service/__app__/onefuzzlib/webhooks.py +++ b/src/api-service/__app__/onefuzzlib/webhooks.py @@ -21,6 +21,7 @@ from pydantic import BaseModel from .__version__ import __version__ +from .azure.creds import get_instance_id, get_instance_name from .azure.queue import queue_object from .azure.storage import StorageType from .orm import ORMMixin @@ -169,13 +170,22 @@ def _add_event(self, event_message: EventMessage) -> None: event_id=event_message.event_id, event_type=event_message.event_type, event=event_message.event, + instance_id=event_message.instance_id, + instance_name=event_message.instance_name, ) message.save() message.queue_webhook() def ping(self) -> EventPing: ping = EventPing(ping_id=uuid4()) - self._add_event(EventMessage(event_type=EventType.ping, event=ping)) + self._add_event( + EventMessage( + event_type=EventType.ping, + event=ping, + instance_id=get_instance_id(), + instance_name=get_instance_name(), + ) + ) return ping def send(self, message_log: WebhookMessageLog) -> bool: @@ -213,7 +223,12 @@ def build_message( ) -> Tuple[bytes, Optional[str]]: data = ( WebhookMessage( - webhook_id=webhook_id, event_id=event_id, event_type=event_type, event=event + webhook_id=webhook_id, + event_id=event_id, + event_type=event_type, + event=event, + instance_id=get_instance_id(), + instance_name=get_instance_name(), ) .json(sort_keys=True, exclude_none=True) .encode() diff --git a/src/api-service/tests/test_webhook_hmac.py b/src/api-service/tests/test_webhook_hmac.py index 8298148672..a49d9a3192 100644 --- a/src/api-service/tests/test_webhook_hmac.py +++ b/src/api-service/tests/test_webhook_hmac.py @@ -4,22 +4,32 @@ # Licensed under the MIT License. import unittest +from unittest.mock import MagicMock, patch from uuid import UUID from onefuzztypes.events import EventPing, EventType -from __app__.onefuzzlib.webhooks import build_message - class TestWebhookHmac(unittest.TestCase): - def test_webhook_hmac(self) -> None: + @patch("__app__.onefuzzlib.webhooks.get_instance_id") + @patch("__app__.onefuzzlib.webhooks.get_instance_name") + def test_webhook_hmac(self, mock_name: MagicMock, mock_id: MagicMock) -> None: + mock_name.return_value = "example" + mock_id.return_value = UUID(int=3) + + # late import to enable the patch to function + from __app__.onefuzzlib.webhooks import build_message + webhook_id = UUID(int=0) event_id = UUID(int=1) event_type = EventType.ping event = EventPing(ping_id=UUID(int=2)) data, digest = build_message( - webhook_id=webhook_id, event_id=event_id, event_type=event_type, event=event + webhook_id=webhook_id, + event_id=event_id, + event_type=event_type, + event=event, ) expected = ( @@ -27,16 +37,19 @@ def test_webhook_hmac(self) -> None: b'"event": {"ping_id": "00000000-0000-0000-0000-000000000002"}, ' b'"event_id": "00000000-0000-0000-0000-000000000001", ' b'"event_type": "ping", ' + b'"instance_id": "00000000-0000-0000-0000-000000000003", ' + b'"instance_name": "example", ' b'"webhook_id": "00000000-0000-0000-0000-000000000000"' b"}" ) expected_digest = ( - "3502f83237ce006b7f6cfa40b89c0295009e3ccb0a1e62ce1d689700c2c6e698" - "61c0de81e011495c2ca89fbf99485b841cee257bcfba326a3edc66f39dc1feec" + "2f0610d708d9938dc053200cd2242b4cca4e9bb7227e5e662f28307f57c7fc9b" + "d1ffcab6fff9f409b3fb856db4f358be9078ec0b64874efac2b8f065211e2a14" ) print(repr(expected)) + print(repr(data)) self.assertEqual(data, expected) self.assertEqual(digest, None) diff --git a/src/pytypes/extra/generate-docs.py b/src/pytypes/extra/generate-docs.py index 8787afa06a..1421fdc9ed 100755 --- a/src/pytypes/extra/generate-docs.py +++ b/src/pytypes/extra/generate-docs.py @@ -216,6 +216,8 @@ def main(): event_id=UUID(int=0), event_type=EventType.ping, event=EventPing(ping_id=UUID(int=0)), + instance_id=UUID(int=0), + instance_name="example", ) layer( diff --git a/src/pytypes/onefuzztypes/events.py b/src/pytypes/onefuzztypes/events.py index d843b112cc..2bf5ac2872 100644 --- a/src/pytypes/onefuzztypes/events.py +++ b/src/pytypes/onefuzztypes/events.py @@ -226,3 +226,5 @@ class EventMessage(BaseEvent): event_id: UUID = Field(default_factory=uuid4) event_type: EventType event: Event + instance_id: UUID + instance_name: str