BIT-2259: Check device trust after each vault unlock (#1286)

This commit is contained in:
David Perez 2024-04-18 14:52:23 -05:00 committed by Álison Fernandes
parent dae98111e6
commit 1365a2a4fe
5 changed files with 27 additions and 17 deletions

View file

@ -439,7 +439,6 @@ class AuthRepositoryImpl(
)
authDiskSource.storeUserKey(userId = userId, userKey = asymmetricalKey)
trustedDeviceManager.trustThisDeviceIfNecessary(userId = userId)
vaultRepository.syncIfNecessary()
return LoginResult.Success
}
@ -1385,7 +1384,6 @@ class AuthRepositoryImpl(
organizationKeys = null,
)
authDiskSource.storeUserKey(userId = userId, userKey = userKey)
trustedDeviceManager.trustThisDeviceIfNecessary(userId = userId)
}
authDiskSource.storePendingAuthRequest(
userId = userId,

View file

@ -8,6 +8,7 @@ import com.bitwarden.crypto.HashPurpose
import com.bitwarden.crypto.Kdf
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.TrustedDeviceManager
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
@ -62,7 +63,8 @@ class VaultLockManagerImpl(
private val settingsRepository: SettingsRepository,
private val appForegroundManager: AppForegroundManager,
private val userLogoutManager: UserLogoutManager,
private val dispatcherManager: DispatcherManager,
private val trustedDeviceManager: TrustedDeviceManager,
dispatcherManager: DispatcherManager,
private val elapsedRealtimeMillisProvider: () -> Long = { SystemClock.elapsedRealtime() },
) : VaultLockManager {
private val unconfinedScope = CoroutineScope(dispatcherManager.unconfined)
@ -165,6 +167,9 @@ class VaultLockManagerImpl(
if (it is VaultUnlockResult.Success) {
clearInvalidUnlockCount(userId = userId)
setVaultToUnlocked(userId = userId)
trustedDeviceManager.trustThisDeviceIfNecessary(
userId = userId,
)
} else {
incrementInvalidUnlockCount(userId = userId)
}

View file

@ -3,6 +3,7 @@ package com.x8bit.bitwarden.data.vault.manager.di
import android.content.Context
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.TrustedDeviceManager
import com.x8bit.bitwarden.data.auth.manager.UserLogoutManager
import com.x8bit.bitwarden.data.platform.manager.AppForegroundManager
import com.x8bit.bitwarden.data.platform.manager.dispatcher.DispatcherManager
@ -52,6 +53,7 @@ object VaultManagerModule {
appForegroundManager: AppForegroundManager,
userLogoutManager: UserLogoutManager,
dispatcherManager: DispatcherManager,
trustedDeviceManager: TrustedDeviceManager,
): VaultLockManager =
VaultLockManagerImpl(
authDiskSource = authDiskSource,
@ -61,6 +63,7 @@ object VaultManagerModule {
appForegroundManager = appForegroundManager,
userLogoutManager = userLogoutManager,
dispatcherManager = dispatcherManager,
trustedDeviceManager = trustedDeviceManager,
)
@Provides

View file

@ -1215,9 +1215,6 @@ class AuthRepositoryTest {
organizationKeys = null,
)
} returns VaultUnlockResult.Success
coEvery {
trustedDeviceManager.trustThisDeviceIfNecessary(userId = USER_ID_1)
} returns true.asSuccess()
coEvery { vaultRepository.syncIfNecessary() } just runs
val result = repository.completeTdeLogin(
@ -1237,7 +1234,6 @@ class AuthRepositoryTest {
),
organizationKeys = null,
)
trustedDeviceManager.trustThisDeviceIfNecessary(userId = USER_ID_1)
vaultRepository.syncIfNecessary()
}
fakeAuthDiskSource.assertUserKey(userId = USER_ID_1, userKey = asymmetricalKey)
@ -2531,9 +2527,6 @@ class AuthRepositoryTest {
)
} returns successResponse.asSuccess()
coEvery { vaultRepository.syncIfNecessary() } just runs
coEvery {
trustedDeviceManager.trustThisDeviceIfNecessary(userId = USER_ID_1)
} returns true.asSuccess()
every {
successResponse.toUserState(
previousUserState = null,
@ -2577,7 +2570,6 @@ class AuthRepositoryTest {
),
organizationKeys = null,
)
trustedDeviceManager.trustThisDeviceIfNecessary(userId = USER_ID_1)
vaultRepository.syncIfNecessary()
}
verify(exactly = 1) {

View file

@ -9,6 +9,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.datasource.sdk.AuthSdkSource
import com.x8bit.bitwarden.data.auth.manager.TrustedDeviceManager
import com.x8bit.bitwarden.data.auth.manager.UserLogoutManager
import com.x8bit.bitwarden.data.auth.repository.util.toSdkParams
import com.x8bit.bitwarden.data.platform.base.FakeDispatcherManager
@ -62,6 +63,7 @@ class VaultLockManagerTest {
every { logout(any()) } just runs
every { softLogout(any()) } just runs
}
private val trustedDeviceManager: TrustedDeviceManager = mockk()
private val mutableVaultTimeoutStateFlow =
MutableStateFlow<VaultTimeout>(VaultTimeout.ThirtyMinutes)
private val mutableVaultTimeoutActionStateFlow = MutableStateFlow(VaultTimeoutAction.LOCK)
@ -79,6 +81,7 @@ class VaultLockManagerTest {
settingsRepository = settingsRepository,
appForegroundManager = fakeAppForegroundManager,
userLogoutManager = userLogoutManager,
trustedDeviceManager = trustedDeviceManager,
dispatcherManager = FakeDispatcherManager(),
elapsedRealtimeMillisProvider = { elapsedRealtimeMillis },
)
@ -545,6 +548,9 @@ class VaultLockManagerTest {
),
)
} returns InitializeCryptoResult.Success.asSuccess()
coEvery {
trustedDeviceManager.trustThisDeviceIfNecessary(userId = USER_ID)
} returns true.asSuccess()
assertFalse(vaultLockManager.isVaultUnlocked(userId = USER_ID))
@ -564,6 +570,7 @@ class VaultLockManagerTest {
),
),
)
trustedDeviceManager.trustThisDeviceIfNecessary(userId = USER_ID)
}
}
@ -702,6 +709,9 @@ class VaultLockManagerTest {
request = InitOrgCryptoRequest(organizationKeys = organizationKeys),
)
} returns InitializeCryptoResult.Success.asSuccess()
coEvery {
trustedDeviceManager.trustThisDeviceIfNecessary(userId = USER_ID)
} returns false.asSuccess()
assertEquals(
emptyList<VaultUnlockData>(),
vaultLockManager.vaultUnlockDataStateFlow.value,
@ -756,12 +766,11 @@ class VaultLockManagerTest {
),
),
)
}
coVerify(exactly = 1) {
vaultSdkSource.initializeOrganizationCrypto(
userId = USER_ID,
request = InitOrgCryptoRequest(organizationKeys = organizationKeys),
)
trustedDeviceManager.trustThisDeviceIfNecessary(userId = USER_ID)
}
}
@ -799,6 +808,9 @@ class VaultLockManagerTest {
coEvery {
vaultSdkSource.getUserEncryptionKey(userId = USER_ID)
} returns userAutoUnlockKey.asSuccess()
coEvery {
trustedDeviceManager.trustThisDeviceIfNecessary(userId = USER_ID)
} returns true.asSuccess()
assertEquals(
emptyList<VaultUnlockData>(),
vaultLockManager.vaultUnlockDataStateFlow.value,
@ -861,15 +873,12 @@ class VaultLockManagerTest {
),
),
)
}
coVerify(exactly = 1) {
vaultSdkSource.initializeOrganizationCrypto(
userId = USER_ID,
request = InitOrgCryptoRequest(organizationKeys = organizationKeys),
)
}
coVerify {
vaultSdkSource.getUserEncryptionKey(userId = USER_ID)
trustedDeviceManager.trustThisDeviceIfNecessary(userId = USER_ID)
}
}
@ -1410,6 +1419,9 @@ class VaultLockManagerTest {
coEvery {
vaultSdkSource.getUserEncryptionKey(userId = userId)
} returns userAutoUnlockKey.asSuccess()
coEvery {
trustedDeviceManager.trustThisDeviceIfNecessary(userId = userId)
} returns true.asSuccess()
val result = vaultLockManager.unlockVault(
userId = userId,