mirror of
https://github.com/bitwarden/android.git
synced 2026-06-08 16:17:05 -05:00
Add KdfTypeJson and associated BaseEnumeratedIntSerializer (#131)
This commit is contained in:
committed by
Álison Fernandes
parent
aafd32fbc3
commit
a55d6a519a
@@ -11,7 +11,7 @@ import kotlinx.serialization.Serializable
|
||||
@Serializable
|
||||
data class InternalPreLoginResponseJson(
|
||||
@SerialName("kdf")
|
||||
val kdfType: Int,
|
||||
val kdfType: KdfTypeJson,
|
||||
@SerialName("kdfIterations")
|
||||
val kdfIterations: UInt,
|
||||
@SerialName("kdfMemory")
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.x8bit.bitwarden.data.auth.datasource.network.model
|
||||
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.serializer.BaseEnumeratedIntSerializer
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
/**
|
||||
* Represents different key derivation functions (KDFs).
|
||||
*/
|
||||
@Serializable(KdfTypeSerializer::class)
|
||||
enum class KdfTypeJson {
|
||||
@SerialName("1")
|
||||
ARGON2_ID,
|
||||
|
||||
@SerialName("0")
|
||||
PBKDF2_SHA256,
|
||||
}
|
||||
|
||||
private class KdfTypeSerializer :
|
||||
BaseEnumeratedIntSerializer<KdfTypeJson>(KdfTypeJson.values())
|
||||
@@ -3,9 +3,6 @@ package com.x8bit.bitwarden.data.auth.datasource.network.model
|
||||
import com.x8bit.bitwarden.data.platform.datasource.network.serializer.BaseSurrogateSerializer
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
private const val KDF_TYPE_ARGON2_ID = 1
|
||||
private const val KDF_TYPE_PBKDF2_SHA256 = 0
|
||||
|
||||
/**
|
||||
* Response body for pre login.
|
||||
*/
|
||||
@@ -21,6 +18,11 @@ data class PreLoginResponseJson(
|
||||
*/
|
||||
sealed class KdfParams {
|
||||
|
||||
/**
|
||||
* The associated [KdfTypeJson].
|
||||
*/
|
||||
abstract val kdfTypeJson: KdfTypeJson
|
||||
|
||||
/**
|
||||
* Models params for the Argon2id algorithm.
|
||||
*/
|
||||
@@ -28,12 +30,20 @@ data class PreLoginResponseJson(
|
||||
val iterations: UInt,
|
||||
val memory: UInt,
|
||||
val parallelism: UInt,
|
||||
) : KdfParams()
|
||||
) : KdfParams() {
|
||||
override val kdfTypeJson: KdfTypeJson
|
||||
get() = KdfTypeJson.ARGON2_ID
|
||||
}
|
||||
|
||||
/**
|
||||
* Models params for the PBKDF2 algorithm.
|
||||
*/
|
||||
data class Pbkdf2(val iterations: UInt) : KdfParams()
|
||||
data class Pbkdf2(
|
||||
val iterations: UInt,
|
||||
) : KdfParams() {
|
||||
override val kdfTypeJson: KdfTypeJson
|
||||
get() = KdfTypeJson.PBKDF2_SHA256
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,13 +55,13 @@ private class PreLoginResponseSerializer :
|
||||
override fun InternalPreLoginResponseJson.toExternalType(): PreLoginResponseJson =
|
||||
PreLoginResponseJson(
|
||||
kdfParams = when (this.kdfType) {
|
||||
KDF_TYPE_PBKDF2_SHA256 -> {
|
||||
KdfTypeJson.PBKDF2_SHA256 -> {
|
||||
PreLoginResponseJson.KdfParams.Pbkdf2(
|
||||
iterations = this.kdfIterations,
|
||||
)
|
||||
}
|
||||
|
||||
KDF_TYPE_ARGON2_ID -> {
|
||||
KdfTypeJson.ARGON2_ID -> {
|
||||
@Suppress("UnsafeCallOnNullableType")
|
||||
PreLoginResponseJson.KdfParams.Argon2ID(
|
||||
iterations = this.kdfIterations,
|
||||
@@ -59,10 +69,6 @@ private class PreLoginResponseSerializer :
|
||||
parallelism = this.kdfParallelism!!,
|
||||
)
|
||||
}
|
||||
|
||||
else -> throw IllegalStateException(
|
||||
"Unable to parse KDF params for unknown kdfType: ${this.kdfType}",
|
||||
)
|
||||
},
|
||||
)
|
||||
|
||||
@@ -70,7 +76,7 @@ private class PreLoginResponseSerializer :
|
||||
when (val params = this.kdfParams) {
|
||||
is PreLoginResponseJson.KdfParams.Argon2ID -> {
|
||||
InternalPreLoginResponseJson(
|
||||
kdfType = KDF_TYPE_ARGON2_ID,
|
||||
kdfType = params.kdfTypeJson,
|
||||
kdfIterations = params.iterations,
|
||||
kdfMemory = params.memory,
|
||||
kdfParallelism = params.parallelism,
|
||||
@@ -79,7 +85,7 @@ private class PreLoginResponseSerializer :
|
||||
|
||||
is PreLoginResponseJson.KdfParams.Pbkdf2 -> {
|
||||
InternalPreLoginResponseJson(
|
||||
kdfType = KDF_TYPE_PBKDF2_SHA256,
|
||||
kdfType = params.kdfTypeJson,
|
||||
kdfIterations = params.iterations,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package com.x8bit.bitwarden.data.platform.datasource.network.serializer
|
||||
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.descriptors.PrimitiveKind
|
||||
import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
|
||||
/**
|
||||
* Base [KSerializer] for mapping an [Enum] with possible values given by [values] to/from integer
|
||||
* values, which should be specified using [SerialName].
|
||||
*/
|
||||
@Suppress("UnnecessaryAbstractClass")
|
||||
abstract class BaseEnumeratedIntSerializer<T : Enum<T>>(
|
||||
private val values: Array<T>,
|
||||
) : KSerializer<T> {
|
||||
|
||||
override val descriptor: SerialDescriptor
|
||||
get() = PrimitiveSerialDescriptor(
|
||||
serialName = this::class.java.simpleName,
|
||||
kind = PrimitiveKind.INT,
|
||||
)
|
||||
|
||||
override fun deserialize(decoder: Decoder): T {
|
||||
val decodedValue = decoder.decodeInt().toString()
|
||||
return values.first { it.serialNameAnnotation?.value == decodedValue }
|
||||
}
|
||||
|
||||
override fun serialize(encoder: Encoder, value: T) {
|
||||
encoder.encodeInt(
|
||||
requireNotNull(
|
||||
value.serialNameAnnotation?.value?.toInt(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private val Enum<*>.serialNameAnnotation: SerialName?
|
||||
get() = javaClass.getDeclaredField(name).getAnnotation(SerialName::class.java)
|
||||
}
|
||||
Reference in New Issue
Block a user