Skip to content

PM-37911: Feat: Update Organization model#6960

Merged
david-livefront merged 1 commit into
mainfrom
PM-37911-organization-network-model
May 29, 2026
Merged

PM-37911: Feat: Update Organization model#6960
david-livefront merged 1 commit into
mainfrom
PM-37911-organization-network-model

Conversation

@david-livefront
Copy link
Copy Markdown
Collaborator

@david-livefront david-livefront commented May 21, 2026

🎟️ Tracking

PM-37911

📔 Objective

This PR updates the Organization network model to include significantly more data. This data is required in order to match the SDK ProfileOrganization.

@david-livefront david-livefront requested a review from a team as a code owner May 21, 2026 19:07
@github-actions github-actions Bot added app:password-manager Bitwarden Password Manager app context app:authenticator Bitwarden Authenticator app context t:feature Change Type - Feature Development labels May 21, 2026
@david-livefront david-livefront force-pushed the PM-37911-organization-network-model branch from aee1dd1 to 2f37379 Compare May 21, 2026 19:10
@codecov
Copy link
Copy Markdown

codecov Bot commented May 21, 2026

Codecov Report

❌ Patch coverage is 76.19048% with 25 lines in your changes missing coverage. Please review.
✅ Project coverage is 84.31%. Comparing base (b57fb9c) to head (f3f06cc).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...auth/repository/util/SyncResponseJsonExtensions.kt 78.43% 16 Missing and 6 partials ⚠️
...twarden/data/auth/repository/AuthRepositoryImpl.kt 0.00% 0 Missing and 1 partial ⚠️
.../feature/removepassword/RemovePasswordViewModel.kt 0.00% 0 Missing and 1 partial ⚠️
...en/ui/platform/feature/rootnav/RootNavViewModel.kt 0.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #6960      +/-   ##
==========================================
- Coverage   86.26%   84.31%   -1.96%     
==========================================
  Files        1008     1008              
  Lines       66332    66433     +101     
  Branches     9308     9316       +8     
==========================================
- Hits        57221    56010    -1211     
- Misses       5902     7223    +1321     
+ Partials     3209     3200       -9     
Flag Coverage Δ
app-data 17.45% <76.19%> (-0.07%) ⬇️
app-ui-auth-tools 19.28% <0.00%> (-0.04%) ⬇️
app-ui-platform 16.44% <0.00%> (-0.59%) ⬇️
app-ui-vault 27.73% <0.00%> (-0.58%) ⬇️
authenticator 6.22% <0.00%> (+0.01%) ⬆️
lib-core-network-bridge 4.07% <0.00%> (-0.02%) ⬇️
lib-data-ui 1.14% <0.00%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 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.

@david-livefront david-livefront force-pushed the PM-37911-organization-network-model branch 4 times, most recently from 0d72f25 to 0851a91 Compare May 21, 2026 21:09
@SaintPatrck SaintPatrck added the ai-review-vnext Request a Claude code review using the vNext workflow label May 22, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 22, 2026

Bitwarden Claude Code Review

Overall Assessment: APPROVE

This PR expands the SyncResponseJson.Profile.Organization network model with the additional fields required by the SDK's ProfileOrganization, introduces three new enums (ProductTierType, ProviderType, MemberDecryptionType) in the network module, and adds a toSdkProfileOrganizations() mapping extension with full unit-test coverage. It also performs a non-semantic rename of shouldUseKeyConnector to isKeyConnectorEnabled (preserving the existing keyConnectorEnabled JSON field) and updates all call sites and test fixtures accordingly. Numeric capacity fields (seats, maxCollections, maxStorageGb) are switched from Int? to UInt? to align with the SDK's unsigned types. No production behavior changes: existing key-connector checks continue to read the same JSON field they did before the rename, and the new mapping function is wired up for later use.

Code Review Details

No findings.

