Skip to content

MM-69458 Improving notification deduplication logic#1321

Open
avasconcelos114 wants to merge 2 commits into
masterfrom
MM-69458
Open

MM-69458 Improving notification deduplication logic#1321
avasconcelos114 wants to merge 2 commits into
masterfrom
MM-69458

Conversation

@avasconcelos114

@avasconcelos114 avasconcelos114 commented Jun 30, 2026

Copy link
Copy Markdown
Member

Summary

This PR is meant to pay some technical debt that was identified during a review in a backport PR. This is aimed to make 3 general improvements:

  1. Moving encryption guard up to prevent mistakenly treating the raw admin API token as an encrypted value
  2. Adding the instance ID to the dedup notification logic so we also take instance installations into consideration when evaluating duplicates
  3. Ensuring parallel operations can't bypass the dedup flow

Ticket Link

Fixes https://mattermost.atlassian.net/browse/MM-69458

Change Impact: 🟠 Medium

Reasoning: The PR hardens admin API token handling (encryption guard ordering) and materially changes webhook notification de-duplication semantics under concurrency (atomic claim, instance-scoped keys, longer TTL), both of which affect correctness of sensitive flows but remain contained to server-side plugin/webhook logic.
Regression Risk: Moderate. Token decryption/config-path behavior and user-facing DM notification delivery/dedup behavior are both impacted; however, the change is localized, has accompanying test updates for the dedup key, and rollback should be straightforward (revert server/plugin/webhook logic).
QA Recommendation: Run targeted manual QA focused on (1) admin API token configuration cases (with/without encryption key) and failure logging/error behavior, and (2) webhook notification delivery under concurrent deliveries to confirm duplicates are suppressed only within the intended instance scope. Skipping manual QA is not recommended for these user-visible correctness paths.
Generated by CodeRabbitAI

- Moving encryption guard up to prevent mistakenly treating the raw admin API token as an encrypted value
@avasconcelos114 avasconcelos114 self-assigned this Jun 30, 2026
@avasconcelos114
avasconcelos114 requested a review from a team as a code owner June 30, 2026 10:18
@avasconcelos114 avasconcelos114 added the 2: Dev Review Requires review by a core committer label Jun 30, 2026
@avasconcelos114 avasconcelos114 changed the title MM-69458 Improving notification dedup MM-69458 Improving notification deduplication logic Jun 30, 2026
@coderabbitai

coderabbitai Bot commented Jun 30, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 36c2a280-1a37-4e37-b1fd-8077893b0b03

📥 Commits

Reviewing files that changed from the base of the PR and between 76cd38f and ba6f251.

📒 Files selected for processing (1)
  • server/webhook.go

📝 Walkthrough

Walkthrough

PostNotifications now atomically claims a longer-lived dedup key that includes Jira instance ID, the dedup key tests cover the new key shape, and OnConfigurationChange checks EncryptionKey before decrypting AdminAPIToken.

Changes

Notification deduplication and encryption guard

Layer / File(s) Summary
Atomic claim and instance-scoped dedup key
server/webhook.go
PostNotifications uses KV.Set(..., SetAtomic(nil)) before sending, skips already-claimed deliveries, fails open on KV errors, keeps the claim on post failure, and extends the dedup TTL. notificationDedupKey now includes instanceID.
Dedup key tests
server/webhook_parser_misc_test.go
TestNotificationDedupKey is updated for instanceID, including a new case for different Jira instances and updated equality/inequality assertions.
Earlier EncryptionKey check
server/plugin.go
The EncryptionKey guard moves before the decrypt attempt in the AdminAPIToken branch, and the later redundant check is removed.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested reviewers: nang2049, ogi-m

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title is concise and clearly describes a major part of the changeset: notification deduplication improvements.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch MM-69458

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@server/webhook.go`:
- Around line 223-237: Keep the in-flight dedup claim from expiring before the
DM send completes. The pre-send claim in PostNotifications uses
notificationDedupKey with the same short notificationDedupTTL, but the
CreateBotDMPost path can take longer than that and allow a second delivery to
reclaim the key and post a duplicate. Update the claim in PostNotifications to
use a longer-lived expiry for the in-flight send, and after CreateBotDMPost
succeeds, optionally restore the expiry back to notificationDedupTTL if you
still want the final dedup window to remain short.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro

Run ID: 3e9a6084-5413-4497-b8d8-3ea286c2db29

📥 Commits

Reviewing files that changed from the base of the PR and between ee838e1 and 76cd38f.

📒 Files selected for processing (3)
  • server/plugin.go
  • server/webhook.go
  • server/webhook_parser_misc_test.go

Comment thread server/webhook.go
Comment thread server/webhook.go Outdated
if err != nil {
p.errorf("PostNotifications: failed to create notification post, err: %v", err)
// Release the claim so the notification can be retried.
if claimed {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

CreateBotDMPost can persist the post and still return an error. Releasing the claim in that case defeats the point of this PR as retry will duplicate. Suggest not releasing on error and letting the TTL expire the key.

post, err := p.CreateBotDMPost(instance.GetID(), mattermostUserID, notification.message, notification.postType)
if err != nil {
    p.errorf("PostNotifications: failed to create notification post, err: %v", err)
    // Dont release the dedup claim
    // TTL will clear the claim
    continue
}

Comment thread server/webhook.go
raw := fmt.Sprintf("%s_%s_%s",
func notificationDedupKey(instanceID types.ID, wh *webhook, recipientID types.ID, message string) string {
raw := fmt.Sprintf("%s_%s_%s_%s",
string(instanceID),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Including instanceID fixes cross instance key collisions. Good catch :))

@nang2049 nang2049 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks @avasconcelos114 just one minor improvement!

@avasconcelos114
avasconcelos114 requested a review from nang2049 July 8, 2026 08:17
@avasconcelos114 avasconcelos114 added the 3: QA Review Requires review by a QA tester label Jul 8, 2026
@avasconcelos114

Copy link
Copy Markdown
Member Author

@ogi-m This should be ready for testing now!

If possible it would be great to have this tested on an HA environment as some reports show that having an issue_updated and issue_assigned both checked in the Jira webhooks will result in a duplicate on an HA environment when each of these 2 events are processed in different nodes

@avasconcelos114
avasconcelos114 requested a review from ogi-m July 8, 2026 08:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

2: Dev Review Requires review by a core committer 3: QA Review Requires review by a QA tester

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants