[PM-9363] Disable cipher key encryption for older server versions (#4006)

This commit is contained in:
mpbw2 2024-10-03 17:42:23 -04:00 committed by GitHub
parent c8dcafe737
commit 1d84479cf3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 108 additions and 1 deletions

View file

@ -3,10 +3,12 @@ package com.x8bit.bitwarden.data.platform.manager
import com.x8bit.bitwarden.data.platform.datasource.disk.model.ServerConfig
import com.x8bit.bitwarden.data.platform.manager.model.FlagKey
import com.x8bit.bitwarden.data.platform.repository.ServerConfigRepository
import com.x8bit.bitwarden.data.platform.util.isServerVersionAtLeast
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
private const val CIPHER_KEY_ENCRYPTION_KEY = "enableCipherKeyEncryption"
private const val CIPHER_KEY_ENC_MIN_SERVER_VERSION = "2024.2.0"
/**
* Primary implementation of [FeatureFlagManager].
@ -16,7 +18,13 @@ class FeatureFlagManagerImpl(
) : FeatureFlagManager {
override val sdkFeatureFlags: Map<String, Boolean>
get() = mapOf(CIPHER_KEY_ENCRYPTION_KEY to true)
get() = mapOf(
CIPHER_KEY_ENCRYPTION_KEY to
isServerVersionAtLeast(
serverConfigRepository.serverConfigStateFlow.value,
CIPHER_KEY_ENC_MIN_SERVER_VERSION,
),
)
override fun <T : Any> getFeatureFlagFlow(key: FlagKey<T>): Flow<T> =
serverConfigRepository

View file

@ -0,0 +1,51 @@
package com.x8bit.bitwarden.data.platform.util
import com.x8bit.bitwarden.data.platform.datasource.disk.model.ServerConfig
import kotlin.text.split
import kotlin.text.toIntOrNull
private const val VERSION_SEPARATOR = "."
private const val SUFFIX_SEPARATOR = "-"
/**
* Checks if the server version is greater than another provided version, returns true if it is.
*/
fun isServerVersionAtLeast(serverConfig: ServerConfig?, version: String): Boolean {
val serverVersion = serverConfig
?.serverData
?.version
if (serverVersion.isNullOrEmpty() || version.isEmpty()) {
return false
}
val serverVersionParts = getVersionComponents(serverVersion)
val otherVersionParts = getVersionComponents(version)
if (serverVersionParts.isNullOrEmpty() || otherVersionParts.isNullOrEmpty()) {
return false
}
// Must iterate through all indices to establish if versions are equal
for (i in serverVersionParts.indices) {
val serverPart = serverVersionParts.getOrNull(i)?.toIntOrNull() ?: 0
val otherPart = otherVersionParts.getOrNull(i)?.toIntOrNull() ?: 0
if (serverPart > otherPart) {
return true
} else if (serverPart < otherPart) {
return false
}
}
// Versions are equal
return true
}
/**
* Extracts the version components from a version string, disregarding any suffixes.
*/
private fun getVersionComponents(version: String?): List<String>? {
val versionComponents = version?.split(SUFFIX_SEPARATOR)?.first()
return versionComponents?.split(VERSION_SEPARATOR)
}

View file

@ -7,6 +7,7 @@ import com.x8bit.bitwarden.data.platform.datasource.network.model.ConfigResponse
import com.x8bit.bitwarden.data.platform.datasource.network.model.ConfigResponseJson.ServerJson
import com.x8bit.bitwarden.data.platform.manager.model.FlagKey
import com.x8bit.bitwarden.data.platform.repository.util.FakeServerConfigRepository
import com.x8bit.bitwarden.data.platform.util.isServerVersionAtLeast
import kotlinx.coroutines.test.runTest
import kotlinx.serialization.json.JsonPrimitive
import org.junit.Test
@ -33,6 +34,53 @@ class FeatureFlagManagerTest {
assertEquals(expected, actual)
}
@Test
fun `server version is at least supplied version`() {
val result =
isServerVersionAtLeast(
fakeServerConfigRepository.serverConfigStateFlow.value,
"2024.2.0",
)
// This relies on the fake server version being "2024.7.0"
assertTrue(result)
}
@Test
fun `server version is not at least supplied version`() {
val result =
isServerVersionAtLeast(
fakeServerConfigRepository.serverConfigStateFlow.value,
"2024.12.0-suffix",
)
// This relies on the fake server version being "2024.7.0"
assertFalse(result)
}
@Test
fun `server version is the same as supplied version`() {
val result =
isServerVersionAtLeast(
fakeServerConfigRepository.serverConfigStateFlow.value,
"2024.7.0",
)
// This relies on the fake server version being "2024.7.0"
assertTrue(result)
}
@Test
fun `server version is not the same as blank supplied version`() {
val result =
isServerVersionAtLeast(
fakeServerConfigRepository.serverConfigStateFlow.value,
"",
)
assertFalse(result)
}
@Test
fun `ServerConfigRepository flow with value should trigger new flags`() = runTest {
fakeServerConfigRepository.serverConfigValue = null