Skip to content

[PM-42240] perms still returned for members who were previously custom - #8244

Open
JaredScar wants to merge 2 commits into
mainfrom
ac/pm-42240-perms-still-returned-for-members-who-were-previously-custom
Open

[PM-42240] perms still returned for members who were previously custom#8244
JaredScar wants to merge 2 commits into
mainfrom
ac/pm-42240-perms-still-returned-for-members-who-were-previously-custom

Conversation

@JaredScar

Copy link
Copy Markdown
Contributor

🎟️ Tracking

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

📔 Objective

Fixes bug found in QA where previously custom users would still send back the permissions map to the frontend even though it is now irrelevant if they are no longer a custom user.

- Updated logic to clear permissions for non-Custom roles to prevent stale data.
- Adjusted response models to ensure permissions are only returned for Custom roles.
- Added unit tests to verify that permissions are correctly managed during role changes.
- Ensured consistency across models and response handling for organization users.
…ests

- Added comments for clarity on the optional Permissions property for backward compatibility.
- Updated unit tests in OrganizationUserControllerPutTests to ensure permissions are cleared when converting from Custom roles.
- Adjusted setup methods to include model parameters for consistency in tests.
@JaredScar
JaredScar requested a review from a team as a code owner August 21, 2026 16:49
@JaredScar JaredScar added the ai-review Request a Claude code review label Aug 21, 2026
@JaredScar JaredScar added the t:bugfix Change Type - Bugfix label Aug 21, 2026
@github-actions

github-actions Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

🤖 Bitwarden Claude Code Review

Overall Assessment: APPROVE

This PR stops custom permissions from being persisted or returned for members who are not in the Custom role, covering both the v1 (OrganizationUserUpdateRequestModel.ToOrganizationUser) and v2 (OrganizationUser.UpdateOrganizationUser) update paths, the public API update model, and the member/profile response models. The read-side gating matches the existing behavior in MemberBaseModel and in CoreHelpers.BuildIdentityClaims, which only emits permission claims for the Custom branch, so authorization is unaffected. ProfileOrganizationResponseModel correctly returns new Permissions() rather than null for non-Custom members, preserving the prior contract since LoadClassFromJsonData already returned an empty instance for an empty blob. Test coverage was added for the entity, the internal request model, the response models, and the controller.

Code Review Details
  • ❓ : Existing stale Permissions rows are not cleaned up; two server-side consumers (UserDecryptionOptionsBuilder, OrganizationDomainService) still read them without a Custom role check
    • src/Core/AdminConsole/Entities/OrganizationUser.cs:172

Minor, not blocking: the public API change in MemberUpdateRequestModel.ToOrganizationUser is the only modified production file without an accompanying unit test.

Comment on lines +172 to +177
if (organizationUserType != OrganizationUserType.Custom)
{
// Custom permissions only apply to the Custom role. Clear them so a member demoted from Custom doesn't
// keep a stale permissions blob.
Permissions = null;
}

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: Was a one-time cleanup of existing stale Permissions rows considered?

Why this may still matter after this PR

This PR stops new stale blobs from being written and hides them in OrganizationUserResponseModel / ProfileOrganizationResponseModel, but rows already in the database keep their blob until the member is edited again. A couple of server-side consumers read GetPermissions() without a Custom role check and are not covered by the response-model gating:

  • src/Identity/IdentityServer/UserDecryptionOptionsBuilder.cs:177organizationUser.GetPermissions() is { ManageResetPassword: true } is OR'd with the Admin/Owner check, so a member demoted from Custom with a stale ManageResetPassword: true blob would still get HasManageResetPasswordPermission = true in the TDE decryption options (which drives the post-SSO "must set a master password" flow).
  • src/Core/AdminConsole/Services/Implementations/OrganizationDomainService.cs:116o.GetPermissions()?.ManageSso == true keeps those members on the domain-verification notification list.

Authorization itself looks safe — CoreHelpers.BuildIdentityClaims only emits permission claims for the Custom branch, so CurrentContext.ManageUsers/ManageResetPassword etc. are unaffected.

If a migration is out of scope here, a follow-up ticket (or adding a Type is Custom guard at those two call sites) would close the loop.

@codecov

codecov Bot commented Aug 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 94.44444% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 68.57%. Comparing base (ac309aa) to head (97dd5be).

Files with missing lines Patch % Lines
...odels/Response/ProfileOrganizationResponseModel.cs 66.66% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8244      +/-   ##
==========================================
+ Coverage   63.29%   68.57%   +5.28%     
==========================================
  Files        2401     2401              
  Lines      104043   104055      +12     
  Branches     9426     9432       +6     
==========================================
+ Hits        65857    71360    +5503     
+ Misses      35930    30341    -5589     
- Partials     2256     2354      +98     

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

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

Labels

ai-review Request a Claude code review t:bugfix Change Type - Bugfix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant