mirror of
https://github.com/bitwarden/android.git
synced 2025-02-17 12:30:00 +03:00
PM-11226: Wrap Key Connector APIs (#3794)
This commit is contained in:
parent
43a6495b98
commit
17fd3ec0f0
12 changed files with 606 additions and 22 deletions
|
@ -2,7 +2,6 @@ package com.x8bit.bitwarden.data.auth.datasource.network.api
|
||||||
|
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.CreateAccountKeysRequest
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.CreateAccountKeysRequest
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.DeleteAccountRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.DeleteAccountRequestJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.KeyConnectorKeyRequestJson
|
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.ResetPasswordRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.ResetPasswordRequestJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.SetPasswordRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.SetPasswordRequestJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.VerifyOtpRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.VerifyOtpRequestJson
|
||||||
|
@ -53,12 +52,6 @@ interface AuthenticatedAccountsApi {
|
||||||
@HTTP(method = "POST", path = "/accounts/password", hasBody = true)
|
@HTTP(method = "POST", path = "/accounts/password", hasBody = true)
|
||||||
suspend fun resetPassword(@Body body: ResetPasswordRequestJson): Result<Unit>
|
suspend fun resetPassword(@Body body: ResetPasswordRequestJson): Result<Unit>
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the key connector key.
|
|
||||||
*/
|
|
||||||
@POST("/accounts/set-key-connector-key")
|
|
||||||
suspend fun setKeyConnectorKey(@Body body: KeyConnectorKeyRequestJson): Result<Unit>
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the password.
|
* Sets the password.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -2,9 +2,7 @@ package com.x8bit.bitwarden.data.auth.datasource.network.api
|
||||||
|
|
||||||
import androidx.annotation.Keep
|
import androidx.annotation.Keep
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.KeyConnectorMasterKeyRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.KeyConnectorMasterKeyRequestJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.KeyConnectorMasterKeyResponseJson
|
|
||||||
import retrofit2.http.Body
|
import retrofit2.http.Body
|
||||||
import retrofit2.http.GET
|
|
||||||
import retrofit2.http.POST
|
import retrofit2.http.POST
|
||||||
import retrofit2.http.Url
|
import retrofit2.http.Url
|
||||||
|
|
||||||
|
@ -18,9 +16,4 @@ interface AuthenticatedKeyConnectorApi {
|
||||||
@Url url: String,
|
@Url url: String,
|
||||||
@Body body: KeyConnectorMasterKeyRequestJson,
|
@Body body: KeyConnectorMasterKeyRequestJson,
|
||||||
): Result<Unit>
|
): Result<Unit>
|
||||||
|
|
||||||
@GET
|
|
||||||
suspend fun getMasterKeyFromKeyConnector(
|
|
||||||
@Url url: String,
|
|
||||||
): Result<KeyConnectorMasterKeyResponseJson>
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
package com.x8bit.bitwarden.data.auth.datasource.network.api
|
package com.x8bit.bitwarden.data.auth.datasource.network.api
|
||||||
|
|
||||||
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.KeyConnectorKeyRequestJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.PasswordHintRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.PasswordHintRequestJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.ResendEmailRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.ResendEmailRequestJson
|
||||||
|
import com.x8bit.bitwarden.data.platform.datasource.network.util.HEADER_KEY_AUTHORIZATION
|
||||||
import retrofit2.http.Body
|
import retrofit2.http.Body
|
||||||
|
import retrofit2.http.Header
|
||||||
import retrofit2.http.POST
|
import retrofit2.http.POST
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -18,4 +21,10 @@ interface UnauthenticatedAccountsApi {
|
||||||
suspend fun resendVerificationCodeEmail(
|
suspend fun resendVerificationCodeEmail(
|
||||||
@Body body: ResendEmailRequestJson,
|
@Body body: ResendEmailRequestJson,
|
||||||
): Result<Unit>
|
): Result<Unit>
|
||||||
|
|
||||||
|
@POST("/accounts/set-key-connector-key")
|
||||||
|
suspend fun setKeyConnectorKey(
|
||||||
|
@Body body: KeyConnectorKeyRequestJson,
|
||||||
|
@Header(HEADER_KEY_AUTHORIZATION) bearerToken: String,
|
||||||
|
): Result<Unit>
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
package com.x8bit.bitwarden.data.auth.datasource.network.api
|
||||||
|
|
||||||
|
import androidx.annotation.Keep
|
||||||
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.KeyConnectorMasterKeyRequestJson
|
||||||
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.KeyConnectorMasterKeyResponseJson
|
||||||
|
import com.x8bit.bitwarden.data.platform.datasource.network.util.HEADER_KEY_AUTHORIZATION
|
||||||
|
import retrofit2.http.Body
|
||||||
|
import retrofit2.http.GET
|
||||||
|
import retrofit2.http.Header
|
||||||
|
import retrofit2.http.POST
|
||||||
|
import retrofit2.http.Url
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines raw calls specific for key connectors that use custom urls.
|
||||||
|
*/
|
||||||
|
@Keep
|
||||||
|
interface UnauthenticatedKeyConnectorApi {
|
||||||
|
@POST
|
||||||
|
suspend fun storeMasterKeyToKeyConnector(
|
||||||
|
@Url url: String,
|
||||||
|
@Header(HEADER_KEY_AUTHORIZATION) bearerToken: String,
|
||||||
|
@Body body: KeyConnectorMasterKeyRequestJson,
|
||||||
|
): Result<Unit>
|
||||||
|
|
||||||
|
@GET
|
||||||
|
suspend fun getMasterKeyFromKeyConnector(
|
||||||
|
@Url url: String,
|
||||||
|
@Header(HEADER_KEY_AUTHORIZATION) bearerToken: String,
|
||||||
|
): Result<KeyConnectorMasterKeyResponseJson>
|
||||||
|
}
|
|
@ -38,6 +38,7 @@ object AuthNetworkModule {
|
||||||
): AccountsService = AccountsServiceImpl(
|
): AccountsService = AccountsServiceImpl(
|
||||||
unauthenticatedAccountsApi = retrofits.unauthenticatedApiRetrofit.create(),
|
unauthenticatedAccountsApi = retrofits.unauthenticatedApiRetrofit.create(),
|
||||||
authenticatedAccountsApi = retrofits.authenticatedApiRetrofit.create(),
|
authenticatedAccountsApi = retrofits.authenticatedApiRetrofit.create(),
|
||||||
|
unauthenticatedKeyConnectorApi = retrofits.createStaticRetrofit().create(),
|
||||||
authenticatedKeyConnectorApi = retrofits
|
authenticatedKeyConnectorApi = retrofits
|
||||||
.createStaticRetrofit(isAuthenticated = true)
|
.createStaticRetrofit(isAuthenticated = true)
|
||||||
.create(),
|
.create(),
|
||||||
|
|
|
@ -59,8 +59,14 @@ interface AccountsService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the key connector key.
|
* Set the key connector key.
|
||||||
|
*
|
||||||
|
* This API requires the [accessToken] to be passed in manually because it occurs during the
|
||||||
|
* login process.
|
||||||
*/
|
*/
|
||||||
suspend fun setKeyConnectorKey(body: KeyConnectorKeyRequestJson): Result<Unit>
|
suspend fun setKeyConnectorKey(
|
||||||
|
accessToken: String,
|
||||||
|
body: KeyConnectorKeyRequestJson,
|
||||||
|
): Result<Unit>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the password.
|
* Set the password.
|
||||||
|
@ -69,13 +75,32 @@ interface AccountsService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the master key from the key connector.
|
* Retrieves the master key from the key connector.
|
||||||
|
*
|
||||||
|
* This API requires the [accessToken] to be passed in manually because it occurs during the
|
||||||
|
* login process.
|
||||||
*/
|
*/
|
||||||
suspend fun getMasterKeyFromKeyConnector(
|
suspend fun getMasterKeyFromKeyConnector(
|
||||||
url: String,
|
url: String,
|
||||||
|
accessToken: String,
|
||||||
): Result<KeyConnectorMasterKeyResponseJson>
|
): Result<KeyConnectorMasterKeyResponseJson>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores the master key to the key connector.
|
* Stores the master key to the key connector.
|
||||||
*/
|
*/
|
||||||
suspend fun storeMasterKeyToKeyConnector(url: String, masterKey: String): Result<Unit>
|
suspend fun storeMasterKeyToKeyConnector(
|
||||||
|
url: String,
|
||||||
|
masterKey: String,
|
||||||
|
): Result<Unit>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the master key to the key connector.
|
||||||
|
*
|
||||||
|
* This API requires the [accessToken] to be passed in manually because it occurs during the
|
||||||
|
* login process.
|
||||||
|
*/
|
||||||
|
suspend fun storeMasterKeyToKeyConnector(
|
||||||
|
url: String,
|
||||||
|
accessToken: String,
|
||||||
|
masterKey: String,
|
||||||
|
): Result<Unit>
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.x8bit.bitwarden.data.auth.datasource.network.service
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.api.AuthenticatedAccountsApi
|
import com.x8bit.bitwarden.data.auth.datasource.network.api.AuthenticatedAccountsApi
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.api.AuthenticatedKeyConnectorApi
|
import com.x8bit.bitwarden.data.auth.datasource.network.api.AuthenticatedKeyConnectorApi
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.api.UnauthenticatedAccountsApi
|
import com.x8bit.bitwarden.data.auth.datasource.network.api.UnauthenticatedAccountsApi
|
||||||
|
import com.x8bit.bitwarden.data.auth.datasource.network.api.UnauthenticatedKeyConnectorApi
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.CreateAccountKeysRequest
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.CreateAccountKeysRequest
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.DeleteAccountRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.DeleteAccountRequestJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.DeleteAccountResponseJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.DeleteAccountResponseJson
|
||||||
|
@ -16,6 +17,7 @@ import com.x8bit.bitwarden.data.auth.datasource.network.model.ResetPasswordReque
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.SetPasswordRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.SetPasswordRequestJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.VerifyOtpRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.VerifyOtpRequestJson
|
||||||
import com.x8bit.bitwarden.data.platform.datasource.network.model.toBitwardenError
|
import com.x8bit.bitwarden.data.platform.datasource.network.model.toBitwardenError
|
||||||
|
import com.x8bit.bitwarden.data.platform.datasource.network.util.HEADER_VALUE_BEARER_PREFIX
|
||||||
import com.x8bit.bitwarden.data.platform.datasource.network.util.parseErrorBodyOrNull
|
import com.x8bit.bitwarden.data.platform.datasource.network.util.parseErrorBodyOrNull
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
|
@ -26,6 +28,7 @@ import kotlinx.serialization.json.Json
|
||||||
class AccountsServiceImpl(
|
class AccountsServiceImpl(
|
||||||
private val unauthenticatedAccountsApi: UnauthenticatedAccountsApi,
|
private val unauthenticatedAccountsApi: UnauthenticatedAccountsApi,
|
||||||
private val authenticatedAccountsApi: AuthenticatedAccountsApi,
|
private val authenticatedAccountsApi: AuthenticatedAccountsApi,
|
||||||
|
private val unauthenticatedKeyConnectorApi: UnauthenticatedKeyConnectorApi,
|
||||||
private val authenticatedKeyConnectorApi: AuthenticatedKeyConnectorApi,
|
private val authenticatedKeyConnectorApi: AuthenticatedKeyConnectorApi,
|
||||||
private val json: Json,
|
private val json: Json,
|
||||||
) : AccountsService {
|
) : AccountsService {
|
||||||
|
@ -109,8 +112,12 @@ class AccountsServiceImpl(
|
||||||
}
|
}
|
||||||
|
|
||||||
override suspend fun setKeyConnectorKey(
|
override suspend fun setKeyConnectorKey(
|
||||||
|
accessToken: String,
|
||||||
body: KeyConnectorKeyRequestJson,
|
body: KeyConnectorKeyRequestJson,
|
||||||
): Result<Unit> = authenticatedAccountsApi.setKeyConnectorKey(body)
|
): Result<Unit> = unauthenticatedAccountsApi.setKeyConnectorKey(
|
||||||
|
body = body,
|
||||||
|
bearerToken = "$HEADER_VALUE_BEARER_PREFIX$accessToken",
|
||||||
|
)
|
||||||
|
|
||||||
override suspend fun setPassword(
|
override suspend fun setPassword(
|
||||||
body: SetPasswordRequestJson,
|
body: SetPasswordRequestJson,
|
||||||
|
@ -118,8 +125,12 @@ class AccountsServiceImpl(
|
||||||
|
|
||||||
override suspend fun getMasterKeyFromKeyConnector(
|
override suspend fun getMasterKeyFromKeyConnector(
|
||||||
url: String,
|
url: String,
|
||||||
|
accessToken: String,
|
||||||
): Result<KeyConnectorMasterKeyResponseJson> =
|
): Result<KeyConnectorMasterKeyResponseJson> =
|
||||||
authenticatedKeyConnectorApi.getMasterKeyFromKeyConnector(url = "$url/user-keys")
|
unauthenticatedKeyConnectorApi.getMasterKeyFromKeyConnector(
|
||||||
|
url = "$url/user-keys",
|
||||||
|
bearerToken = "$HEADER_VALUE_BEARER_PREFIX$accessToken",
|
||||||
|
)
|
||||||
|
|
||||||
override suspend fun storeMasterKeyToKeyConnector(
|
override suspend fun storeMasterKeyToKeyConnector(
|
||||||
url: String,
|
url: String,
|
||||||
|
@ -129,4 +140,15 @@ class AccountsServiceImpl(
|
||||||
url = "$url/user-keys",
|
url = "$url/user-keys",
|
||||||
body = KeyConnectorMasterKeyRequestJson(masterKey = masterKey),
|
body = KeyConnectorMasterKeyRequestJson(masterKey = masterKey),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
override suspend fun storeMasterKeyToKeyConnector(
|
||||||
|
url: String,
|
||||||
|
accessToken: String,
|
||||||
|
masterKey: String,
|
||||||
|
): Result<Unit> =
|
||||||
|
unauthenticatedKeyConnectorApi.storeMasterKeyToKeyConnector(
|
||||||
|
url = "$url/user-keys",
|
||||||
|
bearerToken = "$HEADER_VALUE_BEARER_PREFIX$accessToken",
|
||||||
|
body = KeyConnectorMasterKeyRequestJson(masterKey = masterKey),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.x8bit.bitwarden.data.auth.manager
|
||||||
|
|
||||||
|
import com.bitwarden.core.KeyConnectorResponse
|
||||||
|
import com.bitwarden.crypto.Kdf
|
||||||
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.KdfTypeJson
|
||||||
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.KeyConnectorMasterKeyResponseJson
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Manager used to interface with a key connector.
|
||||||
|
*/
|
||||||
|
interface KeyConnectorManager {
|
||||||
|
/**
|
||||||
|
* Retrieves the master key from the key connector.
|
||||||
|
*/
|
||||||
|
suspend fun getMasterKeyFromKeyConnector(
|
||||||
|
url: String,
|
||||||
|
accessToken: String,
|
||||||
|
): Result<KeyConnectorMasterKeyResponseJson>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrates an existing user to use the key connector.
|
||||||
|
*/
|
||||||
|
@Suppress("LongParameterList")
|
||||||
|
suspend fun migrateExistingUserToKeyConnector(
|
||||||
|
userId: String,
|
||||||
|
url: String,
|
||||||
|
userKeyEncrypted: String,
|
||||||
|
email: String,
|
||||||
|
masterPassword: String,
|
||||||
|
kdf: Kdf,
|
||||||
|
): Result<Unit>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Migrates a new user to use the key connector.
|
||||||
|
*/
|
||||||
|
@Suppress("LongParameterList")
|
||||||
|
suspend fun migrateNewUserToKeyConnector(
|
||||||
|
url: String,
|
||||||
|
accessToken: String,
|
||||||
|
kdfType: KdfTypeJson,
|
||||||
|
kdfIterations: Int?,
|
||||||
|
kdfMemory: Int?,
|
||||||
|
kdfParallelism: Int?,
|
||||||
|
organizationIdentifier: String,
|
||||||
|
): Result<KeyConnectorResponse>
|
||||||
|
}
|
|
@ -0,0 +1,88 @@
|
||||||
|
package com.x8bit.bitwarden.data.auth.manager
|
||||||
|
|
||||||
|
import com.bitwarden.core.KeyConnectorResponse
|
||||||
|
import com.bitwarden.crypto.Kdf
|
||||||
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.KdfTypeJson
|
||||||
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.KeyConnectorKeyRequestJson
|
||||||
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.KeyConnectorMasterKeyResponseJson
|
||||||
|
import com.x8bit.bitwarden.data.auth.datasource.network.service.AccountsService
|
||||||
|
import com.x8bit.bitwarden.data.auth.datasource.sdk.AuthSdkSource
|
||||||
|
import com.x8bit.bitwarden.data.platform.util.flatMap
|
||||||
|
import com.x8bit.bitwarden.data.vault.datasource.sdk.VaultSdkSource
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default implementation of the [KeyConnectorManager].
|
||||||
|
*/
|
||||||
|
class KeyConnectorManagerImpl(
|
||||||
|
private val accountsService: AccountsService,
|
||||||
|
private val authSdkSource: AuthSdkSource,
|
||||||
|
private val vaultSdkSource: VaultSdkSource,
|
||||||
|
) : KeyConnectorManager {
|
||||||
|
override suspend fun getMasterKeyFromKeyConnector(
|
||||||
|
url: String,
|
||||||
|
accessToken: String,
|
||||||
|
): Result<KeyConnectorMasterKeyResponseJson> =
|
||||||
|
accountsService.getMasterKeyFromKeyConnector(
|
||||||
|
url = url,
|
||||||
|
accessToken = accessToken,
|
||||||
|
)
|
||||||
|
|
||||||
|
override suspend fun migrateExistingUserToKeyConnector(
|
||||||
|
userId: String,
|
||||||
|
url: String,
|
||||||
|
userKeyEncrypted: String,
|
||||||
|
email: String,
|
||||||
|
masterPassword: String,
|
||||||
|
kdf: Kdf,
|
||||||
|
): Result<Unit> =
|
||||||
|
vaultSdkSource
|
||||||
|
.deriveKeyConnector(
|
||||||
|
userId = userId,
|
||||||
|
userKeyEncrypted = userKeyEncrypted,
|
||||||
|
email = email,
|
||||||
|
password = masterPassword,
|
||||||
|
kdf = kdf,
|
||||||
|
)
|
||||||
|
.flatMap { masterKey ->
|
||||||
|
accountsService.storeMasterKeyToKeyConnector(url = url, masterKey = masterKey)
|
||||||
|
}
|
||||||
|
.flatMap { accountsService.convertToKeyConnector() }
|
||||||
|
|
||||||
|
override suspend fun migrateNewUserToKeyConnector(
|
||||||
|
url: String,
|
||||||
|
accessToken: String,
|
||||||
|
kdfType: KdfTypeJson,
|
||||||
|
kdfIterations: Int?,
|
||||||
|
kdfMemory: Int?,
|
||||||
|
kdfParallelism: Int?,
|
||||||
|
organizationIdentifier: String,
|
||||||
|
): Result<KeyConnectorResponse> =
|
||||||
|
authSdkSource
|
||||||
|
.makeKeyConnectorKeys()
|
||||||
|
.flatMap { keyConnectorResponse ->
|
||||||
|
accountsService
|
||||||
|
.storeMasterKeyToKeyConnector(
|
||||||
|
url = url,
|
||||||
|
accessToken = accessToken,
|
||||||
|
masterKey = keyConnectorResponse.masterKey,
|
||||||
|
)
|
||||||
|
.flatMap {
|
||||||
|
accountsService.setKeyConnectorKey(
|
||||||
|
accessToken = accessToken,
|
||||||
|
body = KeyConnectorKeyRequestJson(
|
||||||
|
userKey = keyConnectorResponse.encryptedUserKey,
|
||||||
|
keys = KeyConnectorKeyRequestJson.Keys(
|
||||||
|
publicKey = keyConnectorResponse.keys.public,
|
||||||
|
encryptedPrivateKey = keyConnectorResponse.keys.private,
|
||||||
|
),
|
||||||
|
kdfType = kdfType,
|
||||||
|
kdfIterations = kdfIterations,
|
||||||
|
kdfMemory = kdfMemory,
|
||||||
|
kdfParallelism = kdfParallelism,
|
||||||
|
organizationIdentifier = organizationIdentifier,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.map { keyConnectorResponse }
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ package com.x8bit.bitwarden.data.auth.manager.di
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
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.AccountsService
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.service.AuthRequestsService
|
import com.x8bit.bitwarden.data.auth.datasource.network.service.AuthRequestsService
|
||||||
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.datasource.network.service.NewAuthRequestService
|
import com.x8bit.bitwarden.data.auth.datasource.network.service.NewAuthRequestService
|
||||||
|
@ -10,6 +11,8 @@ import com.x8bit.bitwarden.data.auth.manager.AuthRequestManager
|
||||||
import com.x8bit.bitwarden.data.auth.manager.AuthRequestManagerImpl
|
import com.x8bit.bitwarden.data.auth.manager.AuthRequestManagerImpl
|
||||||
import com.x8bit.bitwarden.data.auth.manager.AuthRequestNotificationManager
|
import com.x8bit.bitwarden.data.auth.manager.AuthRequestNotificationManager
|
||||||
import com.x8bit.bitwarden.data.auth.manager.AuthRequestNotificationManagerImpl
|
import com.x8bit.bitwarden.data.auth.manager.AuthRequestNotificationManagerImpl
|
||||||
|
import com.x8bit.bitwarden.data.auth.manager.KeyConnectorManager
|
||||||
|
import com.x8bit.bitwarden.data.auth.manager.KeyConnectorManagerImpl
|
||||||
import com.x8bit.bitwarden.data.auth.manager.TrustedDeviceManager
|
import com.x8bit.bitwarden.data.auth.manager.TrustedDeviceManager
|
||||||
import com.x8bit.bitwarden.data.auth.manager.TrustedDeviceManagerImpl
|
import com.x8bit.bitwarden.data.auth.manager.TrustedDeviceManagerImpl
|
||||||
import com.x8bit.bitwarden.data.auth.manager.UserLogoutManager
|
import com.x8bit.bitwarden.data.auth.manager.UserLogoutManager
|
||||||
|
@ -71,6 +74,19 @@ object AuthManagerModule {
|
||||||
authDiskSource = authDiskSource,
|
authDiskSource = authDiskSource,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Provides
|
||||||
|
@Singleton
|
||||||
|
fun provideKeyConnectorManager(
|
||||||
|
accountsService: AccountsService,
|
||||||
|
authSdkSource: AuthSdkSource,
|
||||||
|
vaultSdkSource: VaultSdkSource,
|
||||||
|
): KeyConnectorManager =
|
||||||
|
KeyConnectorManagerImpl(
|
||||||
|
accountsService = accountsService,
|
||||||
|
authSdkSource = authSdkSource,
|
||||||
|
vaultSdkSource = vaultSdkSource,
|
||||||
|
)
|
||||||
|
|
||||||
@Provides
|
@Provides
|
||||||
@Singleton
|
@Singleton
|
||||||
fun provideTrustedDeviceManager(
|
fun provideTrustedDeviceManager(
|
||||||
|
|
|
@ -3,6 +3,7 @@ package com.x8bit.bitwarden.data.auth.datasource.network.service
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.api.AuthenticatedAccountsApi
|
import com.x8bit.bitwarden.data.auth.datasource.network.api.AuthenticatedAccountsApi
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.api.AuthenticatedKeyConnectorApi
|
import com.x8bit.bitwarden.data.auth.datasource.network.api.AuthenticatedKeyConnectorApi
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.api.UnauthenticatedAccountsApi
|
import com.x8bit.bitwarden.data.auth.datasource.network.api.UnauthenticatedAccountsApi
|
||||||
|
import com.x8bit.bitwarden.data.auth.datasource.network.api.UnauthenticatedKeyConnectorApi
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.KdfTypeJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.KdfTypeJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.KeyConnectorKeyRequestJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.KeyConnectorKeyRequestJson
|
||||||
import com.x8bit.bitwarden.data.auth.datasource.network.model.KeyConnectorMasterKeyResponseJson
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.KeyConnectorMasterKeyResponseJson
|
||||||
|
@ -24,10 +25,12 @@ class AccountsServiceTest : BaseServiceTest() {
|
||||||
|
|
||||||
private val unauthenticatedAccountsApi: UnauthenticatedAccountsApi = retrofit.create()
|
private val unauthenticatedAccountsApi: UnauthenticatedAccountsApi = retrofit.create()
|
||||||
private val authenticatedAccountsApi: AuthenticatedAccountsApi = retrofit.create()
|
private val authenticatedAccountsApi: AuthenticatedAccountsApi = retrofit.create()
|
||||||
|
private val unauthenticatedKeyConnectorApi: UnauthenticatedKeyConnectorApi = retrofit.create()
|
||||||
private val authenticatedKeyConnectorApi: AuthenticatedKeyConnectorApi = retrofit.create()
|
private val authenticatedKeyConnectorApi: AuthenticatedKeyConnectorApi = retrofit.create()
|
||||||
private val service = AccountsServiceImpl(
|
private val service = AccountsServiceImpl(
|
||||||
unauthenticatedAccountsApi = unauthenticatedAccountsApi,
|
unauthenticatedAccountsApi = unauthenticatedAccountsApi,
|
||||||
authenticatedAccountsApi = authenticatedAccountsApi,
|
authenticatedAccountsApi = authenticatedAccountsApi,
|
||||||
|
unauthenticatedKeyConnectorApi = unauthenticatedKeyConnectorApi,
|
||||||
authenticatedKeyConnectorApi = authenticatedKeyConnectorApi,
|
authenticatedKeyConnectorApi = authenticatedKeyConnectorApi,
|
||||||
json = json,
|
json = json,
|
||||||
)
|
)
|
||||||
|
@ -189,10 +192,11 @@ class AccountsServiceTest : BaseServiceTest() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `setKeyConnectorKey with empty response is success`() = runTest {
|
fun `setKeyConnectorKey with token and empty response is success`() = runTest {
|
||||||
val response = MockResponse().setBody("")
|
val response = MockResponse().setBody("")
|
||||||
server.enqueue(response)
|
server.enqueue(response)
|
||||||
val result = service.setKeyConnectorKey(
|
val result = service.setKeyConnectorKey(
|
||||||
|
accessToken = "token",
|
||||||
body = KeyConnectorKeyRequestJson(
|
body = KeyConnectorKeyRequestJson(
|
||||||
organizationIdentifier = "organizationId",
|
organizationIdentifier = "organizationId",
|
||||||
kdfIterations = 7,
|
kdfIterations = 7,
|
||||||
|
@ -210,11 +214,14 @@ class AccountsServiceTest : BaseServiceTest() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `getMasterKeyFromKeyConnector with empty response is success`() = runTest {
|
fun `getMasterKeyFromKeyConnector with token and empty response is success`() = runTest {
|
||||||
val masterKey = "masterKey"
|
val masterKey = "masterKey"
|
||||||
val response = MockResponse().setBody("""{ "key": "$masterKey" }""")
|
val response = MockResponse().setBody("""{ "key": "$masterKey" }""")
|
||||||
server.enqueue(response)
|
server.enqueue(response)
|
||||||
val result = service.getMasterKeyFromKeyConnector(url = "$url/test")
|
val result = service.getMasterKeyFromKeyConnector(
|
||||||
|
url = "$url/test",
|
||||||
|
accessToken = "token",
|
||||||
|
)
|
||||||
assertEquals(
|
assertEquals(
|
||||||
KeyConnectorMasterKeyResponseJson(masterKey = masterKey).asSuccess(),
|
KeyConnectorMasterKeyResponseJson(masterKey = masterKey).asSuccess(),
|
||||||
result,
|
result,
|
||||||
|
@ -222,7 +229,7 @@ class AccountsServiceTest : BaseServiceTest() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun `storeMasterKeyToKeyConnector success should return Success`() = runTest {
|
fun `storeMasterKeyToKeyConnector without token success should return Success`() = runTest {
|
||||||
val response = MockResponse()
|
val response = MockResponse()
|
||||||
server.enqueue(response)
|
server.enqueue(response)
|
||||||
val result = service.storeMasterKeyToKeyConnector(
|
val result = service.storeMasterKeyToKeyConnector(
|
||||||
|
@ -231,4 +238,16 @@ class AccountsServiceTest : BaseServiceTest() {
|
||||||
)
|
)
|
||||||
assertEquals(Unit.asSuccess(), result)
|
assertEquals(Unit.asSuccess(), result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `storeMasterKeyToKeyConnector with token success should return Success`() = runTest {
|
||||||
|
val response = MockResponse()
|
||||||
|
server.enqueue(response)
|
||||||
|
val result = service.storeMasterKeyToKeyConnector(
|
||||||
|
url = "$url/test",
|
||||||
|
masterKey = "masterKey",
|
||||||
|
accessToken = "token",
|
||||||
|
)
|
||||||
|
assertEquals(Unit.asSuccess(), result)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,342 @@
|
||||||
|
package com.x8bit.bitwarden.data.auth.manager
|
||||||
|
|
||||||
|
import com.bitwarden.core.KeyConnectorResponse
|
||||||
|
import com.bitwarden.crypto.Kdf
|
||||||
|
import com.bitwarden.crypto.RsaKeyPair
|
||||||
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.KdfTypeJson
|
||||||
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.KeyConnectorKeyRequestJson
|
||||||
|
import com.x8bit.bitwarden.data.auth.datasource.network.model.KeyConnectorMasterKeyResponseJson
|
||||||
|
import com.x8bit.bitwarden.data.auth.datasource.network.service.AccountsService
|
||||||
|
import com.x8bit.bitwarden.data.auth.datasource.sdk.AuthSdkSource
|
||||||
|
import com.x8bit.bitwarden.data.platform.util.asFailure
|
||||||
|
import com.x8bit.bitwarden.data.platform.util.asSuccess
|
||||||
|
import com.x8bit.bitwarden.data.vault.datasource.sdk.VaultSdkSource
|
||||||
|
import io.mockk.coEvery
|
||||||
|
import io.mockk.every
|
||||||
|
import io.mockk.mockk
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import org.junit.Test
|
||||||
|
import org.junit.jupiter.api.Assertions.assertEquals
|
||||||
|
|
||||||
|
class KeyConnectorManagerTest {
|
||||||
|
private val accountsService: AccountsService = mockk()
|
||||||
|
private val authSdkSource: AuthSdkSource = mockk()
|
||||||
|
private val vaultSdkSource: VaultSdkSource = mockk()
|
||||||
|
|
||||||
|
private val keyConnectorManager: KeyConnectorManager = KeyConnectorManagerImpl(
|
||||||
|
accountsService = accountsService,
|
||||||
|
authSdkSource = authSdkSource,
|
||||||
|
vaultSdkSource = vaultSdkSource,
|
||||||
|
)
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `getMasterKeyFromKeyConnector with service failure should return failure`() = runTest {
|
||||||
|
val expectedResult = Throwable("Fail").asFailure()
|
||||||
|
coEvery {
|
||||||
|
accountsService.getMasterKeyFromKeyConnector(url = URL, accessToken = ACCESS_TOKEN)
|
||||||
|
} returns expectedResult
|
||||||
|
|
||||||
|
val result = keyConnectorManager.getMasterKeyFromKeyConnector(
|
||||||
|
url = URL,
|
||||||
|
accessToken = ACCESS_TOKEN,
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(expectedResult, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `getMasterKeyFromKeyConnector with service success should return success`() = runTest {
|
||||||
|
val expectedResult = mockk<KeyConnectorMasterKeyResponseJson>().asSuccess()
|
||||||
|
coEvery {
|
||||||
|
accountsService.getMasterKeyFromKeyConnector(url = URL, accessToken = ACCESS_TOKEN)
|
||||||
|
} returns expectedResult
|
||||||
|
|
||||||
|
val result = keyConnectorManager.getMasterKeyFromKeyConnector(
|
||||||
|
url = URL,
|
||||||
|
accessToken = ACCESS_TOKEN,
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(expectedResult, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("MaxLineLength")
|
||||||
|
@Test
|
||||||
|
fun `migrateExistingUserToKeyConnector with deriveKeyConnector failure should return failure`() =
|
||||||
|
runTest {
|
||||||
|
val expectedResult = Throwable("Fail").asFailure()
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.deriveKeyConnector(
|
||||||
|
userId = USER_ID,
|
||||||
|
userKeyEncrypted = ENCRYPTED_USER_KEY,
|
||||||
|
email = EMAIL,
|
||||||
|
password = MASTER_PASSWORD,
|
||||||
|
kdf = KDF,
|
||||||
|
)
|
||||||
|
} returns expectedResult
|
||||||
|
|
||||||
|
val result = keyConnectorManager.migrateExistingUserToKeyConnector(
|
||||||
|
userId = USER_ID,
|
||||||
|
url = URL,
|
||||||
|
userKeyEncrypted = ENCRYPTED_USER_KEY,
|
||||||
|
email = EMAIL,
|
||||||
|
masterPassword = MASTER_PASSWORD,
|
||||||
|
kdf = KDF,
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(expectedResult, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("MaxLineLength")
|
||||||
|
@Test
|
||||||
|
fun `migrateExistingUserToKeyConnector with storeMasterKeyToKeyConnector failure should return failure`() =
|
||||||
|
runTest {
|
||||||
|
val expectedResult = Throwable("Fail").asFailure()
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.deriveKeyConnector(
|
||||||
|
userId = USER_ID,
|
||||||
|
userKeyEncrypted = ENCRYPTED_USER_KEY,
|
||||||
|
email = EMAIL,
|
||||||
|
password = MASTER_PASSWORD,
|
||||||
|
kdf = KDF,
|
||||||
|
)
|
||||||
|
} returns MASTER_KEY.asSuccess()
|
||||||
|
coEvery {
|
||||||
|
accountsService.storeMasterKeyToKeyConnector(url = URL, masterKey = MASTER_KEY)
|
||||||
|
} returns expectedResult
|
||||||
|
|
||||||
|
val result = keyConnectorManager.migrateExistingUserToKeyConnector(
|
||||||
|
userId = USER_ID,
|
||||||
|
url = URL,
|
||||||
|
userKeyEncrypted = ENCRYPTED_USER_KEY,
|
||||||
|
email = EMAIL,
|
||||||
|
masterPassword = MASTER_PASSWORD,
|
||||||
|
kdf = KDF,
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(expectedResult, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("MaxLineLength")
|
||||||
|
@Test
|
||||||
|
fun `migrateExistingUserToKeyConnector with convertToKeyConnector failure should return failure`() =
|
||||||
|
runTest {
|
||||||
|
val expectedResult = Throwable("Fail").asFailure()
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.deriveKeyConnector(
|
||||||
|
userId = USER_ID,
|
||||||
|
userKeyEncrypted = ENCRYPTED_USER_KEY,
|
||||||
|
email = EMAIL,
|
||||||
|
password = MASTER_PASSWORD,
|
||||||
|
kdf = KDF,
|
||||||
|
)
|
||||||
|
} returns MASTER_KEY.asSuccess()
|
||||||
|
coEvery {
|
||||||
|
accountsService.storeMasterKeyToKeyConnector(url = URL, masterKey = MASTER_KEY)
|
||||||
|
} returns Unit.asSuccess()
|
||||||
|
coEvery { accountsService.convertToKeyConnector() } returns expectedResult
|
||||||
|
|
||||||
|
val result = keyConnectorManager.migrateExistingUserToKeyConnector(
|
||||||
|
userId = USER_ID,
|
||||||
|
url = URL,
|
||||||
|
userKeyEncrypted = ENCRYPTED_USER_KEY,
|
||||||
|
email = EMAIL,
|
||||||
|
masterPassword = MASTER_PASSWORD,
|
||||||
|
kdf = KDF,
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(expectedResult, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `migrateExistingUserToKeyConnector should return success`() = runTest {
|
||||||
|
coEvery {
|
||||||
|
vaultSdkSource.deriveKeyConnector(
|
||||||
|
userId = USER_ID,
|
||||||
|
userKeyEncrypted = ENCRYPTED_USER_KEY,
|
||||||
|
email = EMAIL,
|
||||||
|
password = MASTER_PASSWORD,
|
||||||
|
kdf = KDF,
|
||||||
|
)
|
||||||
|
} returns MASTER_KEY.asSuccess()
|
||||||
|
coEvery {
|
||||||
|
accountsService.storeMasterKeyToKeyConnector(url = URL, masterKey = MASTER_KEY)
|
||||||
|
} returns Unit.asSuccess()
|
||||||
|
coEvery { accountsService.convertToKeyConnector() } returns Unit.asSuccess()
|
||||||
|
|
||||||
|
val result = keyConnectorManager.migrateExistingUserToKeyConnector(
|
||||||
|
userId = USER_ID,
|
||||||
|
url = URL,
|
||||||
|
userKeyEncrypted = ENCRYPTED_USER_KEY,
|
||||||
|
email = EMAIL,
|
||||||
|
masterPassword = MASTER_PASSWORD,
|
||||||
|
kdf = KDF,
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(Unit.asSuccess(), result)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `migrateNewUserToKeyConnector with makeKeyConnectorKeys failure should return failure`() =
|
||||||
|
runTest {
|
||||||
|
val expectedResult = Throwable("Fail").asFailure()
|
||||||
|
coEvery { authSdkSource.makeKeyConnectorKeys() } returns expectedResult
|
||||||
|
|
||||||
|
val result = keyConnectorManager.migrateNewUserToKeyConnector(
|
||||||
|
url = URL,
|
||||||
|
accessToken = ACCESS_TOKEN,
|
||||||
|
kdfType = KDF_TYPE,
|
||||||
|
kdfIterations = KDF_ITERATIONS,
|
||||||
|
kdfMemory = KDF_MEMORY,
|
||||||
|
kdfParallelism = KDF_PARALLELISM,
|
||||||
|
organizationIdentifier = ORGANIZATION_IDENTIFIER,
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(expectedResult, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("MaxLineLength")
|
||||||
|
@Test
|
||||||
|
fun `migrateNewUserToKeyConnector with storeMasterKeyToKeyConnector failure should return failure`() =
|
||||||
|
runTest {
|
||||||
|
val keyConnectorResponse: KeyConnectorResponse = mockk {
|
||||||
|
every { masterKey } returns MASTER_KEY
|
||||||
|
}
|
||||||
|
val expectedResult = Throwable("Fail").asFailure()
|
||||||
|
coEvery {
|
||||||
|
authSdkSource.makeKeyConnectorKeys()
|
||||||
|
} returns keyConnectorResponse.asSuccess()
|
||||||
|
coEvery {
|
||||||
|
accountsService.storeMasterKeyToKeyConnector(
|
||||||
|
url = URL,
|
||||||
|
accessToken = ACCESS_TOKEN,
|
||||||
|
masterKey = MASTER_KEY,
|
||||||
|
)
|
||||||
|
} returns expectedResult
|
||||||
|
|
||||||
|
val result = keyConnectorManager.migrateNewUserToKeyConnector(
|
||||||
|
url = URL,
|
||||||
|
accessToken = ACCESS_TOKEN,
|
||||||
|
kdfType = KDF_TYPE,
|
||||||
|
kdfIterations = KDF_ITERATIONS,
|
||||||
|
kdfMemory = KDF_MEMORY,
|
||||||
|
kdfParallelism = KDF_PARALLELISM,
|
||||||
|
organizationIdentifier = ORGANIZATION_IDENTIFIER,
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(expectedResult, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `migrateNewUserToKeyConnector with setKeyConnectorKey failure should return failure`() =
|
||||||
|
runTest {
|
||||||
|
val keyConnectorResponse: KeyConnectorResponse = mockk {
|
||||||
|
every { masterKey } returns MASTER_KEY
|
||||||
|
every { encryptedUserKey } returns ENCRYPTED_USER_KEY
|
||||||
|
every { keys } returns RsaKeyPair(public = PUBLIC_KEY, private = PRIVATE_KEY)
|
||||||
|
}
|
||||||
|
val expectedResult = Throwable("Fail").asFailure()
|
||||||
|
coEvery {
|
||||||
|
authSdkSource.makeKeyConnectorKeys()
|
||||||
|
} returns keyConnectorResponse.asSuccess()
|
||||||
|
coEvery {
|
||||||
|
accountsService.storeMasterKeyToKeyConnector(
|
||||||
|
url = URL,
|
||||||
|
accessToken = ACCESS_TOKEN,
|
||||||
|
masterKey = MASTER_KEY,
|
||||||
|
)
|
||||||
|
} returns Unit.asSuccess()
|
||||||
|
coEvery {
|
||||||
|
accountsService.setKeyConnectorKey(
|
||||||
|
accessToken = ACCESS_TOKEN,
|
||||||
|
body = KeyConnectorKeyRequestJson(
|
||||||
|
userKey = ENCRYPTED_USER_KEY,
|
||||||
|
keys = KeyConnectorKeyRequestJson.Keys(
|
||||||
|
publicKey = PUBLIC_KEY,
|
||||||
|
encryptedPrivateKey = PRIVATE_KEY,
|
||||||
|
),
|
||||||
|
kdfType = KDF_TYPE,
|
||||||
|
kdfIterations = KDF_ITERATIONS,
|
||||||
|
kdfMemory = KDF_MEMORY,
|
||||||
|
kdfParallelism = KDF_PARALLELISM,
|
||||||
|
organizationIdentifier = ORGANIZATION_IDENTIFIER,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns expectedResult
|
||||||
|
|
||||||
|
val result = keyConnectorManager.migrateNewUserToKeyConnector(
|
||||||
|
url = URL,
|
||||||
|
accessToken = ACCESS_TOKEN,
|
||||||
|
kdfType = KDF_TYPE,
|
||||||
|
kdfIterations = KDF_ITERATIONS,
|
||||||
|
kdfMemory = KDF_MEMORY,
|
||||||
|
kdfParallelism = KDF_PARALLELISM,
|
||||||
|
organizationIdentifier = ORGANIZATION_IDENTIFIER,
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(expectedResult, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `migrateNewUserToKeyConnector should return succeed`() = runTest {
|
||||||
|
val keyConnectorResponse: KeyConnectorResponse = mockk {
|
||||||
|
every { masterKey } returns MASTER_KEY
|
||||||
|
every { encryptedUserKey } returns ENCRYPTED_USER_KEY
|
||||||
|
every { keys } returns RsaKeyPair(public = PUBLIC_KEY, private = PRIVATE_KEY)
|
||||||
|
}
|
||||||
|
coEvery {
|
||||||
|
authSdkSource.makeKeyConnectorKeys()
|
||||||
|
} returns keyConnectorResponse.asSuccess()
|
||||||
|
coEvery {
|
||||||
|
accountsService.storeMasterKeyToKeyConnector(
|
||||||
|
url = URL,
|
||||||
|
accessToken = ACCESS_TOKEN,
|
||||||
|
masterKey = MASTER_KEY,
|
||||||
|
)
|
||||||
|
} returns Unit.asSuccess()
|
||||||
|
coEvery {
|
||||||
|
accountsService.setKeyConnectorKey(
|
||||||
|
accessToken = ACCESS_TOKEN,
|
||||||
|
body = KeyConnectorKeyRequestJson(
|
||||||
|
userKey = ENCRYPTED_USER_KEY,
|
||||||
|
keys = KeyConnectorKeyRequestJson.Keys(
|
||||||
|
publicKey = PUBLIC_KEY,
|
||||||
|
encryptedPrivateKey = PRIVATE_KEY,
|
||||||
|
),
|
||||||
|
kdfType = KDF_TYPE,
|
||||||
|
kdfIterations = KDF_ITERATIONS,
|
||||||
|
kdfMemory = KDF_MEMORY,
|
||||||
|
kdfParallelism = KDF_PARALLELISM,
|
||||||
|
organizationIdentifier = ORGANIZATION_IDENTIFIER,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
} returns Unit.asSuccess()
|
||||||
|
|
||||||
|
val result = keyConnectorManager.migrateNewUserToKeyConnector(
|
||||||
|
url = URL,
|
||||||
|
accessToken = ACCESS_TOKEN,
|
||||||
|
kdfType = KDF_TYPE,
|
||||||
|
kdfIterations = KDF_ITERATIONS,
|
||||||
|
kdfMemory = KDF_MEMORY,
|
||||||
|
kdfParallelism = KDF_PARALLELISM,
|
||||||
|
organizationIdentifier = ORGANIZATION_IDENTIFIER,
|
||||||
|
)
|
||||||
|
|
||||||
|
assertEquals(keyConnectorResponse.asSuccess(), result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private const val ACCESS_TOKEN: String = "token"
|
||||||
|
private const val USER_ID: String = "userId"
|
||||||
|
private const val URL: String = "www.example.com"
|
||||||
|
private const val ENCRYPTED_USER_KEY: String = "userKeyEncrypted"
|
||||||
|
private const val EMAIL: String = "email@email.com"
|
||||||
|
private const val MASTER_PASSWORD: String = "masterPassword"
|
||||||
|
private const val MASTER_KEY: String = "masterKey"
|
||||||
|
private const val PUBLIC_KEY: String = "publicKey"
|
||||||
|
private const val PRIVATE_KEY: String = "privateKey"
|
||||||
|
private const val ORGANIZATION_IDENTIFIER: String = "org_identifier"
|
||||||
|
private val KDF: Kdf = mockk()
|
||||||
|
private val KDF_TYPE: KdfTypeJson = KdfTypeJson.ARGON2_ID
|
||||||
|
private const val KDF_ITERATIONS: Int = 1
|
||||||
|
private const val KDF_MEMORY: Int = 2
|
||||||
|
private const val KDF_PARALLELISM: Int = 3
|
Loading…
Add table
Reference in a new issue