Skip to content

[PM-38269] refactor: remove redundant permissions round-trip in OrganizationUserUserDetailsQuery - #8119

Open
r-tome wants to merge 3 commits into
mainfrom
pm-38269/remove-redundant-permissions-roundtrip
Open

[PM-38269] refactor: remove redundant permissions round-trip in OrganizationUserUserDetailsQuery#8119
r-tome wants to merge 3 commits into
mainfrom
pm-38269/remove-redundant-permissions-roundtrip

Conversation

@r-tome

@r-tome r-tome commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

🎟️ Tracking

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

📔 Objective

For each Custom-role user, OrganizationUserUserDetailsQuery was deserializing the Permissions JSON string from the database and immediately re-serializing it back to a string — a no-op round-trip before the string reaches the API response model, which deserializes it once anyway.

This PR removes the three identical if (Type == Custom) blocks from GetOrganizationUserUserDetails, Get, and GetAccountRecoveryEnrolledUsers, and drops the now-unused using Bit.Core.Utilities import.

An API integration test is added to OrganizationUsersControllerGetTests to verify that Custom-user permissions survive the full pipeline (DB → query → response model → JSON) correctly.

@r-tome r-tome added ai-review Request a Claude code review t:tech-debt Change Type - Tech debt labels Jul 31, 2026
@github-actions

github-actions Bot commented Jul 31, 2026

Copy link
Copy Markdown
Contributor

🤖 Bitwarden Claude Code Review

Overall Assessment: APPROVE

Reviewed the removal of the Permissions deserialize/re-serialize round-trip from OrganizationUserUserDetailsQuery, the deletion of the now-dead GetOrganizationUserUserDetails method and its interface member, and the accompanying test cleanup. The refactor is behavior-preserving for the only consumer, OrganizationUsersController.GetAll: OrganizationUserUserDetailsResponseModel already deserializes the raw Permissions string via CoreHelpers.LoadClassFromJsonData<Permissions> with the same options the removed ClassToJsonData used. Confirmed GetOrganizationUserUserDetails has zero remaining references across src/, bitwarden_license/, and test/, that GetPermissions() remains used by other call sites (Admin portal, public API, UserDecryptionOptionsBuilder), and that the two removed usings in the controller test are not needed elsewhere in that file.

Code Review Details
  • ♻️ : GetMany_Setup no longer stubs anything GetAll reads, so GetMany_ReturnsUsers asserts over an empty result set and passes vacuously (pre-existing, but adjacent to this cleanup)
    • test/Api.Test/AdminConsole/Controllers/OrganizationUsersControllerTests.cs:548

The only behavioral delta is a Custom user whose Permissions column is NULL/empty: the response permissions changes from null to an all-false object, which is semantically equivalent and already the shape returned for every other user — not flagged.

PR Metadata Assessment

  • QUESTION: The description still claims an API integration test was added to OrganizationUsersControllerGetTests, but no such file exists in the diff or the repo — worth updating to match the final scope.

@r-tome
r-tome force-pushed the pm-38269/remove-redundant-permissions-roundtrip branch from 0f4bebe to e0ba63b Compare July 31, 2026 16:36
@codecov

codecov Bot commented Jul 31, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 63.64%. Comparing base (fc4c606) to head (d060b68).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8119      +/-   ##
==========================================
- Coverage   68.12%   63.64%   -4.49%     
==========================================
  Files        2373     2373              
  Lines      102846   102816      -30     
  Branches     9328     9325       -3     
==========================================
- Hits        70068    65437    -4631     
- Misses      30454    35150    +4696     
+ Partials     2324     2229      -95     

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

…izationUserUserDetailsQuery

For each Custom-role user the query was deserializing the Permissions JSON
string then immediately re-serializing it back — a no-op before the string
reaches the response model, which deserializes it once anyway. Remove the
three identical if (Type == Custom) blocks and the now-unused CoreHelpers
import.
@r-tome
r-tome force-pushed the pm-38269/remove-redundant-permissions-roundtrip branch from e0ba63b to ed04d6f Compare August 3, 2026 09:50
The method became a bare pass-through after the permissions round-trip
was removed and has no callers in production code. Remove it from the
interface and implementation, delete the unit tests that only covered it,
and drop the stale stub from GetMany_Setup in the controller tests.
@r-tome
r-tome marked this pull request as ready for review August 3, 2026 10:07
@r-tome
r-tome requested a review from a team as a code owner August 3, 2026 10:07
@r-tome
r-tome requested a review from jrmccannon August 3, 2026 10:07

@jrmccannon jrmccannon 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.

No notes.


sutProvider.GetDependency<IOrganizationUserUserDetailsQuery>().GetOrganizationUserUserDetails(Arg.Any<OrganizationUserUserDetailsQueryRequest>()).Returns(organizationUsers);

sutProvider.GetDependency<IAuthorizationService>().AuthorizeAsync(

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.

♻️ DEBT: With the stub removed, GetMany_Setup no longer arranges anything GetAll reads, so GetMany_ReturnsUsers passes vacuously.

Details

OrganizationUsersController.GetAll resolves members through _organizationUserUserDetailsQuery.Get(request) (or GetAccountRecoveryEnrolledUsers), never IOrganizationUserRepository.GetManyDetailsByOrganizationAsync. That repository stub therefore has no effect, and the auto-mocked IOrganizationUserUserDetailsQuery returns an empty sequence, so response.Data is empty and Assert.True(response.Data.All(r => organizationUsers.Any(ou => ou.Id == r.Id))) is true regardless of the injected organizationUsers.

Since this PR is a dead-code cleanup, consider finishing the job in the setup: stub the query instead, e.g.

sutProvider.GetDependency<IOrganizationUserUserDetailsQuery>()
    .Get(Arg.Any<OrganizationUserUserDetailsQueryRequest>())
    .Returns(organizationUsers.Select(ou => (ou, false, false)));

(or delete GetMany_ReturnsUsers if the coverage is not worth restoring). Note the vacuity predates this PR — the removed stub was on a method GetAll never called — so this is optional.

@r-tome r-tome added needs-qa and removed ai-review Request a Claude code review labels Aug 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-qa t:tech-debt Change Type - Tech debt

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants