diff --git a/engine/apps/api/serializers/webhook.py b/engine/apps/api/serializers/webhook.py index 3d1cd32c..72d6a935 100644 --- a/engine/apps/api/serializers/webhook.py +++ b/engine/apps/api/serializers/webhook.py @@ -4,6 +4,7 @@ from rest_framework import serializers from rest_framework.validators import UniqueTogetherValidator from apps.webhooks.models import Webhook, WebhookResponse +from apps.webhooks.models.webhook import WEBHOOK_FIELD_PLACEHOLDER from common.api_helpers.custom_fields import TeamPrimaryKeyRelatedField from common.api_helpers.utils import CurrentOrganizationDefault, CurrentTeamDefault, CurrentUserDefault from common.jinja_templater import apply_jinja_template @@ -66,6 +67,21 @@ class WebhookSerializer(serializers.ModelSerializer): validators = [UniqueTogetherValidator(queryset=Webhook.objects.all(), fields=["name", "organization"])] + def to_representation(self, instance): + result = super().to_representation(instance) + if instance.password: + result["password"] = WEBHOOK_FIELD_PLACEHOLDER + if instance.authorization_header: + result["authorization_header"] = WEBHOOK_FIELD_PLACEHOLDER + return result + + def to_internal_value(self, data): + if data.get("password") == WEBHOOK_FIELD_PLACEHOLDER: + data["password"] = self.instance.password + if data.get("authorization_header") == WEBHOOK_FIELD_PLACEHOLDER: + data["authorization_header"] = self.instance.authorization_header + return super().to_internal_value(data) + def _validate_template_field(self, template): try: apply_jinja_template(template, alert_payload=defaultdict(str), alert_group_id="alert_group_1") diff --git a/engine/apps/api/tests/test_webhooks.py b/engine/apps/api/tests/test_webhooks.py index 31015481..f379425b 100644 --- a/engine/apps/api/tests/test_webhooks.py +++ b/engine/apps/api/tests/test_webhooks.py @@ -10,6 +10,7 @@ from rest_framework.test import APIClient from apps.api.permissions import LegacyAccessControlRole from apps.webhooks.models import Webhook +from apps.webhooks.models.webhook import WEBHOOK_FIELD_PLACEHOLDER TEST_URL = "https://some-url" @@ -44,8 +45,8 @@ def test_get_list_webhooks(webhook_internal_api_setup, make_user_auth_headers): "url": "https://github.com/", "data": '{"name": "{{ alert_payload }}"}', "username": "Chris Vanstras", - "password": "qwerty", - "authorization_header": "auth_token", + "password": WEBHOOK_FIELD_PLACEHOLDER, + "authorization_header": WEBHOOK_FIELD_PLACEHOLDER, "forward_all": False, "headers": None, "http_method": "POST", @@ -85,8 +86,8 @@ def test_get_detail_webhook(webhook_internal_api_setup, make_user_auth_headers): "url": "https://github.com/", "data": '{"name": "{{ alert_payload }}"}', "username": "Chris Vanstras", - "password": "qwerty", - "authorization_header": "auth_token", + "password": WEBHOOK_FIELD_PLACEHOLDER, + "authorization_header": WEBHOOK_FIELD_PLACEHOLDER, "forward_all": False, "headers": None, "http_method": "POST", diff --git a/engine/apps/webhooks/models/webhook.py b/engine/apps/webhooks/models/webhook.py index 50233336..97036576 100644 --- a/engine/apps/webhooks/models/webhook.py +++ b/engine/apps/webhooks/models/webhook.py @@ -23,6 +23,8 @@ from common.jinja_templater import apply_jinja_template from common.jinja_templater.apply_jinja_template import JinjaTemplateError, JinjaTemplateWarning from common.public_primary_keys import generate_public_primary_key, increase_public_primary_key_length +WEBHOOK_FIELD_PLACEHOLDER = "****************" + def generate_public_primary_key_for_webhook(): prefix = "WH" diff --git a/engine/apps/webhooks/tasks/trigger_webhook.py b/engine/apps/webhooks/tasks/trigger_webhook.py index fab0df1a..c0e9e566 100644 --- a/engine/apps/webhooks/tasks/trigger_webhook.py +++ b/engine/apps/webhooks/tasks/trigger_webhook.py @@ -11,6 +11,7 @@ from apps.alerts.models import AlertGroup, AlertGroupLogRecord, EscalationPolicy from apps.base.models import UserNotificationPolicyLogRecord from apps.user_management.models import User from apps.webhooks.models import Webhook, WebhookResponse +from apps.webhooks.models.webhook import WEBHOOK_FIELD_PLACEHOLDER from apps.webhooks.utils import ( InvalidWebhookData, InvalidWebhookHeaders, @@ -94,6 +95,12 @@ def _build_payload(webhook, alert_group, user): return data +def mask_authorization_header(headers): + if "Authorization" in headers: + headers["Authorization"] = WEBHOOK_FIELD_PLACEHOLDER + return headers + + def make_request(webhook, alert_group, data): status = { "url": None, @@ -115,7 +122,8 @@ def make_request(webhook, alert_group, data): if triggered: status["url"] = webhook.build_url(data) request_kwargs = webhook.build_request_kwargs(data, raise_data_errors=True) - status["request_headers"] = json.dumps(request_kwargs.get("headers", {})) + headers = mask_authorization_header(request_kwargs.get("headers", {})) + status["request_headers"] = json.dumps(headers) if "json" in request_kwargs: status["request_data"] = json.dumps(request_kwargs["json"]) else: diff --git a/grafana-plugin/src/containers/OutgoingWebhook2Form/OutgoingWebhook2Form.config.tsx b/grafana-plugin/src/containers/OutgoingWebhook2Form/OutgoingWebhook2Form.config.tsx index 52de59f3..06f98e40 100644 --- a/grafana-plugin/src/containers/OutgoingWebhook2Form/OutgoingWebhook2Form.config.tsx +++ b/grafana-plugin/src/containers/OutgoingWebhook2Form/OutgoingWebhook2Form.config.tsx @@ -161,7 +161,7 @@ export const form: { name: string; fields: FormItem[] } = { }, { name: 'authorization_header', - type: FormItemType.Input, + type: FormItemType.Password, }, { name: 'trigger_template',