PM-14271 Disable editing SSH key fields in edit mode

The commit disables editing of public key, private key, and fingerprint fields for SSH keys in edit mode. This is achieved by:

- Making the corresponding text fields read-only.
- Removing the handlers that were previously updating the ViewModel with text changes for these fields.
This commit is contained in:
Patrick Honkonen 2024-10-30 13:58:26 -04:00
parent 56367cc14e
commit 4c4de106c4
No known key found for this signature in database
GPG key ID: B63AF42A5531C877
5 changed files with 20 additions and 155 deletions

View file

@ -46,7 +46,8 @@ fun LazyListScope.vaultAddEditSshKeyItems(
BitwardenTextField(
label = stringResource(id = R.string.public_key),
value = sshKeyState.publicKey,
onValueChange = sshKeyTypeHandlers.onPublicKeyTextChange,
readOnly = true,
onValueChange = { },
modifier = Modifier
.testTag("PublicKeyEntry")
.fillMaxWidth()
@ -59,7 +60,8 @@ fun LazyListScope.vaultAddEditSshKeyItems(
BitwardenPasswordField(
label = stringResource(id = R.string.private_key),
value = sshKeyState.privateKey,
onValueChange = sshKeyTypeHandlers.onPrivateKeyTextChange,
readOnly = true,
onValueChange = { /* no-op */ },
showPassword = sshKeyState.showPrivateKey,
showPasswordChange = { sshKeyTypeHandlers.onPrivateKeyVisibilityChange(it) },
showPasswordTestTag = "ViewPrivateKeyButton",
@ -75,7 +77,8 @@ fun LazyListScope.vaultAddEditSshKeyItems(
BitwardenTextField(
label = stringResource(id = R.string.fingerprint),
value = sshKeyState.fingerprint,
onValueChange = sshKeyTypeHandlers.onFingerprintTextChange,
readOnly = true,
onValueChange = { /* no-op */ },
modifier = Modifier
.testTag("FingerprintEntry")
.fillMaxWidth()
@ -116,10 +119,7 @@ private fun VaultAddEditSshKeyItems_preview() {
onHiddenFieldVisibilityChange = { },
),
sshKeyTypeHandlers = VaultAddEditSshKeyTypeHandlers(
onPublicKeyTextChange = { },
onPrivateKeyTextChange = { },
onPrivateKeyVisibilityChange = { },
onFingerprintTextChange = { },
),
)
}

View file

@ -1394,48 +1394,18 @@ class VaultAddEditViewModel @Inject constructor(
private fun handleSshKeyTypeActions(action: VaultAddEditAction.ItemType.SshKeyType) {
when (action) {
is VaultAddEditAction.ItemType.SshKeyType.PublicKeyTextChange -> {
handlePublicKeyTextChange(action)
}
is VaultAddEditAction.ItemType.SshKeyType.PrivateKeyTextChange -> {
handlePrivateKeyTextChange(action)
}
is VaultAddEditAction.ItemType.SshKeyType.PrivateKeyVisibilityChange -> {
handlePrivateKeyVisibilityChange(action)
}
is VaultAddEditAction.ItemType.SshKeyType.FingerprintTextChange -> {
handleSshKeyFingerprintTextChange(action)
}
}
}
private fun handlePublicKeyTextChange(
action: VaultAddEditAction.ItemType.SshKeyType.PublicKeyTextChange,
) {
updateSshKeyContent { it.copy(publicKey = action.publicKey) }
}
private fun handlePrivateKeyTextChange(
action: VaultAddEditAction.ItemType.SshKeyType.PrivateKeyTextChange,
) {
updateSshKeyContent { it.copy(privateKey = action.privateKey) }
}
private fun handlePrivateKeyVisibilityChange(
action: VaultAddEditAction.ItemType.SshKeyType.PrivateKeyVisibilityChange,
) {
updateSshKeyContent { it.copy(showPrivateKey = action.isVisible) }
}
private fun handleSshKeyFingerprintTextChange(
action: VaultAddEditAction.ItemType.SshKeyType.FingerprintTextChange,
) {
updateSshKeyContent { it.copy(fingerprint = action.fingerprint) }
}
//endregion SSH Key Type Handlers
//region Internal Type Handlers
@ -3062,25 +3032,11 @@ sealed class VaultAddEditAction {
* Represents actions specific to the SSH Key type.
*/
sealed class SshKeyType : ItemType() {
/**
* Fired when the public key text input is changed.
*/
data class PublicKeyTextChange(val publicKey: String) : SshKeyType()
/**
* Fired when the private key text input is changed.
*/
data class PrivateKeyTextChange(val privateKey: String) : SshKeyType()
/**
* Fired when the private key's visibility has changed.
*/
data class PrivateKeyVisibilityChange(val isVisible: Boolean) : SshKeyType()
/**
* Fired when the fingerprint text input is changed.
*/
data class FingerprintTextChange(val fingerprint: String) : SshKeyType()
}
}

View file

@ -10,16 +10,10 @@ import com.x8bit.bitwarden.ui.vault.feature.addedit.VaultAddEditViewModel
* These handlers are used to update the ViewModel with user actions such as text changes and
* visibility changes for different SSH key fields (public key, private key, fingerprint).
*
* @property onPublicKeyTextChange Handler for changes in the public key text field.
* @property onPrivateKeyTextChange Handler for changes in the private key text field.
* @property onPrivateKeyVisibilityChange Handler for toggling the visibility of the private key.
* @property onFingerprintTextChange Handler for changes in the fingerprint text field.
*/
data class VaultAddEditSshKeyTypeHandlers(
val onPublicKeyTextChange: (String) -> Unit,
val onPrivateKeyTextChange: (String) -> Unit,
val onPrivateKeyVisibilityChange: (Boolean) -> Unit,
val onFingerprintTextChange: (String) -> Unit,
) {
@Suppress("UndocumentedPublicClass")
companion object {
@ -31,20 +25,7 @@ data class VaultAddEditSshKeyTypeHandlers(
*/
fun create(viewModel: VaultAddEditViewModel): VaultAddEditSshKeyTypeHandlers =
VaultAddEditSshKeyTypeHandlers(
onPublicKeyTextChange = { newPublicKey ->
viewModel.trySendAction(
VaultAddEditAction.ItemType.SshKeyType.PublicKeyTextChange(
publicKey = newPublicKey,
),
)
},
onPrivateKeyTextChange = { newPrivateKey ->
viewModel.trySendAction(
VaultAddEditAction.ItemType.SshKeyType.PrivateKeyTextChange(
privateKey = newPrivateKey,
),
)
},
onPrivateKeyVisibilityChange = {
viewModel.trySendAction(
VaultAddEditAction.ItemType.SshKeyType.PrivateKeyVisibilityChange(
@ -52,13 +33,6 @@ data class VaultAddEditSshKeyTypeHandlers(
),
)
},
onFingerprintTextChange = { newFingerprint ->
viewModel.trySendAction(
VaultAddEditAction.ItemType.SshKeyType.FingerprintTextChange(
fingerprint = newFingerprint,
),
)
},
)
}
}

View file

@ -18,6 +18,7 @@ import androidx.compose.ui.test.hasContentDescription
import androidx.compose.ui.test.hasSetTextAction
import androidx.compose.ui.test.hasText
import androidx.compose.ui.test.isDialog
import androidx.compose.ui.test.isEditable
import androidx.compose.ui.test.isPopup
import androidx.compose.ui.test.onAllNodesWithContentDescription
import androidx.compose.ui.test.onAllNodesWithText
@ -3323,54 +3324,33 @@ class VaultAddEditScreenTest : BaseComposeTest() {
}
@Test
fun `in ItemType_SshKeys changing the public key should trigger PublicKeyTextChange`() {
fun `in ItemType_SshKeys the public key field should be read only`() {
mutableStateFlow.value = DEFAULT_STATE_SSH_KEYS
composeTestRule
.onNodeWithTextAfterScroll("Public key")
.performTextInput("TestPublicKey")
verify {
viewModel.trySendAction(
VaultAddEditAction.ItemType.SshKeyType.PublicKeyTextChange(
publicKey = "TestPublicKey",
),
)
}
.onNodeWithTextAfterScroll(text = "Public key")
.assertExists()
.assert(!isEditable())
}
@Test
fun `in ItemType_SshKeys changing the private key should trigger PrivateKeyTextChange`() {
fun `in ItemType_SshKeys the private key field should be read only`() {
mutableStateFlow.value = DEFAULT_STATE_SSH_KEYS
composeTestRule
.onNodeWithTextAfterScroll("Private key")
.performTextInput("TestPrivateKey")
verify {
viewModel.trySendAction(
VaultAddEditAction.ItemType.SshKeyType.PrivateKeyTextChange(
privateKey = "TestPrivateKey",
),
)
}
.onNodeWithTextAfterScroll(text = "Private key")
.assertExists()
.assert(!isEditable())
}
@Test
fun `in ItemType_SshKeys changing the fingerprint should trigger FingerprintTextChange`() {
fun `in ItemType_SshKeys the fingerprint field should be read only`() {
mutableStateFlow.value = DEFAULT_STATE_SSH_KEYS
composeTestRule
.onNodeWithTextAfterScroll("Fingerprint")
.performTextInput("TestFingerprint")
verify {
viewModel.trySendAction(
VaultAddEditAction.ItemType.SshKeyType.FingerprintTextChange(
fingerprint = "TestFingerprint",
),
)
}
.onNodeWithTextAfterScroll(text = "Fingerprint")
.assertExists()
.assert(!isEditable())
}
@Suppress("MaxLineLength")

View file

@ -2725,36 +2725,6 @@ class VaultAddEditViewModelTest : BaseViewModelTest() {
)
}
@Test
fun `PublicKeyTextChange should update public key`() = runTest {
val action = VaultAddEditAction.ItemType.SshKeyType.PublicKeyTextChange(
publicKey = "newPublicKey",
)
val expectedState = createVaultAddItemState(
typeContentViewState = VaultAddEditState.ViewState.Content.ItemType.SshKey(
publicKey = "newPublicKey",
),
)
viewModel.trySendAction(action)
assertEquals(expectedState, viewModel.stateFlow.value)
}
@Test
fun `PrivateKeyTextChange should update private key`() = runTest {
val action = VaultAddEditAction.ItemType.SshKeyType.PrivateKeyTextChange(
privateKey = "newPrivateKey",
)
val expectedState = createVaultAddItemState(
typeContentViewState = VaultAddEditState.ViewState.Content.ItemType.SshKey(
privateKey = "newPrivateKey",
),
)
viewModel.trySendAction(action)
assertEquals(expectedState, viewModel.stateFlow.value)
}
@Test
fun `PrivateKeyVisibilityChange should update private key visibility`() = runTest {
val action = VaultAddEditAction.ItemType.SshKeyType.PrivateKeyVisibilityChange(
@ -2769,21 +2739,6 @@ class VaultAddEditViewModelTest : BaseViewModelTest() {
assertEquals(expectedState, viewModel.stateFlow.value)
}
@Test
fun `FingerprintTextChange should update fingerprint`() = runTest {
val action = VaultAddEditAction.ItemType.SshKeyType.FingerprintTextChange(
fingerprint = "newFingerprint",
)
val expectedState = createVaultAddItemState(
typeContentViewState = VaultAddEditState.ViewState.Content.ItemType.SshKey(
fingerprint = "newFingerprint",
),
)
viewModel.trySendAction(action)
assertEquals(expectedState, viewModel.stateFlow.value)
}
}
@Test