Skip to content

Commit

Permalink
Merge pull request #5288 from grafana/dev
Browse files Browse the repository at this point in the history
v1.13.3
  • Loading branch information
matiasb authored Nov 21, 2024
2 parents 83e3584 + 67604c6 commit 8a528c4
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 5 deletions.
6 changes: 4 additions & 2 deletions engine/apps/email/inbound.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ def dispatch(self, request):
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):
Expand Down Expand Up @@ -138,14 +139,15 @@ def message(self) -> AnymailInboundMessage | None:
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):
Expand Down
6 changes: 4 additions & 2 deletions engine/apps/public_api/serializers/resolution_notes.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -34,8 +35,9 @@ class Meta:
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)

Expand Down
50 changes: 50 additions & 0 deletions engine/apps/public_api/tests/test_resolution_notes.py
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion engine/engine/middlewares.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def log_message(request, response, tag, message=""):
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)
Expand Down

0 comments on commit 8a528c4

Please sign in to comment.