Simplify add-edit item conversion to CipherView (#384)

This commit is contained in:
David Perez 2023-12-13 10:08:39 -06:00 committed by Álison Fernandes
parent 3d6111cd8b
commit dede9232ec
2 changed files with 148 additions and 108 deletions

View file

@ -15,9 +15,9 @@ import com.x8bit.bitwarden.ui.platform.base.BaseViewModel
import com.x8bit.bitwarden.ui.platform.base.util.Text
import com.x8bit.bitwarden.ui.platform.base.util.asText
import com.x8bit.bitwarden.ui.platform.base.util.concat
import com.x8bit.bitwarden.ui.vault.feature.additem.util.toViewState
import com.x8bit.bitwarden.ui.vault.feature.additem.VaultAddItemAction.ItemType.SecureNotesType.TooltipClick.toCustomField
import com.x8bit.bitwarden.ui.vault.feature.additem.model.CustomFieldType
import com.x8bit.bitwarden.ui.vault.feature.additem.util.toViewState
import com.x8bit.bitwarden.ui.vault.feature.vault.util.toCipherView
import com.x8bit.bitwarden.ui.vault.model.VaultAddEditType
import com.x8bit.bitwarden.ui.vault.model.VaultLinkedFieldType
@ -826,7 +826,32 @@ data class VaultAddItemState(
abstract val masterPasswordReprompt: Boolean
/**
* The ownership email associated with the login item.
* Indicates whether this item is marked as a favorite.
*/
abstract val favorite: Boolean
/**
* Additional custom fields associated with the item.
*/
abstract val customFieldData: List<Custom>
/**
* Any additional notes or comments associated with the item.
*/
abstract val notes: String
/**
* The folder that this item belongs too.
*/
abstract val folderName: Text
/**
* The list of folders that this item could be added too.
*/
abstract val availableFolders: List<Text>
/**
* The ownership email associated with the item.
*/
abstract val ownership: String
@ -841,33 +866,29 @@ data class VaultAddItemState(
* @property username The username required for the login item.
* @property password The password required for the login item.
* @property uri The URI associated with the login item.
* @property folderName The folder used for the login item
* @property favorite Indicates whether this login item is marked as a favorite.
* @property notes Any additional notes or comments associated with the login item.
* @property availableFolders Retrieves a list of available folders.
*/
@Parcelize
data class Login(
@IgnoredOnParcel
override val originalCipher: CipherView? = null,
override val name: String = "",
val username: String = "",
val password: String = "",
val uri: String = "",
val folderName: Text = DEFAULT_FOLDER,
val favorite: Boolean = false,
override val masterPasswordReprompt: Boolean = false,
val customFieldData: List<Custom> = emptyList(),
val notes: String = "",
override val folderName: Text = DEFAULT_FOLDER,
// TODO: Update this property to get available owners from the data layer (BIT-501)
val availableFolders: List<Text> = listOf(
override val availableFolders: List<Text> = listOf(
"Folder 1".asText(),
"Folder 2".asText(),
"Folder 3".asText(),
),
override val favorite: Boolean = false,
override val masterPasswordReprompt: Boolean = false,
override val customFieldData: List<Custom> = emptyList(),
override val notes: String = "",
// TODO: Update this property to get available owners from the data layer (BIT-501)
override val ownership: String = DEFAULT_OWNERSHIP,
override val availableOwners: List<String> = listOf("a@b.com", "c@d.com"),
val username: String = "",
val password: String = "",
val uri: String = "",
) : Content() {
override val displayStringResId: Int get() = ItemTypeOption.LOGIN.labelRes
}
@ -880,7 +901,18 @@ data class VaultAddItemState(
@IgnoredOnParcel
override val originalCipher: CipherView? = null,
override val name: String = "",
override val folderName: Text = DEFAULT_FOLDER,
// TODO: Update this property to get available owners from the data layer (BIT-501)
override val availableFolders: List<Text> = listOf(
"Folder 1".asText(),
"Folder 2".asText(),
"Folder 3".asText(),
),
override val favorite: Boolean = false,
override val masterPasswordReprompt: Boolean = false,
override val customFieldData: List<Custom> = emptyList(),
override val notes: String = "",
// TODO: Update this property to get available owners from the data layer (BIT-501)
override val ownership: String = DEFAULT_OWNERSHIP,
override val availableOwners: List<String> = listOf("a@b.com", "c@d.com"),
) : Content() {
@ -895,7 +927,18 @@ data class VaultAddItemState(
@IgnoredOnParcel
override val originalCipher: CipherView? = null,
override val name: String = "",
override val folderName: Text = DEFAULT_FOLDER,
// TODO: Update this property to get available owners from the data layer (BIT-501)
override val availableFolders: List<Text> = listOf(
"Folder 1".asText(),
"Folder 2".asText(),
"Folder 3".asText(),
),
override val favorite: Boolean = false,
override val masterPasswordReprompt: Boolean = false,
override val customFieldData: List<Custom> = emptyList(),
override val notes: String = "",
// TODO: Update this property to get available owners from the data layer (BIT-501)
override val ownership: String = DEFAULT_OWNERSHIP,
override val availableOwners: List<String> = listOf("a@b.com", "c@d.com"),
) : Content() {
@ -906,8 +949,6 @@ data class VaultAddItemState(
* Represents the `SecureNotes` item type.
*
* @property folderName The folder used for the SecureNotes item
* @property favorite Indicates whether this SecureNotes item is marked as a favorite.
* @property notes Notes or comments associated with the SecureNotes item.
* @property availableFolders A list of available folders.
*/
@Parcelize
@ -915,16 +956,18 @@ data class VaultAddItemState(
@IgnoredOnParcel
override val originalCipher: CipherView? = null,
override val name: String = "",
val folderName: Text = DEFAULT_FOLDER,
val favorite: Boolean = false,
override val masterPasswordReprompt: Boolean = false,
val notes: String = "",
val availableFolders: List<Text> = listOf(
override val folderName: Text = DEFAULT_FOLDER,
// TODO: Update this property to get available owners from the data layer (BIT-501)
override val availableFolders: List<Text> = listOf(
"Folder 1".asText(),
"Folder 2".asText(),
"Folder 3".asText(),
),
val customFieldData: List<Custom> = emptyList(),
override val favorite: Boolean = false,
override val masterPasswordReprompt: Boolean = false,
override val customFieldData: List<Custom> = emptyList(),
override val notes: String = "",
// TODO: Update this property to get available owners from the data layer (BIT-501)
override val ownership: String = DEFAULT_OWNERSHIP,
override val availableOwners: List<String> = listOf("a@b.com", "c@d.com"),
) : Content() {

View file

@ -1,10 +1,12 @@
package com.x8bit.bitwarden.ui.vault.feature.vault.util
import com.bitwarden.core.CardView
import com.bitwarden.core.CipherRepromptType
import com.bitwarden.core.CipherType
import com.bitwarden.core.CipherView
import com.bitwarden.core.FieldType
import com.bitwarden.core.FieldView
import com.bitwarden.core.IdentityView
import com.bitwarden.core.LoginUriView
import com.bitwarden.core.LoginView
import com.bitwarden.core.SecureNoteType
@ -89,17 +91,6 @@ fun VaultData.toViewState(): VaultState.ViewState =
* Transforms a [VaultAddItemState.ViewState.Content] into [CipherView].
*/
fun VaultAddItemState.ViewState.Content.toCipherView(): CipherView =
when (this) {
is VaultAddItemState.ViewState.Content.Card -> toCardCipherView()
is VaultAddItemState.ViewState.Content.Identity -> toIdentityCipherView()
is VaultAddItemState.ViewState.Content.Login -> toLoginCipherView()
is VaultAddItemState.ViewState.Content.SecureNotes -> toSecureNotesCipherView()
}
/**
* Transforms [VaultAddItemState.ViewState.Content.Login] into [CipherView].
*/
private fun VaultAddItemState.ViewState.Content.Login.toLoginCipherView(): CipherView =
CipherView(
// Pulled from original cipher when editing, otherwise uses defaults
id = this.originalCipher?.id,
@ -116,88 +107,94 @@ private fun VaultAddItemState.ViewState.Content.Login.toLoginCipherView(): Ciphe
revisionDate = this.originalCipher?.revisionDate ?: Instant.now(),
// Type specific section
type = CipherType.LOGIN,
login = LoginView(
username = this.username,
password = this.password,
passwordRevisionDate = this.originalCipher?.login?.passwordRevisionDate,
type = this.toCipherType(),
identity = this.toIdentityView(),
secureNote = this.toSecureNotesView(),
login = this.toLoginView(),
card = this.toCardView(),
// Fields we always grab from the UI
name = this.name,
notes = this.notes,
favorite = this.favorite,
// TODO Use real folder ID (BIT-528)
folderId = this.originalCipher?.folderId,
// TODO Use real organization ID (BIT-780)
organizationId = this.originalCipher?.organizationId,
reprompt = this.toCipherRepromptType(),
fields = this.customFieldData.map { it.toFieldView() },
)
private fun VaultAddItemState.ViewState.Content.toCipherType(): CipherType =
when (this) {
is VaultAddItemState.ViewState.Content.Card -> CipherType.CARD
is VaultAddItemState.ViewState.Content.Identity -> CipherType.IDENTITY
is VaultAddItemState.ViewState.Content.Login -> CipherType.LOGIN
is VaultAddItemState.ViewState.Content.SecureNotes -> CipherType.SECURE_NOTE
}
private fun VaultAddItemState.ViewState.Content.toCardView(): CardView? =
(this as? VaultAddItemState.ViewState.Content.Card)?.let {
// TODO Create real CardView from Content (BIT-668)
CardView(
cardholderName = null,
expMonth = null,
expYear = null,
code = null,
brand = null,
number = null,
)
}
private fun VaultAddItemState.ViewState.Content.toIdentityView(): IdentityView? =
(this as? VaultAddItemState.ViewState.Content.Identity)?.let {
// TODO Create real IdentityView from Content (BIT-508)
IdentityView(
title = null,
firstName = null,
lastName = null,
middleName = null,
address1 = null,
address2 = null,
address3 = null,
city = null,
state = null,
postalCode = null,
country = null,
company = null,
email = null,
phone = null,
ssn = null,
username = null,
passportNumber = null,
licenseNumber = null,
)
}
private fun VaultAddItemState.ViewState.Content.toLoginView(): LoginView? =
(this as? VaultAddItemState.ViewState.Content.Login)?.let {
LoginView(
username = it.username,
password = it.password,
passwordRevisionDate = it.originalCipher?.login?.passwordRevisionDate,
uris = listOf(
// TODO Implement URI list (BIT-1094)
LoginUriView(
uri = this.uri,
uri = it.uri,
// TODO Implement URI settings in (BIT-1094)
match = UriMatchType.DOMAIN,
),
),
// TODO implement totp in BIT-1066
totp = this.originalCipher?.login?.totp,
autofillOnPageLoad = this.originalCipher?.login?.autofillOnPageLoad,
),
identity = null,
card = null,
secureNote = null,
// TODO Implement TOTP (BIT-1066)
totp = it.originalCipher?.login?.totp,
autofillOnPageLoad = it.originalCipher?.login?.autofillOnPageLoad,
)
}
// Fields we always grab from the UI
name = this.name,
notes = this.notes,
favorite = this.favorite,
// TODO Use real folder ID (BIT-528)
folderId = this.originalCipher?.folderId,
// TODO Use real organization ID (BIT-780)
organizationId = this.originalCipher?.organizationId,
reprompt = this.toCipherRepromptType(),
fields = this.customFieldData.map { it.toFieldView() },
)
/**
* Transforms [VaultAddItemState.ViewState.Content.SecureNotes] into [CipherView].
*/
private fun VaultAddItemState.ViewState.Content.SecureNotes.toSecureNotesCipherView(): CipherView =
CipherView(
// Pulled from original cipher when editing, otherwise uses defaults
id = this.originalCipher?.id,
collectionIds = this.originalCipher?.collectionIds.orEmpty(),
key = this.originalCipher?.key,
edit = this.originalCipher?.edit ?: true,
viewPassword = this.originalCipher?.viewPassword ?: true,
localData = this.originalCipher?.localData,
attachments = this.originalCipher?.attachments,
organizationUseTotp = this.originalCipher?.organizationUseTotp ?: false,
passwordHistory = this.originalCipher?.passwordHistory,
creationDate = this.originalCipher?.creationDate ?: Instant.now(),
deletedDate = this.originalCipher?.deletedDate,
revisionDate = this.originalCipher?.revisionDate ?: Instant.now(),
// Type specific section
type = CipherType.SECURE_NOTE,
secureNote = SecureNoteView(type = SecureNoteType.GENERIC),
login = null,
identity = null,
card = null,
// Fields we always grab from the UI
name = this.name,
notes = this.notes,
favorite = this.favorite,
// TODO Use real folder ID (BIT-528)
folderId = this.originalCipher?.folderId,
// TODO Use real organization ID (BIT-780)
organizationId = this.originalCipher?.organizationId,
reprompt = this.toCipherRepromptType(),
fields = this.customFieldData.map { it.toFieldView() },
)
/**
* Transforms [VaultAddItemState.ViewState.Content.Identity] into [CipherView].
*/
private fun VaultAddItemState.ViewState.Content.Identity.toIdentityCipherView(): CipherView =
TODO("create Identity CipherView BIT-508")
/**
* Transforms [VaultAddItemState.ViewState.Content.Card] into [CipherView].
*/
private fun VaultAddItemState.ViewState.Content.Card.toCardCipherView(): CipherView =
TODO("create Card CipherView BIT-668")
private fun VaultAddItemState.ViewState.Content.toSecureNotesView(): SecureNoteView? =
(this as? VaultAddItemState.ViewState.Content.SecureNotes)?.let {
SecureNoteView(type = SecureNoteType.GENERIC)
}
private fun VaultAddItemState.ViewState.Content.toCipherRepromptType(): CipherRepromptType =
if (this.masterPasswordReprompt) {