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
|
package com.x8bit.bitwarden.data.auth.manager
|
||||||
|
|
||||||
|
import com.bitwarden.crypto.TrustDeviceResponse
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manager used to establish trust with this device.
|
* Manager used to establish trust with this device.
|
||||||
*/
|
*/
|
||||||
|
@ -8,4 +10,12 @@ interface TrustedDeviceManager {
|
||||||
* Establishes trust with this device if necessary.
|
* Establishes trust with this device if necessary.
|
||||||
*/
|
*/
|
||||||
suspend fun trustThisDeviceIfNecessary(userId: String): Result<Boolean>
|
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
|
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.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
|
||||||
|
@ -32,26 +33,31 @@ class TrustedDeviceManagerImpl(
|
||||||
} else {
|
} else {
|
||||||
vaultSdkSource
|
vaultSdkSource
|
||||||
.getTrustDevice(userId = userId)
|
.getTrustDevice(userId = userId)
|
||||||
.flatMap { trustedDevice ->
|
.flatMap { trustThisDevice(userId = userId, trustDeviceResponse = it) }
|
||||||
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),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.also { authDiskSource.shouldTrustDevice = false }
|
.also { authDiskSource.shouldTrustDevice = false }
|
||||||
.map { true }
|
.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"
|
private const val USER_ID: String = "userId"
|
||||||
|
|
Loading…
Reference in a new issue