SaintPatrck
SaintPatrck previously approved these changes May 22, 2026
@david-livefront david-livefront force-pushed the PM-37911-organization-network-model branch 4 times, most recently from 7671d18 to c4cab72 Compare May 29, 2026 14:59
Comment on lines +49 to +135
userIsClaimedByOrganization: Boolean = false,
limitItemDeletion: Boolean = false,
useSso: Boolean = false,
useOrganizationDomains: Boolean = false,
shouldUseKeyConnector: Boolean = false,
useScim: Boolean = false,
useCustomPermissions: Boolean = false,
useResetPassword: Boolean = false,
useSecretsManager: Boolean = false,
usePasswordManager: Boolean = false,
useActivateAutofillPolicy: Boolean = false,
useAutomaticUserConfirmation: Boolean = false,
ssoBound: Boolean = false,
resetPasswordEnrolled: Boolean = false,
organizationUserId: String? = "mockOrganizationUserId-$number",
hasPublicAndPrivateKeys: Boolean = false,
isProviderUser: Boolean = false,
isMember: Boolean = false,
familySponsorshipAvailable: Boolean = false,
productTierType: ProductTierType = ProductTierType.FREE,
accessSecretsManager: Boolean = false,
limitCollectionCreation: Boolean = false,
limitCollectionDeletion: Boolean = false,
allowAdminAccessToAllCollectionItems: Boolean = false,
useAccessIntelligence: Boolean = false,
useAdminSponsoredFamilies: Boolean = false,
useDisableSmAdsForUsers: Boolean = false,
isAdminInitiated: Boolean = false,
ssoEnabled: Boolean = false,
ssoMemberDecryptionType: MemberDecryptionType? = null,
usePhishingBlocker: Boolean = false,
useMyItems: Boolean = false,
): ProfileOrganization =
ProfileOrganization(
id = id,
name = name,
status = status,
type = type,
enabled = enabled,
usePolicies = usePolicies,
useGroups = useGroups,
useDirectory = useDirectory,
useEvents = shouldUseEvents,
useTotp = useTotp,
use2fa = use2fa,
useApi = useApi,
useSso = useSso,
useOrganizationDomains = useOrganizationDomains,
useKeyConnector = shouldUseKeyConnector,
useScim = useScim,
useCustomPermissions = useCustomPermissions,
useResetPassword = useResetPassword,
useSecretsManager = useSecretsManager,
usePasswordManager = usePasswordManager,
useActivateAutofillPolicy = useActivateAutofillPolicy,
useAutomaticUserConfirmation = useAutomaticUserConfirmation,
selfHost = selfHost,
usersGetPremium = usersGetPremium,
seats = seats,
maxCollections = maxCollections,
maxStorageGb = maxStorageGb,
ssoBound = ssoBound,
identifier = identifier,
permissions = permissions,
resetPasswordEnrolled = resetPasswordEnrolled,
userId = userId,
organizationUserId = organizationUserId,
hasPublicAndPrivateKeys = hasPublicAndPrivateKeys,
providerId = providerId,
providerName = providerName,
providerType = providerType,
isProviderUser = isProviderUser,
isMember = isMember,
familySponsorshipFriendlyName = familySponsorshipFriendlyName,
familySponsorshipAvailable = familySponsorshipAvailable,
productTierType = productTierType,
keyConnectorEnabled = keyConnectorEnabled,
keyConnectorUrl = keyConnectorUrl,
familySponsorshipLastSyncDate = familySponsorshipLastSyncDate,
familySponsorshipValidUntil = familySponsorshipValidUntil,
familySponsorshipToDelete = familySponsorshipToDelete,
accessSecretsManager = accessSecretsManager,
limitCollectionCreation = limitCollectionCreation,
limitCollectionDeletion = limitCollectionDeletion,
limitItemDeletion = limitItemDeletion,
allowAdminAccessToAllCollectionItems = allowAdminAccessToAllCollectionItems,
userIsManagedByOrganization = userIsClaimedByOrganization,
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.

🎨 SUGGESTED: The parameter userIsClaimedByOrganization populates the SDK's userIsManagedByOrganization field, which is semantically a different concept.

Details and fix

On line 49 the helper accepts userIsClaimedByOrganization, but on line 135 it is mapped to userIsManagedByOrganization. The network model has both userIsClaimedByOrganization and userIsManagedByOrganization as distinct fields, and the production mapper at SyncResponseJsonExtensions.kt:122 correctly uses this.userIsManagedByOrganization. As-is, a future test that does createMockSdkProfileOrganization(userIsClaimedByOrganization = true) will not produce an equivalent of createMockOrganizationNetwork(userIsClaimedByOrganization = true).toSdkProfileOrganization(), since the network mock only flips userIsClaimedByOrganization while the SDK mock flips userIsManagedByOrganization.

Suggested fix: rename the parameter to userIsManagedByOrganization (default false) so the helper matches the SDK's actual field. This also makes it possible to assert the correct mapping path when a future test needs to verify userIsManagedByOrganization = true.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

@claude userIsManagedByOrganization is the deprecated name for the userIsClaimedByOrganization. We want to use the new name wherever possible

Copy link
Copy Markdown
Contributor

@claude claude Bot May 29, 2026

Choose a reason for hiding this comment

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

Claude finished @david-livefront's task in 44s —— View job


Response

Thanks for the clarification — you're right, and my earlier suggestion was wrong on this. Tracing through:

  • The network model only exposes the new name: SyncResponseJson.kt:455-456 defines userIsClaimedByOrganization.
  • The SDK still uses the deprecated name: ProfileOrganization.userIsManagedByOrganization.
  • The mapper bridges them at SyncResponseJsonExtensions.kt:122 (userIsManagedByOrganization = this.userIsClaimedByOrganization).
  • The helper does the same bridge at ProfileOrganizationUtil.kt:135 so the parameter name on both the network and SDK mock factories reads as userIsClaimedByOrganization, which is the convention you want.

That means createMockSdkProfileOrganization(userIsClaimedByOrganization = true) and createMockOrganizationNetwork(userIsClaimedByOrganization = true).toSdkProfileOrganization() do produce equivalent SDK objects — the concern in my original comment doesn't hold. No change needed.

@david-livefront david-livefront force-pushed the PM-37911-organization-network-model branch from c4cab72 to c86916a Compare May 29, 2026 15:23
@david-livefront david-livefront force-pushed the PM-37911-organization-network-model branch from c86916a to f3f06cc Compare May 29, 2026 15:25
*/
@Suppress("MaxLineLength")
fun List<SyncResponseJson.Profile.Organization>.toSdkProfileOrganizations(): List<ProfileOrganization> =
this.mapNotNull { it.toSdkProfileOrganization() }
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This function is currently used only for tests, but it will keep us in-sync with the SDK.

I will also be updating other spots in the app to use ProfileOrganization in a future PR.

@david-livefront
Copy link
Copy Markdown
Collaborator Author

Thanks @SaintPatrck

@david-livefront david-livefront added this pull request to the merge queue May 29, 2026
Merged via the queue into main with commit a3bcff9 May 29, 2026
44 checks passed
@david-livefront david-livefront deleted the PM-37911-organization-network-model branch May 29, 2026 18:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ai-review-vnext Request a Claude code review using the vNext workflow app:authenticator Bitwarden Authenticator app context app:password-manager Bitwarden Password Manager app context t:feature Change Type - Feature Development

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants