diff --git a/engine/apps/slack/tests/test_interactive_api_endpoint.py b/engine/apps/slack/tests/test_interactive_api_endpoint.py index a8be48c3..f0d8728b 100644 --- a/engine/apps/slack/tests/test_interactive_api_endpoint.py +++ b/engine/apps/slack/tests/test_interactive_api_endpoint.py @@ -55,6 +55,38 @@ def slack_team_identity(make_slack_team_identity): ) +@patch("apps.slack.views.SlackEventApiEndpointView.verify_signature", return_value=True) +@patch("apps.slack.views.SlackEventApiEndpointView._open_warning_window_if_needed") +@pytest.mark.django_db +def test_no_user_in_organization_for_slack_team_identity( + mock_open_warning_window_if_needed, + _mock_verify_signature, + make_organization, + make_slack_user_identity, + slack_team_identity, +): + # only create SlackUserIdentity, not actual OnCall user + make_slack_user_identity(slack_team_identity=slack_team_identity, slack_id=SLACK_USER_ID) + organization = make_organization(slack_team_identity=slack_team_identity, grafana_url="https://test.com") + + event_payload = { + "type": PayloadType.BLOCK_ACTIONS, + "trigger_id": EVENT_TRIGGER_ID, + "user": {"id": SLACK_USER_ID}, + "team": {"id": SLACK_TEAM_ID}, + "actions": [{"value": json.dumps({"organization_id": organization.id})}], + } + + response = _make_request(event_payload) + assert response.status_code == status.HTTP_200_OK + + mock_open_warning_window_if_needed.assert_called_once_with( + event_payload, + slack_team_identity, + "Permission denied. Please connect your Slack account to OnCall: https://test.com/a/grafana-oncall-app/users/me/", + ) + + @patch("apps.slack.views.SlackEventApiEndpointView.verify_signature", return_value=True) @patch("apps.slack.views.SlackEventApiEndpointView._open_warning_window_if_needed") @pytest.mark.django_db diff --git a/engine/apps/slack/views.py b/engine/apps/slack/views.py index 2c7aff6b..5668009e 100644 --- a/engine/apps/slack/views.py +++ b/engine/apps/slack/views.py @@ -3,6 +3,7 @@ import hmac import json import logging from contextlib import suppress +from urllib.parse import urljoin from django.conf import settings from django.core.exceptions import ObjectDoesNotExist @@ -291,11 +292,13 @@ class SlackEventApiEndpointView(APIView): return Response() elif organization: user = slack_user_identity.get_user(organization) - if not user: - # Means that user slack_user_identity is not in any organization, connected to this Slack workspace - warning_text = "Permission denied. Please connect your Slack account to OnCall." - # Open pop-up to inform user why OnCall bot doesn't work if any action was triggered - self._open_warning_window_if_needed(payload, slack_team_identity, warning_text) + if not user: # SlackUserIdentity exists but not connected to any user in this organization + user_settings_url = urljoin(organization.grafana_url, "/a/grafana-oncall-app/users/me/") + self._open_warning_window_if_needed( + payload, + slack_team_identity, + f"Permission denied. Please connect your Slack account to OnCall: {user_settings_url}", + ) return Response(status=200) # direct paging / manual incident / schedule update dialogs don't require organization to be set elif ( diff --git a/engine/config_integrations/alertmanager.py b/engine/config_integrations/alertmanager.py index 6f695d4d..2df1d9bc 100644 --- a/engine/config_integrations/alertmanager.py +++ b/engine/config_integrations/alertmanager.py @@ -13,7 +13,7 @@ featured_tag_name = "Prometheus" # Behaviour -source_link = "{{ payload.externalURL }}" +source_link = "{{ payload.alerts[0].generatorURL }}" grouping_id = "{{ payload.groupKey }}" diff --git a/engine/config_integrations/grafana_alerting.py b/engine/config_integrations/grafana_alerting.py index 3209a0fc..0dc5b6d6 100644 --- a/engine/config_integrations/grafana_alerting.py +++ b/engine/config_integrations/grafana_alerting.py @@ -15,7 +15,7 @@ based_on_alertmanager = True # Behaviour -source_link = "{{ payload.externalURL }}" +source_link = "{{ payload.alerts[0].generatorURL }}" grouping_id = "{{ payload.groupKey }}" diff --git a/engine/settings/base.py b/engine/settings/base.py index 788f958f..22d92333 100644 --- a/engine/settings/base.py +++ b/engine/settings/base.py @@ -964,6 +964,6 @@ DETACHED_INTEGRATIONS_SERVER = getenv_boolean("DETACHED_INTEGRATIONS_SERVER", de ACKNOWLEDGE_REMINDER_TASK_EXPIRY_DAYS = os.environ.get("ACKNOWLEDGE_REMINDER_TASK_EXPIRY_DAYS", default=14) -SYNC_V2_MAX_TASKS = getenv_integer("SYNC_V2_MAX_TASKS", 10) -SYNC_V2_PERIOD_SECONDS = getenv_integer("SYNC_V2_PERIOD_SECONDS", 300) +SYNC_V2_MAX_TASKS = getenv_integer("SYNC_V2_MAX_TASKS", 6) +SYNC_V2_PERIOD_SECONDS = getenv_integer("SYNC_V2_PERIOD_SECONDS", 240) SYNC_V2_BATCH_SIZE = getenv_integer("SYNC_V2_BATCH_SIZE", 500)