From b671bf0626b8e25e3fe5adcdfed4d98f66482e6f Mon Sep 17 00:00:00 2001 From: David Perez Date: Tue, 11 Jun 2024 14:26:33 -0500 Subject: [PATCH] BIT-2420: Add attachments to cipher update requests (#1443) --- .../network/model/AttachmentJsonRequest.kt | 6 +++--- .../datasource/network/model/CipherJsonRequest.kt | 3 +++ .../data/vault/manager/CipherManagerImpl.kt | 11 ++--------- .../repository/util/VaultSdkCipherExtensions.kt | 14 ++++++++++++++ .../network/model/AttachmentJsonRequestUtil.kt | 2 +- .../network/model/CipherJsonRequestUtil.kt | 7 +++++++ .../util/VaultSdkCipherExtensionsTest.kt | 12 ++++++++++++ 7 files changed, 42 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/network/model/AttachmentJsonRequest.kt b/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/network/model/AttachmentJsonRequest.kt index d5dfa5991..598879293 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/network/model/AttachmentJsonRequest.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/network/model/AttachmentJsonRequest.kt @@ -9,11 +9,11 @@ import kotlinx.serialization.Serializable @Serializable data class AttachmentJsonRequest( @SerialName("fileName") - val fileName: String, + val fileName: String?, @SerialName("key") - val key: String, + val key: String?, @SerialName("fileSize") - val fileSize: String, + val fileSize: String?, ) diff --git a/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/network/model/CipherJsonRequest.kt b/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/network/model/CipherJsonRequest.kt index 2a588303c..dc7adef69 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/network/model/CipherJsonRequest.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/vault/datasource/network/model/CipherJsonRequest.kt @@ -29,6 +29,9 @@ data class CipherJsonRequest( @SerialName("notes") val notes: String?, + @SerialName("attachments2") + val attachments: Map?, + @SerialName("reprompt") val reprompt: CipherRepromptTypeJson, diff --git a/app/src/main/java/com/x8bit/bitwarden/data/vault/manager/CipherManagerImpl.kt b/app/src/main/java/com/x8bit/bitwarden/data/vault/manager/CipherManagerImpl.kt index 1940cea87..ad82db849 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/vault/manager/CipherManagerImpl.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/vault/manager/CipherManagerImpl.kt @@ -9,7 +9,6 @@ import com.x8bit.bitwarden.data.platform.util.asFailure import com.x8bit.bitwarden.data.platform.util.asSuccess import com.x8bit.bitwarden.data.platform.util.flatMap import com.x8bit.bitwarden.data.vault.datasource.disk.VaultDiskSource -import com.x8bit.bitwarden.data.vault.datasource.network.model.AttachmentJsonRequest import com.x8bit.bitwarden.data.vault.datasource.network.model.CreateCipherInOrganizationJsonRequest import com.x8bit.bitwarden.data.vault.datasource.network.model.ShareCipherJsonRequest import com.x8bit.bitwarden.data.vault.datasource.network.model.UpdateCipherCollectionsJsonRequest @@ -28,6 +27,7 @@ import com.x8bit.bitwarden.data.vault.repository.model.UpdateCipherResult import com.x8bit.bitwarden.data.vault.repository.util.toEncryptedNetworkCipher import com.x8bit.bitwarden.data.vault.repository.util.toEncryptedNetworkCipherResponse import com.x8bit.bitwarden.data.vault.repository.util.toEncryptedSdkCipher +import com.x8bit.bitwarden.data.vault.repository.util.toNetworkAttachmentRequest import java.io.File import java.time.Clock @@ -345,14 +345,7 @@ class CipherManagerImpl( ciphersService .createAttachment( cipherId = cipherId, - body = AttachmentJsonRequest( - // We know these values are present because - // - the filename/size are passed into the function - // - the SDK call fills in the key - fileName = requireNotNull(attachment.fileName), - key = requireNotNull(attachment.key), - fileSize = requireNotNull(attachment.size), - ), + body = attachment.toNetworkAttachmentRequest(), ) .flatMap { attachmentJsonResponse -> val encryptedFile = File("${cacheFile.absolutePath}.enc") diff --git a/app/src/main/java/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkCipherExtensions.kt b/app/src/main/java/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkCipherExtensions.kt index 8304dcb5f..a1f60683e 100644 --- a/app/src/main/java/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkCipherExtensions.kt +++ b/app/src/main/java/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkCipherExtensions.kt @@ -18,6 +18,7 @@ import com.bitwarden.core.PasswordHistory import com.bitwarden.core.SecureNote import com.bitwarden.core.SecureNoteType import com.bitwarden.core.UriMatchType +import com.x8bit.bitwarden.data.vault.datasource.network.model.AttachmentJsonRequest import com.x8bit.bitwarden.data.vault.datasource.network.model.CipherJsonRequest import com.x8bit.bitwarden.data.vault.datasource.network.model.CipherRepromptTypeJson import com.x8bit.bitwarden.data.vault.datasource.network.model.CipherTypeJson @@ -37,6 +38,9 @@ import java.util.Locale fun Cipher.toEncryptedNetworkCipher(): CipherJsonRequest = CipherJsonRequest( notes = notes, + attachments = attachments + ?.filter { it.id != null } + ?.associate { requireNotNull(it.id) to it.toNetworkAttachmentRequest() }, reprompt = reprompt.toNetworkRepromptType(), passwordHistory = passwordHistory?.toEncryptedNetworkPasswordHistoryList(), lastKnownRevisionDate = ZonedDateTime.ofInstant(revisionDate, ZoneOffset.UTC), @@ -218,6 +222,16 @@ private fun Attachment.toNetworkAttachment(): SyncResponseJson.Cipher.Attachment key = key, ) +/** + * Converts a Bitwarden SDK [Attachment] object to a corresponding [AttachmentJsonRequest] object. + */ +fun Attachment.toNetworkAttachmentRequest(): AttachmentJsonRequest = + AttachmentJsonRequest( + fileName = fileName, + fileSize = size, + key = key, + ) + /** * Converts a Bitwarden SDK [Login] object to a corresponding * [SyncResponseJson.Cipher.Login] object. diff --git a/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/network/model/AttachmentJsonRequestUtil.kt b/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/network/model/AttachmentJsonRequestUtil.kt index b47a721d3..748ecdc38 100644 --- a/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/network/model/AttachmentJsonRequestUtil.kt +++ b/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/network/model/AttachmentJsonRequestUtil.kt @@ -7,5 +7,5 @@ fun createMockAttachmentJsonRequest(number: Int): AttachmentJsonRequest = AttachmentJsonRequest( fileName = "mockFileName-$number", key = "mockKey-$number", - fileSize = "1000", + fileSize = "1", ) diff --git a/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/network/model/CipherJsonRequestUtil.kt b/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/network/model/CipherJsonRequestUtil.kt index 7963fd055..789dd86c4 100644 --- a/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/network/model/CipherJsonRequestUtil.kt +++ b/app/src/test/java/com/x8bit/bitwarden/data/vault/datasource/network/model/CipherJsonRequestUtil.kt @@ -7,6 +7,13 @@ import java.time.ZonedDateTime */ fun createMockCipherJsonRequest(number: Int, hasNullUri: Boolean = false): CipherJsonRequest = CipherJsonRequest( + attachments = mapOf( + "mockId-$number" to AttachmentJsonRequest( + fileName = "mockFileName-$number", + key = "mockKey-$number", + fileSize = "1" + ), + ), organizationId = "mockOrganizationId-$number", folderId = "mockFolderId-$number", name = "mockName-$number", diff --git a/app/src/test/java/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkCipherExtensionsTest.kt b/app/src/test/java/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkCipherExtensionsTest.kt index 2abe2ce0d..2063b7c08 100644 --- a/app/src/test/java/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkCipherExtensionsTest.kt +++ b/app/src/test/java/com/x8bit/bitwarden/data/vault/repository/util/VaultSdkCipherExtensionsTest.kt @@ -9,6 +9,7 @@ import com.x8bit.bitwarden.data.vault.datasource.network.model.CipherTypeJson import com.x8bit.bitwarden.data.vault.datasource.network.model.FieldTypeJson import com.x8bit.bitwarden.data.vault.datasource.network.model.UriMatchTypeJson import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockAttachment +import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockAttachmentJsonRequest import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockCard import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockCipher import com.x8bit.bitwarden.data.vault.datasource.network.model.createMockCipherJsonRequest @@ -74,6 +75,17 @@ class VaultSdkCipherExtensionsTest { ) } + @Suppress("MaxLineLength") + @Test + fun `toNetworkAttachmentRequest should convert an Sdk Attachment to a Network Attachment Request`() { + val sdkAttachment = createMockSdkAttachment(number = 1) + val attachmentRequest = sdkAttachment.toNetworkAttachmentRequest() + assertEquals( + createMockAttachmentJsonRequest(number = 1), + attachmentRequest, + ) + } + @Test fun `toEncryptedSdkCipherList should convert list of Network Cipher to List of Sdk Cipher`() { val syncCiphers = listOf(