Skip to content

[PM-39998] Omit org owner and admin Sends from policy enforcement#7982

Open
mcamirault wants to merge 2 commits into
mainfrom
tools/pm-39998/exempt-owner-admin-sends-from-policy-disabling
Open

[PM-39998] Omit org owner and admin Sends from policy enforcement#7982
mcamirault wants to merge 2 commits into
mainfrom
tools/pm-39998/exempt-owner-admin-sends-from-policy-disabling

Conversation

@mcamirault

Copy link
Copy Markdown
Contributor

🎟️ Tracking

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

📔 Objective

For the new Manage Send policy we want org Owners and Admins to be exempt from its enforcement, including the disabling of existing Sends that are noncompliant with the policy. This PR adds a check that will exempt a user's Sends from being disabled if they are an Owner or Admin within the org that has set the policy.

@mcamirault mcamirault requested a review from a team July 14, 2026 17:28
@mcamirault mcamirault requested a review from a team as a code owner July 14, 2026 17:28
@mcamirault mcamirault added the t:bugfix Change Type - Bugfix label Jul 14, 2026
@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

🤖 Bitwarden Claude Code Review

Overall Assessment: REQUEST CHANGES

This PR exempts org owners and admins from SendControls policy enforcement by fetching their user IDs via GetManyByMinimumRoleAsync and skipping their Sends when disabling non-compliant ones. The core logic in SendControlsSyncPolicyEvent is sound on MSSQL, and a unit test verifies owner/admin Sends are left enabled. However, the exemption depends on UserId being populated on OrganizationUserUserDetails, which is not guaranteed across both ORMs.

Code Review Details
  • ❌ : Owner/admin exemption silently fails on PostgreSQL/MySQL/SQLite — the EF Core GetManyByMinimumRoleAsync projection omits UserId, so GetUserId() returns null for every row and all owner/admin Sends get disabled anyway. Fix by adding UserId = e.UserId to the projection in src/Infrastructure.EntityFramework/AdminConsole/Repositories/OrganizationUserRepository.cs:806. The new unit test mocks the repository, so it does not catch this parity gap.
    • src/Core/AdminConsole/OrganizationFeatures/Policies/PolicyEventHandlers/SendControlsSyncPolicyEvent.cs:95

@codecov

codecov Bot commented Jul 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 66.58%. Comparing base (d6cb0a1) to head (f427c24).
⚠️ Report is 7 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #7982      +/-   ##
==========================================
+ Coverage   62.03%   66.58%   +4.54%     
==========================================
  Files        2276     2277       +1     
  Lines       99404    99456      +52     
  Branches     8980     8982       +2     
==========================================
+ Hits        61667    66223    +4556     
+ Misses      35565    30964    -4601     
- Partials     2172     2269      +97     

☔ 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.

var orgSendIds = await sendRepository.GetIdsByOrganizationIdAsync(postUpsertedPolicyState.OrganizationId);
// We fetch all of the owners and admins in the org so we can ignore their Sends when enforcing policy compliance
// This could be a heavy call in theory but in practice owners and admins should be a minority of org users
var orgOwnerAndAdminUserIds = (await orgUserRepository.GetManyByMinimumRoleAsync(postUpsertedPolicyState.OrganizationId, Core.Enums.OrganizationUserType.Admin)).Select(oud => oud.GetUserId());

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.

💭 At some point it would be good to collapse the verification of whether a Send is compliant, to the PolicyRequirement itself, which owns the concept of "given a policy and some domain data (the user trying to Send, the Send itself), is this valid?". This way if we change how the policy works, it'll "just work" for this side effect

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

Labels

needs-qa t:bugfix Change Type - Bugfix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants