commit
8a528c4b2c
4 changed files with 59 additions and 5 deletions
|
|
@ -77,6 +77,7 @@ class InboundEmailWebhookView(AlertChannelDefiningMixin, APIView):
|
|||
integration_token = self.get_integration_token_from_request(request)
|
||||
if integration_token is None:
|
||||
return HttpResponse(status=status.HTTP_400_BAD_REQUEST)
|
||||
request.inbound_email_integration_token = integration_token # used in RequestTimeLoggingMiddleware
|
||||
return super().dispatch(request, alert_channel_key=integration_token)
|
||||
|
||||
def post(self, request):
|
||||
|
|
@ -138,14 +139,15 @@ class InboundEmailWebhookView(AlertChannelDefiningMixin, APIView):
|
|||
try:
|
||||
view.run_validators(self.request)
|
||||
events = view.parse_events(self.request)
|
||||
except (AnymailWebhookValidationFailure, AnymailAPIError) as e:
|
||||
logger.info(f"inbound email webhook validation failed for ESP {esp}: {e}")
|
||||
except (AnymailWebhookValidationFailure, AnymailAPIError):
|
||||
continue
|
||||
|
||||
messages = [event.message for event in events if isinstance(event, AnymailInboundEvent)]
|
||||
if messages:
|
||||
logger.info(f"Received inbound email message from ESP: {esp}")
|
||||
return messages[0]
|
||||
|
||||
logger.error("Failed to parse inbound email message")
|
||||
return None
|
||||
|
||||
def check_inbound_email_settings_set(self):
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
from rest_framework import serializers
|
||||
|
||||
from apps.alerts.models import AlertGroup, ResolutionNote
|
||||
from apps.user_management.models import ServiceAccountUser
|
||||
from common.api_helpers.custom_fields import OrganizationFilteredPrimaryKeyRelatedField, UserIdField
|
||||
from common.api_helpers.exceptions import BadRequest
|
||||
from common.api_helpers.mixins import EagerLoadingMixin
|
||||
|
|
@ -34,8 +35,9 @@ class ResolutionNoteSerializer(EagerLoadingMixin, serializers.ModelSerializer):
|
|||
SELECT_RELATED = ["alert_group", "resolution_note_slack_message", "author"]
|
||||
|
||||
def create(self, validated_data):
|
||||
if self.context["request"].user.pk:
|
||||
validated_data["author"] = self.context["request"].user
|
||||
user = self.context["request"].user
|
||||
if not isinstance(user, ServiceAccountUser) and user.pk:
|
||||
validated_data["author"] = user
|
||||
validated_data["source"] = ResolutionNote.Source.WEB
|
||||
return super().create(validated_data)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,16 @@
|
|||
from unittest.mock import patch
|
||||
|
||||
import httpretty
|
||||
import pytest
|
||||
from django.urls import reverse
|
||||
from rest_framework import status
|
||||
from rest_framework.test import APIClient
|
||||
|
||||
from apps.alerts.models import ResolutionNote
|
||||
from apps.api import permissions
|
||||
from apps.auth_token.auth import ApiTokenAuthentication, GrafanaServiceAccountAuthentication
|
||||
from apps.auth_token.models import ApiAuthToken, ServiceAccountToken
|
||||
from apps.auth_token.tests.helpers import setup_service_account_api_mocks
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
|
|
@ -146,6 +149,53 @@ def test_create_resolution_note(
|
|||
mock_send_update_resolution_note_signal.assert_called_once()
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
@httpretty.activate(verbose=True, allow_net_connect=False)
|
||||
@patch("apps.alerts.tasks.send_update_resolution_note_signal.send_update_resolution_note_signal.apply_async")
|
||||
def test_create_resolution_note_via_service_account(
|
||||
mock_send_update_resolution_note_signal,
|
||||
make_organization,
|
||||
make_service_account_for_organization,
|
||||
make_token_for_service_account,
|
||||
make_alert_receive_channel,
|
||||
make_alert_group,
|
||||
):
|
||||
organization = make_organization(grafana_url="http://grafana.test")
|
||||
service_account = make_service_account_for_organization(organization)
|
||||
token_string = "glsa_token"
|
||||
make_token_for_service_account(service_account, token_string)
|
||||
|
||||
perms = {
|
||||
permissions.RBACPermission.Permissions.ALERT_GROUPS_WRITE.value: ["*"],
|
||||
}
|
||||
setup_service_account_api_mocks(organization, perms)
|
||||
|
||||
alert_receive_channel = make_alert_receive_channel(organization)
|
||||
alert_group = make_alert_group(alert_receive_channel)
|
||||
data = {
|
||||
"alert_group_id": alert_group.public_primary_key,
|
||||
"text": "Test Resolution Note Message",
|
||||
}
|
||||
url = reverse("api-public:resolution_notes-list")
|
||||
client = APIClient()
|
||||
response = client.post(
|
||||
url,
|
||||
data=data,
|
||||
format="json",
|
||||
HTTP_AUTHORIZATION=f"{token_string}",
|
||||
HTTP_X_GRAFANA_URL=organization.grafana_url,
|
||||
)
|
||||
if not organization.is_rbac_permissions_enabled:
|
||||
assert response.status_code == status.HTTP_403_FORBIDDEN
|
||||
else:
|
||||
assert response.status_code == status.HTTP_201_CREATED
|
||||
mock_send_update_resolution_note_signal.assert_called_once()
|
||||
resolution_note = ResolutionNote.objects.get(public_primary_key=response.data["id"])
|
||||
assert resolution_note.author is None
|
||||
assert resolution_note.text == data["text"]
|
||||
assert resolution_note.alert_group == alert_group
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_create_resolution_note_invalid_text(
|
||||
make_organization_and_user_with_token,
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ class RequestTimeLoggingMiddleware(MiddlewareMixin):
|
|||
if len(split_path) >= 5:
|
||||
integration_token = split_path[4]
|
||||
else:
|
||||
integration_token = None
|
||||
integration_token = getattr(request, "inbound_email_integration_token", None)
|
||||
|
||||
message += f"integration_type={integration_type} integration_token={integration_token} "
|
||||
logging.info(message)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue