mirror of
https://github.com/bitwarden/android.git
synced 2024-10-31 07:05:35 +03:00
Remove the in-memory deviceKey (#1270)
This commit is contained in:
parent
20f7811b6a
commit
921240d173
5 changed files with 11 additions and 54 deletions
|
@ -119,15 +119,8 @@ interface AuthDiskSource {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores the device key for the given [userId].
|
* Stores the device key for the given [userId].
|
||||||
*
|
|
||||||
* When [inMemoryOnly] is `true`, the value will only be available via a call to [getDeviceKey]
|
|
||||||
* during the current app session.
|
|
||||||
*/
|
*/
|
||||||
fun storeDeviceKey(
|
fun storeDeviceKey(userId: String, deviceKey: String?)
|
||||||
userId: String,
|
|
||||||
deviceKey: String?,
|
|
||||||
inMemoryOnly: Boolean = false,
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the stored [PendingAuthRequestJson] for the given [userId].
|
* Gets the stored [PendingAuthRequestJson] for the given [userId].
|
||||||
|
|
|
@ -56,7 +56,6 @@ class AuthDiskSourceImpl(
|
||||||
),
|
),
|
||||||
AuthDiskSource {
|
AuthDiskSource {
|
||||||
|
|
||||||
private val inMemoryDeviceKeys = mutableMapOf<String, String?>()
|
|
||||||
private val inMemoryPinProtectedUserKeys = mutableMapOf<String, String?>()
|
private val inMemoryPinProtectedUserKeys = mutableMapOf<String, String?>()
|
||||||
private val mutableOrganizationsFlowMap =
|
private val mutableOrganizationsFlowMap =
|
||||||
mutableMapOf<String, MutableSharedFlow<List<SyncResponseJson.Profile.Organization>?>>()
|
mutableMapOf<String, MutableSharedFlow<List<SyncResponseJson.Profile.Organization>?>>()
|
||||||
|
@ -200,15 +199,12 @@ class AuthDiskSourceImpl(
|
||||||
|
|
||||||
override fun getDeviceKey(
|
override fun getDeviceKey(
|
||||||
userId: String,
|
userId: String,
|
||||||
): String? = inMemoryDeviceKeys[userId] ?: getEncryptedString(key = "${DEVICE_KEY_KEY}_$userId")
|
): String? = getEncryptedString(key = "${DEVICE_KEY_KEY}_$userId")
|
||||||
|
|
||||||
override fun storeDeviceKey(
|
override fun storeDeviceKey(
|
||||||
userId: String,
|
userId: String,
|
||||||
deviceKey: String?,
|
deviceKey: String?,
|
||||||
inMemoryOnly: Boolean,
|
|
||||||
) {
|
) {
|
||||||
inMemoryDeviceKeys[userId] = deviceKey
|
|
||||||
if (inMemoryOnly) return
|
|
||||||
putEncryptedString(key = "${DEVICE_KEY_KEY}_$userId", value = deviceKey)
|
putEncryptedString(key = "${DEVICE_KEY_KEY}_$userId", value = deviceKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import com.bitwarden.crypto.TrustDeviceResponse
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
|
import com.x8bit.bitwarden.data.auth.datasource.disk.AuthDiskSource
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.service.DevicesService
|
import com.x8bit.bitwarden.data.auth.datasource.network.service.DevicesService
|
||||||
import com.x8bit.bitwarden.data.auth.manager.util.toUserStateJson
|
import com.x8bit.bitwarden.data.auth.manager.util.toUserStateJson
|
||||||
|
import com.x8bit.bitwarden.data.platform.util.asSuccess
|
||||||
import com.x8bit.bitwarden.data.platform.util.flatMap
|
import com.x8bit.bitwarden.data.platform.util.flatMap
|
||||||
import com.x8bit.bitwarden.data.vault.datasource.sdk.VaultSdkSource
|
import com.x8bit.bitwarden.data.vault.datasource.sdk.VaultSdkSource
|
||||||
|
|
||||||
|
@ -17,19 +18,7 @@ class TrustedDeviceManagerImpl(
|
||||||
) : TrustedDeviceManager {
|
) : TrustedDeviceManager {
|
||||||
override suspend fun trustThisDeviceIfNecessary(userId: String): Result<Boolean> =
|
override suspend fun trustThisDeviceIfNecessary(userId: String): Result<Boolean> =
|
||||||
if (!authDiskSource.shouldTrustDevice) {
|
if (!authDiskSource.shouldTrustDevice) {
|
||||||
// Even though we are not trusting the device, we still store the device key in
|
false.asSuccess()
|
||||||
// memory. This allows the user to be "trusted" for this session but on timeout
|
|
||||||
// or reboot, the "trust" will be gone.
|
|
||||||
vaultSdkSource
|
|
||||||
.getTrustDevice(userId = userId)
|
|
||||||
.onSuccess { trustedDevice ->
|
|
||||||
authDiskSource.storeDeviceKey(
|
|
||||||
userId = userId,
|
|
||||||
deviceKey = trustedDevice.deviceKey,
|
|
||||||
inMemoryOnly = true,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
.map { false }
|
|
||||||
} else {
|
} else {
|
||||||
vaultSdkSource
|
vaultSdkSource
|
||||||
.getTrustDevice(userId = userId)
|
.getTrustDevice(userId = userId)
|
||||||
|
|
|
@ -38,7 +38,7 @@ class FakeAuthDiskSource : AuthDiskSource {
|
||||||
mutableMapOf<String, List<SyncResponseJson.Profile.Organization>?>()
|
mutableMapOf<String, List<SyncResponseJson.Profile.Organization>?>()
|
||||||
private val storedOrganizationKeys = mutableMapOf<String, Map<String, String>?>()
|
private val storedOrganizationKeys = mutableMapOf<String, Map<String, String>?>()
|
||||||
private val storedAccountTokens = mutableMapOf<String, AccountTokensJson?>()
|
private val storedAccountTokens = mutableMapOf<String, AccountTokensJson?>()
|
||||||
private val storedDeviceKey = mutableMapOf<String, Pair<String?, Boolean>>()
|
private val storedDeviceKey = mutableMapOf<String, String?>()
|
||||||
private val storedPendingAuthRequests = mutableMapOf<String, PendingAuthRequestJson?>()
|
private val storedPendingAuthRequests = mutableMapOf<String, PendingAuthRequestJson?>()
|
||||||
private val storedBiometricKeys = mutableMapOf<String, String?>()
|
private val storedBiometricKeys = mutableMapOf<String, String?>()
|
||||||
private val storedMasterPasswordHashes = mutableMapOf<String, String?>()
|
private val storedMasterPasswordHashes = mutableMapOf<String, String?>()
|
||||||
|
@ -166,14 +166,10 @@ class FakeAuthDiskSource : AuthDiskSource {
|
||||||
getMutableOrganizationsFlow(userId = userId).tryEmit(organizations)
|
getMutableOrganizationsFlow(userId = userId).tryEmit(organizations)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDeviceKey(userId: String): String? = storedDeviceKey[userId]?.first
|
override fun getDeviceKey(userId: String): String? = storedDeviceKey[userId]
|
||||||
|
|
||||||
override fun storeDeviceKey(
|
override fun storeDeviceKey(userId: String, deviceKey: String?) {
|
||||||
userId: String,
|
storedDeviceKey[userId] = deviceKey
|
||||||
deviceKey: String?,
|
|
||||||
inMemoryOnly: Boolean,
|
|
||||||
) {
|
|
||||||
storedDeviceKey[userId] = deviceKey to inMemoryOnly
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getPendingAuthRequest(userId: String): PendingAuthRequestJson? =
|
override fun getPendingAuthRequest(userId: String): PendingAuthRequestJson? =
|
||||||
|
@ -301,8 +297,8 @@ class FakeAuthDiskSource : AuthDiskSource {
|
||||||
/**
|
/**
|
||||||
* Assert that the [deviceKey] was stored successfully using the [userId].
|
* Assert that the [deviceKey] was stored successfully using the [userId].
|
||||||
*/
|
*/
|
||||||
fun assertDeviceKey(userId: String, deviceKey: String?, inMemoryOnly: Boolean = false) {
|
fun assertDeviceKey(userId: String, deviceKey: String?) {
|
||||||
assertEquals(deviceKey to inMemoryOnly, storedDeviceKey[userId])
|
assertEquals(deviceKey, storedDeviceKey[userId])
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -53,30 +53,13 @@ class TrustedDeviceManagerTests {
|
||||||
@Test
|
@Test
|
||||||
fun `trustThisDeviceIfNecessary when shouldTrustDevice false should return success with false`() =
|
fun `trustThisDeviceIfNecessary when shouldTrustDevice false should return success with false`() =
|
||||||
runTest {
|
runTest {
|
||||||
val deviceKey = "deviceKey"
|
|
||||||
val trustedDeviceResponse = TrustDeviceResponse(
|
|
||||||
deviceKey = deviceKey,
|
|
||||||
protectedUserKey = "protectedUserKey",
|
|
||||||
protectedDevicePrivateKey = "protectedDevicePrivateKey",
|
|
||||||
protectedDevicePublicKey = "protectedDevicePublicKey",
|
|
||||||
)
|
|
||||||
fakeAuthDiskSource.shouldTrustDevice = false
|
fakeAuthDiskSource.shouldTrustDevice = false
|
||||||
coEvery {
|
|
||||||
vaultSdkSource.getTrustDevice(userId = USER_ID)
|
|
||||||
} returns trustedDeviceResponse.asSuccess()
|
|
||||||
|
|
||||||
val result = manager.trustThisDeviceIfNecessary(userId = USER_ID)
|
val result = manager.trustThisDeviceIfNecessary(userId = USER_ID)
|
||||||
|
|
||||||
assertEquals(false.asSuccess(), result)
|
assertEquals(false.asSuccess(), result)
|
||||||
fakeAuthDiskSource.assertDeviceKey(
|
|
||||||
userId = USER_ID,
|
|
||||||
deviceKey = deviceKey,
|
|
||||||
inMemoryOnly = true,
|
|
||||||
)
|
|
||||||
coVerify(exactly = 1) {
|
|
||||||
vaultSdkSource.getTrustDevice(userId = USER_ID)
|
|
||||||
}
|
|
||||||
coVerify(exactly = 0) {
|
coVerify(exactly = 0) {
|
||||||
|
vaultSdkSource.getTrustDevice(userId = USER_ID)
|
||||||
devicesService.trustDevice(
|
devicesService.trustDevice(
|
||||||
appId = any(),
|
appId = any(),
|
||||||
encryptedUserKey = any(),
|
encryptedUserKey = any(),
|
||||||
|
|
Loading…
Reference in a new issue