mirror of
https://github.com/bitwarden/android.git
synced 2026-03-11 20:54:58 -05:00
[PM-23278] Upgrade user KDF settings to minimums (#5955)
Co-authored-by: David Perez <david@livefront.com>
This commit is contained in:
@@ -5,6 +5,7 @@ import com.bitwarden.network.model.DeleteAccountRequestJson
|
||||
import com.bitwarden.network.model.NetworkResult
|
||||
import com.bitwarden.network.model.ResetPasswordRequestJson
|
||||
import com.bitwarden.network.model.SetPasswordRequestJson
|
||||
import com.bitwarden.network.model.UpdateKdfJsonRequest
|
||||
import com.bitwarden.network.model.VerifyOtpRequestJson
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.HTTP
|
||||
@@ -36,6 +37,12 @@ internal interface AuthenticatedAccountsApi {
|
||||
@POST("/accounts/request-otp")
|
||||
suspend fun requestOtp(): NetworkResult<Unit>
|
||||
|
||||
/**
|
||||
* Update the KDF settings for the current account.
|
||||
*/
|
||||
@POST("/accounts/kdf")
|
||||
suspend fun updateKdf(@Body body: UpdateKdfJsonRequest): NetworkResult<Unit>
|
||||
|
||||
@POST("/accounts/verify-otp")
|
||||
suspend fun verifyOtp(
|
||||
@Body body: VerifyOtpRequestJson,
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.bitwarden.network.model
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Represents the data used to authenticate with the master password.
|
||||
*/
|
||||
@Serializable
|
||||
data class MasterPasswordAuthenticationDataJson(
|
||||
@SerialName("Kdf")
|
||||
val kdf: KdfJson,
|
||||
|
||||
@SerialName("MasterPasswordAuthenticationHash")
|
||||
val masterPasswordAuthenticationHash: String,
|
||||
|
||||
@SerialName("Salt")
|
||||
val salt: String,
|
||||
)
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.bitwarden.network.model
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Represents the request body used to update the user's kdf settings.
|
||||
*/
|
||||
@Serializable
|
||||
data class UpdateKdfJsonRequest(
|
||||
@SerialName("authenticationData")
|
||||
val authenticationData: MasterPasswordAuthenticationDataJson,
|
||||
|
||||
@SerialName("key")
|
||||
val key: String,
|
||||
|
||||
@SerialName("masterPasswordHash")
|
||||
val masterPasswordHash: String,
|
||||
|
||||
@SerialName("newMasterPasswordHash")
|
||||
val newMasterPasswordHash: String,
|
||||
|
||||
@SerialName("unlockData")
|
||||
val unlockData: MasterPasswordUnlockDataJson,
|
||||
)
|
||||
@@ -8,6 +8,7 @@ import com.bitwarden.network.model.ResendEmailRequestJson
|
||||
import com.bitwarden.network.model.ResendNewDeviceOtpRequestJson
|
||||
import com.bitwarden.network.model.ResetPasswordRequestJson
|
||||
import com.bitwarden.network.model.SetPasswordRequestJson
|
||||
import com.bitwarden.network.model.UpdateKdfJsonRequest
|
||||
import com.bitwarden.network.model.VerificationCodeResponseJson
|
||||
import com.bitwarden.network.model.VerificationOtpResponseJson
|
||||
|
||||
@@ -115,4 +116,9 @@ interface AccountsService {
|
||||
accessToken: String,
|
||||
masterKey: String,
|
||||
): Result<Unit>
|
||||
|
||||
/**
|
||||
* Update the KDF settings for the current account.
|
||||
*/
|
||||
suspend fun updateKdf(body: UpdateKdfJsonRequest): Result<Unit>
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.bitwarden.network.model.ResendEmailRequestJson
|
||||
import com.bitwarden.network.model.ResendNewDeviceOtpRequestJson
|
||||
import com.bitwarden.network.model.ResetPasswordRequestJson
|
||||
import com.bitwarden.network.model.SetPasswordRequestJson
|
||||
import com.bitwarden.network.model.UpdateKdfJsonRequest
|
||||
import com.bitwarden.network.model.VerificationCodeResponseJson
|
||||
import com.bitwarden.network.model.VerificationOtpResponseJson
|
||||
import com.bitwarden.network.model.VerifyOtpRequestJson
|
||||
@@ -209,4 +210,9 @@ internal class AccountsServiceImpl(
|
||||
body = KeyConnectorMasterKeyRequestJson(masterKey = masterKey),
|
||||
)
|
||||
.toResult()
|
||||
|
||||
override suspend fun updateKdf(body: UpdateKdfJsonRequest): Result<Unit> =
|
||||
authenticatedAccountsApi
|
||||
.updateKdf(body)
|
||||
.toResult()
|
||||
}
|
||||
|
||||
@@ -6,15 +6,19 @@ import com.bitwarden.network.api.AuthenticatedKeyConnectorApi
|
||||
import com.bitwarden.network.api.UnauthenticatedAccountsApi
|
||||
import com.bitwarden.network.api.UnauthenticatedKeyConnectorApi
|
||||
import com.bitwarden.network.base.BaseServiceTest
|
||||
import com.bitwarden.network.model.KdfJson
|
||||
import com.bitwarden.network.model.KdfTypeJson
|
||||
import com.bitwarden.network.model.KeyConnectorKeyRequestJson
|
||||
import com.bitwarden.network.model.KeyConnectorMasterKeyResponseJson
|
||||
import com.bitwarden.network.model.MasterPasswordAuthenticationDataJson
|
||||
import com.bitwarden.network.model.MasterPasswordUnlockDataJson
|
||||
import com.bitwarden.network.model.PasswordHintResponseJson
|
||||
import com.bitwarden.network.model.RegisterRequestJson
|
||||
import com.bitwarden.network.model.ResendEmailRequestJson
|
||||
import com.bitwarden.network.model.ResendNewDeviceOtpRequestJson
|
||||
import com.bitwarden.network.model.ResetPasswordRequestJson
|
||||
import com.bitwarden.network.model.SetPasswordRequestJson
|
||||
import com.bitwarden.network.model.UpdateKdfJsonRequest
|
||||
import com.bitwarden.network.model.VerificationCodeResponseJson
|
||||
import com.bitwarden.network.model.VerificationOtpResponseJson
|
||||
import kotlinx.coroutines.test.runTest
|
||||
@@ -291,6 +295,25 @@ class AccountsServiceTest : BaseServiceTest() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `updateKdf success should return Success`() = runTest {
|
||||
val response = MockResponse().setResponseCode(200)
|
||||
server.enqueue(response)
|
||||
|
||||
val result = service.updateKdf(body = UPDATE_KDF_REQUEST)
|
||||
|
||||
assertTrue(result.isSuccess)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `updateKdf failure should return Failure`() = runTest {
|
||||
val response = MockResponse().setResponseCode(400)
|
||||
server.enqueue(response)
|
||||
|
||||
val result = service.updateKdf(body = UPDATE_KDF_REQUEST)
|
||||
|
||||
assertTrue(result.isFailure)
|
||||
}
|
||||
|
||||
fun `resendNewDeviceOtp with 400 response is Error`() = runTest {
|
||||
val response = MockResponse().setResponseCode(400).setBody(INVALID_JSON)
|
||||
server.enqueue(response)
|
||||
@@ -318,3 +341,29 @@ private const val INVALID_JSON = """
|
||||
"validationErrors": null
|
||||
}
|
||||
"""
|
||||
|
||||
private val UPDATE_KDF_REQUEST = UpdateKdfJsonRequest(
|
||||
authenticationData = MasterPasswordAuthenticationDataJson(
|
||||
kdf = KdfJson(
|
||||
kdfType = KdfTypeJson.PBKDF2_SHA256,
|
||||
iterations = 7,
|
||||
memory = 1,
|
||||
parallelism = 2,
|
||||
),
|
||||
masterPasswordAuthenticationHash = "mockMasterPasswordHash",
|
||||
salt = "mockSalt",
|
||||
),
|
||||
key = "mockKey",
|
||||
masterPasswordHash = "mockMasterPasswordHash",
|
||||
newMasterPasswordHash = "mockNewMasterPasswordHash",
|
||||
unlockData = MasterPasswordUnlockDataJson(
|
||||
kdf = KdfJson(
|
||||
kdfType = KdfTypeJson.PBKDF2_SHA256,
|
||||
iterations = 7,
|
||||
memory = 1,
|
||||
parallelism = 2,
|
||||
),
|
||||
masterKeyWrappedUserKey = "mockMasterPasswordKey",
|
||||
salt = "mockSalt",
|
||||
),
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user