mirror of
https://github.com/bitwarden/android.git
synced 2024-10-31 15:15:34 +03:00
Add AuthDiskSource helper for knowing when the user changes (#1007)
This commit is contained in:
parent
2739b9e001
commit
6bfb9440b5
4 changed files with 109 additions and 13 deletions
|
@ -0,0 +1,9 @@
|
|||
package com.x8bit.bitwarden.data.auth.repository.model
|
||||
|
||||
/**
|
||||
* Contains the values of the previous and new active user IDs when switching active users.
|
||||
*/
|
||||
data class UserSwitchingData(
|
||||
val previousActiveUserId: String?,
|
||||
val currentActiveUserId: String?,
|
||||
)
|
|
@ -2,6 +2,7 @@ package com.x8bit.bitwarden.data.auth.repository.util
|
|||
|
||||
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
|
||||
import com.x8bit.bitwarden.data.auth.repository.model.UserOrganizations
|
||||
import com.x8bit.bitwarden.data.auth.repository.model.UserSwitchingData
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
|
@ -53,3 +54,23 @@ val AuthDiskSource.userOrganizationsListFlow: Flow<List<UserOrganizations>>
|
|||
) { values -> values.toList() }
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
|
||||
/**
|
||||
* Returns a [Flow] that emits every time the active user is changed.
|
||||
*/
|
||||
val AuthDiskSource.userSwitchingChangesFlow: Flow<UserSwitchingData>
|
||||
get() {
|
||||
var lastActiveUserId: String? = null
|
||||
return this
|
||||
.userStateFlow
|
||||
.map { it?.activeUserId }
|
||||
.distinctUntilChanged()
|
||||
.map { activeUserId ->
|
||||
val previousActiveUserId = lastActiveUserId
|
||||
lastActiveUserId = activeUserId
|
||||
UserSwitchingData(
|
||||
previousActiveUserId = previousActiveUserId,
|
||||
currentActiveUserId = activeUserId,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
|
|||
import com.x8bit.bitwarden.data.auth.datasource.sdk.AuthSdkSource
|
||||
import com.x8bit.bitwarden.data.auth.manager.UserLogoutManager
|
||||
import com.x8bit.bitwarden.data.auth.repository.util.toSdkParams
|
||||
import com.x8bit.bitwarden.data.auth.repository.util.userSwitchingChangesFlow
|
||||
import com.x8bit.bitwarden.data.platform.manager.AppForegroundManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.model.AppForegroundState
|
||||
|
@ -36,7 +37,6 @@ import kotlinx.coroutines.flow.flatMapLatest
|
|||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.mapNotNull
|
||||
import kotlinx.coroutines.flow.merge
|
||||
import kotlinx.coroutines.flow.onCompletion
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
|
@ -300,21 +300,15 @@ class VaultLockManagerImpl(
|
|||
}
|
||||
|
||||
private fun observeUserSwitchingChanges() {
|
||||
var lastActiveUserId: String? = null
|
||||
|
||||
authDiskSource
|
||||
.userStateFlow
|
||||
.mapNotNull { it?.activeUserId }
|
||||
.distinctUntilChanged()
|
||||
.onEach { activeUserId ->
|
||||
val previousActiveUserId = lastActiveUserId
|
||||
lastActiveUserId = activeUserId
|
||||
if (previousActiveUserId != null &&
|
||||
activeUserId != previousActiveUserId
|
||||
) {
|
||||
.userSwitchingChangesFlow
|
||||
.onEach { userSwitchingData ->
|
||||
val previousActiveUserId = userSwitchingData.previousActiveUserId
|
||||
val currentActiveUserId = userSwitchingData.currentActiveUserId
|
||||
if (previousActiveUserId != null && currentActiveUserId != null) {
|
||||
handleUserSwitch(
|
||||
previousActiveUserId = previousActiveUserId,
|
||||
currentActiveUserId = activeUserId,
|
||||
currentActiveUserId = currentActiveUserId,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ 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.repository.model.Organization
|
||||
import com.x8bit.bitwarden.data.auth.repository.model.UserOrganizations
|
||||
import com.x8bit.bitwarden.data.auth.repository.model.UserSwitchingData
|
||||
import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockOrganization
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
|
@ -154,4 +155,75 @@ class AuthDiskSourceExtensionsTest {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `userSwitchingChangesFlow should emit changes when active user changes`() = runTest {
|
||||
authDiskSource.userSwitchingChangesFlow.test {
|
||||
assertEquals(
|
||||
UserSwitchingData(
|
||||
previousActiveUserId = null,
|
||||
currentActiveUserId = null,
|
||||
),
|
||||
awaitItem(),
|
||||
)
|
||||
authDiskSource.userState = MOCK_USER_STATE
|
||||
assertEquals(
|
||||
UserSwitchingData(
|
||||
previousActiveUserId = null,
|
||||
currentActiveUserId = MOCK_USER_ID,
|
||||
),
|
||||
awaitItem(),
|
||||
)
|
||||
authDiskSource.userState = MOCK_USER_STATE.copy(
|
||||
accounts = mapOf(
|
||||
MOCK_USER_ID to MOCK_ACCOUNT,
|
||||
"mockId-2" to mockk(),
|
||||
),
|
||||
)
|
||||
expectNoEvents()
|
||||
authDiskSource.userState = null
|
||||
assertEquals(
|
||||
UserSwitchingData(
|
||||
previousActiveUserId = MOCK_USER_ID,
|
||||
currentActiveUserId = null,
|
||||
),
|
||||
awaitItem(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private const val MOCK_USER_ID: String = "mockId-1"
|
||||
|
||||
private val MOCK_PROFILE = AccountJson.Profile(
|
||||
userId = MOCK_USER_ID,
|
||||
email = "email",
|
||||
isEmailVerified = true,
|
||||
name = null,
|
||||
stamp = null,
|
||||
organizationId = null,
|
||||
avatarColorHex = null,
|
||||
hasPremium = false,
|
||||
forcePasswordResetReason = null,
|
||||
kdfType = null,
|
||||
kdfIterations = null,
|
||||
kdfMemory = null,
|
||||
kdfParallelism = null,
|
||||
userDecryptionOptions = null,
|
||||
)
|
||||
|
||||
private val MOCK_ACCOUNT = AccountJson(
|
||||
profile = MOCK_PROFILE,
|
||||
tokens = AccountJson.Tokens(
|
||||
accessToken = "accessToken",
|
||||
refreshToken = "refreshToken",
|
||||
),
|
||||
settings = AccountJson.Settings(
|
||||
environmentUrlData = null,
|
||||
),
|
||||
)
|
||||
|
||||
private val MOCK_USER_STATE = UserStateJson(
|
||||
activeUserId = MOCK_USER_ID,
|
||||
accounts = mapOf(MOCK_USER_ID to MOCK_ACCOUNT),
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue