[PM-14186] Update SDK to make SSH key properties required (#4200)

This commit is contained in:
Patrick Honkonen 2024-10-30 14:42:33 -04:00 committed by GitHub
parent 56367cc14e
commit eaa7923d1f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 77 additions and 98 deletions

View file

@ -731,13 +731,13 @@ data class SyncResponseJson(
@Serializable @Serializable
data class SshKey( data class SshKey(
@SerialName("publicKey") @SerialName("publicKey")
val publicKey: String?, val publicKey: String,
@SerialName("privateKey") @SerialName("privateKey")
val privateKey: String?, val privateKey: String,
@SerialName("keyFingerprint") @SerialName("keyFingerprint")
val keyFingerprint: String?, val keyFingerprint: String,
) )
/** /**

View file

@ -53,58 +53,52 @@ fun VaultItemSshKeyContent(
) )
} }
sshKeyItemState.publicKey?.let { publicKey -> item {
item { Spacer(modifier = Modifier.height(8.dp))
Spacer(modifier = Modifier.height(8.dp)) BitwardenTextField(
BitwardenTextField( label = stringResource(id = R.string.public_key),
label = stringResource(id = R.string.public_key), value = sshKeyItemState.publicKey,
value = publicKey, onValueChange = { },
onValueChange = { }, singleLine = false,
singleLine = false, readOnly = true,
readOnly = true, modifier = Modifier
modifier = Modifier .testTag("SshKeyItemPublicKeyEntry")
.testTag("SshKeyItemPublicKeyEntry") .fillMaxWidth()
.fillMaxWidth() .padding(horizontal = 16.dp),
.padding(horizontal = 16.dp), )
)
}
} }
sshKeyItemState.privateKey?.let { privateKey -> item {
item { Spacer(modifier = Modifier.height(8.dp))
Spacer(modifier = Modifier.height(8.dp)) BitwardenPasswordField(
BitwardenPasswordField( label = stringResource(id = R.string.private_key),
label = stringResource(id = R.string.private_key), value = sshKeyItemState.privateKey,
value = privateKey, onValueChange = { },
onValueChange = { }, singleLine = false,
singleLine = false, readOnly = true,
readOnly = true, showPassword = sshKeyItemState.showPrivateKey,
showPassword = sshKeyItemState.showPrivateKey, showPasswordTestTag = "ViewPrivateKeyButton",
showPasswordTestTag = "ViewPrivateKeyButton", showPasswordChange = vaultSshKeyItemTypeHandlers.onShowPrivateKeyClick,
showPasswordChange = vaultSshKeyItemTypeHandlers.onShowPrivateKeyClick, modifier = Modifier
modifier = Modifier .testTag("SshKeyItemPrivateKeyEntry")
.testTag("SshKeyItemPrivateKeyEntry") .fillMaxWidth()
.fillMaxWidth() .padding(horizontal = 16.dp),
.padding(horizontal = 16.dp), )
)
}
} }
sshKeyItemState.fingerprint?.let { fingerprint -> item {
item { Spacer(modifier = Modifier.height(8.dp))
Spacer(modifier = Modifier.height(8.dp)) BitwardenTextField(
BitwardenTextField( label = stringResource(id = R.string.fingerprint),
label = stringResource(id = R.string.fingerprint), value = sshKeyItemState.fingerprint,
value = fingerprint, onValueChange = { },
onValueChange = { }, singleLine = false,
singleLine = false, readOnly = true,
readOnly = true, modifier = Modifier
modifier = Modifier .testTag("SshKeyItemFingerprintEntry")
.testTag("SshKeyItemFingerprintEntry") .fillMaxWidth()
.fillMaxWidth() .padding(horizontal = 16.dp),
.padding(horizontal = 16.dp), )
)
}
} }
item { item {

View file

@ -1410,9 +1410,9 @@ data class VaultItemState(
*/ */
data class SshKey( data class SshKey(
val name: String?, val name: String?,
val publicKey: String?, val publicKey: String,
val privateKey: String?, val privateKey: String,
val fingerprint: String?, val fingerprint: String,
val showPrivateKey: Boolean, val showPrivateKey: Boolean,
) : ItemType() ) : ItemType()
} }

View file

@ -995,9 +995,9 @@ data class VaultState(
override val extraIconList: List<IconRes> = emptyList(), override val extraIconList: List<IconRes> = emptyList(),
override val overflowOptions: List<ListingItemOverflowAction.VaultAction>, override val overflowOptions: List<ListingItemOverflowAction.VaultAction>,
override val shouldShowMasterPasswordReprompt: Boolean, override val shouldShowMasterPasswordReprompt: Boolean,
val publicKey: Text?, val publicKey: Text,
val privateKey: Text?, val privateKey: Text,
val fingerprint: Text?, val fingerprint: Text,
) : VaultItem() { ) : VaultItem() {
override val supportingLabel: Text? get() = null override val supportingLabel: Text? get() = null
} }

View file

@ -74,9 +74,9 @@ private fun VaultAddEditState.ViewState.Content.ItemType.toCipherType(): CipherT
private fun VaultAddEditState.ViewState.Content.ItemType.toSshKeyView(): SshKeyView? = private fun VaultAddEditState.ViewState.Content.ItemType.toSshKeyView(): SshKeyView? =
(this as? VaultAddEditState.ViewState.Content.ItemType.SshKey)?.let { (this as? VaultAddEditState.ViewState.Content.ItemType.SshKey)?.let {
SshKeyView( SshKeyView(
publicKey = it.publicKey.orNullIfBlank(), publicKey = it.publicKey,
privateKey = it.privateKey.orNullIfBlank(), privateKey = it.privateKey,
fingerprint = it.fingerprint.orNullIfBlank(), fingerprint = it.fingerprint,
) )
} }

View file

@ -276,13 +276,16 @@ private fun CipherView.toVaultItemOrNull(
name = name.asText(), name = name.asText(),
publicKey = sshKey publicKey = sshKey
?.publicKey ?.publicKey
?.asText(), .orEmpty()
.asText(),
privateKey = sshKey privateKey = sshKey
?.privateKey ?.privateKey
?.asText(), .orEmpty()
.asText(),
fingerprint = sshKey fingerprint = sshKey
?.fingerprint ?.fingerprint
?.asText(), .orEmpty()
.asText(),
overflowOptions = toOverflowActions( overflowOptions = toOverflowActions(
hasMasterPassword = hasMasterPassword, hasMasterPassword = hasMasterPassword,
isPremiumUser = isPremiumUser, isPremiumUser = isPremiumUser,

View file

@ -2151,12 +2151,6 @@ class VaultItemScreenTest : BaseComposeTest() {
val publicKey = "the public key" val publicKey = "the public key"
mutableStateFlow.update { it.copy(viewState = DEFAULT_SSH_KEY_VIEW_STATE) } mutableStateFlow.update { it.copy(viewState = DEFAULT_SSH_KEY_VIEW_STATE) }
composeTestRule.onNodeWithTextAfterScroll(publicKey).assertIsDisplayed() composeTestRule.onNodeWithTextAfterScroll(publicKey).assertIsDisplayed()
mutableStateFlow.update { currentState ->
updateSshKeyType(currentState) { copy(publicKey = null) }
}
composeTestRule.assertScrollableNodeDoesNotExist(publicKey)
} }
@Test @Test
@ -2173,12 +2167,6 @@ class VaultItemScreenTest : BaseComposeTest() {
composeTestRule composeTestRule
.onNodeWithText(privateKey) .onNodeWithText(privateKey)
.assertIsDisplayed() .assertIsDisplayed()
mutableStateFlow.update { currentState ->
updateSshKeyType(currentState) { copy(privateKey = null) }
}
composeTestRule.assertScrollableNodeDoesNotExist(privateKey)
} }
@Test @Test
@ -2205,12 +2193,6 @@ class VaultItemScreenTest : BaseComposeTest() {
val fingerprint = "the fingerprint" val fingerprint = "the fingerprint"
mutableStateFlow.update { it.copy(viewState = DEFAULT_SSH_KEY_VIEW_STATE) } mutableStateFlow.update { it.copy(viewState = DEFAULT_SSH_KEY_VIEW_STATE) }
composeTestRule.onNodeWithTextAfterScroll(fingerprint).assertIsDisplayed() composeTestRule.onNodeWithTextAfterScroll(fingerprint).assertIsDisplayed()
mutableStateFlow.update { currentState ->
updateSshKeyType(currentState) { copy(fingerprint = null) }
}
composeTestRule.assertScrollableNodeDoesNotExist(fingerprint)
} }
//endregion ssh key //endregion ssh key

View file

@ -75,9 +75,9 @@ fun createIdentityView(isEmpty: Boolean): IdentityView =
fun createSshKeyView(isEmpty: Boolean): SshKeyView = fun createSshKeyView(isEmpty: Boolean): SshKeyView =
SshKeyView( SshKeyView(
privateKey = "privateKey".takeUnless { isEmpty }, privateKey = "privateKey".takeUnless { isEmpty }.orEmpty(),
publicKey = "publicKey".takeUnless { isEmpty }, publicKey = "publicKey".takeUnless { isEmpty }.orEmpty(),
fingerprint = "fingerprint".takeUnless { isEmpty }, fingerprint = "fingerprint".takeUnless { isEmpty }.orEmpty(),
) )
fun createCipherView(type: CipherType, isEmpty: Boolean): CipherView = fun createCipherView(type: CipherType, isEmpty: Boolean): CipherView =
@ -154,7 +154,7 @@ fun createCipherView(type: CipherType, isEmpty: Boolean): CipherView =
creationDate = Instant.ofEpochSecond(1_000L), creationDate = Instant.ofEpochSecond(1_000L),
deletedDate = null, deletedDate = null,
revisionDate = Instant.ofEpochSecond(1_000L), revisionDate = Instant.ofEpochSecond(1_000L),
sshKey = createSshKeyView(isEmpty = isEmpty), sshKey = createSshKeyView(isEmpty),
) )
fun createCommonContent( fun createCommonContent(
@ -272,8 +272,8 @@ fun createIdentityContent(
fun createSshKeyContent(isEmpty: Boolean): VaultItemState.ViewState.Content.ItemType.SshKey = fun createSshKeyContent(isEmpty: Boolean): VaultItemState.ViewState.Content.ItemType.SshKey =
VaultItemState.ViewState.Content.ItemType.SshKey( VaultItemState.ViewState.Content.ItemType.SshKey(
name = "mockName".takeUnless { isEmpty }, name = "mockName".takeUnless { isEmpty },
privateKey = "privateKey".takeUnless { isEmpty }, privateKey = "privateKey".takeUnless { isEmpty }.orEmpty(),
publicKey = "publicKey".takeUnless { isEmpty }, publicKey = "publicKey".takeUnless { isEmpty }.orEmpty(),
fingerprint = "fingerprint".takeUnless { isEmpty }, fingerprint = "fingerprint".takeUnless { isEmpty }.orEmpty(),
showPrivateKey = false, showPrivateKey = false,
) )

View file

@ -906,9 +906,9 @@ class VaultDataExtensionsTest {
folderId = null, folderId = null,
sshKey = createMockSshKeyView(number = 1) sshKey = createMockSshKeyView(number = 1)
.copy( .copy(
publicKey = null, publicKey = "publicKey",
privateKey = null, privateKey = "privateKey",
fingerprint = null, fingerprint = "fingerprint",
), ),
), ),
createMockCipherView( createMockCipherView(
@ -945,16 +945,16 @@ class VaultDataExtensionsTest {
createMockSshKeyVaultItem(number = 1), createMockSshKeyVaultItem(number = 1),
createMockSshKeyVaultItem(number = 2) createMockSshKeyVaultItem(number = 2)
.copy( .copy(
publicKey = null, publicKey = "publicKey".asText(),
privateKey = null, privateKey = "privateKey".asText(),
fingerprint = null, fingerprint = "fingerprint".asText(),
shouldShowMasterPasswordReprompt = true, shouldShowMasterPasswordReprompt = true,
), ),
createMockSshKeyVaultItem(number = 3) createMockSshKeyVaultItem(number = 3)
.copy( .copy(
publicKey = null, publicKey = "".asText(),
privateKey = null, privateKey = "".asText(),
fingerprint = null, fingerprint = "".asText(),
), ),
), ),
trashItemsCount = 0, trashItemsCount = 0,

View file

@ -24,7 +24,7 @@ androidxSplash = "1.1.0-rc01"
androidXAppCompat = "1.7.0" androidXAppCompat = "1.7.0"
androdixAutofill = "1.1.0" androdixAutofill = "1.1.0"
androidxWork = "2.9.1" androidxWork = "2.9.1"
bitwardenSdk = "1.0.0-20241024.173753-4" bitwardenSdk = "1.0.0-20241030.101847-8"
crashlytics = "3.0.2" crashlytics = "3.0.2"
detekt = "1.23.7" detekt = "1.23.7"
firebaseBom = "33.5.1" firebaseBom = "33.5.1"