mirror of
https://github.com/bitwarden/android.git
synced 2024-10-31 15:15:34 +03:00
Establish device trust directly with a TrustDeviceResponse (#1246)
This commit is contained in:
parent
05d1607024
commit
2ae8a76103
3 changed files with 90 additions and 19 deletions
|
@ -1,5 +1,7 @@
|
|||
package com.x8bit.bitwarden.data.auth.manager
|
||||
|
||||
import com.bitwarden.crypto.TrustDeviceResponse
|
||||
|
||||
/**
|
||||
* Manager used to establish trust with this device.
|
||||
*/
|
||||
|
@ -8,4 +10,12 @@ interface TrustedDeviceManager {
|
|||
* Establishes trust with this device if necessary.
|
||||
*/
|
||||
suspend fun trustThisDeviceIfNecessary(userId: String): Result<Boolean>
|
||||
|
||||
/**
|
||||
* Establishes trust with this device based on the provided [TrustDeviceResponse].
|
||||
*/
|
||||
suspend fun trustThisDevice(
|
||||
userId: String,
|
||||
trustDeviceResponse: TrustDeviceResponse,
|
||||
): Result<Unit>
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.x8bit.bitwarden.data.auth.manager
|
||||
|
||||
import com.bitwarden.crypto.TrustDeviceResponse
|
||||
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.manager.util.toUserStateJson
|
||||
|
@ -32,26 +33,31 @@ class TrustedDeviceManagerImpl(
|
|||
} else {
|
||||
vaultSdkSource
|
||||
.getTrustDevice(userId = userId)
|
||||
.flatMap { trustedDevice ->
|
||||
devicesService
|
||||
.trustDevice(
|
||||
appId = authDiskSource.uniqueAppId,
|
||||
encryptedDevicePrivateKey = trustedDevice.protectedDevicePrivateKey,
|
||||
encryptedDevicePublicKey = trustedDevice.protectedDevicePublicKey,
|
||||
encryptedUserKey = trustedDevice.protectedUserKey,
|
||||
)
|
||||
.onSuccess {
|
||||
authDiskSource.storeDeviceKey(
|
||||
userId = userId,
|
||||
deviceKey = trustedDevice.deviceKey,
|
||||
)
|
||||
authDiskSource.userState = trustedDevice.toUserStateJson(
|
||||
userId = userId,
|
||||
previousUserState = requireNotNull(authDiskSource.userState),
|
||||
)
|
||||
}
|
||||
}
|
||||
.flatMap { trustThisDevice(userId = userId, trustDeviceResponse = it) }
|
||||
.also { authDiskSource.shouldTrustDevice = false }
|
||||
.map { true }
|
||||
}
|
||||
|
||||
override suspend fun trustThisDevice(
|
||||
userId: String,
|
||||
trustDeviceResponse: TrustDeviceResponse,
|
||||
): Result<Unit> = devicesService
|
||||
.trustDevice(
|
||||
appId = authDiskSource.uniqueAppId,
|
||||
encryptedDevicePrivateKey = trustDeviceResponse.protectedDevicePrivateKey,
|
||||
encryptedDevicePublicKey = trustDeviceResponse.protectedDevicePublicKey,
|
||||
encryptedUserKey = trustDeviceResponse.protectedUserKey,
|
||||
)
|
||||
.onSuccess {
|
||||
authDiskSource.storeDeviceKey(
|
||||
userId = userId,
|
||||
deviceKey = trustDeviceResponse.deviceKey,
|
||||
)
|
||||
authDiskSource.userState = trustDeviceResponse.toUserStateJson(
|
||||
userId = userId,
|
||||
previousUserState = requireNotNull(authDiskSource.userState),
|
||||
)
|
||||
}
|
||||
.also { authDiskSource.shouldTrustDevice = false }
|
||||
.map { Unit }
|
||||
}
|
||||
|
|
|
@ -207,6 +207,61 @@ class TrustedDeviceManagerTests {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `trustThisDevice when success should return success with true`() = runTest {
|
||||
val deviceKey = "deviceKey"
|
||||
val protectedUserKey = "protectedUserKey"
|
||||
val protectedDevicePrivateKey = "protectedDevicePrivateKey"
|
||||
val protectedDevicePublicKey = "protectedDevicePublicKey"
|
||||
val trustDeviceResponse = TrustDeviceResponse(
|
||||
deviceKey = deviceKey,
|
||||
protectedUserKey = protectedUserKey,
|
||||
protectedDevicePrivateKey = protectedDevicePrivateKey,
|
||||
protectedDevicePublicKey = protectedDevicePublicKey,
|
||||
)
|
||||
val trustedDeviceKeysResponseJson = TrustedDeviceKeysResponseJson(
|
||||
id = "id",
|
||||
name = "name",
|
||||
identifier = "identifier",
|
||||
type = 0,
|
||||
creationDate = ZonedDateTime.parse("2024-09-13T01:00:00.00Z"),
|
||||
)
|
||||
fakeAuthDiskSource.userState = DEFAULT_USER_STATE
|
||||
fakeAuthDiskSource.shouldTrustDevice = true
|
||||
coEvery {
|
||||
devicesService.trustDevice(
|
||||
appId = "testUniqueAppId",
|
||||
encryptedUserKey = protectedUserKey,
|
||||
encryptedDevicePublicKey = protectedDevicePublicKey,
|
||||
encryptedDevicePrivateKey = protectedDevicePrivateKey,
|
||||
)
|
||||
} returns trustedDeviceKeysResponseJson.asSuccess()
|
||||
every {
|
||||
trustDeviceResponse.toUserStateJson(
|
||||
userId = USER_ID,
|
||||
previousUserState = DEFAULT_USER_STATE,
|
||||
)
|
||||
} returns UPDATED_USER_STATE
|
||||
|
||||
val result = manager.trustThisDevice(
|
||||
userId = USER_ID,
|
||||
trustDeviceResponse = trustDeviceResponse,
|
||||
)
|
||||
|
||||
assertEquals(Unit.asSuccess(), result)
|
||||
fakeAuthDiskSource.assertDeviceKey(userId = USER_ID, deviceKey = deviceKey)
|
||||
assertFalse(fakeAuthDiskSource.shouldTrustDevice)
|
||||
fakeAuthDiskSource.assertUserState(UPDATED_USER_STATE)
|
||||
coVerify(exactly = 1) {
|
||||
devicesService.trustDevice(
|
||||
appId = "testUniqueAppId",
|
||||
encryptedUserKey = protectedUserKey,
|
||||
encryptedDevicePublicKey = protectedDevicePublicKey,
|
||||
encryptedDevicePrivateKey = protectedDevicePrivateKey,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private const val USER_ID: String = "userId"
|
||||
|
|
Loading…
Reference in a new issue