[PM-27806] Reverted changes to order of StorePolicies after sync (#6130)

This commit is contained in:
aj-rosado 2025-11-06 16:54:22 +00:00 committed by GitHub
parent 94ed32790f
commit b715a51188
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 50 additions and 36 deletions

View File

@ -14,6 +14,7 @@ import com.bitwarden.vault.DecryptCipherListResult
import com.bitwarden.vault.FolderView
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
import com.x8bit.bitwarden.data.auth.manager.UserLogoutManager
import com.x8bit.bitwarden.data.auth.manager.UserStateManager
import com.x8bit.bitwarden.data.auth.repository.model.LogoutReason
import com.x8bit.bitwarden.data.auth.repository.util.toUpdatedUserStateJson
import com.x8bit.bitwarden.data.auth.repository.util.userSwitchingChangesFlow
@ -78,6 +79,7 @@ class VaultSyncManagerImpl(
private val vaultDiskSource: VaultDiskSource,
private val vaultSdkSource: VaultSdkSource,
private val userLogoutManager: UserLogoutManager,
private val userStateManager: UserStateManager,
private val vaultLockManager: VaultLockManager,
private val clock: Clock,
databaseSchemeManager: DatabaseSchemeManager,
@ -301,44 +303,46 @@ class VaultSyncManagerImpl(
return syncService.sync().fold(
onSuccess = { syncResponse ->
val localSecurityStamp = authDiskSource.userState?.activeAccount?.profile?.stamp
val serverSecurityStamp = syncResponse.profile.securityStamp
// Log the user out if the stamps do not match
localSecurityStamp?.let {
if (serverSecurityStamp != localSecurityStamp) {
// Ensure UserLogoutManager is available
userLogoutManager.softLogout(
userId = userId,
reason = LogoutReason.SecurityStamp,
)
return SyncVaultDataResult.Error(SecurityStampMismatchException())
userStateManager.userStateTransaction {
val localSecurityStamp = authDiskSource.userState?.activeAccount?.profile?.stamp
val serverSecurityStamp = syncResponse.profile.securityStamp
// Log the user out if the stamps do not match
localSecurityStamp?.let {
if (serverSecurityStamp != localSecurityStamp) {
// Ensure UserLogoutManager is available
userLogoutManager.softLogout(
userId = userId,
reason = LogoutReason.SecurityStamp,
)
return@userStateTransaction SyncVaultDataResult.Error(
SecurityStampMismatchException(),
)
}
}
// Update user information with additional information from sync response
authDiskSource.userState = authDiskSource.userState?.toUpdatedUserStateJson(
syncResponse = syncResponse,
)
unlockVaultForOrganizationsIfNecessary(syncResponse = syncResponse)
storeProfileData(syncResponse = syncResponse)
// Treat absent network policies as known empty data to
// distinguish between unknown null data.
authDiskSource.storePolicies(
userId = userId,
policies = syncResponse.policies.orEmpty(),
)
settingsDiskSource.storeLastSyncTime(
userId = userId,
lastSyncTime = clock.instant(),
)
vaultDiskSource.replaceVaultData(userId = userId, vault = syncResponse)
val itemsAvailable = syncResponse.ciphers?.isNotEmpty() == true
SyncVaultDataResult.Success(itemsAvailable = itemsAvailable)
}
// Treat absent network policies as known empty data to
// distinguish between unknown null data.
// The user state update will trigger flows that depend on the latest policies.
// We must store the new policies first to prevent old data on UserState.
authDiskSource.storePolicies(
userId = userId,
policies = syncResponse.policies.orEmpty(),
)
// Update user information with additional information from sync response
authDiskSource.userState = authDiskSource.userState?.toUpdatedUserStateJson(
syncResponse = syncResponse,
)
unlockVaultForOrganizationsIfNecessary(syncResponse = syncResponse)
storeProfileData(syncResponse = syncResponse)
settingsDiskSource.storeLastSyncTime(
userId = userId,
lastSyncTime = clock.instant(),
)
vaultDiskSource.replaceVaultData(userId = userId, vault = syncResponse)
val itemsAvailable = syncResponse.ciphers?.isNotEmpty() == true
SyncVaultDataResult.Success(itemsAvailable = itemsAvailable)
},
onFailure = {
updateVaultStateFlowsToError(throwable = it)

View File

@ -13,6 +13,7 @@ import com.x8bit.bitwarden.data.auth.datasource.sdk.AuthSdkSource
import com.x8bit.bitwarden.data.auth.manager.KdfManager
import com.x8bit.bitwarden.data.auth.manager.TrustedDeviceManager
import com.x8bit.bitwarden.data.auth.manager.UserLogoutManager
import com.x8bit.bitwarden.data.auth.manager.UserStateManager
import com.x8bit.bitwarden.data.platform.datasource.disk.SettingsDiskSource
import com.x8bit.bitwarden.data.platform.manager.AppStateManager
import com.x8bit.bitwarden.data.platform.manager.DatabaseSchemeManager
@ -182,6 +183,7 @@ object VaultManagerModule {
vaultDiskSource: VaultDiskSource,
vaultSdkSource: VaultSdkSource,
userLogoutManager: UserLogoutManager,
userStateManager: UserStateManager,
vaultLockManager: VaultLockManager,
clock: Clock,
databaseSchemeManager: DatabaseSchemeManager,
@ -194,6 +196,7 @@ object VaultManagerModule {
vaultDiskSource = vaultDiskSource,
vaultSdkSource = vaultSdkSource,
userLogoutManager = userLogoutManager,
userStateManager = userStateManager,
vaultLockManager = vaultLockManager,
clock = clock,
databaseSchemeManager = databaseSchemeManager,

View File

@ -29,6 +29,7 @@ import com.x8bit.bitwarden.data.auth.datasource.disk.model.AccountTokensJson
import com.x8bit.bitwarden.data.auth.datasource.disk.model.UserStateJson
import com.x8bit.bitwarden.data.auth.datasource.disk.util.FakeAuthDiskSource
import com.x8bit.bitwarden.data.auth.manager.UserLogoutManager
import com.x8bit.bitwarden.data.auth.manager.UserStateManager
import com.x8bit.bitwarden.data.auth.repository.model.LogoutReason
import com.x8bit.bitwarden.data.platform.datasource.disk.SettingsDiskSource
import com.x8bit.bitwarden.data.platform.error.MissingPropertyException
@ -64,6 +65,7 @@ import io.mockk.just
import io.mockk.mockk
import io.mockk.mockkConstructor
import io.mockk.runs
import io.mockk.slot
import io.mockk.unmockkConstructor
import io.mockk.verify
import kotlinx.coroutines.flow.Flow
@ -126,6 +128,10 @@ class VaultSyncManagerTest {
private val userLogoutManager: UserLogoutManager = mockk {
every { softLogout(any(), any()) } just runs
}
private val userStateManager: UserStateManager = mockk {
val blockSlot = slot<suspend () -> SyncVaultDataResult>()
coEvery { userStateTransaction(capture(blockSlot)) } coAnswers { blockSlot.captured() }
}
private val mutableFullSyncFlow = bufferedMutableSharedFlow<String>()
private val pushManager: PushManager = mockk {
every { fullSyncFlow } returns mutableFullSyncFlow
@ -142,6 +148,7 @@ class VaultSyncManagerTest {
vaultDiskSource = vaultDiskSource,
vaultSdkSource = vaultSdkSource,
userLogoutManager = userLogoutManager,
userStateManager = userStateManager,
vaultLockManager = vaultLockManager,
clock = clock,
databaseSchemeManager = databaseSchemeManager,