Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix orphaned messages in Slack #2023

Merged
merged 41 commits into from
Jun 1, 2023
Merged

Conversation

vstpme
Copy link
Member

@vstpme vstpme commented May 25, 2023

What this PR does

Reworks Slack handlers for buttons and select menus for AG Slack messages.

Screenshot 2023-05-31 at 19 34 05

Current implementation

  • It's possible to end up with orphaned Slack messages that are posted to Slack but have no SlackMessage instance in the DB. For such messages, clicking buttons will result in an exception and HTTP 500. See private repo issue for more info.
  • Bug in authorization system, which effectively bypasses any permission checks. For example, it's possible to resolve an alert group while being a Viewer.
  • No tests covering most buttons.

Changes in this PR

  • Make the system more robust, don't use SlackMessage model to figure out the alert group being interacted on, instead embed alert_group_pk to every button and use it when receiving interaction requests from Slack.
  • Existing orphaned Slack messages will be repaired. Clicking buttons under orphaned messages will work (and missing SlackMessage instance will be created on interaction). This is possible because some buttons already have alert_group_pk embedded, and it's possible to get this data on button clicks (even if the clicked button itself doesn't have alert_group_pk embedded).
  • Fix authorization. Show warning window when unauthorized:
Screenshot 2023-05-31 at 19 40 02
  • Added tests for all the buttons under AG message. Add tests checking authorization, actual execution of scenario steps, orphan message repairing, backward compatibility, etc. Also add tests on AlertGroupSlackRenderer checking that correct data is embedded into buttons.
  • Cosmetic changes such as renaming incident to Alert Group.

Which issue(s) this PR fixes

Related to https://github.com/grafana/oncall-private/issues/1841

Checklist

  • Unit, integration, and e2e (if applicable) tests updated
  • Documentation added (or pr:no public docs PR label added if not required)
  • CHANGELOG.md updated (or pr:no changelog PR label added if not required)

@vstpme vstpme force-pushed the vadimkerr/fix-slack-message-not-in-db branch from 98b9b64 to 153072d Compare May 25, 2023 13:53
@vstpme vstpme added the pr:no public docs Added to a PR that does not require public documentation updates label May 31, 2023
@@ -80,7 +80,8 @@ def get_alert_group(self):
self.alert_group.slack_message = self
self.alert_group.save(update_fields=["slack_message"])
return self.alert_group
return self.alert.group
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no alert field on SlackMessage

@@ -217,32 +218,3 @@ def send_slack_notification(self, user, alert_group, notification_policy):
pass
else:
raise e

@classmethod
def get_alert_group_from_slack_message_payload(cls, slack_team_identity, payload):
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

REQUIRED_PERMISSIONS = []
ACTION_VERBOSE = ""
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACTION_VERBOSE is not needed anymore, it was used to send messages to AG thread with information about interaction attempt. Now it's a simple warning popup in case of authorization failure.

@vstpme vstpme marked this pull request as ready for review May 31, 2023 19:14
@vstpme vstpme requested a review from a team May 31, 2023 19:14
@vstpme vstpme changed the title Fix slack message not in db Fix orphaned messages in Slack May 31, 2023
Copy link
Contributor

@matiasb matiasb left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, nice 👍

"alert_group_pk": alert_group_pk,
"message_ts": message_ts,
"alert_group_pk": alert_group.pk,
"message_ts": payload.get("message_ts") or payload["container"]["message_ts"],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

engine/apps/slack/scenarios/step_mixins.py Outdated Show resolved Hide resolved
self._get_alert_group_from_action(payload) # Try to get alert_group_pk from PRESSED button
or self._get_alert_group_from_message(payload) # Try to use alert_group_pk from ANY button in message
or self._get_alert_group_from_slack_message_in_db(slack_team_identity, payload) # Fetch message from DB
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

❤️

@vstpme vstpme enabled auto-merge June 1, 2023 10:15
@vstpme vstpme added this pull request to the merge queue Jun 1, 2023
Merged via the queue into dev with commit d1373b5 Jun 1, 2023
@vstpme vstpme deleted the vadimkerr/fix-slack-message-not-in-db branch June 1, 2023 10:25
Comment on lines +421 to +433
def _alert_group_action_value(self, **kwargs):
"""
Store organization and alert group IDs in Slack button or select menu values.
alert_group_pk is used in apps.slack.scenarios.step_mixins.AlertGroupActionsMixin to get the right alert group
when handling AG actions in Slack.
"""

data = {
"organization_id": self.alert_group.channel.organization_id,
"alert_group_pk": self.alert_group.pk,
**kwargs,
}
return json.dumps(data) # Slack block elements allow to pass value as string only (max 2000 chars)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice 👍

@@ -80,7 +80,8 @@ def get_alert_group(self):
self.alert_group.slack_message = self
self.alert_group.save(update_fields=["slack_message"])
return self.alert_group
return self.alert.group
else:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what does _alert_group (a few lines above) refer to? I see an alert_group reference defined, but no _alert_group

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
pr:no public docs Added to a PR that does not require public documentation updates
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants