mirror of
https://github.com/bitwarden/android.git
synced 2026-03-13 21:54:17 -05:00
PM-24089: Remove Mutual TLS feature flag (#5566)
This commit is contained in:
@@ -25,7 +25,6 @@ sealed class FlagKey<out T : Any> {
|
||||
ImportLoginsFlow,
|
||||
CredentialExchangeProtocolImport,
|
||||
CredentialExchangeProtocolExport,
|
||||
MutualTls,
|
||||
SingleTapPasskeyCreation,
|
||||
SingleTapPasskeyAuthentication,
|
||||
AnonAddySelfHostAlias,
|
||||
@@ -80,14 +79,6 @@ sealed class FlagKey<out T : Any> {
|
||||
override val defaultValue: Boolean = false
|
||||
}
|
||||
|
||||
/**
|
||||
* Data object holding the feature flag key for the Mutual TLS feature.
|
||||
*/
|
||||
data object MutualTls : FlagKey<Boolean>() {
|
||||
override val keyName: String = "mutual-tls"
|
||||
override val defaultValue: Boolean = false
|
||||
}
|
||||
|
||||
/**
|
||||
* Data object holding the feature flag key to enable single tap passkey creation.
|
||||
*/
|
||||
|
||||
@@ -323,59 +323,58 @@ fun EnvironmentScreen(
|
||||
.standardHorizontalMargin(),
|
||||
)
|
||||
|
||||
if (state.showMutualTlsOptions) {
|
||||
Spacer(modifier = Modifier.height(height = 16.dp))
|
||||
Spacer(modifier = Modifier.height(height = 16.dp))
|
||||
|
||||
BitwardenListHeaderText(
|
||||
label = stringResource(id = R.string.client_certificate_mtls),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.standardHorizontalMargin()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(height = 8.dp))
|
||||
BitwardenListHeaderText(
|
||||
label = stringResource(id = R.string.client_certificate_mtls),
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.standardHorizontalMargin()
|
||||
.padding(horizontal = 16.dp),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(height = 8.dp))
|
||||
|
||||
BitwardenTextField(
|
||||
label = stringResource(id = R.string.certificate_alias),
|
||||
value = state.keyAlias,
|
||||
supportingText = stringResource(
|
||||
id = R.string.certificate_used_for_client_authentication,
|
||||
),
|
||||
onValueChange = {},
|
||||
readOnly = true,
|
||||
cardStyle = CardStyle.Full,
|
||||
textFieldTestTag = "KeyAliasEntry",
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.focusProperties { canFocus = false }
|
||||
.standardHorizontalMargin(),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(height = 16.dp))
|
||||
BitwardenTextField(
|
||||
label = stringResource(id = R.string.certificate_alias),
|
||||
value = state.keyAlias,
|
||||
supportingText = stringResource(
|
||||
id = R.string.certificate_used_for_client_authentication,
|
||||
),
|
||||
onValueChange = {},
|
||||
readOnly = true,
|
||||
cardStyle = CardStyle.Full,
|
||||
textFieldTestTag = "KeyAliasEntry",
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.focusProperties { canFocus = false }
|
||||
.standardHorizontalMargin(),
|
||||
)
|
||||
Spacer(modifier = Modifier.height(height = 16.dp))
|
||||
|
||||
BitwardenFilledButton(
|
||||
label = stringResource(id = R.string.import_certificate),
|
||||
onClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(EnvironmentAction.ImportCertificateClick) }
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.standardHorizontalMargin()
|
||||
.testTag("ImportCertificateButton"),
|
||||
)
|
||||
BitwardenFilledButton(
|
||||
label = stringResource(id = R.string.import_certificate),
|
||||
onClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(EnvironmentAction.ImportCertificateClick) }
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.standardHorizontalMargin()
|
||||
.testTag("ImportCertificateButton"),
|
||||
)
|
||||
|
||||
Spacer(modifier = Modifier.height(height = 12.dp))
|
||||
Spacer(modifier = Modifier.height(height = 12.dp))
|
||||
|
||||
BitwardenOutlinedButton(
|
||||
label = stringResource(id = R.string.choose_system_certificate),
|
||||
onClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(EnvironmentAction.ChooseSystemCertificateClick) }
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.standardHorizontalMargin()
|
||||
.testTag("ChooseSystemCertificateButton"),
|
||||
)
|
||||
|
||||
BitwardenOutlinedButton(
|
||||
label = stringResource(id = R.string.choose_system_certificate),
|
||||
onClick = remember(viewModel) {
|
||||
{ viewModel.trySendAction(EnvironmentAction.ChooseSystemCertificateClick) }
|
||||
},
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.standardHorizontalMargin()
|
||||
.testTag("ChooseSystemCertificateButton"),
|
||||
)
|
||||
}
|
||||
Spacer(modifier = Modifier.height(height = 16.dp))
|
||||
Spacer(modifier = Modifier.navigationBarsPadding())
|
||||
}
|
||||
|
||||
@@ -16,8 +16,6 @@ import com.bitwarden.ui.util.asText
|
||||
import com.x8bit.bitwarden.R
|
||||
import com.x8bit.bitwarden.data.platform.datasource.disk.model.MutualTlsKeyHost
|
||||
import com.x8bit.bitwarden.data.platform.manager.CertificateManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.FeatureFlagManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.model.FlagKey
|
||||
import com.x8bit.bitwarden.data.platform.manager.model.ImportPrivateKeyResult
|
||||
import com.x8bit.bitwarden.data.platform.repository.EnvironmentRepository
|
||||
import com.x8bit.bitwarden.data.vault.manager.FileManager
|
||||
@@ -28,7 +26,6 @@ import com.x8bit.bitwarden.ui.platform.manager.snackbar.SnackbarRelay
|
||||
import com.x8bit.bitwarden.ui.platform.manager.snackbar.SnackbarRelayManager
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.update
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -46,7 +43,6 @@ class EnvironmentViewModel @Inject constructor(
|
||||
private val environmentRepository: EnvironmentRepository,
|
||||
private val fileManager: FileManager,
|
||||
private val certificateManager: CertificateManager,
|
||||
private val featureFlagManager: FeatureFlagManager,
|
||||
private val snackbarRelayManager: SnackbarRelayManager,
|
||||
private val savedStateHandle: SavedStateHandle,
|
||||
) : BaseViewModel<EnvironmentState, EnvironmentEvent, EnvironmentAction>(
|
||||
@@ -70,21 +66,13 @@ class EnvironmentViewModel @Inject constructor(
|
||||
keyAlias = keyAlias,
|
||||
keyHost = keyHost,
|
||||
dialog = null,
|
||||
showMutualTlsOptions = featureFlagManager.getFeatureFlag(FlagKey.MutualTls),
|
||||
)
|
||||
},
|
||||
) {
|
||||
|
||||
init {
|
||||
stateFlow
|
||||
.onEach {
|
||||
savedStateHandle[KEY_STATE] = it
|
||||
}
|
||||
.launchIn(viewModelScope)
|
||||
|
||||
featureFlagManager.getFeatureFlagFlow(FlagKey.MutualTls)
|
||||
.map { EnvironmentAction.Internal.MutualTlsFeatureFlagUpdate(it) }
|
||||
.onEach(::handleAction)
|
||||
.onEach { savedStateHandle[KEY_STATE] = it }
|
||||
.launchIn(viewModelScope)
|
||||
}
|
||||
|
||||
@@ -275,10 +263,6 @@ class EnvironmentViewModel @Inject constructor(
|
||||
is EnvironmentAction.Internal.ImportKeyResultReceive -> {
|
||||
handleSaveKeyResultReceive(action)
|
||||
}
|
||||
|
||||
is EnvironmentAction.Internal.MutualTlsFeatureFlagUpdate -> {
|
||||
handleMutualTlsFeatureFlagUpdate(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -361,16 +345,6 @@ class EnvironmentViewModel @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleMutualTlsFeatureFlagUpdate(
|
||||
action: EnvironmentAction.Internal.MutualTlsFeatureFlagUpdate,
|
||||
) {
|
||||
mutableStateFlow.update {
|
||||
it.copy(
|
||||
showMutualTlsOptions = action.enabled,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleChooseSystemCertificateClickAction() {
|
||||
mutableStateFlow.update {
|
||||
it.copy(
|
||||
@@ -472,7 +446,6 @@ data class EnvironmentState(
|
||||
val iconsServerUrl: String,
|
||||
val keyAlias: String,
|
||||
val dialog: DialogState?,
|
||||
val showMutualTlsOptions: Boolean,
|
||||
// internal
|
||||
private val keyHost: MutualTlsKeyHost?,
|
||||
) : Parcelable {
|
||||
@@ -692,12 +665,5 @@ sealed class EnvironmentAction {
|
||||
data class ImportKeyResultReceive(
|
||||
val result: ImportPrivateKeyResult,
|
||||
) : Internal()
|
||||
|
||||
/**
|
||||
* Indicates the mutual TLS feature flag was updated.
|
||||
*/
|
||||
data class MutualTlsFeatureFlagUpdate(
|
||||
val enabled: Boolean,
|
||||
) : Internal()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,6 @@ fun <T : Any> FlagKey<T>.ListItemContent(
|
||||
FlagKey.CredentialExchangeProtocolImport,
|
||||
FlagKey.CredentialExchangeProtocolExport,
|
||||
FlagKey.CipherKeyEncryption,
|
||||
FlagKey.MutualTls,
|
||||
FlagKey.SingleTapPasskeyCreation,
|
||||
FlagKey.SingleTapPasskeyAuthentication,
|
||||
FlagKey.AnonAddySelfHostAlias,
|
||||
@@ -85,7 +84,6 @@ private fun <T : Any> FlagKey<T>.getDisplayLabel(): String = when (this) {
|
||||
FlagKey.CredentialExchangeProtocolImport -> stringResource(R.string.cxp_import)
|
||||
FlagKey.CredentialExchangeProtocolExport -> stringResource(R.string.cxp_export)
|
||||
FlagKey.CipherKeyEncryption -> stringResource(R.string.cipher_key_encryption)
|
||||
FlagKey.MutualTls -> stringResource(R.string.mutual_tls)
|
||||
FlagKey.SingleTapPasskeyCreation -> stringResource(R.string.single_tap_passkey_creation)
|
||||
FlagKey.SingleTapPasskeyAuthentication -> {
|
||||
stringResource(R.string.single_tap_passkey_authentication)
|
||||
|
||||
@@ -865,7 +865,6 @@ Do you want to switch to this account?</string>
|
||||
<string name="you_ll_only_need_to_set_up_authenticator_key">You’ll only need to set up Authenticator Key for logins that require two-factor authentication with a code. The key will continuously generate six-digit codes you can use to log in.</string>
|
||||
<string name="coachmark_3_of_3">3 OF 3</string>
|
||||
<string name="you_must_add_a_web_address_to_use_autofill_to_access_this_account">You must add a web address to use autofill to access this account.</string>
|
||||
<string name="mutual_tls">Mutual TLS</string>
|
||||
<string name="single_tap_passkey_creation">Single tap passkey creation</string>
|
||||
<string name="single_tap_passkey_authentication">Single tap passkey sign-on</string>
|
||||
<string name="learn_about_new_logins">Learn about new logins</string>
|
||||
|
||||
@@ -37,10 +37,6 @@ class FlagKeyTest {
|
||||
FlagKey.SingleTapPasskeyAuthentication.keyName,
|
||||
"single-tap-passkey-authentication",
|
||||
)
|
||||
assertEquals(
|
||||
FlagKey.MutualTls.keyName,
|
||||
"mutual-tls",
|
||||
)
|
||||
assertEquals(
|
||||
FlagKey.AnonAddySelfHostAlias.keyName,
|
||||
"anon-addy-self-host-alias",
|
||||
|
||||
@@ -437,7 +437,6 @@ class EnvironmentScreenTest : BitwardenComposeTest() {
|
||||
iconsServerUrl = "",
|
||||
keyHost = null,
|
||||
dialog = null,
|
||||
showMutualTlsOptions = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,6 @@ import com.bitwarden.ui.util.asText
|
||||
import com.x8bit.bitwarden.R
|
||||
import com.x8bit.bitwarden.data.platform.datasource.disk.model.MutualTlsKeyHost
|
||||
import com.x8bit.bitwarden.data.platform.manager.CertificateManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.FeatureFlagManager
|
||||
import com.x8bit.bitwarden.data.platform.manager.model.FlagKey
|
||||
import com.x8bit.bitwarden.data.platform.manager.model.ImportPrivateKeyResult
|
||||
import com.x8bit.bitwarden.data.platform.repository.util.FakeEnvironmentRepository
|
||||
import com.x8bit.bitwarden.data.vault.manager.FileManager
|
||||
@@ -28,7 +26,6 @@ import io.mockk.just
|
||||
import io.mockk.mockk
|
||||
import io.mockk.runs
|
||||
import io.mockk.verify
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.jupiter.api.Assertions.assertEquals
|
||||
import org.junit.jupiter.api.Test
|
||||
@@ -37,11 +34,6 @@ import org.junit.jupiter.api.Test
|
||||
class EnvironmentViewModelTest : BaseViewModelTest() {
|
||||
|
||||
private val fakeEnvironmentRepository = FakeEnvironmentRepository()
|
||||
private val mutableMutualTlsFeatureFlagFlow = MutableStateFlow(true)
|
||||
private val mockFeatureFlagManager = mockk<FeatureFlagManager> {
|
||||
every { getFeatureFlag(FlagKey.MutualTls) } returns true
|
||||
every { getFeatureFlagFlow(FlagKey.MutualTls) } returns mutableMutualTlsFeatureFlagFlow
|
||||
}
|
||||
private val mockCertificateManager = mockk<CertificateManager> {
|
||||
every { getMutualTlsKeyAliases() } returns emptyList()
|
||||
}
|
||||
@@ -814,7 +806,6 @@ class EnvironmentViewModelTest : BaseViewModelTest() {
|
||||
): EnvironmentViewModel =
|
||||
EnvironmentViewModel(
|
||||
environmentRepository = fakeEnvironmentRepository,
|
||||
featureFlagManager = mockFeatureFlagManager,
|
||||
certificateManager = mockCertificateManager,
|
||||
fileManager = mockFileManager,
|
||||
snackbarRelayManager = snackbarRelayManager,
|
||||
@@ -833,7 +824,6 @@ class EnvironmentViewModelTest : BaseViewModelTest() {
|
||||
iconsServerUrl = "",
|
||||
keyHost = null,
|
||||
dialog = null,
|
||||
showMutualTlsOptions = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,7 +148,6 @@ private val DEFAULT_MAP_VALUE: ImmutableMap<FlagKey<Any>, Any> = persistentMapOf
|
||||
FlagKey.ImportLoginsFlow to true,
|
||||
FlagKey.CredentialExchangeProtocolImport to true,
|
||||
FlagKey.CredentialExchangeProtocolExport to true,
|
||||
FlagKey.MutualTls to true,
|
||||
FlagKey.SingleTapPasskeyCreation to true,
|
||||
FlagKey.SingleTapPasskeyAuthentication to true,
|
||||
FlagKey.AnonAddySelfHostAlias to true,
|
||||
@@ -164,7 +163,6 @@ private val UPDATED_MAP_VALUE: ImmutableMap<FlagKey<Any>, Any> = persistentMapOf
|
||||
FlagKey.ImportLoginsFlow to false,
|
||||
FlagKey.CredentialExchangeProtocolImport to false,
|
||||
FlagKey.CredentialExchangeProtocolExport to false,
|
||||
FlagKey.MutualTls to false,
|
||||
FlagKey.SingleTapPasskeyCreation to false,
|
||||
FlagKey.SingleTapPasskeyAuthentication to false,
|
||||
FlagKey.AnonAddySelfHostAlias to false,
|
||||
|
||||
Reference in New Issue
Block a user