Skip to content

[PM-41863] Fix redundant Send event logging - #8327

Open
harr1424 wants to merge 2 commits into
mainfrom
tools/PM-41863-fix-duplicate-send-event-logs
Open

[PM-41863] Fix redundant Send event logging#8327
harr1424 wants to merge 2 commits into
mainfrom
tools/PM-41863-fix-duplicate-send-event-logs

Conversation

@harr1424

@harr1424 harr1424 commented Sep 9, 2026

Copy link
Copy Markdown
Contributor

🎟️ Tracking

https://bitwarden.atlassian.net/browse/PM-41863

📔 Objective

This PR eliminates a redundant Send event log that occurred when working with File type Sends. The root cause was that SaveSendAsync() was being called twice as part of a two-stage process unique to File type Sends.

@codecov

codecov Bot commented Sep 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 80.95238% with 4 lines in your changes missing coverage. Please review.
✅ Project coverage is 63.99%. Comparing base (19ebcf3) to head (5343149).

Files with missing lines Patch % Lines
src/Api/Tools/Controllers/SendsController.cs 0.00% 3 Missing ⚠️
...Core/Dirt/Services/Implementations/EventService.cs 87.50% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@           Coverage Diff           @@
##             main    #8327   +/-   ##
=======================================
  Coverage   63.99%   63.99%           
=======================================
  Files        2471     2471           
  Lines      105800   105816   +16     
  Branches     9596     9599    +3     
=======================================
+ Hits        67705    67716   +11     
- Misses      35745    35749    +4     
- Partials     2350     2351    +1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@harr1424
harr1424 marked this pull request as ready for review September 10, 2026 00:48
@harr1424
harr1424 requested review from a team as code owners September 10, 2026 00:48
@harr1424
harr1424 requested a review from AlexRubik September 10, 2026 00:48
@github-actions

github-actions Bot commented Sep 10, 2026

Copy link
Copy Markdown
Contributor

🤖 Bitwarden Claude Code Review

Overall Assessment: APPROVE

This PR threads a logEvent flag through SaveSendAsync / ConfirmFileSize so the file-upload finalization step no longer emits a Send_Edited_* event on top of the Send_Created_* already logged by PostFile / SaveFileSendAsync. Both production call sites of ConfirmFileSize (the Azure Event Grid webhook and the self-hosted UploadFileToExistingSendAsync path) only ever finalize a not-yet-validated upload, so the suppressed edit event was always redundant, and the deletion event on a failed size check still logs unconditionally. Unit coverage was added for each new branch, including the anti-hijacking delete path. The diff also contains a second, unrelated behavior change in EventService.LogSendEventAsync that defaults DeviceType to Server for non-access Send events.

Code Review Details
  • ❓ : Server device-type default also applies to user-initiated create/edit/delete events whose request carries no Device-Type value
    • src/Core/Dirt/Services/Implementations/EventService.cs:720

Comment on lines +716 to +723
// Create/edit/delete events have no org context and can come from a request with no
// Device-Type header at all, e.g. DeleteSendsJob's scheduled expiration cleanup, which runs
// with no HTTP request and thus no CurrentContext.DeviceType. Report Server instead of unknown.
var deviceType = _currentContext.DeviceType;
if (deviceType == null && organizationContext == null)
{
deviceType = DeviceType.Server;
}

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.

QUESTION: organizationContext == null also matches user-initiated create/edit/delete, so a client request without a Device-Type value is recorded as Server.

Details

CurrentContext.DeviceType is populated only from the Device-Type header or the devicetype JWT claim, and that claim is issued only when a device is attached to the token (BaseRequestValidator.cs:614). A user API key / client-credentials token carries neither, so a genuine POST /sends or DELETE /sends/{id} from such a caller now lands in the audit log attributed to Server rather than staying unattributed.

Elsewhere in this file the Server device type keys off an explicit system-actor signal (systemUser is EventSystemUser.SCIM) rather than the absence of a header. Would gating on something that positively identifies the non-HTTP caller — e.g. _currentContext.HttpContext is null, or an EventSystemUser passed by DeleteSendsJob — better match the intent described in the comment, and keep real client actions out of the Server bucket?

This is also worth calling out in the PR description: the objective covers only the redundant event, but this changes recorded DeviceType for every Send create/edit/delete event.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

❌ Incorrect

A user API key / client-credentials token carries neither, so a genuine POST /sends or DELETE /sends/{id} from such a caller now lands in the audit log attributed to Server rather than staying unattributed.

This is not true.

This is also worth calling out in the PR description: the objective covers only the redundant event, but this changes recorded DeviceType for every Send create/edit/delete event.

This is also not true.

The changes introduced in this PR do not attribute server to any client initiated Send Event.

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant